From 14b0079842d92768d83016772cd19f3fda69529c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Chris=20Suszy=C5=84ski?= Date: Thu, 9 Dec 2021 17:19:36 +0100 Subject: [PATCH 1/3] Allow overriding of build.sh for downstream projects --- hack/build-flags.sh | 13 +++++++++---- hack/build.sh | 25 ++++++++++++++++--------- hack/build.sh.d/README.md | 4 ++++ 3 files changed, 29 insertions(+), 13 deletions(-) create mode 100644 hack/build.sh.d/README.md diff --git a/hack/build-flags.sh b/hack/build-flags.sh index e77ffb2598..4e66e8530c 100644 --- a/hack/build-flags.sh +++ b/hack/build-flags.sh @@ -14,17 +14,22 @@ function build_flags() { local base="${1}" - local now="$(date -u '+%Y-%m-%d %H:%M:%S')" - local rev="$(git rev-parse --short HEAD)" + local now rev + now="$(date -u '+%Y-%m-%d %H:%M:%S')" + rev="$(git rev-parse --short HEAD)" local pkg="knative.dev/client/pkg/kn/commands/version" local version="${TAG:-}" # Use vYYYYMMDD-local- for the version string, if not passed. if [[ -z "${version}" ]]; then # Get the commit, excluding any tags but keeping the "dirty" flag - local commit="$(git describe --always --dirty --match '^$')" + local commit + commit="$(git describe --always --dirty --match '^$')" [[ -n "${commit}" ]] || abort "error getting the current commit" version="v$(date +%Y%m%d)-local-${commit}" fi - echo "-X '${pkg}.BuildDate=${now}' -X ${pkg}.Version=${version} -X ${pkg}.GitRevision=${rev}" + echo "-X '${pkg}.BuildDate=${now}' \ + -X ${pkg}.Version=${version} \ + -X ${pkg}.GitRevision=${rev}\ + ${EXTERNAL_LD_FLAGS:-}" } diff --git a/hack/build.sh b/hack/build.sh index 76817d0eed..9369c109d2 100755 --- a/hack/build.sh +++ b/hack/build.sh @@ -128,7 +128,7 @@ source_lint() { go_build() { echo "🚧 Compile" - go build -mod=vendor -ldflags "$(build_flags $(basedir))" -o kn ./cmd/... + go build -mod=vendor -ldflags "$(build_flags "$(basedir)")" -o kn ./cmd/... if $(file kn | grep -q -i "Windows"); then mv kn kn.exe @@ -136,7 +136,8 @@ go_build() { } go_test() { - local test_output=$(mktemp /tmp/kn-client-test-output.XXXXXX) + local test_output + test_output="$(mktemp /tmp/kn-client-test-output.XXXXXX)" local red="" local reset="" @@ -164,7 +165,8 @@ check_license() { local required_keywords=("Authors" "Apache License" "LICENSE-2.0") local extensions_to_check=("sh" "go" "yaml" "yml" "json") - local check_output=$(mktemp /tmp/kn-client-licence-check.XXXXXX) + local check_output + check_output="$(mktemp /tmp/kn-client-licence-check.XXXXXX)" for ext in "${extensions_to_check[@]}"; do find . -name "*.$ext" -a \! -path "./vendor/*" -a \! -path "./.*" -a \! -path "./third_party/*" -print0 | while IFS= read -r -d '' path; do @@ -242,9 +244,10 @@ basedir() { fi fi - local dir=$(dirname "$script") - local full_dir=$(cd "${dir}/.." && pwd) - echo ${full_dir} + local dir full_dir + dir=$(dirname "$script") + full_dir=$(cd "${dir}/.." && pwd) + echo "${full_dir}" } # Checks if a flag is present in the arguments. @@ -262,8 +265,9 @@ has_flag() { } cross_build() { - local basedir=$(basedir) - local ld_flags="$(build_flags $basedir)" + local basedir ld_flags + basedir=$(basedir) + ld_flags="$(build_flags $basedir)" local failed=0 echo "⚔️ ${S}Compile" @@ -353,9 +357,12 @@ fi source $(basedir)/vendor/knative.dev/hack/library.sh # Shared funcs with CI +while IFS= read -r -d '' file; do + source "${file}" +done < <(find "$(basedir)/hack/build.sh.d" -name '*.sh' -print0) source $(basedir)/hack/build-flags.sh # Fixe emoji labels for certain terminals apply_emoji_fixes -run $* +run "$@" diff --git a/hack/build.sh.d/README.md b/hack/build.sh.d/README.md new file mode 100644 index 0000000000..de123ab660 --- /dev/null +++ b/hack/build.sh.d/README.md @@ -0,0 +1,4 @@ +# Extending build.sh directory + +This directory contains shell scripts named `*.sh`, that can be sourced by +build script, and can be used to extend or override the build script. From c12a435b07c084f05c07a2c4978b152e6d998f66 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Chris=20Suszy=C5=84ski?= Date: Thu, 9 Dec 2021 22:23:30 +0100 Subject: [PATCH 2/3] Embed kn-plugin-event --- go.mod | 15 +- go.sum | 204 +- pkg/kn/root/plugin_register.go | 1 + .../{willf => bits-and-blooms}/bitset/LICENSE | 0 .../coreos/go-semver/semver/LICENSE | 202 ++ .../github.com/coreos/go-semver/semver/NOTICE | 5 + .../github.com/ghodss/yaml/LICENSE | 50 + .../github.com/klauspost/compress/LICENSE | 276 ++ .../compress/internal/snapref/LICENSE | 27 + .../github.com/moby/spdystream/LICENSE | 202 ++ .../github.com/moby/spdystream/NOTICE | 5 + .../github.com/thediveo/enumflag/LICENSE | 176 + .../vbatts/tar-split/archive/tar/LICENSE | 28 + .../github.com/wavesoftware/go-ensure/LICENSE | 201 ++ .../google.golang.org/grpc/NOTICE.txt | 13 + .../knative.dev/kn-plugin-event/LICENSE | 202 ++ .../go/compute/metadata/metadata.go | 23 +- .../go/compute/metadata/retry.go | 114 + .../go/compute/metadata/retry_linux.go | 26 + .../github.com/Microsoft/go-winio/README.md | 27 +- .../hcsshim/osversion/osversion_windows.go | 28 +- .../bitset/.gitignore | 0 .../bitset/.travis.yml | 0 .../{willf => bits-and-blooms}/bitset/LICENSE | 0 .../bitset/README.md | 11 +- .../bitset/azure-pipelines.yml | 0 .../bitset/bitset.go | 23 +- .../github.com/bits-and-blooms/bitset/go.mod | 3 + .../{willf => bits-and-blooms}/bitset/go.sum | 0 .../bitset/popcnt.go | 0 .../bitset/popcnt_19.go | 0 .../bitset/popcnt_amd64.go | 0 .../bitset/popcnt_amd64.s | 0 .../bitset/popcnt_generic.go | 0 .../bitset/trailing_zeros_18.go | 0 .../bitset/trailing_zeros_19.go | 0 .../stargz-snapshotter/estargz/build.go | 61 +- .../stargz-snapshotter/estargz/estargz.go | 553 ++- .../stargz-snapshotter/estargz/go.mod | 3 +- .../stargz-snapshotter/estargz/go.sum | 20 +- .../stargz-snapshotter/estargz/gzip.go | 216 ++ .../stargz-snapshotter/estargz/testutil.go | 2009 +++++++++++ .../stargz-snapshotter/estargz/types.go | 56 +- vendor/github.com/coreos/go-semver/LICENSE | 202 ++ vendor/github.com/coreos/go-semver/NOTICE | 5 + .../coreos/go-semver/semver/semver.go | 296 ++ .../coreos/go-semver/semver/sort.go | 38 + .../cpuguy83/go-md2man/v2/md2man/roff.go | 105 +- .../github.com/evanphx/json-patch/v5/patch.go | 46 +- vendor/github.com/fsnotify/fsnotify/.mailmap | 2 + .../github.com/fsnotify/fsnotify/.travis.yml | 36 - vendor/github.com/fsnotify/fsnotify/AUTHORS | 16 +- .../github.com/fsnotify/fsnotify/CHANGELOG.md | 116 +- vendor/github.com/fsnotify/fsnotify/README.md | 6 +- vendor/github.com/fsnotify/fsnotify/fen.go | 1 + .../github.com/fsnotify/fsnotify/fsnotify.go | 1 + vendor/github.com/fsnotify/fsnotify/go.mod | 4 +- vendor/github.com/fsnotify/fsnotify/go.sum | 4 +- .../github.com/fsnotify/fsnotify/inotify.go | 3 +- .../fsnotify/fsnotify/inotify_poller.go | 1 + vendor/github.com/fsnotify/fsnotify/kqueue.go | 1 + .../fsnotify/fsnotify/open_mode_bsd.go | 1 + .../fsnotify/fsnotify/open_mode_darwin.go | 1 + .../github.com/fsnotify/fsnotify/windows.go | 1 + vendor/github.com/ghodss/yaml/.gitignore | 20 + vendor/github.com/ghodss/yaml/.travis.yml | 7 + vendor/github.com/ghodss/yaml/LICENSE | 50 + vendor/github.com/ghodss/yaml/README.md | 121 + vendor/github.com/ghodss/yaml/fields.go | 501 +++ vendor/github.com/ghodss/yaml/yaml.go | 277 ++ vendor/github.com/go-logr/logr/.golangci.yaml | 29 + vendor/github.com/go-logr/logr/CHANGELOG.md | 6 + .../github.com/go-logr/logr/CONTRIBUTING.md | 17 + vendor/github.com/go-logr/logr/README.md | 209 +- vendor/github.com/go-logr/logr/discard.go | 35 +- vendor/github.com/go-logr/logr/go.mod | 2 +- vendor/github.com/go-logr/logr/logr.go | 528 ++- .../klauspost/compress/.gitattributes | 2 + .../github.com/klauspost/compress/.gitignore | 25 + .../klauspost/compress/.goreleaser.yml | 137 + vendor/github.com/klauspost/compress/LICENSE | 276 ++ .../github.com/klauspost/compress/README.md | 438 +++ .../klauspost/compress/compressible.go | 85 + vendor/github.com/klauspost/compress/gen.sh | 4 + vendor/github.com/klauspost/compress/go.mod | 3 + vendor/github.com/klauspost/compress/go.sum | 0 .../klauspost/compress/huff0/compress.go | 64 + .../klauspost/compress/huff0/decompress.go | 275 +- .../klauspost/compress/huff0/huff0.go | 62 + .../compress/internal/snapref/LICENSE | 27 + .../compress/internal/snapref/decode.go | 264 ++ .../compress/internal/snapref/decode_other.go | 113 + .../compress/internal/snapref/encode.go | 289 ++ .../compress/internal/snapref/encode_other.go | 236 ++ .../compress/internal/snapref/snappy.go | 98 + vendor/github.com/klauspost/compress/s2sx.mod | 4 + vendor/github.com/klauspost/compress/s2sx.sum | 0 .../klauspost/compress/zstd/README.md | 32 +- .../klauspost/compress/zstd/blockdec.go | 4 +- .../klauspost/compress/zstd/decoder.go | 5 +- .../compress/zstd/decoder_options.go | 25 +- .../klauspost/compress/zstd/enc_base.go | 4 +- .../klauspost/compress/zstd/enc_best.go | 161 +- .../klauspost/compress/zstd/enc_better.go | 64 +- .../klauspost/compress/zstd/enc_dfast.go | 61 +- .../klauspost/compress/zstd/enc_fast.go | 37 +- .../klauspost/compress/zstd/encoder.go | 31 +- .../compress/zstd/encoder_options.go | 2 +- .../klauspost/compress/zstd/framedec.go | 32 +- .../klauspost/compress/zstd/hash.go | 60 +- .../compress/zstd/internal/xxhash/xxhash.go | 1 - .../zstd/internal/xxhash/xxhash_amd64.go | 7 +- .../zstd/internal/xxhash/xxhash_amd64.s | 66 +- .../zstd/internal/xxhash/xxhash_other.go | 1 + .../klauspost/compress/zstd/snappy.go | 2 +- .../github.com/klauspost/compress/zstd/zip.go | 9 +- .../github.com/mattn/go-colorable/.travis.yml | 15 - .../github.com/mattn/go-colorable/README.md | 2 +- .../mattn/go-colorable/colorable_appengine.go | 1 + .../mattn/go-colorable/colorable_others.go | 4 +- .../mattn/go-colorable/colorable_windows.go | 14 +- vendor/github.com/mattn/go-colorable/go.mod | 4 +- vendor/github.com/mattn/go-colorable/go.sum | 10 +- .../mattn/go-colorable/noncolorable.go | 10 +- vendor/github.com/mattn/go-isatty/.travis.yml | 14 - vendor/github.com/mattn/go-isatty/go.mod | 2 +- .../github.com/mattn/go-isatty/isatty_bsd.go | 1 + .../mattn/go-isatty/isatty_others.go | 1 + .../mattn/go-isatty/isatty_plan9.go | 1 + .../mattn/go-isatty/isatty_solaris.go | 4 +- .../mattn/go-isatty/isatty_tcgets.go | 1 + .../mattn/go-isatty/isatty_windows.go | 6 +- .../mitchellh/mapstructure/CHANGELOG.md | 10 +- .../mitchellh/mapstructure/decode_hooks.go | 3 +- .../mitchellh/mapstructure/mapstructure.go | 13 +- .../moby/spdystream/CONTRIBUTING.md | 13 + vendor/github.com/moby/spdystream/LICENSE | 202 ++ vendor/github.com/moby/spdystream/MAINTAINERS | 40 + vendor/github.com/moby/spdystream/NOTICE | 5 + vendor/github.com/moby/spdystream/README.md | 77 + .../github.com/moby/spdystream/connection.go | 972 +++++ vendor/github.com/moby/spdystream/go.mod | 5 + vendor/github.com/moby/spdystream/go.sum | 2 + vendor/github.com/moby/spdystream/handlers.go | 52 + vendor/github.com/moby/spdystream/priority.go | 114 + .../moby/spdystream/spdy/dictionary.go | 203 ++ .../github.com/moby/spdystream/spdy/read.go | 364 ++ .../github.com/moby/spdystream/spdy/types.go | 291 ++ .../github.com/moby/spdystream/spdy/write.go | 334 ++ vendor/github.com/moby/spdystream/stream.go | 343 ++ vendor/github.com/moby/spdystream/utils.go | 32 + .../image-spec/specs-go/v1/annotations.go | 6 + .../image-spec/specs-go/v1/config.go | 11 + .../runc/libcontainer/user/MAINTAINERS | 2 - .../runc/libcontainer/user/lookup.go | 41 - .../runc/libcontainer/user/lookup_unix.go | 20 +- .../runc/libcontainer/user/lookup_windows.go | 40 - .../runc/libcontainer/user/user.go | 152 +- .../runc/libcontainer/user/user_fuzzer.go | 42 + .../runtime-spec/specs-go/config.go | 13 +- .../runtime-spec/specs-go/state.go | 29 +- .../opencontainers/selinux/go-selinux/doc.go | 4 - .../selinux/go-selinux/label/label_linux.go | 5 +- .../selinux/go-selinux/selinux.go | 10 +- .../selinux/go-selinux/selinux_linux.go | 13 +- .../selinux/go-selinux/selinux_stub.go | 2 + vendor/github.com/spf13/cast/.travis.yml | 16 - vendor/github.com/spf13/cast/README.md | 2 +- vendor/github.com/spf13/cast/cast.go | 5 + vendor/github.com/spf13/cast/caste.go | 148 +- .../spf13/cast/timeformattype_string.go | 27 + vendor/github.com/spf13/viper/README.md | 91 +- vendor/github.com/spf13/viper/go.mod | 13 +- vendor/github.com/spf13/viper/go.sum | 200 +- .../spf13/viper/internal/encoding/decoder.go | 61 + .../spf13/viper/internal/encoding/encoder.go | 60 + .../spf13/viper/internal/encoding/error.go | 7 + .../viper/internal/encoding/hcl/codec.go | 40 + .../viper/internal/encoding/json/codec.go | 17 + .../viper/internal/encoding/toml/codec.go | 45 + .../viper/internal/encoding/yaml/codec.go | 14 + vendor/github.com/spf13/viper/util.go | 14 +- vendor/github.com/spf13/viper/viper.go | 131 +- vendor/github.com/thediveo/enumflag/LICENSE | 176 + vendor/github.com/thediveo/enumflag/README.md | 166 + vendor/github.com/thediveo/enumflag/doc.go | 16 + .../thediveo/enumflag/enumflag.code-workspace | 7 + .../github.com/thediveo/enumflag/enumflag.go | 196 ++ .../github.com/thediveo/enumflag/enumslice.go | 94 + vendor/github.com/thediveo/enumflag/go.mod | 9 + vendor/github.com/thediveo/enumflag/go.sum | 148 + vendor/github.com/vbatts/tar-split/LICENSE | 28 + .../vbatts/tar-split/archive/tar/common.go | 723 ++++ .../vbatts/tar-split/archive/tar/format.go | 303 ++ .../vbatts/tar-split/archive/tar/reader.go | 923 +++++ .../tar-split/archive/tar/stat_actime1.go | 20 + .../tar-split/archive/tar/stat_actime2.go | 20 + .../vbatts/tar-split/archive/tar/stat_unix.go | 96 + .../vbatts/tar-split/archive/tar/strconv.go | 326 ++ .../vbatts/tar-split/archive/tar/writer.go | 653 ++++ .../wavesoftware/go-ensure/.editorconfig | 15 + .../wavesoftware/go-ensure/.gitignore | 17 + .../wavesoftware/go-ensure/.travis.yml | 15 + .../github.com/wavesoftware/go-ensure/LICENSE | 201 ++ .../wavesoftware/go-ensure/Makefile | 32 + .../wavesoftware/go-ensure/README.md | 55 + .../wavesoftware/go-ensure/errors.go | 33 + .../github.com/wavesoftware/go-ensure/go.mod | 5 + .../github.com/wavesoftware/go-ensure/go.sum | 2 + .../wavesoftware/go-ensure/revive.toml | 35 + vendor/github.com/willf/bitset/go.mod | 3 - vendor/go.uber.org/zap/CHANGELOG.md | 12 + vendor/go.uber.org/zap/go.mod | 2 +- vendor/go.uber.org/zap/go.sum | 29 +- .../go.uber.org/zap/zapcore/json_encoder.go | 12 +- .../x/net/http2/client_conn_pool.go | 33 +- .../golang.org/x/net/http2/hpack/huffman.go | 38 +- vendor/golang.org/x/net/http2/pipe.go | 11 + vendor/golang.org/x/net/http2/transport.go | 1200 +++---- vendor/golang.org/x/oauth2/google/google.go | 2 + .../externalaccount/basecredentials.go | 30 +- vendor/golang.org/x/sys/unix/mkerrors.sh | 7 +- .../golang.org/x/sys/unix/sockcmsg_linux.go | 53 + .../golang.org/x/sys/unix/syscall_darwin.go | 31 + vendor/golang.org/x/sys/unix/sysvshm_unix.go | 4 +- .../x/sys/unix/sysvshm_unix_other.go | 4 +- .../x/sys/unix/zerrors_darwin_amd64.go | 3126 +++++++++-------- .../x/sys/unix/zerrors_darwin_arm64.go | 3126 +++++++++-------- .../x/sys/unix/zsyscall_darwin_arm64.go | 59 + .../x/sys/unix/zsyscall_darwin_arm64.s | 24 + .../x/sys/unix/ztypes_darwin_amd64.go | 91 + .../x/sys/unix/ztypes_darwin_arm64.go | 127 + vendor/golang.org/x/sys/windows/aliases.go | 4 +- vendor/golang.org/x/sys/windows/eventlog.go | 1 + .../x/sys/windows/memory_windows.go | 11 + vendor/golang.org/x/sys/windows/mksyscall.go | 1 + vendor/golang.org/x/sys/windows/race.go | 1 + vendor/golang.org/x/sys/windows/race0.go | 1 + vendor/golang.org/x/sys/windows/service.go | 2 + vendor/golang.org/x/sys/windows/str.go | 1 + vendor/golang.org/x/sys/windows/syscall.go | 1 + .../x/sys/windows/syscall_windows.go | 15 + .../golang.org/x/sys/windows/types_windows.go | 337 +- .../x/sys/windows/zsyscall_windows.go | 152 + .../googleapis/api/httpbody/httpbody.pb.go | 10 +- vendor/google.golang.org/grpc/MAINTAINERS.md | 5 +- vendor/google.golang.org/grpc/Makefile | 2 - vendor/google.golang.org/grpc/NOTICE.txt | 13 + .../grpc/balancer/balancer.go | 68 +- .../grpc/balancer/base/balancer.go | 15 +- .../grpc/balancer/roundrobin/roundrobin.go | 4 +- .../grpc/balancer_conn_wrappers.go | 53 +- vendor/google.golang.org/grpc/clientconn.go | 312 +- .../grpc/connectivity/connectivity.go | 35 +- .../grpc/credentials/go12.go | 30 - .../google.golang.org/grpc/credentials/tls.go | 3 + vendor/google.golang.org/grpc/go.mod | 6 +- vendor/google.golang.org/grpc/go.sum | 22 +- vendor/google.golang.org/grpc/install_gae.sh | 6 - .../grpc/internal/channelz/funcs.go | 2 +- .../grpc/internal/channelz/types_linux.go | 2 - .../grpc/internal/channelz/types_nonlinux.go | 5 +- .../grpc/internal/channelz/util_linux.go | 2 - .../grpc/internal/channelz/util_nonlinux.go | 3 +- .../grpc/internal/credentials/spiffe.go | 2 - .../internal/credentials/spiffe_appengine.go | 31 - .../grpc/internal/credentials/syscallconn.go | 2 - .../credentials/syscallconn_appengine.go | 30 - .../grpc/internal/credentials/util.go | 4 +- .../grpc/internal/envconfig/envconfig.go | 6 +- .../grpc/internal/resolver/config_selector.go | 7 +- .../internal/resolver/dns/dns_resolver.go | 9 +- .../grpc/internal/resolver/dns/go113.go | 33 - .../internal/serviceconfig/serviceconfig.go | 4 +- .../grpc/internal/syscall/syscall_linux.go | 2 - .../grpc/internal/syscall/syscall_nonlinux.go | 21 +- .../grpc/internal/transport/http2_client.go | 42 +- .../grpc/internal/transport/http2_server.go | 36 +- .../grpc/internal/transport/transport.go | 4 +- .../grpc/internal/xds/env/env.go | 95 + vendor/google.golang.org/grpc/pickfirst.go | 21 +- vendor/google.golang.org/grpc/server.go | 50 +- vendor/google.golang.org/grpc/stats/stats.go | 7 +- vendor/google.golang.org/grpc/stream.go | 131 +- vendor/google.golang.org/grpc/version.go | 2 +- vendor/google.golang.org/grpc/vet.sh | 4 - vendor/gopkg.in/ini.v1/.golangci.yml | 21 + vendor/gopkg.in/ini.v1/codecov.yml | 2 +- vendor/gopkg.in/ini.v1/ini.go | 4 +- vendor/gopkg.in/ini.v1/key.go | 17 +- vendor/gopkg.in/ini.v1/parser.go | 12 +- vendor/gopkg.in/ini.v1/section.go | 2 +- .../apimachinery/pkg/util/httpstream/doc.go | 19 + .../pkg/util/httpstream/httpstream.go | 157 + .../pkg/util/httpstream/spdy/connection.go | 187 + .../pkg/util/httpstream/spdy/roundtripper.go | 369 ++ .../pkg/util/httpstream/spdy/upgrade.go | 120 + .../k8s.io/apimachinery/pkg/util/rand/rand.go | 127 + .../pkg/util/remotecommand/constants.go | 53 + .../third_party/forked/golang/netutil/addr.go | 27 + .../client-go/tools/remotecommand/doc.go | 20 + .../tools/remotecommand/errorstream.go | 55 + .../client-go/tools/remotecommand/reader.go | 41 + .../tools/remotecommand/remotecommand.go | 142 + .../client-go/tools/remotecommand/resize.go | 33 + .../client-go/tools/remotecommand/v1.go | 160 + .../client-go/tools/remotecommand/v2.go | 200 ++ .../client-go/tools/remotecommand/v3.go | 111 + .../client-go/tools/remotecommand/v4.go | 119 + .../k8s.io/client-go/transport/spdy/spdy.go | 105 + vendor/k8s.io/client-go/util/exec/exec.go | 52 + vendor/k8s.io/klog/v2/go.mod | 2 +- vendor/k8s.io/klog/v2/go.sum | 4 +- vendor/k8s.io/klog/v2/klog.go | 115 +- vendor/knative.dev/kn-plugin-event/LICENSE | 202 ++ .../kn-plugin-event/internal/cli/cmd/build.go | 51 + .../internal/cli/cmd/builder.go | 36 + .../kn-plugin-event/internal/cli/cmd/root.go | 124 + .../kn-plugin-event/internal/cli/cmd/send.go | 95 + .../internal/cli/cmd/testing.go | 46 + .../kn-plugin-event/internal/cli/cmd/types.go | 7 + .../internal/cli/cmd/version.go | 64 + .../kn-plugin-event/pkg/cli/create.go | 169 + .../kn-plugin-event/pkg/cli/ics/constants.go | 5 + .../kn-plugin-event/pkg/cli/ics/encoding.go | 58 + .../kn-plugin-event/pkg/cli/ics/send.go | 59 + .../kn-plugin-event/pkg/cli/ics/types.go | 33 + .../kn-plugin-event/pkg/cli/options.go | 114 + .../pkg/cli/retcode/retcode.go | 11 + .../kn-plugin-event/pkg/cli/send.go | 37 + .../kn-plugin-event/pkg/cli/target.go | 114 + .../kn-plugin-event/pkg/cli/types.go | 56 + .../kn-plugin-event/pkg/cli/version.go | 9 + .../kn-plugin-event/pkg/configuration/cli.go | 11 + .../pkg/configuration/defaults.go | 22 + .../kn-plugin-event/pkg/configuration/ics.go | 11 + .../pkg/configuration/memoized.go | 29 + .../kn-plugin-event/pkg/event/constants.go | 27 + .../kn-plugin-event/pkg/event/create.go | 81 + .../kn-plugin-event/pkg/event/sender.go | 41 + .../kn-plugin-event/pkg/event/types.go | 92 + .../pkg/k8s/addressresolver.go | 141 + .../kn-plugin-event/pkg/k8s/errors.go | 23 + .../kn-plugin-event/pkg/k8s/jobrunner.go | 143 + .../kn-plugin-event/pkg/k8s/kubeclient.go | 141 + .../kn-plugin-event/pkg/metadata/image.go | 32 + .../kn-plugin-event/pkg/metadata/names.go | 13 + .../kn-plugin-event/pkg/metadata/reflect.go | 18 + .../kn-plugin-event/pkg/metadata/version.go | 9 + .../kn-plugin-event/pkg/plugin/plugin.go | 46 + .../kn-plugin-event/pkg/plugin/testing.go | 35 + .../kn-plugin-event/pkg/sender/create.go | 38 + .../kn-plugin-event/pkg/sender/direct.go | 30 + .../kn-plugin-event/pkg/sender/in_cluster.go | 74 + .../kn-plugin-event/pkg/sender/namespace.go | 13 + .../kn-plugin-event/pkg/sender/types.go | 28 + .../knative.dev/kn-plugin-func/.codecov.yaml | 1 + vendor/knative.dev/kn-plugin-func/Makefile | 4 +- .../kn-plugin-func/buildpacks/builder.go | 23 +- .../kn-plugin-func/buildpacks/utils.go | 31 - vendor/knative.dev/kn-plugin-func/ci | 1 + vendor/knative.dev/kn-plugin-func/client.go | 243 +- .../knative.dev/kn-plugin-func/cmd/build.go | 51 +- .../knative.dev/kn-plugin-func/cmd/config.go | 4 +- .../kn-plugin-func/cmd/config_envs.go | 12 +- .../kn-plugin-func/cmd/config_labels.go | 8 +- .../kn-plugin-func/cmd/config_volumes.go | 12 +- .../knative.dev/kn-plugin-func/cmd/create.go | 45 +- .../knative.dev/kn-plugin-func/cmd/delete.go | 4 +- .../knative.dev/kn-plugin-func/cmd/deploy.go | 6 +- vendor/knative.dev/kn-plugin-func/cmd/emit.go | 2 +- vendor/knative.dev/kn-plugin-func/cmd/info.go | 4 +- vendor/knative.dev/kn-plugin-func/cmd/list.go | 2 +- .../kn-plugin-func/cmd/repository.go | 10 +- vendor/knative.dev/kn-plugin-func/cmd/root.go | 25 +- vendor/knative.dev/kn-plugin-func/cmd/run.go | 4 +- vendor/knative.dev/kn-plugin-func/config.go | 567 +-- .../kn-plugin-func/docker/docker_client.go | 113 +- .../docker/docker_client_generated.go | 488 +++ .../kn-plugin-func/docker/pusher.go | 55 +- .../kn-plugin-func/docker/runner.go | 5 +- vendor/knative.dev/kn-plugin-func/function.go | 243 +- .../kn-plugin-func/function_envs.go | 126 + .../kn-plugin-func/function_labels.go | 75 + .../kn-plugin-func/function_migrations.go | 114 + .../kn-plugin-func/function_options.go | 139 + .../kn-plugin-func/function_volumes.go | 49 + vendor/knative.dev/kn-plugin-func/go.mod | 3 + vendor/knative.dev/kn-plugin-func/go.sum | 3 + .../knative.dev/kn-plugin-func/k8s/dialer.go | 324 ++ .../kn-plugin-func/knative/deployer.go | 4 +- vendor/knative.dev/kn-plugin-func/pkged.go | 2 +- .../kn-plugin-func/repositories.go | 28 +- .../knative.dev/kn-plugin-func/repository.go | 29 +- .../kn-plugin-func/ssh/ssh_dialer.go | 52 +- vendor/knative.dev/kn-plugin-func/template.go | 3 + .../knative.dev/kn-plugin-func/templates.go | 20 +- vendor/modules.txt | 113 +- vendor/sigs.k8s.io/yaml/.gitignore | 4 + vendor/sigs.k8s.io/yaml/.travis.yml | 7 +- vendor/sigs.k8s.io/yaml/README.md | 2 +- vendor/sigs.k8s.io/yaml/go.mod | 2 +- vendor/sigs.k8s.io/yaml/go.sum | 9 +- 403 files changed, 29939 insertions(+), 6722 deletions(-) rename third_party/VENDOR-LICENSE/github.com/{willf => bits-and-blooms}/bitset/LICENSE (100%) create mode 100644 third_party/VENDOR-LICENSE/github.com/coreos/go-semver/semver/LICENSE create mode 100644 third_party/VENDOR-LICENSE/github.com/coreos/go-semver/semver/NOTICE create mode 100644 third_party/VENDOR-LICENSE/github.com/ghodss/yaml/LICENSE create mode 100644 third_party/VENDOR-LICENSE/github.com/klauspost/compress/internal/snapref/LICENSE create mode 100644 third_party/VENDOR-LICENSE/github.com/moby/spdystream/LICENSE create mode 100644 third_party/VENDOR-LICENSE/github.com/moby/spdystream/NOTICE create mode 100644 third_party/VENDOR-LICENSE/github.com/thediveo/enumflag/LICENSE create mode 100644 third_party/VENDOR-LICENSE/github.com/vbatts/tar-split/archive/tar/LICENSE create mode 100644 third_party/VENDOR-LICENSE/github.com/wavesoftware/go-ensure/LICENSE create mode 100644 third_party/VENDOR-LICENSE/google.golang.org/grpc/NOTICE.txt create mode 100644 third_party/VENDOR-LICENSE/knative.dev/kn-plugin-event/LICENSE create mode 100644 vendor/cloud.google.com/go/compute/metadata/retry.go create mode 100644 vendor/cloud.google.com/go/compute/metadata/retry_linux.go rename vendor/github.com/{willf => bits-and-blooms}/bitset/.gitignore (100%) rename vendor/github.com/{willf => bits-and-blooms}/bitset/.travis.yml (100%) rename vendor/github.com/{willf => bits-and-blooms}/bitset/LICENSE (100%) rename vendor/github.com/{willf => bits-and-blooms}/bitset/README.md (84%) rename vendor/github.com/{willf => bits-and-blooms}/bitset/azure-pipelines.yml (100%) rename vendor/github.com/{willf => bits-and-blooms}/bitset/bitset.go (97%) create mode 100644 vendor/github.com/bits-and-blooms/bitset/go.mod rename vendor/github.com/{willf => bits-and-blooms}/bitset/go.sum (100%) rename vendor/github.com/{willf => bits-and-blooms}/bitset/popcnt.go (100%) rename vendor/github.com/{willf => bits-and-blooms}/bitset/popcnt_19.go (100%) rename vendor/github.com/{willf => bits-and-blooms}/bitset/popcnt_amd64.go (100%) rename vendor/github.com/{willf => bits-and-blooms}/bitset/popcnt_amd64.s (100%) rename vendor/github.com/{willf => bits-and-blooms}/bitset/popcnt_generic.go (100%) rename vendor/github.com/{willf => bits-and-blooms}/bitset/trailing_zeros_18.go (100%) rename vendor/github.com/{willf => bits-and-blooms}/bitset/trailing_zeros_19.go (100%) create mode 100644 vendor/github.com/containerd/stargz-snapshotter/estargz/gzip.go create mode 100644 vendor/github.com/containerd/stargz-snapshotter/estargz/testutil.go create mode 100644 vendor/github.com/coreos/go-semver/LICENSE create mode 100644 vendor/github.com/coreos/go-semver/NOTICE create mode 100644 vendor/github.com/coreos/go-semver/semver/semver.go create mode 100644 vendor/github.com/coreos/go-semver/semver/sort.go create mode 100644 vendor/github.com/fsnotify/fsnotify/.mailmap delete mode 100644 vendor/github.com/fsnotify/fsnotify/.travis.yml create mode 100644 vendor/github.com/ghodss/yaml/.gitignore create mode 100644 vendor/github.com/ghodss/yaml/.travis.yml create mode 100644 vendor/github.com/ghodss/yaml/LICENSE create mode 100644 vendor/github.com/ghodss/yaml/README.md create mode 100644 vendor/github.com/ghodss/yaml/fields.go create mode 100644 vendor/github.com/ghodss/yaml/yaml.go create mode 100644 vendor/github.com/go-logr/logr/.golangci.yaml create mode 100644 vendor/github.com/go-logr/logr/CHANGELOG.md create mode 100644 vendor/github.com/go-logr/logr/CONTRIBUTING.md create mode 100644 vendor/github.com/klauspost/compress/.gitattributes create mode 100644 vendor/github.com/klauspost/compress/.gitignore create mode 100644 vendor/github.com/klauspost/compress/.goreleaser.yml create mode 100644 vendor/github.com/klauspost/compress/README.md create mode 100644 vendor/github.com/klauspost/compress/compressible.go create mode 100644 vendor/github.com/klauspost/compress/gen.sh create mode 100644 vendor/github.com/klauspost/compress/go.mod create mode 100644 vendor/github.com/klauspost/compress/go.sum create mode 100644 vendor/github.com/klauspost/compress/internal/snapref/LICENSE create mode 100644 vendor/github.com/klauspost/compress/internal/snapref/decode.go create mode 100644 vendor/github.com/klauspost/compress/internal/snapref/decode_other.go create mode 100644 vendor/github.com/klauspost/compress/internal/snapref/encode.go create mode 100644 vendor/github.com/klauspost/compress/internal/snapref/encode_other.go create mode 100644 vendor/github.com/klauspost/compress/internal/snapref/snappy.go create mode 100644 vendor/github.com/klauspost/compress/s2sx.mod create mode 100644 vendor/github.com/klauspost/compress/s2sx.sum delete mode 100644 vendor/github.com/mattn/go-colorable/.travis.yml delete mode 100644 vendor/github.com/mattn/go-isatty/.travis.yml create mode 100644 vendor/github.com/moby/spdystream/CONTRIBUTING.md create mode 100644 vendor/github.com/moby/spdystream/LICENSE create mode 100644 vendor/github.com/moby/spdystream/MAINTAINERS create mode 100644 vendor/github.com/moby/spdystream/NOTICE create mode 100644 vendor/github.com/moby/spdystream/README.md create mode 100644 vendor/github.com/moby/spdystream/connection.go create mode 100644 vendor/github.com/moby/spdystream/go.mod create mode 100644 vendor/github.com/moby/spdystream/go.sum create mode 100644 vendor/github.com/moby/spdystream/handlers.go create mode 100644 vendor/github.com/moby/spdystream/priority.go create mode 100644 vendor/github.com/moby/spdystream/spdy/dictionary.go create mode 100644 vendor/github.com/moby/spdystream/spdy/read.go create mode 100644 vendor/github.com/moby/spdystream/spdy/types.go create mode 100644 vendor/github.com/moby/spdystream/spdy/write.go create mode 100644 vendor/github.com/moby/spdystream/stream.go create mode 100644 vendor/github.com/moby/spdystream/utils.go delete mode 100644 vendor/github.com/opencontainers/runc/libcontainer/user/MAINTAINERS delete mode 100644 vendor/github.com/opencontainers/runc/libcontainer/user/lookup.go delete mode 100644 vendor/github.com/opencontainers/runc/libcontainer/user/lookup_windows.go create mode 100644 vendor/github.com/opencontainers/runc/libcontainer/user/user_fuzzer.go delete mode 100644 vendor/github.com/spf13/cast/.travis.yml create mode 100644 vendor/github.com/spf13/cast/timeformattype_string.go create mode 100644 vendor/github.com/spf13/viper/internal/encoding/decoder.go create mode 100644 vendor/github.com/spf13/viper/internal/encoding/encoder.go create mode 100644 vendor/github.com/spf13/viper/internal/encoding/error.go create mode 100644 vendor/github.com/spf13/viper/internal/encoding/hcl/codec.go create mode 100644 vendor/github.com/spf13/viper/internal/encoding/json/codec.go create mode 100644 vendor/github.com/spf13/viper/internal/encoding/toml/codec.go create mode 100644 vendor/github.com/spf13/viper/internal/encoding/yaml/codec.go create mode 100644 vendor/github.com/thediveo/enumflag/LICENSE create mode 100644 vendor/github.com/thediveo/enumflag/README.md create mode 100644 vendor/github.com/thediveo/enumflag/doc.go create mode 100644 vendor/github.com/thediveo/enumflag/enumflag.code-workspace create mode 100644 vendor/github.com/thediveo/enumflag/enumflag.go create mode 100644 vendor/github.com/thediveo/enumflag/enumslice.go create mode 100644 vendor/github.com/thediveo/enumflag/go.mod create mode 100644 vendor/github.com/thediveo/enumflag/go.sum create mode 100644 vendor/github.com/vbatts/tar-split/LICENSE create mode 100644 vendor/github.com/vbatts/tar-split/archive/tar/common.go create mode 100644 vendor/github.com/vbatts/tar-split/archive/tar/format.go create mode 100644 vendor/github.com/vbatts/tar-split/archive/tar/reader.go create mode 100644 vendor/github.com/vbatts/tar-split/archive/tar/stat_actime1.go create mode 100644 vendor/github.com/vbatts/tar-split/archive/tar/stat_actime2.go create mode 100644 vendor/github.com/vbatts/tar-split/archive/tar/stat_unix.go create mode 100644 vendor/github.com/vbatts/tar-split/archive/tar/strconv.go create mode 100644 vendor/github.com/vbatts/tar-split/archive/tar/writer.go create mode 100644 vendor/github.com/wavesoftware/go-ensure/.editorconfig create mode 100644 vendor/github.com/wavesoftware/go-ensure/.gitignore create mode 100644 vendor/github.com/wavesoftware/go-ensure/.travis.yml create mode 100644 vendor/github.com/wavesoftware/go-ensure/LICENSE create mode 100644 vendor/github.com/wavesoftware/go-ensure/Makefile create mode 100644 vendor/github.com/wavesoftware/go-ensure/README.md create mode 100644 vendor/github.com/wavesoftware/go-ensure/errors.go create mode 100644 vendor/github.com/wavesoftware/go-ensure/go.mod create mode 100644 vendor/github.com/wavesoftware/go-ensure/go.sum create mode 100644 vendor/github.com/wavesoftware/go-ensure/revive.toml delete mode 100644 vendor/github.com/willf/bitset/go.mod create mode 100644 vendor/google.golang.org/grpc/NOTICE.txt delete mode 100644 vendor/google.golang.org/grpc/credentials/go12.go delete mode 100644 vendor/google.golang.org/grpc/install_gae.sh delete mode 100644 vendor/google.golang.org/grpc/internal/credentials/spiffe_appengine.go delete mode 100644 vendor/google.golang.org/grpc/internal/credentials/syscallconn_appengine.go delete mode 100644 vendor/google.golang.org/grpc/internal/resolver/dns/go113.go create mode 100644 vendor/google.golang.org/grpc/internal/xds/env/env.go create mode 100644 vendor/gopkg.in/ini.v1/.golangci.yml create mode 100644 vendor/k8s.io/apimachinery/pkg/util/httpstream/doc.go create mode 100644 vendor/k8s.io/apimachinery/pkg/util/httpstream/httpstream.go create mode 100644 vendor/k8s.io/apimachinery/pkg/util/httpstream/spdy/connection.go create mode 100644 vendor/k8s.io/apimachinery/pkg/util/httpstream/spdy/roundtripper.go create mode 100644 vendor/k8s.io/apimachinery/pkg/util/httpstream/spdy/upgrade.go create mode 100644 vendor/k8s.io/apimachinery/pkg/util/rand/rand.go create mode 100644 vendor/k8s.io/apimachinery/pkg/util/remotecommand/constants.go create mode 100644 vendor/k8s.io/apimachinery/third_party/forked/golang/netutil/addr.go create mode 100644 vendor/k8s.io/client-go/tools/remotecommand/doc.go create mode 100644 vendor/k8s.io/client-go/tools/remotecommand/errorstream.go create mode 100644 vendor/k8s.io/client-go/tools/remotecommand/reader.go create mode 100644 vendor/k8s.io/client-go/tools/remotecommand/remotecommand.go create mode 100644 vendor/k8s.io/client-go/tools/remotecommand/resize.go create mode 100644 vendor/k8s.io/client-go/tools/remotecommand/v1.go create mode 100644 vendor/k8s.io/client-go/tools/remotecommand/v2.go create mode 100644 vendor/k8s.io/client-go/tools/remotecommand/v3.go create mode 100644 vendor/k8s.io/client-go/tools/remotecommand/v4.go create mode 100644 vendor/k8s.io/client-go/transport/spdy/spdy.go create mode 100644 vendor/k8s.io/client-go/util/exec/exec.go create mode 100644 vendor/knative.dev/kn-plugin-event/LICENSE create mode 100644 vendor/knative.dev/kn-plugin-event/internal/cli/cmd/build.go create mode 100644 vendor/knative.dev/kn-plugin-event/internal/cli/cmd/builder.go create mode 100644 vendor/knative.dev/kn-plugin-event/internal/cli/cmd/root.go create mode 100644 vendor/knative.dev/kn-plugin-event/internal/cli/cmd/send.go create mode 100644 vendor/knative.dev/kn-plugin-event/internal/cli/cmd/testing.go create mode 100644 vendor/knative.dev/kn-plugin-event/internal/cli/cmd/types.go create mode 100644 vendor/knative.dev/kn-plugin-event/internal/cli/cmd/version.go create mode 100644 vendor/knative.dev/kn-plugin-event/pkg/cli/create.go create mode 100644 vendor/knative.dev/kn-plugin-event/pkg/cli/ics/constants.go create mode 100644 vendor/knative.dev/kn-plugin-event/pkg/cli/ics/encoding.go create mode 100644 vendor/knative.dev/kn-plugin-event/pkg/cli/ics/send.go create mode 100644 vendor/knative.dev/kn-plugin-event/pkg/cli/ics/types.go create mode 100644 vendor/knative.dev/kn-plugin-event/pkg/cli/options.go create mode 100644 vendor/knative.dev/kn-plugin-event/pkg/cli/retcode/retcode.go create mode 100644 vendor/knative.dev/kn-plugin-event/pkg/cli/send.go create mode 100644 vendor/knative.dev/kn-plugin-event/pkg/cli/target.go create mode 100644 vendor/knative.dev/kn-plugin-event/pkg/cli/types.go create mode 100644 vendor/knative.dev/kn-plugin-event/pkg/cli/version.go create mode 100644 vendor/knative.dev/kn-plugin-event/pkg/configuration/cli.go create mode 100644 vendor/knative.dev/kn-plugin-event/pkg/configuration/defaults.go create mode 100644 vendor/knative.dev/kn-plugin-event/pkg/configuration/ics.go create mode 100644 vendor/knative.dev/kn-plugin-event/pkg/configuration/memoized.go create mode 100644 vendor/knative.dev/kn-plugin-event/pkg/event/constants.go create mode 100644 vendor/knative.dev/kn-plugin-event/pkg/event/create.go create mode 100644 vendor/knative.dev/kn-plugin-event/pkg/event/sender.go create mode 100644 vendor/knative.dev/kn-plugin-event/pkg/event/types.go create mode 100644 vendor/knative.dev/kn-plugin-event/pkg/k8s/addressresolver.go create mode 100644 vendor/knative.dev/kn-plugin-event/pkg/k8s/errors.go create mode 100644 vendor/knative.dev/kn-plugin-event/pkg/k8s/jobrunner.go create mode 100644 vendor/knative.dev/kn-plugin-event/pkg/k8s/kubeclient.go create mode 100644 vendor/knative.dev/kn-plugin-event/pkg/metadata/image.go create mode 100644 vendor/knative.dev/kn-plugin-event/pkg/metadata/names.go create mode 100644 vendor/knative.dev/kn-plugin-event/pkg/metadata/reflect.go create mode 100644 vendor/knative.dev/kn-plugin-event/pkg/metadata/version.go create mode 100644 vendor/knative.dev/kn-plugin-event/pkg/plugin/plugin.go create mode 100644 vendor/knative.dev/kn-plugin-event/pkg/plugin/testing.go create mode 100644 vendor/knative.dev/kn-plugin-event/pkg/sender/create.go create mode 100644 vendor/knative.dev/kn-plugin-event/pkg/sender/direct.go create mode 100644 vendor/knative.dev/kn-plugin-event/pkg/sender/in_cluster.go create mode 100644 vendor/knative.dev/kn-plugin-event/pkg/sender/namespace.go create mode 100644 vendor/knative.dev/kn-plugin-event/pkg/sender/types.go delete mode 100644 vendor/knative.dev/kn-plugin-func/buildpacks/utils.go create mode 100644 vendor/knative.dev/kn-plugin-func/ci create mode 100644 vendor/knative.dev/kn-plugin-func/docker/docker_client_generated.go create mode 100644 vendor/knative.dev/kn-plugin-func/function_envs.go create mode 100644 vendor/knative.dev/kn-plugin-func/function_labels.go create mode 100644 vendor/knative.dev/kn-plugin-func/function_migrations.go create mode 100644 vendor/knative.dev/kn-plugin-func/function_options.go create mode 100644 vendor/knative.dev/kn-plugin-func/function_volumes.go create mode 100644 vendor/knative.dev/kn-plugin-func/k8s/dialer.go diff --git a/go.mod b/go.mod index 0e88fe6965..d89edc4fcf 100644 --- a/go.mod +++ b/go.mod @@ -7,24 +7,29 @@ require ( github.com/mitchellh/go-homedir v1.1.0 github.com/spf13/cobra v1.2.1 github.com/spf13/pflag v1.0.5 - github.com/spf13/viper v1.8.1 + github.com/spf13/viper v1.9.0 golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b gotest.tools/v3 v3.0.3 k8s.io/api v0.21.4 k8s.io/apiextensions-apiserver v0.21.4 - k8s.io/apimachinery v0.21.4 + k8s.io/apimachinery v0.22.3 k8s.io/cli-runtime v0.21.4 k8s.io/client-go v0.21.4 k8s.io/code-generator v0.21.4 knative.dev/eventing v0.26.1 knative.dev/hack v0.0.0-20210806075220-815cd312d65c + knative.dev/kn-plugin-event v0.26.0 knative.dev/kn-plugin-func v0.20.0 knative.dev/kn-plugin-source-kafka v0.26.0 knative.dev/networking v0.0.0-20210916065741-5e884aff221e knative.dev/pkg v0.0.0-20210919202233-5ae482141474 knative.dev/serving v0.26.0 - sigs.k8s.io/yaml v1.2.0 + sigs.k8s.io/yaml v1.3.0 ) -//TODO: use release branch instread of current `release-next` -replace knative.dev/kn-plugin-func => github.com/openshift-knative/kn-plugin-func v0.19.1-0.20211111003512-0804607608c3 +replace ( + k8s.io/apimachinery => k8s.io/apimachinery v0.21.4 + knative.dev/kn-plugin-event => github.com/openshift-knative/kn-plugin-event v0.26.2-0.20211209202740-89c860ca5062 + // TODO: use release branch instread of current `release-next` + knative.dev/kn-plugin-func => github.com/openshift-knative/kn-plugin-func v0.19.1-0.20211209011132-6e9942151b08 +) diff --git a/go.sum b/go.sum index 91ad137024..0076fc1664 100644 --- a/go.sum +++ b/go.sum @@ -21,8 +21,13 @@ cloud.google.com/go v0.78.0/go.mod h1:QjdrLG0uq+YwhjoVOLsS1t7TW8fs36kLs4XO5R5ECH cloud.google.com/go v0.79.0/go.mod h1:3bzgcEeQlzbuEAYu4mrWhKqWjmpprinYgKJLgKHnbb8= cloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0= cloud.google.com/go v0.83.0/go.mod h1:Z7MJUsANfY0pYPdw0lbnivPx4/vhy/e2FEkSkF7vAVY= -cloud.google.com/go v0.84.0 h1:hVhK90DwCdOAYGME/FJd9vNIZye9HBR6Yy3fu4js3N8= cloud.google.com/go v0.84.0/go.mod h1:RazrYuxIK6Kb7YrzzhPoLmCVzl7Sup4NrbKPg8KHSUM= +cloud.google.com/go v0.87.0/go.mod h1:TpDYlFy7vuLzZMMZ+B6iRiELaY7z/gJPaqbMx6mlWcY= +cloud.google.com/go v0.90.0/go.mod h1:kRX0mNRHe0e2rC6oNakvwQqzyDmg57xJ+SZU1eT2aDQ= +cloud.google.com/go v0.93.3/go.mod h1:8utlLll2EF5XMAV15woO4lSbWQlk8rer9aLOfLh7+YI= +cloud.google.com/go v0.94.1/go.mod h1:qAlAugsXlC+JWO+Bke5vCtc9ONxjQT3drlTTnAplMW4= +cloud.google.com/go v0.97.0 h1:3DXvAyifywvq64LfkKaMOmkWPS1CikIQdMe2lY9vxU8= +cloud.google.com/go v0.97.0/go.mod h1:GF7l59pYBVlXQIBLx3a761cZ41F9bBH3JUlihCt2Udc= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= @@ -32,6 +37,7 @@ cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM7 cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk= +cloud.google.com/go/firestore v1.6.0/go.mod h1:afJwI0vaXwAG54kI7A//lP/lSPDkQORQuMkv56TxEPU= cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= @@ -128,16 +134,18 @@ github.com/Microsoft/go-winio v0.4.16/go.mod h1:XB6nPKklQyQ7GC9LdcBEcBl8PF76WugX github.com/Microsoft/go-winio v0.4.17-0.20210211115548-6eac466e5fa3/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84= github.com/Microsoft/go-winio v0.4.17-0.20210324224401-5516f17a5958/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84= github.com/Microsoft/go-winio v0.4.17/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84= -github.com/Microsoft/go-winio v0.5.0 h1:Elr9Wn+sGKPlkaBvwu4mTrxtmOp3F3yV9qhaHbXGjwU= github.com/Microsoft/go-winio v0.5.0/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84= +github.com/Microsoft/go-winio v0.5.1 h1:aPJp2QD7OOrhO5tQXqQoGSJc+DjDtWTGLOmNyAm6FgY= +github.com/Microsoft/go-winio v0.5.1/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84= github.com/Microsoft/hcsshim v0.8.6/go.mod h1:Op3hHsoHPAvb6lceZHDtd9OkTew38wNoXnJs8iY7rUg= github.com/Microsoft/hcsshim v0.8.7-0.20190325164909-8abdbb8205e4/go.mod h1:Op3hHsoHPAvb6lceZHDtd9OkTew38wNoXnJs8iY7rUg= github.com/Microsoft/hcsshim v0.8.7/go.mod h1:OHd7sQqRFrYd3RmSgbgji+ctCwkbq2wbEYNSzOYtcBQ= github.com/Microsoft/hcsshim v0.8.9/go.mod h1:5692vkUqntj1idxauYlpoINNKeqCiG6Sg38RRsjT5y8= github.com/Microsoft/hcsshim v0.8.14/go.mod h1:NtVKoYxQuTLx6gEq0L96c9Ju4JbRJ4nY2ow3VK6a9Lg= github.com/Microsoft/hcsshim v0.8.15/go.mod h1:x38A4YbHbdxJtc0sF6oIz+RG0npwSCAvn69iY6URG00= -github.com/Microsoft/hcsshim v0.8.16 h1:8/auA4LFIZFTGrqfKhGBSXwM6/4X1fHa/xniyEHu8ac= github.com/Microsoft/hcsshim v0.8.16/go.mod h1:o5/SZqmR7x9JNKsW3pu+nqHm0MF8vbA+VxGOoXdC600= +github.com/Microsoft/hcsshim v0.8.21 h1:btRfUDThBE5IKcvI8O8jOiIkujUsAMBSRsYDYmEi6oM= +github.com/Microsoft/hcsshim v0.8.21/go.mod h1:+w2gRZ5ReXQhFOrvSQeNfhrYB/dg3oDwTOcER2fw4I4= github.com/Microsoft/hcsshim/test v0.0.0-20201218223536-d3e5debf77da/go.mod h1:5hlzMzRKMLyo42nCZ9oml8AdTlq/0cvIaBv6tK1RehU= github.com/Microsoft/hcsshim/test v0.0.0-20210227013316-43a75bb4edd3/go.mod h1:mw7qgWloBUl75W/gVH3cQszUg1+gUITj7D6NY7ywVnY= github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= @@ -182,6 +190,7 @@ github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuy github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= +github.com/alessio/shellescape v1.4.1/go.mod h1:PZAiSCk0LJaZkiCSkPv8qIobYglO3FPpyFjDCtHLS30= github.com/alexflint/go-filemutex v0.0.0-20171022225611-72bdc8eae2ae/go.mod h1:CgnQgUtFrFz9mxFNtED3jI5tLDjKlOM+oUF/sTk6ps0= github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8= github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239 h1:kFOfPq6dUM1hTo4JG6LR5AXSUEsOjtdm0kw0FtQtMJA= @@ -198,6 +207,7 @@ github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hC github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= 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-radix v1.0.0/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= @@ -223,6 +233,8 @@ github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= github.com/bitly/go-simplejson v0.5.0/go.mod h1:cXHtHw4XUPsvGaxgjIAn8PhEWG9NfngEKAMDJEczWVA= +github.com/bits-and-blooms/bitset v1.2.0 h1:Kn4yilvwNtMACtf1eYDlG8H77R07mZSPbMjLyS07ChA= +github.com/bits-and-blooms/bitset v1.2.0/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA= github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84= github.com/bketelsen/crypt v0.0.4/go.mod h1:aI6NrJ0pMGgvZKL1iVgXLnfIFJtfV+bKCoqOes/6LfM= github.com/blang/semver v3.1.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= @@ -258,6 +270,7 @@ github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+ github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/checkpoint-restore/go-criu/v4 v4.0.2/go.mod h1:xUQBLp4RLc5zJtWY++yjOoMoB5lihDt7fai+75m+rGw= github.com/checkpoint-restore/go-criu/v4 v4.1.0/go.mod h1:xUQBLp4RLc5zJtWY++yjOoMoB5lihDt7fai+75m+rGw= +github.com/checkpoint-restore/go-criu/v5 v5.0.0/go.mod h1:cfwC0EG7HMUenopBsUf9d89JlCLQIfgVcNsNN0t6T2M= github.com/cheekybits/genny v1.0.0/go.mod h1:+tQajlRqAUrPI7DOSpB0XAqZYtQakVtB7wXkRAgjxjQ= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= @@ -267,6 +280,7 @@ github.com/cilium/ebpf v0.0.0-20200507155900-a9f01edf17e3/go.mod h1:XT+cAw5wfvso github.com/cilium/ebpf v0.0.0-20200702112145-1c8d4c9ef775/go.mod h1:7cR51M8ViRLIdUjrmSXlK9pkrsDlLHbO8jiB8X8JnOc= github.com/cilium/ebpf v0.2.0/go.mod h1:To2CFviqOWL/M0gIMsvSMlqe7em/l1ALkX1PyjrX2Qs= github.com/cilium/ebpf v0.4.0/go.mod h1:4tRaxcgiL706VnOzHOdBlY8IEAIdxINsQBcU4xJJXRs= +github.com/cilium/ebpf v0.6.2/go.mod h1:4tRaxcgiL706VnOzHOdBlY8IEAIdxINsQBcU4xJJXRs= github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cloudevents/conformance v0.2.0/go.mod h1:rHKDwylBH89Rns6U3wL9ww8bg9/4GbwRCDNuyoC6bcc= @@ -280,6 +294,7 @@ github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGX github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= github.com/containerd/aufs v0.0.0-20200908144142-dab0cbea06f4/go.mod h1:nukgQABAEopAHvB6j7cnP5zJ+/3aVcE7hCYqvIwAHyE= @@ -314,8 +329,10 @@ github.com/containerd/containerd v1.5.0-beta.1/go.mod h1:5HfvG1V2FsKesEGQ17k5/T7 github.com/containerd/containerd v1.5.0-beta.3/go.mod h1:/wr9AVtEM7x9c+n0+stptlo/uBBoBORwEx6ardVcmKU= github.com/containerd/containerd v1.5.0-beta.4/go.mod h1:GmdgZd2zA2GYIBZ0w09ZvgqEq8EfBp/m3lcVZIvPHhI= github.com/containerd/containerd v1.5.0-rc.0/go.mod h1:V/IXoMqNGgBlabz3tHD2TWDoTJseu1FGOKuoA4nNb2s= -github.com/containerd/containerd v1.5.2 h1:MG/Bg1pbmMb61j3wHCFWPxESXHieiKr2xG64px/k8zQ= +github.com/containerd/containerd v1.5.1/go.mod h1:0DOxVqwDy2iZvrZp2JUx/E+hS0UNTVn7dJnIOwtYR4g= github.com/containerd/containerd v1.5.2/go.mod h1:0DOxVqwDy2iZvrZp2JUx/E+hS0UNTVn7dJnIOwtYR4g= +github.com/containerd/containerd v1.5.7 h1:rQyoYtj4KddB3bxG6SAqd4+08gePNyJjRqvOIfV3rkM= +github.com/containerd/containerd v1.5.7/go.mod h1:gyvv6+ugqY25TiXxcZC3L5yOeYgEw0QMhscqVp1AR9c= github.com/containerd/continuity v0.0.0-20190426062206-aaeac12a7ffc/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y= github.com/containerd/continuity v0.0.0-20190815185530-f2a389ac0a02/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y= github.com/containerd/continuity v0.0.0-20191127005431-f65d91d395eb/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y= @@ -346,8 +363,10 @@ github.com/containerd/nri v0.0.0-20210316161719-dbaa18c31c14/go.mod h1:lmxnXF6oM github.com/containerd/nri v0.1.0/go.mod h1:lmxnXF6oMkbqs39FiCt1s0R2HSMhcLel9vNL3m4AaeY= github.com/containerd/stargz-snapshotter/estargz v0.0.0-20201223015020-a9a0c2d64694/go.mod h1:E9uVkkBKf0EaC39j2JVW9EzdNhYvpz6eQIjILHebruk= github.com/containerd/stargz-snapshotter/estargz v0.6.4/go.mod h1:83VWDqHnurTKliEB0YvWMiCfLDwv4Cjj1X9Vk98GJZw= -github.com/containerd/stargz-snapshotter/estargz v0.7.0 h1:1d/rydzTywc76lnjJb6qbPCiTiCwts49AzKps/Ecblw= github.com/containerd/stargz-snapshotter/estargz v0.7.0/go.mod h1:83VWDqHnurTKliEB0YvWMiCfLDwv4Cjj1X9Vk98GJZw= +github.com/containerd/stargz-snapshotter/estargz v0.8.0/go.mod h1:mwIwuwb+D8FX2t45Trwi0hmWmZm5VW7zPP/rekwhWQU= +github.com/containerd/stargz-snapshotter/estargz v0.9.0 h1:PkB6BSTfOKX23erT2GkoUKkJEcXfNcyKskIViK770v8= +github.com/containerd/stargz-snapshotter/estargz v0.9.0/go.mod h1:aE5PCyhFMwR8sbrErO5eM2GcvkyXTTJremG883D4qF0= github.com/containerd/ttrpc v0.0.0-20190828154514-0e0f228740de/go.mod h1:PvCDdDGpgqzQIzDW1TphrGLssLDZp2GuS+X5DkEJB8o= github.com/containerd/ttrpc v0.0.0-20190828172938-92c8520ef9f8/go.mod h1:PvCDdDGpgqzQIzDW1TphrGLssLDZp2GuS+X5DkEJB8o= github.com/containerd/ttrpc v0.0.0-20191028202541-4f1b8fe65a5c/go.mod h1:LPm1u0xBw8r8NOKoOdNMeVHSawSsltak+Ihv+etqsE8= @@ -384,6 +403,7 @@ github.com/coreos/go-iptables v0.4.5/go.mod h1:/mVI274lEDI2ns62jHCDnCyBF9Iwsmeka github.com/coreos/go-iptables v0.5.0/go.mod h1:/mVI274lEDI2ns62jHCDnCyBF9Iwsmekav8Dbxlm1MU= github.com/coreos/go-oidc v2.1.0+incompatible/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHoZ1nMCKZlZ9V6mm3/LKc= github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/coreos/go-semver v0.3.0 h1:wkHLiw0WNATZnSG7epLsujiMCgPAc9xhjJ4tgnAxmfM= github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-systemd v0.0.0-20161114122254-48702e0da86b/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= @@ -396,8 +416,9 @@ github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfc github.com/cpuguy83/go-md2man v1.0.10 h1:BSKMNlYxDvnunlTymqtgONjNnaRV1sTpcovwwjF22jk= github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= -github.com/cpuguy83/go-md2man/v2 v2.0.0 h1:EoUDS0afbrsXAZ9YQ9jdu/mZ2sXgT1/2yyNng4PGlyM= github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= +github.com/cpuguy83/go-md2man/v2 v2.0.1 h1:r/myEWzV9lfsM1tFLgDyu0atFtJ1fXn261LKYj/3DxU= +github.com/cpuguy83/go-md2man/v2 v2.0.1/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/creack/pty v1.1.11 h1:07n33Z8lZxZ2qwegKbObQohDhXDQxiMMz1NOUGYlesw= @@ -455,8 +476,8 @@ github.com/docker/go-units v0.4.0 h1:3uh0PgVws3nIA0Q+MwDC8yjEPf9zjRfZZWXZYDct3Tw github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/docker/libtrust v0.0.0-20150114040149-fa567046d9b1/go.mod h1:cyGadeNEkKy96OOhEzfZl+yxihPEzKnqJwvfuSUqbZE= github.com/docker/libtrust v0.0.0-20160708172513-aabc10ec26b7/go.mod h1:cyGadeNEkKy96OOhEzfZl+yxihPEzKnqJwvfuSUqbZE= -github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM= github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE= +github.com/dprotaso/go-yit v0.0.0-20191028211022-135eb7262960/go.mod h1:9HQzr9D/0PGwMEbC3d5AB7oi67+h4TsQqItC1GVYG58= github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= @@ -467,6 +488,7 @@ github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1 github.com/eapache/queue v1.1.0 h1:YOEu7KNc61ntiQlcEeUIoDTJ2o8mQznoNvUhiigpIqc= github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= +github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153 h1:yUdfgN0XgIJw7foRItutHYUIhlcKzcSf5vDpdhQAKTc= github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc= github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= github.com/emicklei/go-restful v2.9.5+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= @@ -482,14 +504,19 @@ github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5y github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ= +github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/evanphx/json-patch v0.5.2/go.mod h1:ZWS5hhDbVDyob71nXKNL0+PWn6ToqBHMikGIFbs31qQ= github.com/evanphx/json-patch v4.5.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/evanphx/json-patch v4.9.0+incompatible h1:kLcOMZeuLAJvL2BPWLMIj5oaZQobrkAqrL+WFZwQses= github.com/evanphx/json-patch v4.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= -github.com/evanphx/json-patch/v5 v5.5.0 h1:bAmFiUJ+o0o2B4OiTFeE3MqCOtyo+jjPP9iZ0VRxYUc= +github.com/evanphx/json-patch/v5 v5.2.0/go.mod h1:G79N1coSVB93tBe7j6PhzjmR3/2VvlbKOFpnXhI9Bw4= github.com/evanphx/json-patch/v5 v5.5.0/go.mod h1:G79N1coSVB93tBe7j6PhzjmR3/2VvlbKOFpnXhI9Bw4= +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/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= +github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= +github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= github.com/form3tech-oss/jwt-go v3.2.2+incompatible h1:TcekIExNqud5crz4xD2pavyTgWiPvpYe4Xau31I0PRk= github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= @@ -502,8 +529,9 @@ github.com/frankban/quicktest v1.10.0/go.mod h1:ui7WezCLWMWxVWr1GETZY3smRy0G4KWq github.com/frankban/quicktest v1.11.3 h1:8sXhOn0uLys67V8EsXLc6eszDs8VXWxL3iRvebPhedY= github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= -github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= +github.com/fsnotify/fsnotify v1.5.1 h1:mZcQUHVQUQWoPXXtuf9yuEXKudkV2sx1E06UadKWpgI= +github.com/fsnotify/fsnotify v1.5.1/go.mod h1:T3375wBYaZdLLcVNkcVbzGHY7f1l/uK5T5Ai1i3InKU= github.com/fullsailor/pkcs7 v0.0.0-20190404230743-d7302db945fa/go.mod h1:KnogPXtdwXqoenmZCw6S+25EAm2MkxbG0deNDu4cbSA= github.com/garyburd/redigo v0.0.0-20150301180006-535138d7bcd7/go.mod h1:NR3MbYisc3/PwhQ00EMzDiPmrwpPxAn5GI05/YaO1SY= github.com/gdamore/encoding v1.0.0 h1:+7OoQ1Bc6eTm5niUzBa0Ctsh6JbMW6Ra+YNuAtDBdko= @@ -512,6 +540,7 @@ github.com/gdamore/tcell/v2 v2.3.3/go.mod h1:cTTuF84Dlj/RqmaCIV5p4w8uG1zWdk0SF6o github.com/gdamore/tcell/v2 v2.4.0 h1:W6dxJEmaxYvhICFoTY3WrLLEXsQ11SaFnKGVEXW57KM= github.com/gdamore/tcell/v2 v2.4.0/go.mod h1:cTTuF84Dlj/RqmaCIV5p4w8uG1zWdk0SF6oBpwHp4fU= github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/gliderlabs/ssh v0.2.2 h1:6zsha5zo/TWhRhwqCD3+EarCAgZ2yN28ipRnGPnwkI0= github.com/gliderlabs/ssh v0.2.2/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= @@ -543,8 +572,9 @@ github.com/go-logfmt/logfmt v0.5.0 h1:TrB8swr/68K7m9CcGut2g3UOihhbcbiMAYiuTXdEih github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas= github.com/go-logr/logr v0.2.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU= -github.com/go-logr/logr v0.4.0 h1:K7/B1jt6fIBQVd4Owv2MqGQClcgf0R266+7C/QjRcLc= github.com/go-logr/logr v0.4.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU= +github.com/go-logr/logr v1.2.0 h1:QK40JKJyMdUDz+h+xvCsru/bJhvG0UxvePV0ufL/AcE= +github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-openapi/analysis v0.0.0-20180825180245-b006789cd277/go.mod h1:k70tL6pCuVxPJOHXQ+wIac1FUrvNkHolPie/cLEU6hI= github.com/go-openapi/analysis v0.17.0/go.mod h1:IowGgpVeD0vNm45So8nr+IcQ3pxVtpRoBWb8PVZO0ik= github.com/go-openapi/analysis v0.18.0/go.mod h1:IowGgpVeD0vNm45So8nr+IcQ3pxVtpRoBWb8PVZO0ik= @@ -607,6 +637,7 @@ github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LB github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= +github.com/go-training/helloworld v0.0.0-20200225145412-ba5f4379d78b/go.mod h1:hGGmX3bRUkYkc9aKA6mkUxi6d+f1GmZF1je0FlVTgwU= github.com/gobuffalo/flect v0.2.2/go.mod h1:vmkQwuZYhN5Pc4ljYQZzP+1sq+NEkK+lh20jmEmX3jc= github.com/gobuffalo/flect v0.2.3/go.mod h1:vmkQwuZYhN5Pc4ljYQZzP+1sq+NEkK+lh20jmEmX3jc= github.com/gobuffalo/here v0.6.0 h1:hYrd0a6gDmWxBM4TnrGw8mQg24iSVoIkHEk7FodQcBI= @@ -707,6 +738,7 @@ github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/ github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/ko v0.9.3/go.mod h1:Q6jYoY4SzKhRTaniQgnNoLaj4e4fVIWTBLK4FTJQPtM= github.com/google/licenseclassifier v0.0.0-20200708223521-3d09a0ea2f39/go.mod h1:qsqn2hxC+vURpyBRygGUuinTO42MFRLcsmQ/P8v94+M= github.com/google/mako v0.0.0-20190821191249-122f8dcef9e3/go.mod h1:YzLcVlL+NqWnmUEPuhS1LxDDwGO9WNbVlEXaF4IH35g= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= @@ -725,6 +757,8 @@ github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLe github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4= github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= @@ -736,11 +770,12 @@ github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= +github.com/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pfu6SK+H1/DsU0= +github.com/googleapis/gax-go/v2 v2.1.1/go.mod h1:hddJymUZASv3XPyGkUpKj8pPO47Rmb0eJc8R6ouapiM= github.com/googleapis/gnostic v0.4.1/go.mod h1:LRhVm6pbyptWbWbuZ38d1eyptfvIytN3ir6b65WBswg= github.com/googleapis/gnostic v0.5.3 h1:2qsuRm+bzgwSIKikigPASa2GhW8H2Dn4Qq7UxD8K/48= github.com/googleapis/gnostic v0.5.3/go.mod h1:TRWw1s4gxBGjSe301Dai3c7wXJAZy57+/6tawkOvqHQ= github.com/gophercloud/gophercloud v0.1.0/go.mod h1:vxM41WHh5uqHVBMZHzuwNOHh8XEoIEcSTewFxm1c5g8= -github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= github.com/gorilla/handlers v0.0.0-20150720190736-60c7bfde3e33/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ= @@ -768,19 +803,25 @@ github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4 github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= github.com/hashicorp/consul/api v1.3.0/go.mod h1:MmDNSzIMUjNpY/mQ398R4bk2FnqQLoPndWW5VkKPlCE= +github.com/hashicorp/consul/api v1.10.1/go.mod h1:XjsvQN+RJGWI2TWy1/kqaE16HrR2J/FWgkYjdZQsX9M= github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= github.com/hashicorp/consul/sdk v0.3.0/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= +github.com/hashicorp/consul/sdk v0.8.0/go.mod h1:GBvyrGALthsZObzUGsfgHZQDXjg4lOjagTIwIR1vPms= github.com/hashicorp/errwrap v0.0.0-20141028054710-7554cd9344ce/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= github.com/hashicorp/go-hclog v0.9.2/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ= +github.com/hashicorp/go-hclog v0.12.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= github.com/hashicorp/go-multierror v0.0.0-20161216184304-ed905158d874/go.mod h1:JMRHfdO9jKNzS/+BTlxCjKNQHg/jZAft8U7LloJvN7I= github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= github.com/hashicorp/go-multierror v1.1.0/go.mod h1:spPvp8C1qA32ftKqdAHm4hHTbPw+vmowP0z+KUhOZdA= +github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= github.com/hashicorp/go-retryablehttp v0.6.7/go.mod h1:vAew36LZh98gCBJNLH42IQ1ER/9wtLZZ8meHqQvEYWY= github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= +github.com/hashicorp/go-rootcerts v1.0.2/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8= github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= @@ -798,8 +839,11 @@ github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= +github.com/hashicorp/mdns v1.0.1/go.mod h1:4gW7WsVCke5TE7EPeYliwHlRUyBtfCwuFwuMg2DmyNY= github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= +github.com/hashicorp/memberlist v0.2.2/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOnAH9VT3Sh9MUE= github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= +github.com/hashicorp/serf v0.9.5/go.mod h1:UWDWwZeL5cuWDJdl0C6wrvrUwEqtQ4ZKBKKENpqIUyk= github.com/hectane/go-acl v0.0.0-20190604041725-da78bae5fc95/go.mod h1:QiyDdbZLaJ/mZP4Zwc9g2QsfaEA4o7XvvgZegSci5/E= github.com/heroku/color v0.0.6 h1:UTFFMrmMLFcL3OweqP1lAdp8i1y/9oHqkeHjQ/b/Ny0= github.com/heroku/color v0.0.6/go.mod h1:ZBvOcx7cTF2QKOv4LbmoBtNl5uB17qWxGuzZrsi1wLU= @@ -851,6 +895,7 @@ github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHW github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= github.com/joefitzgerald/rainbow-reporter v0.1.0/go.mod h1:481CNgqmVHQZzdIbN52CupLJyoVwB10FQ/IQlF1pdL8= github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg= +github.com/joho/godotenv v1.4.0/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= @@ -864,7 +909,6 @@ github.com/json-iterator/go v1.1.11 h1:uVUAXhF2To8cbw/3xN3pxj6kk7TYKs98NIrTqPlMW github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= -github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/juju/ansiterm v0.0.0-20180109212912-720a0952cc2a/go.mod h1:UJSiEoRfvx3hP73CvoARgeLjaIOjybY9vj8PUPPFGeU= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= @@ -887,8 +931,10 @@ github.com/klauspost/compress v1.11.7/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYs github.com/klauspost/compress v1.11.13/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.12.2/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= github.com/klauspost/compress v1.12.3/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= -github.com/klauspost/compress v1.13.0 h1:2T7tUoQrQT+fQWdaY5rjWztFGAFwbGD04iPJg90ZiOs= github.com/klauspost/compress v1.13.0/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= +github.com/klauspost/compress v1.13.5/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= +github.com/klauspost/compress v1.13.6 h1:P76CopJELS0TiO2mebmnzgWaajssP/EszplttgQxcgc= +github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= github.com/klauspost/pgzip v1.2.5/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= @@ -917,6 +963,7 @@ github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69 github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= github.com/lunixbochs/vtclean v0.0.0-20180621232353-2d01aacdc34a/go.mod h1:pHhQNgMf3btfWnGBVipUOjRYhoOsdGqdm/+2c2E2WMI= github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ= +github.com/magefile/mage v1.11.0/go.mod h1:z5UZb/iS3GoOSn0JgWuiw7dxlurVYTu+/jHXqQg881A= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/magiconair/properties v1.8.5 h1:b6kJs+EmPFMYGkow9GiUyCyOvIwYetYJ3fSaWak/Gls= @@ -937,18 +984,26 @@ github.com/markbates/pkger v0.17.1/go.mod h1:0JoVlrol20BSywW79rN3kdFFsE5xYM+rSCQ github.com/marstr/guid v1.1.0/go.mod h1:74gB1z2wpxxInTG6yaqA7KrtM0NZ+RbrcqDvYHefzho= github.com/matryer/is v1.2.0 h1:92UTHpy8CDwaJ08GqLDzhhuixiBUUD1p3AU6PHddz4A= github.com/matryer/is v1.2.0/go.mod h1:2fLPjFQM9rhQ15aVEtbuwhJinnOqrmgXPNdZsdwlWXA= +github.com/mattmoor/dep-notify v0.0.0-20190205035814-a45dec370a17/go.mod h1:qWnF4u+oS4UWOZMwZcBQXrt5IQIdWc6XVJLDdxGIfdQ= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= -github.com/mattn/go-colorable v0.1.8 h1:c1ghPdyEDarC70ftn0y+A/Ee++9zz8ljHG1b13eJ0s8= +github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= +github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-colorable v0.1.11 h1:nQ+aFkoE2TMGc0b68U2OKSexC+eq46+XwZzWXHRmPYs= +github.com/mattn/go-colorable v0.1.11/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84= +github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= -github.com/mattn/go-isatty v0.0.13 h1:qdl+GuBjcsKKDco5BsxPJlId98mSWNKqYA+Co0SC1yA= github.com/mattn/go-isatty v0.0.13/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= +github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y= +github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/mattn/go-runewidth v0.0.10 h1:CoZ3S2P7pvtP45xOtBw+/mDL2z0RKI576gSkzRRpdGg= @@ -967,11 +1022,13 @@ github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b h1:j7+1HpAFS1zy5+Q4qx1f github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= github.com/miekg/dns v1.1.17/go.mod h1:WgzbA6oji13JREwiNsRDNfl7jYdPnmz+VEuLrA+/48M= +github.com/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso= github.com/miekg/dns v1.1.29/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM= github.com/miekg/pkcs11 v1.0.3/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs= github.com/mistifyio/go-zfs v2.1.1+incompatible/go.mod h1:8AuVvqP/mXw1px98n46wfvcGfQ4ci2FwoAjKYxuo3Z4= github.com/mistifyio/go-zfs v2.1.2-0.20190413222219-f784269be439+incompatible/go.mod h1:8AuVvqP/mXw1px98n46wfvcGfQ4ci2FwoAjKYxuo3Z4= github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= +github.com/mitchellh/cli v1.1.0/go.mod h1:xcISNoH86gajksDmfB23e/pu+B+GeFRMYmoHXxx3xhI= github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= @@ -984,10 +1041,12 @@ github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:F github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.3.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/mapstructure v1.3.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= -github.com/mitchellh/mapstructure v1.4.1 h1:CpVNEelQCZBooIPDn+AR3NpivK/TIKU8bDxdASFVQag= github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mitchellh/mapstructure v1.4.2 h1:6h7AQ0yhTcIsmFmnAwQls75jp2Gzs4iB8W7pjMO+rqo= +github.com/mitchellh/mapstructure v1.4.2/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/osext v0.0.0-20151018003038-5e2d6d41470f/go.mod h1:OkQIRizQZAeMln+1tSwduZz7+Af5oFlKirV/MSYes2A= github.com/moby/locker v1.0.1/go.mod h1:S7SDdo5zpBK84bzzVlKr2V0hz+7x9hWbYC/kq7oQppc= +github.com/moby/spdystream v0.2.0 h1:cjW1zVyyoiM0T7b6UoySUFqzXMoqRckQtXwGPiBhOM8= github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c= github.com/moby/sys/mount v0.2.0 h1:WhCW5B355jtxndN5ovugJlMFJawbUODuW8fSnEH6SSM= github.com/moby/sys/mount v0.2.0/go.mod h1:aAivFE2LB3W4bACsUXChRHQ0qKWsetY4Y9V7sxOougM= @@ -1070,29 +1129,35 @@ github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8 github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= github.com/opencontainers/image-spec v1.0.0/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= -github.com/opencontainers/image-spec v1.0.2-0.20190823105129-775207bd45b6 h1:yN8BPXVwMBAm3Cuvh1L5XE8XpvYRMdsVLd82ILprhUU= github.com/opencontainers/image-spec v1.0.2-0.20190823105129-775207bd45b6/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= +github.com/opencontainers/image-spec v1.0.2-0.20210730191737-8e42a01fb1b7 h1:axgApq2XShTLwQii2zAnIkMPlhGVHbAXHUcHezu5G/k= +github.com/opencontainers/image-spec v1.0.2-0.20210730191737-8e42a01fb1b7/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= github.com/opencontainers/runc v0.0.0-20190115041553-12f6a991201f/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U= github.com/opencontainers/runc v0.1.1/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U= github.com/opencontainers/runc v1.0.0-rc8.0.20190926000215-3e425f80a8c9/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U= github.com/opencontainers/runc v1.0.0-rc9/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U= github.com/opencontainers/runc v1.0.0-rc91/go.mod h1:3Sm6Dt7OT8z88EbdQqqcRN2oCT54jbi72tT/HqgflT8= -github.com/opencontainers/runc v1.0.0-rc93 h1:x2UMpOOVf3kQ8arv/EsDGwim8PTNqzL1/EYDr/+scOM= github.com/opencontainers/runc v1.0.0-rc93/go.mod h1:3NOsor4w32B2tC0Zbl8Knk4Wg84SM2ImC1fxBuqJ/H0= +github.com/opencontainers/runc v1.0.2 h1:opHZMaswlyxz1OuGpBE53Dwe4/xF7EZTY0A2L/FpCOg= +github.com/opencontainers/runc v1.0.2/go.mod h1:aTaHFFwQXuA71CiyxOdFFIorAoemI04suvGRQFzWTD0= github.com/opencontainers/runtime-spec v0.1.2-0.20190507144316-5b71a03e2700/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opencontainers/runtime-spec v1.0.1/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opencontainers/runtime-spec v1.0.2-0.20190207185410-29686dbc5559/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opencontainers/runtime-spec v1.0.2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opencontainers/runtime-spec v1.0.3-0.20200520003142-237cc4f519e2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= -github.com/opencontainers/runtime-spec v1.0.3-0.20200929063507-e6143ca7d51d h1:pNa8metDkwZjb9g4T8s+krQ+HRgZAkqnXml+wNir/+s= github.com/opencontainers/runtime-spec v1.0.3-0.20200929063507-e6143ca7d51d/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= +github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417 h1:3snG66yBm59tKhhSPQrQ/0bCrv1LQbKt40LnUPiUxdc= +github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opencontainers/runtime-tools v0.0.0-20181011054405-1d69bd0f9c39/go.mod h1:r3f7wjNzSs2extwzU3Y+6pKfobzPh+kKFJ3ofN+3nfs= github.com/opencontainers/selinux v1.5.1/go.mod h1:yTcKuYAh6R95iDpefGLQaPaRwJFwyzAJufJyiTt7s0g= github.com/opencontainers/selinux v1.6.0/go.mod h1:VVGKuOLlE7v4PJyT6h7mNWvq1rzqiriPsEqVhc+svHE= -github.com/opencontainers/selinux v1.8.0 h1:+77ba4ar4jsCbL1GLbFL8fFM57w6suPfSS9PDLDY7KM= github.com/opencontainers/selinux v1.8.0/go.mod h1:RScLhm78qiWa2gbVCcGkC7tCGdgk3ogry1nUQF8Evvo= -github.com/openshift-knative/kn-plugin-func v0.19.1-0.20211111003512-0804607608c3 h1:thv6IuJCGdFT84GHplkP7pcqkwVZuY4BoYwaJ2iyEsc= -github.com/openshift-knative/kn-plugin-func v0.19.1-0.20211111003512-0804607608c3/go.mod h1:VBTSkzSgcXxLN9rarwtleAINPiQDF+TesLTAlG/JSi0= +github.com/opencontainers/selinux v1.8.2 h1:c4ca10UMgRcvZ6h0K4HtS15UaVSBEaE+iln2LVpAuGc= +github.com/opencontainers/selinux v1.8.2/go.mod h1:MUIHuUEvKB1wtJjQdOyYRgOnLD2xAPP8dBsCoU0KuF8= +github.com/openshift-knative/kn-plugin-event v0.26.2-0.20211209202740-89c860ca5062 h1:SolI+Rwqy058Dofm6naxk9y3vzQ4anT69UQWKoB0zHI= +github.com/openshift-knative/kn-plugin-event v0.26.2-0.20211209202740-89c860ca5062/go.mod h1:naLIG+DrwI78CKuuuJB8C0D1X/ySUzolzmgctV4+vZQ= +github.com/openshift-knative/kn-plugin-func v0.19.1-0.20211209011132-6e9942151b08 h1:NkAt/jTei6duqeVe7YgBEiRiROYTtwhwAI9PBTvzngw= +github.com/openshift-knative/kn-plugin-func v0.19.1-0.20211209011132-6e9942151b08/go.mod h1:1PbnyT3BJ3dvxDuMQk5ej0gHG+uy/ryH6AS71LhJf1k= github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go.mod h1:Ngi6UdF0k5OKD5t5wlmGhe/EDKPoUM3BXZSSfIuJbis= github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74= github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= @@ -1120,6 +1185,7 @@ github.com/pelletier/go-toml/v2 v2.0.0-beta.2/go.mod h1:+X+aW6gUj6Hda43TeYHVCIvY github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac= github.com/peterbourgon/diskv v2.0.1+incompatible h1:UBdAOUP5p4RWqPBg048CAvpKN+vxiaj6gdUUzhl4XmI= github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= +github.com/phayes/freeport v0.0.0-20180830031419-95f893ade6f2 h1:JhzVVoYvbOACxoUmOs6V/G4D5nPVUW73rKvXxP4XUJc= github.com/phayes/freeport v0.0.0-20180830031419-95f893ade6f2/go.mod h1:iIss55rKnNBTvrwdmkUpLnDpZoAHvWaiq5+iMmen4AE= github.com/pierrec/lz4 v0.0.0-20190327172049-315a67e90e41/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc= github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc= @@ -1138,6 +1204,7 @@ github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= +github.com/posener/complete v1.2.3/go.mod h1:WZIdtGGp+qx0sLrYKtIRAruyNpv6hFCicSgv7Sy7s/s= github.com/pquerna/cachecontrol v0.0.0-20171018203845-0dec1b30a021/go.mod h1:prYjPmNq4d1NPVmpShWobRqXY3q7Vp+80DqgxxUrUIA= github.com/pquerna/ffjson v0.0.0-20181028064349-e517b90714f7/go.mod h1:YARuvh7BUWHNhzDq2OM5tzR2RiCcN2D7sapiKyCel/M= github.com/pquerna/ffjson v0.0.0-20190813045741-dac163c6c0a9/go.mod h1:YARuvh7BUWHNhzDq2OM5tzR2RiCcN2D7sapiKyCel/M= @@ -1172,8 +1239,9 @@ github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB8 github.com/prometheus/common v0.15.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s= github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= github.com/prometheus/common v0.28.0/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= -github.com/prometheus/common v0.30.0 h1:JEkYlQnpzrzQFxi6gnukFPdQ+ac82oRhzMcIduJu/Ug= github.com/prometheus/common v0.30.0/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= +github.com/prometheus/common v0.31.1 h1:d18hG4PkHnNAKNMOmFuXFaiY8Us0nird/2m60uS1AMs= +github.com/prometheus/common v0.31.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= github.com/prometheus/procfs v0.0.0-20180125133057-cb4147076ac7/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= @@ -1223,6 +1291,7 @@ github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb github.com/sabhiram/go-gitignore v0.0.0-20201211074657-223ce5d391b0 h1:4Q/TASkyjpqyR5DL5+6c2FGSDpHM5bTMSspcXr7J6R8= github.com/sabhiram/go-gitignore v0.0.0-20201211074657-223ce5d391b0/go.mod h1:b18R55ulyQ/h3RaWyloPyER7fWQVZvimKKhnI5OfrJQ= github.com/safchain/ethtool v0.0.0-20190326074333-42ed695e3de8/go.mod h1:Z0q5wiBQGYcxhMZ6gUqHn6pYNLypFAvaL3UvgZLR0U4= +github.com/sagikazarmark/crypt v0.1.0/go.mod h1:B/mN0msZuINBtQ1zZLEQcegFJJf9vnYIR88KRMEuODE= github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E= github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= github.com/sclevine/spec v1.2.0/go.mod h1:W4J29eT/Kzv7/b9IWLB055Z+qvVC9vt0Arko24q7p+U= @@ -1245,11 +1314,9 @@ github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/slinkydeveloper/loadastic v0.0.0-20201218203601-5c69eea3b7d8/go.mod h1:vNSJ7ak+2OeAb5bhSHRmMKKcbadbxlokx/Wh1lC50e4= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= -github.com/smartystreets/assertions v1.0.0 h1:UVQPSSmc3qtTi+zPPkCXvZX9VvW/xT/NsRvKfwY81a8= github.com/smartystreets/assertions v1.0.0/go.mod h1:kHHU4qYBaI3q23Pp3VPrmWhuIUrLW/7eUrw0BU5VaoM= github.com/smartystreets/go-aws-auth v0.0.0-20180515143844-0c1422d1fdb9/go.mod h1:SnhjPscd9TpLiy1LpzGSKh3bXCfxxXuqd9xmQJy3slM= github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= -github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/smartystreets/gunit v1.0.0/go.mod h1:qwPWnhz6pn0NnRBP++URONOVyNkPyr4SauJk4cUOwJs= github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= @@ -1261,11 +1328,13 @@ github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTd github.com/spf13/afero v1.6.0 h1:xoax2sJ2DT8S8xA2paPFjDCScCNeWsg75VG0DLRreiY= github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= -github.com/spf13/cast v1.3.1 h1:nFm6S0SMdyzrzcmThSipiEubIDy8WEXKNZ0UOgiRpng= github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= +github.com/spf13/cast v1.4.1 h1:s0hze+J0196ZfEMTs80N7UlFt0BDuQ7Q+JDnHiMWKdA= +github.com/spf13/cast v1.4.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cobra v0.0.2-0.20171109065643-2da4a54c5cee/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= +github.com/spf13/cobra v0.0.7/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE= github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE= github.com/spf13/cobra v1.1.1/go.mod h1:WnodtKOvamDL/PwE2M4iKs8aMDBZ5Q5klgD3qfVJQMI= github.com/spf13/cobra v1.1.3/go.mod h1:pGADOWyqRD/YMrPZigI/zbliZ2wVD/23d+is3pSWzOo= @@ -1284,8 +1353,9 @@ github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DM github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE= github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= github.com/spf13/viper v1.7.1/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= -github.com/spf13/viper v1.8.1 h1:Kq1fyeebqsBfbjZj4EL7gj2IO0mMaiyjYUWcUsl2O44= github.com/spf13/viper v1.8.1/go.mod h1:o0Pch8wJ9BVSWGQMbra6iw0oQ5oktSIBaujf1rJH9Ns= +github.com/spf13/viper v1.9.0 h1:yR6EXjTp0y0cLN8OZg1CRZmOBdI88UcGkhgyJhu6nZk= +github.com/spf13/viper v1.9.0/go.mod h1:+i6ajR7OX2XaiBkrcZJFK21htRk7eDeLg7+O6bhUPP4= github.com/sqs/goreturns v0.0.0-20181028201513-538ac6014518/go.mod h1:CKI4AZ4XmGV240rTHfO0hfE83S6/a3/Q1siZJ/vXf7A= github.com/src-d/gcfg v1.4.0 h1:xXbNR5AlLSA315x2UO+fTSSAXCDf+Ar38/6oyGbDKQ4= github.com/src-d/gcfg v1.4.0/go.mod h1:p/UMsR43ujA89BJY9duynAwIpvqEujIH/jFlfL7jWoI= @@ -1318,6 +1388,8 @@ github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635 h1:kdXcSzyDtse github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= github.com/tchap/go-patricia v2.2.6+incompatible/go.mod h1:bmLyhP68RS6kStMGxByiQ23RP/odRBOTVjwp2cDyi6I= github.com/tchap/go-patricia v2.3.0+incompatible/go.mod h1:bmLyhP68RS6kStMGxByiQ23RP/odRBOTVjwp2cDyi6I= +github.com/thediveo/enumflag v0.10.0 h1:CQIGWQYgFIKTUvRf5FL3K5ksQzzBag/HSUCu3Oin+Jw= +github.com/thediveo/enumflag v0.10.0/go.mod h1:zbsjXNJ3Np5ZXjUDgXeXsF2THwQd6ybEKMLw9XnQZ8o= github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= github.com/tj/assert v0.0.0-20171129193455-018094318fb0/go.mod h1:mZ9/Rh9oLWpLLDRpvE+3b7gP/C2YyLFYxNmcLnPTMe0= github.com/tj/assert v0.0.3 h1:Df/BlaZ20mq6kuai7f5z2TvPFiwC3xaWJSDQNiIS3Rk= @@ -1339,9 +1411,12 @@ github.com/urfave/cli v0.0.0-20171014202726-7bc6a0acffa5/go.mod h1:70zkFmudgCuE/ github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= +github.com/urfave/cli v1.22.4/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= github.com/vbatts/tar-split v0.11.1/go.mod h1:LEuURwDEiWjRjwu46yU3KVGuUdVv/dcnpcEPSzR8z6g= +github.com/vbatts/tar-split v0.11.2 h1:Via6XqJr0hceW4wff3QRzD5gAk/tatMw/4ZA7cTlIME= +github.com/vbatts/tar-split v0.11.2/go.mod h1:vV3ZuO2yWSVsz+pfFzDG/upWH1JhjOiEaWq6kXyQ3VI= github.com/vbauerster/mpb/v5 v5.4.0/go.mod h1:fi4wVo7BVQ22QcvFObm+VwliQXlV1eBT8JDaKXR4JGI= github.com/vdemeester/k8s-pkg-credentialprovider v1.19.7/go.mod h1:K2nMO14cgZitdwBqdQps9tInJgcaXcU/7q5F59lpbNI= github.com/vdemeester/k8s-pkg-credentialprovider v1.21.0-1/go.mod h1:l4LxiP0cmEcc5q4BTDE8tZSyIiyXe0T28x37yHpMzoM= @@ -1353,9 +1428,10 @@ github.com/vishvananda/netns v0.0.0-20180720170159-13995c7128cc/go.mod h1:ZjcWmF github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17pCcGlemwknint6hfoeCVQrEMVwxRLRjXpq+BU= github.com/vishvananda/netns v0.0.0-20200728191858-db3c7e526aae/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0= github.com/vmware/govmomi v0.20.3/go.mod h1:URlwyTFZX72RmxtxuaFL2Uj3fD1JTvZdx59bHWk6aFU= +github.com/wavesoftware/go-ensure v1.0.0 h1:6X3gQL5psBWwtu/H9a+69xQ+JGTUELaLhgOB/iB3AQk= github.com/wavesoftware/go-ensure v1.0.0/go.mod h1:K2UAFSwMTvpiRGay/M3aEYYuurcR8S4A6HkQlJPV8k4= +github.com/wavesoftware/go-magetasks v0.6.0/go.mod h1:8/zmKLAbJFwjAZOF8U2BnmVa9aDrLPtd4XO5b67uflY= github.com/willf/bitset v1.1.11-0.20200630133818-d5bec3311243/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4= -github.com/willf/bitset v1.1.11 h1:N7Z7E9UvjW+sGsEl7k/SJrvY2reP1A07MrGuCjIOjRE= github.com/willf/bitset v1.1.11/go.mod h1:83CECat5yLh5zVOf4P1ErAgKA5UDvKtgyUABdr3+MjI= github.com/xanzy/ssh-agent v0.2.1/go.mod h1:mLlQY/MoOhWBj+gOGMQkOeiEvkx+8pJSI+0Bx9h2kr4= github.com/xanzy/ssh-agent v0.3.0 h1:wUMzuKtKilRgBAD1sUb8gOwwRr2FGoBVumcjoOACClI= @@ -1422,8 +1498,9 @@ go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE= go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/automaxprocs v1.4.0/go.mod h1:/mTEdr7LvHhs0v7mjdxDreTz1OG5zdZGqgOnhWiR/+Q= -go.uber.org/goleak v1.1.10 h1:z+mqJhf6ss6BSfSM671tgKyZBFPTTJM+HLxnhPC3wu0= go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= +go.uber.org/goleak v1.1.11-0.20210813005559-691160354723 h1:sHOAIxRGBp443oHZIPB+HsUGaksVCXVQENPxwTfQdH4= +go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= @@ -1434,8 +1511,9 @@ go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= go.uber.org/zap v1.16.0/go.mod h1:MA8QOfq0BHJwdXa996Y4dYkAqRKB8/1K1QMMZVaNZjQ= go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo= -go.uber.org/zap v1.19.0 h1:mZQZefskPPCMIBCSEH0v2/iUqqLrYtaeqwD6FUGUnFE= go.uber.org/zap v1.19.0/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI= +go.uber.org/zap v1.19.1 h1:ue41HOKd1vGURxrmeKIgELGb3jPW9DMUDGtsinblHwI= +go.uber.org/zap v1.19.1/go.mod h1:j3DNczoxDZroyBnOT1L/Q79cfUMGZxlv/9dzN7SM1rI= golang.org/x/crypto v0.0.0-20171113213409-9f005a07e0d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181009213950-7c1a557ab941/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= @@ -1455,6 +1533,7 @@ golang.org/x/crypto v0.0.0-20190617133340-57b3e21c3d56/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190829043050-9756ffdc2472/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200423211502-4bdfaf469ed5/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= @@ -1496,7 +1575,6 @@ golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRu golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 h1:VLliZ0d+/avPrXXH+OakdXhpJuEoBZuwh1m2j7U6Iug= golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= @@ -1577,8 +1655,9 @@ golang.org/x/net v0.0.0-20210610132358-84b48f89b13b/go.mod h1:9nx3DQGgdP8bBQD5qx golang.org/x/net v0.0.0-20210614182718-04defd469f4e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210825183410-e898025ed96a/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20210929193557-e81a3d93ecf6 h1:Z04ewVs7JhXaYkmDhBERPi41gnltfQpMWDnTnQbaCqk= golang.org/x/net v0.0.0-20210929193557-e81a3d93ecf6/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20211020060615-d418f374d309 h1:A0lJIi+hcTR6aajJH4YqKWwohY4aW9RO7oRMcdv+HKI= +golang.org/x/net v0.0.0-20211020060615-d418f374d309/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -1595,8 +1674,10 @@ golang.org/x/oauth2 v0.0.0-20210402161424-2e8d93401602/go.mod h1:KelEdhl1UZF7XfJ golang.org/x/oauth2 v0.0.0-20210427180440-81ed05c6b58c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210628180205-a41e5a781914/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f h1:Qmd2pbz05z7z6lm0DrgQVVPuBm92jqujBKMHMOlOQEw= +golang.org/x/oauth2 v0.0.0-20210805134026-6f1e6394065a/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20211005180243-6b3c2da341f1 h1:B333XXssMuKQeBwiNODx4TupZy7bf4sxFZnN2ZOcvUE= +golang.org/x/oauth2 v0.0.0-20211005180243-6b3c2da341f1/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -1644,10 +1725,12 @@ golang.org/x/sys v0.0.0-20190812073006-9eafafc0a87e/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191002063906-3421d5a6bb1c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191010194322-b09406accb47/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191022100944-742c48ecaeb7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1719,10 +1802,17 @@ golang.org/x/sys v0.0.0-20210603125802-9665404d3644/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20210608053332-aa57babbf139/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210819135213-f52c844e1c1c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211002104244-808efd93c36d h1:SABT8Vei3iTiu+Gy8KOzpSNz+W1EQ5YBCRtiEETxF+0= +golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210908233432-aa78b53d3365/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210917161153-d61c044b1678/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211002104244-808efd93c36d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359 h1:2B5p2L5IfGiD7+b9BOoRMC6DgObAVZV+Fsp050NqXik= +golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20201210144234-2321bbc49cbf/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= @@ -1830,6 +1920,7 @@ golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.6/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo= golang.org/x/tools v0.1.7 h1:6j8CgantCy3yc8JGBqkDLMKWqZ0RDU2g1HVgacojGWQ= golang.org/x/tools v0.1.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -1875,8 +1966,14 @@ google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk google.golang.org/api v0.44.0/go.mod h1:EBOGZqzyhtvMDoxwS97ctnh0zUmYY6CxqXsc1AvkYD8= google.golang.org/api v0.47.0/go.mod h1:Wbvgpq1HddcWVtzsVLyfLp8lDg6AA241LmgIL59tHXo= google.golang.org/api v0.48.0/go.mod h1:71Pr1vy+TAZRPkPs/xlCf5SsU8WjuAWv1Pfjbtukyy4= -google.golang.org/api v0.50.0 h1:LX7NFCFYOHzr7WHaYiRUpeipZe9o5L8T+2F4Z798VDw= google.golang.org/api v0.50.0/go.mod h1:4bNT5pAuq5ji4SRZm+5QIkjny9JAyVD/3gaSihNefaw= +google.golang.org/api v0.51.0/go.mod h1:t4HdrdoNgyN5cbEfm7Lum0lcLDLiise1F8qDKX00sOU= +google.golang.org/api v0.54.0/go.mod h1:7C4bFFOvVDGXjfDTAsgGwDgAxRDeQ4X8NvUedIt6z3k= +google.golang.org/api v0.55.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE= +google.golang.org/api v0.56.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE= +google.golang.org/api v0.57.0/go.mod h1:dVPlbZyBo2/OjBpmvNdpn2GRm6rPy75jyU7bmhdrMgI= +google.golang.org/api v0.58.0 h1:MDkAbYIB1JpSgCTOCYYoIec/coMlKK4oVbpnBLLcyT0= +google.golang.org/api v0.58.0/go.mod h1:cAbP2FsxoGVNwtgNAmmn3y5G1TWAiVYRmg4yku3lv+E= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= @@ -1941,8 +2038,21 @@ google.golang.org/genproto v0.0.0-20210603172842-58e84a565dcf/go.mod h1:UODoCrxH google.golang.org/genproto v0.0.0-20210604141403-392c879c8b08/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= google.golang.org/genproto v0.0.0-20210608205507-b6d2f5bf0d7d/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= google.golang.org/genproto v0.0.0-20210610141715-e7a9b787a5a4/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= -google.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84 h1:R1r5J0u6Cx+RNl/6mezTw6oA14cmKC96FeUwL6A9bd4= google.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84/go.mod h1:SzzZ/N+nwJDaO1kznhnlzqS8ocJICar6hYhVyhi++24= +google.golang.org/genproto v0.0.0-20210713002101-d411969a0d9a/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k= +google.golang.org/genproto v0.0.0-20210716133855-ce7ef5c701ea/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k= +google.golang.org/genproto v0.0.0-20210728212813-7823e685a01f/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= +google.golang.org/genproto v0.0.0-20210805201207-89edb61ffb67/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= +google.golang.org/genproto v0.0.0-20210813162853-db860fec028c/go.mod h1:cFeNkxwySK631ADgubI+/XFU/xp8FD5KIVV4rj8UC5w= +google.golang.org/genproto v0.0.0-20210821163610-241b8fcbd6c8/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210828152312-66f60bf46e71/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210831024726-fe130286e0e2/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210903162649-d08c68adba83/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210909211513-a8c4777a87af/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210917145530-b395a37504d4/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210924002016-3dee208752a0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20211027162914-98a5263abeca h1:+e+aQDO4/c9KaG8PXWHTc6/+Du6kz+BKcXCSnV4SSTE= +google.golang.org/genproto v0.0.0-20211027162914-98a5263abeca/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/grpc v0.0.0-20160317175043-d3ddb4469d5a/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= @@ -1972,8 +2082,11 @@ google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAG google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= google.golang.org/grpc v1.37.1/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= -google.golang.org/grpc v1.40.0 h1:AGJ0Ih4mHjSeibYkFGh1dD9KJ/eOtZ93I6hoHhukQ5Q= +google.golang.org/grpc v1.39.0/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= +google.golang.org/grpc v1.39.1/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= +google.golang.org/grpc v1.41.0 h1:f+PlOh7QV4iIJkPrx5NQ7qaNGFQ3OTse67yaDHfju4E= +google.golang.org/grpc v1.41.0/go.mod h1:U3l9uK9J0sini8mHphKoXyaqDA/8VyGnDee1zzIUK6k= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= @@ -2011,8 +2124,9 @@ gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/ini.v1 v1.56.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= -gopkg.in/ini.v1 v1.62.0 h1:duBzk771uxoUuOlyRLkHsygud9+5lrlGjdFBb4mSKDU= gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/ini.v1 v1.63.2 h1:tGK/CyBg7SMzb60vP1M03vNZ3VDu3wGQJwn7Sxi9r3c= +gopkg.in/ini.v1 v1.63.2/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/jcmturner/aescts.v1 v1.0.1/go.mod h1:nsR8qBOg+OucoIW+WMhB3GspUQXq9XorLnQb9XtvcOo= gopkg.in/jcmturner/dnsutils.v1 v1.0.1/go.mod h1:m3v+5svpVOhtFAP/wSz+yzh4Mc0Fg7eRhxkJMWSIz9Q= gopkg.in/jcmturner/goidentity.v3 v3.0.0/go.mod h1:oG2kH0IvSYNIu80dVAyu/yoefjq1mNfM5bm88whjWx4= @@ -2045,6 +2159,7 @@ gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.0-20191026110619-0b21df46bc1d/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200605160147-a5ece683394c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= @@ -2075,12 +2190,6 @@ k8s.io/api v0.21.4/go.mod h1:fTVGP+M4D8+00FN2cMnJqk/eb/GH53bvmNs2SVTmpFk= k8s.io/apiextensions-apiserver v0.19.7/go.mod h1:XJNNtjISNNePDEUClHt/igzMpQcmjVVh88QH+PKztPU= k8s.io/apiextensions-apiserver v0.21.4 h1:HkajN/vmT/9HnFmUxvpXfSGkTCvH/ax4e3+j6mqWUDU= k8s.io/apiextensions-apiserver v0.21.4/go.mod h1:OoC8LhI9LnV+wKjZkXIBbLUwtnOGJiTRE33qctH5CIk= -k8s.io/apimachinery v0.19.7/go.mod h1:6sRbGRAVY5DOCuZwB5XkqguBqpqLU6q/kOaOdk29z6Q= -k8s.io/apimachinery v0.20.1/go.mod h1:WlLqWAHZGg07AeltaI0MV5uk1Omp8xaN0JGLY6gkRpU= -k8s.io/apimachinery v0.20.4/go.mod h1:WlLqWAHZGg07AeltaI0MV5uk1Omp8xaN0JGLY6gkRpU= -k8s.io/apimachinery v0.20.6/go.mod h1:ejZXtW1Ra6V1O5H8xPBGz+T3+4gfkTCeExAHKU57MAc= -k8s.io/apimachinery v0.21.0/go.mod h1:jbreFvJo3ov9rj7eWT7+sYiRx+qZuCYXwWT1bcDswPY= -k8s.io/apimachinery v0.21.1/go.mod h1:jbreFvJo3ov9rj7eWT7+sYiRx+qZuCYXwWT1bcDswPY= k8s.io/apimachinery v0.21.4 h1:KDq0lWZVslHkuE5I7iGAQHwpK0aDTlar1E7IWEc4CNw= k8s.io/apimachinery v0.21.4/go.mod h1:H/IM+5vH9kZRNJ4l3x/fXP/5bOPJaVP/guptnZPeCFI= k8s.io/apiserver v0.19.7/go.mod h1:DmWVQggNePspa+vSsVytVbS3iBSDTXdJVt0akfHacKk= @@ -2132,8 +2241,9 @@ k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE= k8s.io/klog/v2 v2.2.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y= k8s.io/klog/v2 v2.4.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y= k8s.io/klog/v2 v2.5.0/go.mod h1:hy9LJ/NvuK+iVyP4Ehqva4HxZG/oXyIS3n3Jmire4Ec= -k8s.io/klog/v2 v2.8.0 h1:Q3gmuM9hKEjefWFFYF0Mat+YyFJvsUyYuwyNNJ5C9Ts= k8s.io/klog/v2 v2.8.0/go.mod h1:hy9LJ/NvuK+iVyP4Ehqva4HxZG/oXyIS3n3Jmire4Ec= +k8s.io/klog/v2 v2.30.0 h1:bUO6drIvCIsvZ/XFgfxoGFQU/a4Qkh0iAlvUR7vlHJw= +k8s.io/klog/v2 v2.30.0/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= k8s.io/kube-openapi v0.0.0-20200805222855-6aeccd4b50c6/go.mod h1:UuqjUnNftUyPE5H64/qeyjQoUZhGpeFDVdxjTeEVN2o= k8s.io/kube-openapi v0.0.0-20201113171705-d219536bb9fd/go.mod h1:WOJ3KddDSol4tAGcJo0Tvi+dK12EcqSLqcWsryKMpfM= k8s.io/kube-openapi v0.0.0-20210113233702-8566a335510f/go.mod h1:WOJ3KddDSol4tAGcJo0Tvi+dK12EcqSLqcWsryKMpfM= @@ -2192,6 +2302,7 @@ sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.9/go.mod h1:dzAXnQb sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.14/go.mod h1:LEScyzhFmoF5pso/YSeBstl57mOzx9xlU9n85RGrDQg= sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.15/go.mod h1:LEScyzhFmoF5pso/YSeBstl57mOzx9xlU9n85RGrDQg= sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.22/go.mod h1:LEScyzhFmoF5pso/YSeBstl57mOzx9xlU9n85RGrDQg= +sigs.k8s.io/kind v0.11.1/go.mod h1:fRpgVhtqAWrtLB9ED7zQahUimpUXuG/iHT88xYqEGIA= sigs.k8s.io/kustomize v2.0.3+incompatible h1:JUufWFNlI44MdtnjUqVnvh29rR37PQFzPbLXqhyOyX0= sigs.k8s.io/kustomize v2.0.3+incompatible/go.mod h1:MkjgH3RdOWrievjo6c9T245dYlB5QeXV4WCbnt/PEpU= sigs.k8s.io/kustomize/api v0.8.8 h1:G2z6JPSSjtWWgMeWSoHdXqyftJNmMmyxXpwENGoOtGE= @@ -2205,6 +2316,7 @@ sigs.k8s.io/structured-merge-diff/v4 v4.1.0/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK sigs.k8s.io/structured-merge-diff/v4 v4.1.2 h1:Hr/htKFmJEbtMgS/UD0N+gtgctAqz81t3nu+sPzynno= sigs.k8s.io/structured-merge-diff/v4 v4.1.2/go.mod h1:j/nl6xW8vLS49O8YvXW1ocPhZawJtm+Yrr7PPRQ0Vg4= sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= -sigs.k8s.io/yaml v1.2.0 h1:kr/MCeFWJWTwyaHoR9c8EjH9OumOmoF9YGiZd7lFm/Q= sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc= +sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo= +sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8= sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU= diff --git a/pkg/kn/root/plugin_register.go b/pkg/kn/root/plugin_register.go index 969b0620dc..6100004f3a 100644 --- a/pkg/kn/root/plugin_register.go +++ b/pkg/kn/root/plugin_register.go @@ -18,6 +18,7 @@ package root import ( // Add #plugins# import here. Don't remove this line, it triggers an automatic replacement. + _ "knative.dev/kn-plugin-event/pkg/plugin" _ "knative.dev/kn-plugin-func/plugin" _ "knative.dev/kn-plugin-source-kafka/plugin" ) diff --git a/third_party/VENDOR-LICENSE/github.com/willf/bitset/LICENSE b/third_party/VENDOR-LICENSE/github.com/bits-and-blooms/bitset/LICENSE similarity index 100% rename from third_party/VENDOR-LICENSE/github.com/willf/bitset/LICENSE rename to third_party/VENDOR-LICENSE/github.com/bits-and-blooms/bitset/LICENSE diff --git a/third_party/VENDOR-LICENSE/github.com/coreos/go-semver/semver/LICENSE b/third_party/VENDOR-LICENSE/github.com/coreos/go-semver/semver/LICENSE new file mode 100644 index 0000000000..d645695673 --- /dev/null +++ b/third_party/VENDOR-LICENSE/github.com/coreos/go-semver/semver/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/third_party/VENDOR-LICENSE/github.com/coreos/go-semver/semver/NOTICE b/third_party/VENDOR-LICENSE/github.com/coreos/go-semver/semver/NOTICE new file mode 100644 index 0000000000..23a0ada2fb --- /dev/null +++ b/third_party/VENDOR-LICENSE/github.com/coreos/go-semver/semver/NOTICE @@ -0,0 +1,5 @@ +CoreOS Project +Copyright 2018 CoreOS, Inc + +This product includes software developed at CoreOS, Inc. +(http://www.coreos.com/). diff --git a/third_party/VENDOR-LICENSE/github.com/ghodss/yaml/LICENSE b/third_party/VENDOR-LICENSE/github.com/ghodss/yaml/LICENSE new file mode 100644 index 0000000000..7805d36de7 --- /dev/null +++ b/third_party/VENDOR-LICENSE/github.com/ghodss/yaml/LICENSE @@ -0,0 +1,50 @@ +The MIT License (MIT) + +Copyright (c) 2014 Sam Ghods + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + + +Copyright (c) 2012 The Go Authors. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/third_party/VENDOR-LICENSE/github.com/klauspost/compress/LICENSE b/third_party/VENDOR-LICENSE/github.com/klauspost/compress/LICENSE index 1eb75ef68e..87d5574777 100644 --- a/third_party/VENDOR-LICENSE/github.com/klauspost/compress/LICENSE +++ b/third_party/VENDOR-LICENSE/github.com/klauspost/compress/LICENSE @@ -26,3 +26,279 @@ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +------------------ + +Files: gzhttp/* + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2016-2017 The New York Times Company + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +------------------ + +Files: s2/cmd/internal/readahead/* + +The MIT License (MIT) + +Copyright (c) 2015 Klaus Post + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +--------------------- +Files: snappy/* +Files: internal/snapref/* + +Copyright (c) 2011 The Snappy-Go Authors. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +----------------- + +Files: s2/cmd/internal/filepathx/* + +Copyright 2016 The filepathx Authors + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/third_party/VENDOR-LICENSE/github.com/klauspost/compress/internal/snapref/LICENSE b/third_party/VENDOR-LICENSE/github.com/klauspost/compress/internal/snapref/LICENSE new file mode 100644 index 0000000000..6050c10f4c --- /dev/null +++ b/third_party/VENDOR-LICENSE/github.com/klauspost/compress/internal/snapref/LICENSE @@ -0,0 +1,27 @@ +Copyright (c) 2011 The Snappy-Go Authors. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/third_party/VENDOR-LICENSE/github.com/moby/spdystream/LICENSE b/third_party/VENDOR-LICENSE/github.com/moby/spdystream/LICENSE new file mode 100644 index 0000000000..d645695673 --- /dev/null +++ b/third_party/VENDOR-LICENSE/github.com/moby/spdystream/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/third_party/VENDOR-LICENSE/github.com/moby/spdystream/NOTICE b/third_party/VENDOR-LICENSE/github.com/moby/spdystream/NOTICE new file mode 100644 index 0000000000..b9b11c9ab7 --- /dev/null +++ b/third_party/VENDOR-LICENSE/github.com/moby/spdystream/NOTICE @@ -0,0 +1,5 @@ +SpdyStream +Copyright 2014-2021 Docker Inc. + +This product includes software developed at +Docker Inc. (https://www.docker.com/). diff --git a/third_party/VENDOR-LICENSE/github.com/thediveo/enumflag/LICENSE b/third_party/VENDOR-LICENSE/github.com/thediveo/enumflag/LICENSE new file mode 100644 index 0000000000..d9a10c0d8e --- /dev/null +++ b/third_party/VENDOR-LICENSE/github.com/thediveo/enumflag/LICENSE @@ -0,0 +1,176 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS diff --git a/third_party/VENDOR-LICENSE/github.com/vbatts/tar-split/archive/tar/LICENSE b/third_party/VENDOR-LICENSE/github.com/vbatts/tar-split/archive/tar/LICENSE new file mode 100644 index 0000000000..ca03685b15 --- /dev/null +++ b/third_party/VENDOR-LICENSE/github.com/vbatts/tar-split/archive/tar/LICENSE @@ -0,0 +1,28 @@ +Copyright (c) 2015 Vincent Batts, Raleigh, NC, USA + +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this +list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its contributors +may be used to endorse or promote products derived from this software without +specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/third_party/VENDOR-LICENSE/github.com/wavesoftware/go-ensure/LICENSE b/third_party/VENDOR-LICENSE/github.com/wavesoftware/go-ensure/LICENSE new file mode 100644 index 0000000000..6c180a6f23 --- /dev/null +++ b/third_party/VENDOR-LICENSE/github.com/wavesoftware/go-ensure/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2020 Wave Software + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/third_party/VENDOR-LICENSE/google.golang.org/grpc/NOTICE.txt b/third_party/VENDOR-LICENSE/google.golang.org/grpc/NOTICE.txt new file mode 100644 index 0000000000..530197749e --- /dev/null +++ b/third_party/VENDOR-LICENSE/google.golang.org/grpc/NOTICE.txt @@ -0,0 +1,13 @@ +Copyright 2014 gRPC authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/third_party/VENDOR-LICENSE/knative.dev/kn-plugin-event/LICENSE b/third_party/VENDOR-LICENSE/knative.dev/kn-plugin-event/LICENSE new file mode 100644 index 0000000000..059b110a18 --- /dev/null +++ b/third_party/VENDOR-LICENSE/knative.dev/kn-plugin-event/LICENSE @@ -0,0 +1,202 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2020 Knative CLI Event Contributors + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + diff --git a/vendor/cloud.google.com/go/compute/metadata/metadata.go b/vendor/cloud.google.com/go/compute/metadata/metadata.go index 545bd9d379..b6e1f7b614 100644 --- a/vendor/cloud.google.com/go/compute/metadata/metadata.go +++ b/vendor/cloud.google.com/go/compute/metadata/metadata.go @@ -282,6 +282,7 @@ func NewClient(c *http.Client) *Client { // getETag returns a value from the metadata service as well as the associated ETag. // This func is otherwise equivalent to Get. func (c *Client) getETag(suffix string) (value, etag string, err error) { + ctx := context.TODO() // Using a fixed IP makes it very difficult to spoof the metadata service in // a container, which is an important use-case for local testing of cloud // deployments. To enable spoofing of the metadata service, the environment @@ -304,9 +305,25 @@ func (c *Client) getETag(suffix string) (value, etag string, err error) { } req.Header.Set("Metadata-Flavor", "Google") req.Header.Set("User-Agent", userAgent) - res, err := c.hc.Do(req) - if err != nil { - return "", "", err + var res *http.Response + var reqErr error + retryer := newRetryer() + for { + res, reqErr = c.hc.Do(req) + var code int + if res != nil { + code = res.StatusCode + } + if delay, shouldRetry := retryer.Retry(code, reqErr); shouldRetry { + if err := sleep(ctx, delay); err != nil { + return "", "", err + } + continue + } + break + } + if reqErr != nil { + return "", "", nil } defer res.Body.Close() if res.StatusCode == http.StatusNotFound { diff --git a/vendor/cloud.google.com/go/compute/metadata/retry.go b/vendor/cloud.google.com/go/compute/metadata/retry.go new file mode 100644 index 0000000000..0f18f3cda1 --- /dev/null +++ b/vendor/cloud.google.com/go/compute/metadata/retry.go @@ -0,0 +1,114 @@ +// Copyright 2021 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package metadata + +import ( + "context" + "io" + "math/rand" + "net/http" + "time" +) + +const ( + maxRetryAttempts = 5 +) + +var ( + syscallRetryable = func(err error) bool { return false } +) + +// defaultBackoff is basically equivalent to gax.Backoff without the need for +// the dependency. +type defaultBackoff struct { + max time.Duration + mul float64 + cur time.Duration +} + +func (b *defaultBackoff) Pause() time.Duration { + d := time.Duration(1 + rand.Int63n(int64(b.cur))) + b.cur = time.Duration(float64(b.cur) * b.mul) + if b.cur > b.max { + b.cur = b.max + } + return d +} + +// sleep is the equivalent of gax.Sleep without the need for the dependency. +func sleep(ctx context.Context, d time.Duration) error { + t := time.NewTimer(d) + select { + case <-ctx.Done(): + t.Stop() + return ctx.Err() + case <-t.C: + return nil + } +} + +func newRetryer() *metadataRetryer { + return &metadataRetryer{bo: &defaultBackoff{ + cur: 100 * time.Millisecond, + max: 30 * time.Second, + mul: 2, + }} +} + +type backoff interface { + Pause() time.Duration +} + +type metadataRetryer struct { + bo backoff + attempts int +} + +func (r *metadataRetryer) Retry(status int, err error) (time.Duration, bool) { + if status == http.StatusOK { + return 0, false + } + retryOk := shouldRetry(status, err) + if !retryOk { + return 0, false + } + if r.attempts == maxRetryAttempts { + return 0, false + } + r.attempts++ + return r.bo.Pause(), true +} + +func shouldRetry(status int, err error) bool { + if 500 <= status && status <= 599 { + return true + } + if err == io.ErrUnexpectedEOF { + return true + } + // Transient network errors should be retried. + if syscallRetryable(err) { + return true + } + if err, ok := err.(interface{ Temporary() bool }); ok { + if err.Temporary() { + return true + } + } + if err, ok := err.(interface{ Unwrap() error }); ok { + return shouldRetry(status, err.Unwrap()) + } + return false +} diff --git a/vendor/cloud.google.com/go/compute/metadata/retry_linux.go b/vendor/cloud.google.com/go/compute/metadata/retry_linux.go new file mode 100644 index 0000000000..bb412f8917 --- /dev/null +++ b/vendor/cloud.google.com/go/compute/metadata/retry_linux.go @@ -0,0 +1,26 @@ +// Copyright 2021 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//go:build linux +// +build linux + +package metadata + +import "syscall" + +func init() { + // Initialize syscallRetryable to return true on transient socket-level + // errors. These errors are specific to Linux. + syscallRetryable = func(err error) bool { return err == syscall.ECONNRESET || err == syscall.ECONNREFUSED } +} diff --git a/vendor/github.com/Microsoft/go-winio/README.md b/vendor/github.com/Microsoft/go-winio/README.md index 60c93fe506..683be1dcf9 100644 --- a/vendor/github.com/Microsoft/go-winio/README.md +++ b/vendor/github.com/Microsoft/go-winio/README.md @@ -11,12 +11,27 @@ package. Please see the LICENSE file for licensing information. -This project has adopted the [Microsoft Open Source Code of -Conduct](https://opensource.microsoft.com/codeofconduct/). For more information -see the [Code of Conduct -FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or contact -[opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional -questions or comments. +## Contributing +This project welcomes contributions and suggestions. Most contributions require you to agree to a Contributor License Agreement (CLA) +declaring that you have the right to, and actually do, grant us the rights to use your contribution. For details, visit https://cla.microsoft.com. + +When you submit a pull request, a CLA-bot will automatically determine whether you need to provide a CLA and decorate the PR +appropriately (e.g., label, comment). Simply follow the instructions provided by the bot. You will only need to do this once across all repos using our CLA. + +We also require that contributors sign their commits using git commit -s or git commit --signoff to certify they either authored the work themselves +or otherwise have permission to use it in this project. Please see https://developercertificate.org/ for more info, as well as to make sure that you can +attest to the rules listed. Our CI uses the DCO Github app to ensure that all commits in a given PR are signed-off. + + +## Code of Conduct + +This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). +For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or +contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments. + + + +## Special Thanks Thanks to natefinch for the inspiration for this library. See https://github.com/natefinch/npipe for another named pipe implementation. diff --git a/vendor/github.com/Microsoft/hcsshim/osversion/osversion_windows.go b/vendor/github.com/Microsoft/hcsshim/osversion/osversion_windows.go index 42e58403de..3ab3bcd89a 100644 --- a/vendor/github.com/Microsoft/hcsshim/osversion/osversion_windows.go +++ b/vendor/github.com/Microsoft/hcsshim/osversion/osversion_windows.go @@ -2,6 +2,7 @@ package osversion import ( "fmt" + "sync" "golang.org/x/sys/windows" ) @@ -15,19 +16,26 @@ type OSVersion struct { Build uint16 } +var ( + osv OSVersion + once sync.Once +) + // Get gets the operating system version on Windows. // The calling application must be manifested to get the correct version information. func Get() OSVersion { - var err error - osv := OSVersion{} - osv.Version, err = windows.GetVersion() - if err != nil { - // GetVersion never fails. - panic(err) - } - osv.MajorVersion = uint8(osv.Version & 0xFF) - osv.MinorVersion = uint8(osv.Version >> 8 & 0xFF) - osv.Build = uint16(osv.Version >> 16) + once.Do(func() { + var err error + osv = OSVersion{} + osv.Version, err = windows.GetVersion() + if err != nil { + // GetVersion never fails. + panic(err) + } + osv.MajorVersion = uint8(osv.Version & 0xFF) + osv.MinorVersion = uint8(osv.Version >> 8 & 0xFF) + osv.Build = uint16(osv.Version >> 16) + }) return osv } diff --git a/vendor/github.com/willf/bitset/.gitignore b/vendor/github.com/bits-and-blooms/bitset/.gitignore similarity index 100% rename from vendor/github.com/willf/bitset/.gitignore rename to vendor/github.com/bits-and-blooms/bitset/.gitignore diff --git a/vendor/github.com/willf/bitset/.travis.yml b/vendor/github.com/bits-and-blooms/bitset/.travis.yml similarity index 100% rename from vendor/github.com/willf/bitset/.travis.yml rename to vendor/github.com/bits-and-blooms/bitset/.travis.yml diff --git a/vendor/github.com/willf/bitset/LICENSE b/vendor/github.com/bits-and-blooms/bitset/LICENSE similarity index 100% rename from vendor/github.com/willf/bitset/LICENSE rename to vendor/github.com/bits-and-blooms/bitset/LICENSE diff --git a/vendor/github.com/willf/bitset/README.md b/vendor/github.com/bits-and-blooms/bitset/README.md similarity index 84% rename from vendor/github.com/willf/bitset/README.md rename to vendor/github.com/bits-and-blooms/bitset/README.md index 50338e71df..97e83071e4 100644 --- a/vendor/github.com/willf/bitset/README.md +++ b/vendor/github.com/bits-and-blooms/bitset/README.md @@ -2,10 +2,9 @@ *Go language library to map between non-negative integers and boolean values* -[![Test](https://github.com/willf/bitset/workflows/Test/badge.svg)](https://github.com/willf/bitset/actions?query=workflow%3ATest) -[![Master Coverage Status](https://coveralls.io/repos/willf/bitset/badge.svg?branch=master&service=github)](https://coveralls.io/github/willf/bitset?branch=master) +[![Test](https://github.com/bits-and-blooms/bitset/workflows/Test/badge.svg)](https://github.com/willf/bitset/actions?query=workflow%3ATest) [![Go Report Card](https://goreportcard.com/badge/github.com/willf/bitset)](https://goreportcard.com/report/github.com/willf/bitset) -[![PkgGoDev](https://pkg.go.dev/badge/github.com/willf/bitset?tab=doc)](https://pkg.go.dev/github.com/willf/bitset?tab=doc) +[![PkgGoDev](https://pkg.go.dev/badge/github.com/bits-and-blooms/bitset?tab=doc)](https://pkg.go.dev/github.com/bits-and-blooms/bitset?tab=doc) ## Description @@ -30,7 +29,7 @@ import ( "fmt" "math/rand" - "github.com/willf/bitset" + "github.com/bits-and-blooms/bitset" ) func main() { @@ -63,7 +62,7 @@ func main() { As an alternative to BitSets, one should check out the 'big' package, which provides a (less set-theoretical) view of bitsets. -Package documentation is at: https://pkg.go.dev/github.com/willf/bitset?tab=doc +Package documentation is at: https://pkg.go.dev/github.com/bits-and-blooms/bitset?tab=doc ## Memory Usage @@ -78,7 +77,7 @@ It is possible that a later version will match the `math/bits` return signature ## Installation ```bash -go get github.com/willf/bitset +go get github.com/bits-and-blooms/bitset ``` ## Contributing diff --git a/vendor/github.com/willf/bitset/azure-pipelines.yml b/vendor/github.com/bits-and-blooms/bitset/azure-pipelines.yml similarity index 100% rename from vendor/github.com/willf/bitset/azure-pipelines.yml rename to vendor/github.com/bits-and-blooms/bitset/azure-pipelines.yml diff --git a/vendor/github.com/willf/bitset/bitset.go b/vendor/github.com/bits-and-blooms/bitset/bitset.go similarity index 97% rename from vendor/github.com/willf/bitset/bitset.go rename to vendor/github.com/bits-and-blooms/bitset/bitset.go index 21e889da2e..d688806a54 100644 --- a/vendor/github.com/willf/bitset/bitset.go +++ b/vendor/github.com/bits-and-blooms/bitset/bitset.go @@ -209,6 +209,27 @@ func (b *BitSet) Flip(i uint) *BitSet { return b } +// FlipRange bit in [start, end). +// If end>= Cap(), this function will panic. +// Warning: using a very large value for 'end' +// may lead to a memory shortage and a panic: the caller is responsible +// for providing sensible parameters in line with their memory capacity. +func (b *BitSet) FlipRange(start, end uint) *BitSet { + if start >= end { + return b + } + + b.extendSetMaybe(end - 1) + var startWord uint = start >> log2WordSize + var endWord uint = end >> log2WordSize + b.set[startWord] ^= ^(^uint64(0) << (start & (wordSize - 1))) + for i := startWord; i < endWord; i++ { + b.set[i] = ^b.set[i] + } + b.set[endWord] ^= ^uint64(0) >> (-end & (wordSize - 1)) + return b +} + // Shrink shrinks BitSet so that the provided value is the last possible // set value. It clears all bits > the provided index and reduces the size // and length of the set. @@ -519,7 +540,7 @@ func (b *BitSet) Copy(c *BitSet) (count uint) { } // Count (number of set bits). -// Also known as "popcount" or "popularity count". +// Also known as "popcount" or "population count". func (b *BitSet) Count() uint { if b != nil && b.set != nil { return uint(popcntSlice(b.set)) diff --git a/vendor/github.com/bits-and-blooms/bitset/go.mod b/vendor/github.com/bits-and-blooms/bitset/go.mod new file mode 100644 index 0000000000..c43e4522b7 --- /dev/null +++ b/vendor/github.com/bits-and-blooms/bitset/go.mod @@ -0,0 +1,3 @@ +module github.com/bits-and-blooms/bitset + +go 1.14 diff --git a/vendor/github.com/willf/bitset/go.sum b/vendor/github.com/bits-and-blooms/bitset/go.sum similarity index 100% rename from vendor/github.com/willf/bitset/go.sum rename to vendor/github.com/bits-and-blooms/bitset/go.sum diff --git a/vendor/github.com/willf/bitset/popcnt.go b/vendor/github.com/bits-and-blooms/bitset/popcnt.go similarity index 100% rename from vendor/github.com/willf/bitset/popcnt.go rename to vendor/github.com/bits-and-blooms/bitset/popcnt.go diff --git a/vendor/github.com/willf/bitset/popcnt_19.go b/vendor/github.com/bits-and-blooms/bitset/popcnt_19.go similarity index 100% rename from vendor/github.com/willf/bitset/popcnt_19.go rename to vendor/github.com/bits-and-blooms/bitset/popcnt_19.go diff --git a/vendor/github.com/willf/bitset/popcnt_amd64.go b/vendor/github.com/bits-and-blooms/bitset/popcnt_amd64.go similarity index 100% rename from vendor/github.com/willf/bitset/popcnt_amd64.go rename to vendor/github.com/bits-and-blooms/bitset/popcnt_amd64.go diff --git a/vendor/github.com/willf/bitset/popcnt_amd64.s b/vendor/github.com/bits-and-blooms/bitset/popcnt_amd64.s similarity index 100% rename from vendor/github.com/willf/bitset/popcnt_amd64.s rename to vendor/github.com/bits-and-blooms/bitset/popcnt_amd64.s diff --git a/vendor/github.com/willf/bitset/popcnt_generic.go b/vendor/github.com/bits-and-blooms/bitset/popcnt_generic.go similarity index 100% rename from vendor/github.com/willf/bitset/popcnt_generic.go rename to vendor/github.com/bits-and-blooms/bitset/popcnt_generic.go diff --git a/vendor/github.com/willf/bitset/trailing_zeros_18.go b/vendor/github.com/bits-and-blooms/bitset/trailing_zeros_18.go similarity index 100% rename from vendor/github.com/willf/bitset/trailing_zeros_18.go rename to vendor/github.com/bits-and-blooms/bitset/trailing_zeros_18.go diff --git a/vendor/github.com/willf/bitset/trailing_zeros_19.go b/vendor/github.com/bits-and-blooms/bitset/trailing_zeros_19.go similarity index 100% rename from vendor/github.com/willf/bitset/trailing_zeros_19.go rename to vendor/github.com/bits-and-blooms/bitset/trailing_zeros_19.go diff --git a/vendor/github.com/containerd/stargz-snapshotter/estargz/build.go b/vendor/github.com/containerd/stargz-snapshotter/estargz/build.go index fc42b6c348..708b266899 100644 --- a/vendor/github.com/containerd/stargz-snapshotter/estargz/build.go +++ b/vendor/github.com/containerd/stargz-snapshotter/estargz/build.go @@ -26,7 +26,6 @@ import ( "archive/tar" "bytes" "compress/gzip" - "encoding/json" "fmt" "io" "io/ioutil" @@ -48,6 +47,7 @@ type options struct { compressionLevel int prioritizedFiles []string missedPrioritizedFiles *[]string + compression Compression } type Option func(o *options) error @@ -95,6 +95,15 @@ func WithAllowPrioritizeNotFound(missedFiles *[]string) Option { } } +// WithCompression specifies compression algorithm to be used. +// Default is gzip. +func WithCompression(compression Compression) Option { + return func(o *options) error { + o.compression = compression + return nil + } +} + // Blob is an eStargz blob. type Blob struct { io.ReadCloser @@ -126,6 +135,9 @@ func Build(tarBlob *io.SectionReader, opt ...Option) (_ *Blob, rErr error) { return nil, err } } + if opts.compression == nil { + opts.compression = newGzipCompressionWithLevel(opts.compressionLevel) + } layerFiles := newTempFiles() defer func() { if rErr != nil { @@ -155,7 +167,7 @@ func Build(tarBlob *io.SectionReader, opt ...Option) (_ *Blob, rErr error) { if err != nil { return err } - sw := NewWriterLevel(esgzFile, opts.compressionLevel) + sw := NewWriterWithCompressor(esgzFile, opts.compression) sw.ChunkSize = opts.chunkSize if err := sw.AppendTar(readerFromEntries(parts...)); err != nil { return err @@ -187,11 +199,12 @@ func Build(tarBlob *io.SectionReader, opt ...Option) (_ *Blob, rErr error) { diffID := digest.Canonical.Digester() pr, pw := io.Pipe() go func() { - r, err := gzip.NewReader(io.TeeReader(io.MultiReader(append(rs, tocAndFooter)...), pw)) + r, err := opts.compression.Reader(io.TeeReader(io.MultiReader(append(rs, tocAndFooter)...), pw)) if err != nil { pw.CloseWithError(err) return } + defer r.Close() if _, err := io.Copy(diffID.Hash(), r); err != nil { pw.CloseWithError(err) return @@ -213,7 +226,7 @@ func Build(tarBlob *io.SectionReader, opt ...Option) (_ *Blob, rErr error) { // Writers doesn't write TOC and footer to the underlying writers so they can be // combined into a single eStargz and tocAndFooter returned by this function can // be appended at the tail of that combined blob. -func closeWithCombine(compressionLevel int, ws ...*Writer) (tocAndFooter io.Reader, tocDgst digest.Digest, err error) { +func closeWithCombine(compressionLevel int, ws ...*Writer) (tocAndFooterR io.Reader, tocDgst digest.Digest, err error) { if len(ws) == 0 { return nil, "", fmt.Errorf("at least one writer must be passed") } @@ -230,7 +243,7 @@ func closeWithCombine(compressionLevel int, ws ...*Writer) (tocAndFooter io.Read } } var ( - mtoc = new(jtoc) + mtoc = new(JTOC) currentOffset int64 ) mtoc.Version = ws[0].toc.Version @@ -248,40 +261,16 @@ func closeWithCombine(compressionLevel int, ws ...*Writer) (tocAndFooter io.Read currentOffset += w.cw.n } - tocJSON, err := json.MarshalIndent(mtoc, "", "\t") + return tocAndFooter(ws[0].compressor, mtoc, currentOffset) +} + +func tocAndFooter(compressor Compressor, toc *JTOC, offset int64) (io.Reader, digest.Digest, error) { + buf := new(bytes.Buffer) + tocDigest, err := compressor.WriteTOCAndFooter(buf, offset, toc, nil) if err != nil { return nil, "", err } - pr, pw := io.Pipe() - go func() { - zw, _ := gzip.NewWriterLevel(pw, compressionLevel) - tw := tar.NewWriter(zw) - if err := tw.WriteHeader(&tar.Header{ - Typeflag: tar.TypeReg, - Name: TOCTarName, - Size: int64(len(tocJSON)), - }); err != nil { - pw.CloseWithError(err) - return - } - if _, err := tw.Write(tocJSON); err != nil { - pw.CloseWithError(err) - return - } - if err := tw.Close(); err != nil { - pw.CloseWithError(err) - return - } - if err := zw.Close(); err != nil { - pw.CloseWithError(err) - return - } - pw.Close() - }() - return io.MultiReader( - pr, - bytes.NewReader(footerBytes(currentOffset)), - ), digest.FromBytes(tocJSON), nil + return buf, tocDigest, nil } // divideEntries divides passed entries to the parts at least the number specified by the diff --git a/vendor/github.com/containerd/stargz-snapshotter/estargz/estargz.go b/vendor/github.com/containerd/stargz-snapshotter/estargz/estargz.go index c45a7aacaf..3ef0291160 100644 --- a/vendor/github.com/containerd/stargz-snapshotter/estargz/estargz.go +++ b/vendor/github.com/containerd/stargz-snapshotter/estargz/estargz.go @@ -23,13 +23,10 @@ package estargz import ( - "archive/tar" "bufio" "bytes" "compress/gzip" "crypto/sha256" - "encoding/binary" - "encoding/json" "fmt" "hash" "io" @@ -37,7 +34,6 @@ import ( "os" "path" "sort" - "strconv" "strings" "sync" "time" @@ -45,12 +41,13 @@ import ( "github.com/containerd/stargz-snapshotter/estargz/errorutil" digest "github.com/opencontainers/go-digest" "github.com/pkg/errors" + "github.com/vbatts/tar-split/archive/tar" ) // A Reader permits random access reads from a stargz file. type Reader struct { sr *io.SectionReader - toc *jtoc + toc *JTOC tocDigest digest.Digest // m stores all non-chunk entries, keyed by name. @@ -60,39 +57,116 @@ type Reader struct { // are split up. For a file with a single chunk, it's only // stored in m. chunks map[string][]*TOCEntry + + decompressor Decompressor +} + +type openOpts struct { + tocOffset int64 + decompressors []Decompressor + telemetry *Telemetry +} + +// OpenOption is an option used during opening the layer +type OpenOption func(o *openOpts) error + +// WithTOCOffset option specifies the offset of TOC +func WithTOCOffset(tocOffset int64) OpenOption { + return func(o *openOpts) error { + o.tocOffset = tocOffset + return nil + } +} + +// WithDecompressors option specifies decompressors to use. +// Default is gzip-based decompressor. +func WithDecompressors(decompressors ...Decompressor) OpenOption { + return func(o *openOpts) error { + o.decompressors = decompressors + return nil + } +} + +// WithTelemetry option specifies the telemetry hooks +func WithTelemetry(telemetry *Telemetry) OpenOption { + return func(o *openOpts) error { + o.telemetry = telemetry + return nil + } +} + +// MeasureLatencyHook is a func which takes start time and records the diff +type MeasureLatencyHook func(time.Time) + +// Telemetry is a struct which defines telemetry hooks. By implementing these hooks you should be able to record +// the latency metrics of the respective steps of estargz open operation. To be used with estargz.OpenWithTelemetry(...) +type Telemetry struct { + GetFooterLatency MeasureLatencyHook // measure time to get stargz footer (in milliseconds) + GetTocLatency MeasureLatencyHook // measure time to GET TOC JSON (in milliseconds) + DeserializeTocLatency MeasureLatencyHook // measure time to deserialize TOC JSON (in milliseconds) } // Open opens a stargz file for reading. +// The behaviour is configurable using options. // // Note that each entry name is normalized as the path that is relative to root. -func Open(sr *io.SectionReader) (*Reader, error) { - tocOff, footerSize, err := OpenFooter(sr) - if err != nil { - return nil, errors.Wrapf(err, "error parsing footer") +func Open(sr *io.SectionReader, opt ...OpenOption) (*Reader, error) { + var opts openOpts + for _, o := range opt { + if err := o(&opts); err != nil { + return nil, err + } } - tocTargz := make([]byte, sr.Size()-tocOff-footerSize) - if _, err := sr.ReadAt(tocTargz, tocOff); err != nil { - return nil, fmt.Errorf("error reading %d byte TOC targz: %v", len(tocTargz), err) + + gzipCompressors := []Decompressor{new(GzipDecompressor), new(legacyGzipDecompressor)} + decompressors := append(gzipCompressors, opts.decompressors...) + + // Determine the size to fetch. Try to fetch as many bytes as possible. + fetchSize := maxFooterSize(sr.Size(), decompressors...) + if maybeTocOffset := opts.tocOffset; maybeTocOffset > fetchSize { + if maybeTocOffset > sr.Size() { + return nil, fmt.Errorf("blob size %d is smaller than the toc offset", sr.Size()) + } + fetchSize = sr.Size() - maybeTocOffset } - zr, err := gzip.NewReader(bytes.NewReader(tocTargz)) - if err != nil { - return nil, fmt.Errorf("malformed TOC gzip header: %v", err) + + start := time.Now() // before getting layer footer + footer := make([]byte, fetchSize) + if _, err := sr.ReadAt(footer, sr.Size()-fetchSize); err != nil { + return nil, fmt.Errorf("error reading footer: %v", err) } - zr.Multistream(false) - tr := tar.NewReader(zr) - h, err := tr.Next() - if err != nil { - return nil, fmt.Errorf("failed to find tar header in TOC gzip stream: %v", err) + if opts.telemetry != nil && opts.telemetry.GetFooterLatency != nil { + opts.telemetry.GetFooterLatency(start) } - if h.Name != TOCTarName { - return nil, fmt.Errorf("TOC tar entry had name %q; expected %q", h.Name, TOCTarName) + + var allErr []error + var found bool + var r *Reader + for _, d := range decompressors { + fSize := d.FooterSize() + fOffset := positive(int64(len(footer)) - fSize) + maybeTocBytes := footer[:fOffset] + _, tocOffset, tocSize, err := d.ParseFooter(footer[fOffset:]) + if err != nil { + allErr = append(allErr, err) + continue + } + if tocSize <= 0 { + tocSize = sr.Size() - tocOffset - fSize + } + if tocSize < int64(len(maybeTocBytes)) { + maybeTocBytes = maybeTocBytes[:tocSize] + } + r, err = parseTOC(d, sr, tocOffset, tocSize, maybeTocBytes, opts) + if err == nil { + found = true + break + } + allErr = append(allErr, err) } - dgstr := digest.Canonical.Digester() - toc := new(jtoc) - if err := json.NewDecoder(io.TeeReader(tr, dgstr.Hash())).Decode(&toc); err != nil { - return nil, fmt.Errorf("error decoding TOC JSON: %v", err) + if !found { + return nil, errorutil.Aggregate(allErr) } - r := &Reader{sr: sr, toc: toc, tocDigest: dgstr.Digest()} if err := r.initFields(); err != nil { return nil, fmt.Errorf("failed to initialize fields of entries: %v", err) } @@ -100,17 +174,26 @@ func Open(sr *io.SectionReader) (*Reader, error) { } // OpenFooter extracts and parses footer from the given blob. +// only supports gzip-based eStargz. func OpenFooter(sr *io.SectionReader) (tocOffset int64, footerSize int64, rErr error) { if sr.Size() < FooterSize && sr.Size() < legacyFooterSize { return 0, 0, fmt.Errorf("blob size %d is smaller than the footer size", sr.Size()) } - // TODO: read a bigger chunk (1MB?) at once here to hopefully - // get the TOC + footer in one go. var footer [FooterSize]byte if _, err := sr.ReadAt(footer[:], sr.Size()-FooterSize); err != nil { return 0, 0, fmt.Errorf("error reading footer: %v", err) } - return parseFooter(footer[:]) + var allErr []error + for _, d := range []Decompressor{new(GzipDecompressor), new(legacyGzipDecompressor)} { + fSize := d.FooterSize() + fOffset := positive(int64(len(footer)) - fSize) + _, tocOffset, _, err := d.ParseFooter(footer[fOffset:]) + if err == nil { + return tocOffset, fSize, err + } + allErr = append(allErr, err) + } + return 0, 0, errorutil.Aggregate(allErr) } // initFields populates the Reader from r.toc after decoding it from @@ -243,6 +326,10 @@ func (r *Reader) getOrCreateDir(d string) *TOCEntry { return e } +func (r *Reader) TOCDigest() digest.Digest { + return r.tocDigest +} + // VerifyTOC checks that the TOC JSON in the passed blob matches the // passed digests and that the TOC JSON contains digests for all chunks // contained in the blob. If the verification succceeds, this function @@ -252,33 +339,73 @@ func (r *Reader) VerifyTOC(tocDigest digest.Digest) (TOCEntryVerifier, error) { if r.tocDigest != tocDigest { return nil, fmt.Errorf("invalid TOC JSON %q; want %q", r.tocDigest, tocDigest) } - digestMap := make(map[int64]digest.Digest) // map from chunk offset to the digest + return r.Verifiers() +} + +// Verifiers returns TOCEntryVerifier of this chunk. Use VerifyTOC instead in most cases +// because this doesn't verify TOC. +func (r *Reader) Verifiers() (TOCEntryVerifier, error) { + chunkDigestMap := make(map[int64]digest.Digest) // map from chunk offset to the chunk digest + regDigestMap := make(map[int64]digest.Digest) // map from chunk offset to the reg file digest + var chunkDigestMapIncomplete bool + var regDigestMapIncomplete bool + var containsChunk bool for _, e := range r.toc.Entries { - if e.Type == "reg" || e.Type == "chunk" { - if e.Type == "reg" && e.Size == 0 { - continue // ignores empty file - } + if e.Type != "reg" && e.Type != "chunk" { + continue + } + + // offset must be unique in stargz blob + _, dOK := chunkDigestMap[e.Offset] + _, rOK := regDigestMap[e.Offset] + if dOK || rOK { + return nil, fmt.Errorf("offset %d found twice", e.Offset) + } - // offset must be unique in stargz blob - if _, ok := digestMap[e.Offset]; ok { - return nil, fmt.Errorf("offset %d found twice", e.Offset) + if e.Type == "reg" { + if e.Size == 0 { + continue // ignores empty file } - // all chunk entries must contain digest - if e.ChunkDigest == "" { - return nil, fmt.Errorf("ChunkDigest of %q(off=%d) not found in TOC JSON", - e.Name, e.Offset) + // record the digest of regular file payload + if e.Digest != "" { + d, err := digest.Parse(e.Digest) + if err != nil { + return nil, errors.Wrapf(err, + "failed to parse regular file digest %q", e.Digest) + } + regDigestMap[e.Offset] = d + } else { + regDigestMapIncomplete = true } + } else { + containsChunk = true // this layer contains "chunk" entries. + } + // "reg" also can contain ChunkDigest (e.g. when "reg" is the first entry of + // chunked file) + if e.ChunkDigest != "" { d, err := digest.Parse(e.ChunkDigest) if err != nil { - return nil, errors.Wrapf(err, "failed to parse digest %q", e.ChunkDigest) + return nil, errors.Wrapf(err, + "failed to parse chunk digest %q", e.ChunkDigest) } - digestMap[e.Offset] = d + chunkDigestMap[e.Offset] = d + } else { + chunkDigestMapIncomplete = true + } + } + + if chunkDigestMapIncomplete { + // Though some chunk digests are not found, if this layer doesn't contain + // "chunk"s and all digest of "reg" files are recorded, we can use them instead. + if !containsChunk && !regDigestMapIncomplete { + return &verifier{digestMap: regDigestMap}, nil } + return nil, fmt.Errorf("some ChunkDigest not found in TOC JSON") } - return &verifier{digestMap: digestMap}, nil + return &verifier{digestMap: chunkDigestMap}, nil } // verifier is an implementation of TOCEntryVerifier which holds verifiers keyed by @@ -413,17 +540,17 @@ func (fr *fileReader) ReadAt(p []byte, off int64) (n int, err error) { off -= ent.ChunkOffset finalEnt := fr.ents[len(fr.ents)-1] - gzOff := ent.Offset - // gzBytesRemain is the number of compressed gzip bytes in this - // file remaining, over 1+ gzip chunks. - gzBytesRemain := finalEnt.NextOffset() - gzOff + compressedOff := ent.Offset + // compressedBytesRemain is the number of compressed bytes in this + // file remaining, over 1+ chunks. + compressedBytesRemain := finalEnt.NextOffset() - compressedOff - sr := io.NewSectionReader(fr.r.sr, gzOff, gzBytesRemain) + sr := io.NewSectionReader(fr.r.sr, compressedOff, compressedBytesRemain) - const maxGZread = 2 << 20 - var bufSize = maxGZread - if gzBytesRemain < maxGZread { - bufSize = int(gzBytesRemain) + const maxRead = 2 << 20 + var bufSize = maxRead + if compressedBytesRemain < maxRead { + bufSize = int(compressedBytesRemain) } br := bufio.NewReaderSize(sr, bufSize) @@ -431,14 +558,15 @@ func (fr *fileReader) ReadAt(p []byte, off int64) (n int, err error) { return 0, fmt.Errorf("fileReader.ReadAt.peek: %v", err) } - gz, err := gzip.NewReader(br) + dr, err := fr.r.decompressor.Reader(br) if err != nil { - return 0, fmt.Errorf("fileReader.ReadAt.gzipNewReader: %v", err) + return 0, fmt.Errorf("fileReader.ReadAt.decompressor.Reader: %v", err) } - if n, err := io.CopyN(ioutil.Discard, gz, off); n != off || err != nil { + defer dr.Close() + if n, err := io.CopyN(ioutil.Discard, dr, off); n != off || err != nil { return 0, fmt.Errorf("discard of %d bytes = %v, %v", off, n, err) } - return io.ReadFull(gz, p) + return io.ReadFull(dr, p) } // A Writer writes stargz files. @@ -447,14 +575,14 @@ func (fr *fileReader) ReadAt(p []byte, off int64) (n int, err error) { type Writer struct { bw *bufio.Writer cw *countWriter - toc *jtoc + toc *JTOC diffHash hash.Hash // SHA-256 of uncompressed tar - closed bool - gz *gzip.Writer - lastUsername map[int]string - lastGroupname map[int]string - compressionLevel int + closed bool + gz io.WriteCloser + lastUsername map[int]string + lastGroupname map[int]string + compressor Compressor // ChunkSize optionally controls the maximum number of bytes // of data of a regular file that can be written in one gzip @@ -463,16 +591,21 @@ type Writer struct { ChunkSize int } -// currentGzipWriter writes to the current w.gz field, which can +// currentCompressionWriter writes to the current w.gz field, which can // change throughout writing a tar entry. // // Additionally, it updates w's SHA-256 of the uncompressed bytes // of the tar file. -type currentGzipWriter struct{ w *Writer } +type currentCompressionWriter struct{ w *Writer } -func (cgw currentGzipWriter) Write(p []byte) (int, error) { - cgw.w.diffHash.Write(p) - return cgw.w.gz.Write(p) +func (ccw currentCompressionWriter) Write(p []byte) (int, error) { + ccw.w.diffHash.Write(p) + if ccw.w.gz == nil { + if err := ccw.w.condOpenGz(); err != nil { + return 0, err + } + } + return ccw.w.gz.Write(p) } func (w *Writer) chunkSize() int { @@ -482,26 +615,53 @@ func (w *Writer) chunkSize() int { return w.ChunkSize } -// NewWriter returns a new stargz writer writing to w. +// Unpack decompresses the given estargz blob and returns a ReadCloser of the tar blob. +// TOC JSON and footer are removed. +func Unpack(sr *io.SectionReader, c Decompressor) (io.ReadCloser, error) { + footerSize := c.FooterSize() + if sr.Size() < footerSize { + return nil, fmt.Errorf("blob is too small; %d < %d", sr.Size(), footerSize) + } + footerOffset := sr.Size() - footerSize + footer := make([]byte, footerSize) + if _, err := sr.ReadAt(footer, footerOffset); err != nil { + return nil, err + } + blobPayloadSize, _, _, err := c.ParseFooter(footer) + if err != nil { + return nil, errors.Wrapf(err, "failed to parse footer") + } + return c.Reader(io.LimitReader(sr, blobPayloadSize)) +} + +// NewWriter returns a new stargz writer (gzip-based) writing to w. // // The writer must be closed to write its trailing table of contents. func NewWriter(w io.Writer) *Writer { return NewWriterLevel(w, gzip.BestCompression) } -// NewWriterLevel returns a new stargz writer writing to w. +// NewWriterLevel returns a new stargz writer (gzip-based) writing to w. // The compression level is configurable. // // The writer must be closed to write its trailing table of contents. func NewWriterLevel(w io.Writer, compressionLevel int) *Writer { + return NewWriterWithCompressor(w, NewGzipCompressorWithLevel(compressionLevel)) +} + +// NewWriterWithCompressor returns a new stargz writer writing to w. +// The compression method is configurable. +// +// The writer must be closed to write its trailing table of contents. +func NewWriterWithCompressor(w io.Writer, c Compressor) *Writer { bw := bufio.NewWriter(w) cw := &countWriter{w: bw} return &Writer{ - bw: bw, - cw: cw, - toc: &jtoc{Version: 1}, - diffHash: sha256.New(), - compressionLevel: compressionLevel, + bw: bw, + cw: cw, + toc: &JTOC{Version: 1}, + diffHash: sha256.New(), + compressor: c, } } @@ -517,42 +677,16 @@ func (w *Writer) Close() (digest.Digest, error) { return "", err } - // Write the TOC index. - tocOff := w.cw.n - w.gz, _ = gzip.NewWriterLevel(w.cw, w.compressionLevel) - tw := tar.NewWriter(currentGzipWriter{w}) - tocJSON, err := json.MarshalIndent(w.toc, "", "\t") + // Write the TOC index and footer. + tocDigest, err := w.compressor.WriteTOCAndFooter(w.cw, w.cw.n, w.toc, w.diffHash) if err != nil { return "", err } - if err := tw.WriteHeader(&tar.Header{ - Typeflag: tar.TypeReg, - Name: TOCTarName, - Size: int64(len(tocJSON)), - }); err != nil { - return "", err - } - if _, err := tw.Write(tocJSON); err != nil { - return "", err - } - - if err := tw.Close(); err != nil { - return "", err - } - if err := w.closeGz(); err != nil { - return "", err - } - - // And a little footer with pointer to the TOC gzip stream. - if _, err := w.bw.Write(footerBytes(tocOff)); err != nil { - return "", err - } - if err := w.bw.Flush(); err != nil { return "", err } - return digest.FromBytes(tocJSON), nil + return tocDigest, nil } func (w *Writer) closeGz() error { @@ -584,39 +718,82 @@ func (w *Writer) nameIfChanged(mp *map[int]string, id int, name string) string { return name } -func (w *Writer) condOpenGz() { +func (w *Writer) condOpenGz() (err error) { if w.gz == nil { - w.gz, _ = gzip.NewWriterLevel(w.cw, w.compressionLevel) + w.gz, err = w.compressor.Writer(w.cw) } + return } // AppendTar reads the tar or tar.gz file from r and appends // each of its contents to w. // // The input r can optionally be gzip compressed but the output will -// always be gzip compressed. +// always be compressed by the specified compressor. func (w *Writer) AppendTar(r io.Reader) error { + return w.appendTar(r, false) +} + +// AppendTarLossLess reads the tar or tar.gz file from r and appends +// each of its contents to w. +// +// The input r can optionally be gzip compressed but the output will +// always be compressed by the specified compressor. +// +// The difference of this func with AppendTar is that this writes +// the input tar stream into w without any modification (e.g. to header bytes). +// +// Note that if the input tar stream already contains TOC JSON, this returns +// error because w cannot overwrite the TOC JSON to the one generated by w without +// lossy modification. To avoid this error, if the input stream is known to be stargz/estargz, +// you shoud decompress it and remove TOC JSON in advance. +func (w *Writer) AppendTarLossLess(r io.Reader) error { + return w.appendTar(r, true) +} + +func (w *Writer) appendTar(r io.Reader, lossless bool) error { + var src io.Reader br := bufio.NewReader(r) - var tr *tar.Reader if isGzip(br) { - // NewReader can't fail if isGzip returned true. zr, _ := gzip.NewReader(br) - tr = tar.NewReader(zr) + src = zr } else { - tr = tar.NewReader(br) + src = io.Reader(br) + } + dst := currentCompressionWriter{w} + var tw *tar.Writer + if !lossless { + tw = tar.NewWriter(dst) // use tar writer only when this isn't lossless mode. + } + tr := tar.NewReader(src) + if lossless { + tr.RawAccounting = true } for { h, err := tr.Next() if err == io.EOF { + if lossless { + if remain := tr.RawBytes(); len(remain) > 0 { + // Collect the remaining null bytes. + // https://github.com/vbatts/tar-split/blob/80a436fd6164c557b131f7c59ed69bd81af69761/concept/main.go#L49-L53 + if _, err := dst.Write(remain); err != nil { + return err + } + } + } break } if err != nil { return fmt.Errorf("error reading from source tar: tar.Reader.Next: %v", err) } - if h.Name == TOCTarName { + if cleanEntryName(h.Name) == TOCTarName { // It is possible for a layer to be "stargzified" twice during the // distribution lifecycle. So we reserve "TOCTarName" here to avoid // duplicated entries in the resulting layer. + if lossless { + // We cannot handle this in lossless way. + return fmt.Errorf("existing TOC JSON is not allowed; decompress layer before append") + } continue } @@ -639,11 +816,18 @@ func (w *Writer) AppendTar(r io.Reader) error { ModTime3339: formatModtime(h.ModTime), Xattrs: xattrs, } - w.condOpenGz() - tw := tar.NewWriter(currentGzipWriter{w}) - if err := tw.WriteHeader(h); err != nil { + if err := w.condOpenGz(); err != nil { return err } + if tw != nil { + if err := tw.WriteHeader(h); err != nil { + return err + } + } else { + if _, err := dst.Write(tr.RawBytes()); err != nil { + return err + } + } switch h.Typeflag { case tar.TypeLink: ent.Type = "hardlink" @@ -699,10 +883,18 @@ func (w *Writer) AppendTar(r io.Reader) error { ent.ChunkOffset = written chunkDigest := digest.Canonical.Digester() - w.condOpenGz() + if err := w.condOpenGz(); err != nil { + return err + } teeChunk := io.TeeReader(tee, chunkDigest.Hash()) - if _, err := io.CopyN(tw, teeChunk, chunkSize); err != nil { + var out io.Writer + if tw != nil { + out = tw + } else { + out = dst + } + if _, err := io.CopyN(out, teeChunk, chunkSize); err != nil { return fmt.Errorf("error copying %q: %v", h.Name, err) } ent.ChunkDigest = chunkDigest.Digest().String() @@ -719,11 +911,18 @@ func (w *Writer) AppendTar(r io.Reader) error { if payloadDigest != nil { regFileEntry.Digest = payloadDigest.Digest().String() } - if err := tw.Flush(); err != nil { - return err + if tw != nil { + if err := tw.Flush(); err != nil { + return err + } } } - return nil + remainDest := ioutil.Discard + if lossless { + remainDest = dst // Preserve the remaining bytes in lossless mode + } + _, err := io.Copy(remainDest, src) + return err } // DiffID returns the SHA-256 of the uncompressed tar bytes. @@ -732,83 +931,54 @@ func (w *Writer) DiffID() string { return fmt.Sprintf("sha256:%x", w.diffHash.Sum(nil)) } -// footerBytes returns the 51 bytes footer. -func footerBytes(tocOff int64) []byte { - buf := bytes.NewBuffer(make([]byte, 0, FooterSize)) - gz, _ := gzip.NewWriterLevel(buf, gzip.NoCompression) // MUST be NoCompression to keep 51 bytes - - // Extra header indicating the offset of TOCJSON - // https://tools.ietf.org/html/rfc1952#section-2.3.1.1 - header := make([]byte, 4) - header[0], header[1] = 'S', 'G' - subfield := fmt.Sprintf("%016xSTARGZ", tocOff) - binary.LittleEndian.PutUint16(header[2:4], uint16(len(subfield))) // little-endian per RFC1952 - gz.Header.Extra = append(header, []byte(subfield)...) - gz.Close() - if buf.Len() != FooterSize { - panic(fmt.Sprintf("footer buffer = %d, not %d", buf.Len(), FooterSize)) +func maxFooterSize(blobSize int64, decompressors ...Decompressor) (res int64) { + for _, d := range decompressors { + if s := d.FooterSize(); res < s && s <= blobSize { + res = s + } } - return buf.Bytes() + return } -func parseFooter(p []byte) (tocOffset int64, footerSize int64, rErr error) { - var allErr []error - - tocOffset, err := parseEStargzFooter(p) - if err == nil { - return tocOffset, FooterSize, nil - } - allErr = append(allErr, err) - - pad := len(p) - legacyFooterSize - if pad < 0 { - pad = 0 - } - tocOffset, err = parseLegacyFooter(p[pad:]) - if err == nil { - return tocOffset, legacyFooterSize, nil +func parseTOC(d Decompressor, sr *io.SectionReader, tocOff, tocSize int64, tocBytes []byte, opts openOpts) (*Reader, error) { + if len(tocBytes) > 0 { + start := time.Now() + toc, tocDgst, err := d.ParseTOC(bytes.NewReader(tocBytes)) + if err == nil { + if opts.telemetry != nil && opts.telemetry.DeserializeTocLatency != nil { + opts.telemetry.DeserializeTocLatency(start) + } + return &Reader{ + sr: sr, + toc: toc, + tocDigest: tocDgst, + decompressor: d, + }, nil + } } - return 0, 0, errorutil.Aggregate(append(allErr, err)) -} -func parseEStargzFooter(p []byte) (tocOffset int64, err error) { - if len(p) != FooterSize { - return 0, fmt.Errorf("invalid length %d cannot be parsed", len(p)) - } - zr, err := gzip.NewReader(bytes.NewReader(p)) - if err != nil { - return 0, err - } - extra := zr.Header.Extra - si1, si2, subfieldlen, subfield := extra[0], extra[1], extra[2:4], extra[4:] - if si1 != 'S' || si2 != 'G' { - return 0, fmt.Errorf("invalid subfield IDs: %q, %q; want E, S", si1, si2) + start := time.Now() + tocBytes = make([]byte, tocSize) + if _, err := sr.ReadAt(tocBytes, tocOff); err != nil { + return nil, fmt.Errorf("error reading %d byte TOC targz: %v", len(tocBytes), err) } - if slen := binary.LittleEndian.Uint16(subfieldlen); slen != uint16(16+len("STARGZ")) { - return 0, fmt.Errorf("invalid length of subfield %d; want %d", slen, 16+len("STARGZ")) + if opts.telemetry != nil && opts.telemetry.GetTocLatency != nil { + opts.telemetry.GetTocLatency(start) } - if string(subfield[16:]) != "STARGZ" { - return 0, fmt.Errorf("STARGZ magic string must be included in the footer subfield") - } - return strconv.ParseInt(string(subfield[:16]), 16, 64) -} - -func parseLegacyFooter(p []byte) (tocOffset int64, err error) { - if len(p) != legacyFooterSize { - return 0, fmt.Errorf("legacy: invalid length %d cannot be parsed", len(p)) - } - zr, err := gzip.NewReader(bytes.NewReader(p)) + start = time.Now() + toc, tocDgst, err := d.ParseTOC(bytes.NewReader(tocBytes)) if err != nil { - return 0, errors.Wrapf(err, "legacy: failed to get footer gzip reader") + return nil, err } - extra := zr.Header.Extra - if len(extra) != 16+len("STARGZ") { - return 0, fmt.Errorf("legacy: invalid stargz's extra field size") + if opts.telemetry != nil && opts.telemetry.DeserializeTocLatency != nil { + opts.telemetry.DeserializeTocLatency(start) } - if string(extra[16:]) != "STARGZ" { - return 0, fmt.Errorf("legacy: magic string STARGZ not found") - } - return strconv.ParseInt(string(extra[:16]), 16, 64) + return &Reader{ + sr: sr, + toc: toc, + tocDigest: tocDgst, + decompressor: d, + }, nil } func formatModtime(t time.Time) string { @@ -847,3 +1017,10 @@ func isGzip(br *bufio.Reader) bool { peek, _ := br.Peek(3) return len(peek) >= 3 && peek[0] == gzipID1 && peek[1] == gzipID2 && peek[2] == gzipDeflate } + +func positive(n int64) int64 { + if n < 0 { + return 0 + } + return n +} diff --git a/vendor/github.com/containerd/stargz-snapshotter/estargz/go.mod b/vendor/github.com/containerd/stargz-snapshotter/estargz/go.mod index bf76d34030..144d022ba7 100644 --- a/vendor/github.com/containerd/stargz-snapshotter/estargz/go.mod +++ b/vendor/github.com/containerd/stargz-snapshotter/estargz/go.mod @@ -3,8 +3,9 @@ module github.com/containerd/stargz-snapshotter/estargz go 1.16 require ( - github.com/klauspost/compress v1.12.3 + github.com/klauspost/compress v1.13.6 github.com/opencontainers/go-digest v1.0.0 github.com/pkg/errors v0.9.1 + github.com/vbatts/tar-split v0.11.2 golang.org/x/sync v0.0.0-20201207232520-09787c993a3a ) diff --git a/vendor/github.com/containerd/stargz-snapshotter/estargz/go.sum b/vendor/github.com/containerd/stargz-snapshotter/estargz/go.sum index 793b74fda1..d3c934ff81 100644 --- a/vendor/github.com/containerd/stargz-snapshotter/estargz/go.sum +++ b/vendor/github.com/containerd/stargz-snapshotter/estargz/go.sum @@ -1,10 +1,22 @@ -github.com/golang/snappy v0.0.3 h1:fHPg5GQYlCeLIPB9BZqMVR5nR9A+IM5zcgeTdjMYmLA= -github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/klauspost/compress v1.12.3 h1:G5AfA94pHPysR56qqrkO2pxEexdDzrpFJ6yt/VqWxVU= -github.com/klauspost/compress v1.12.3/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/klauspost/compress v1.13.6 h1:P76CopJELS0TiO2mebmnzgWaajssP/EszplttgQxcgc= +github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= +github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/urfave/cli v1.22.4/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= +github.com/vbatts/tar-split v0.11.2 h1:Via6XqJr0hceW4wff3QRzD5gAk/tatMw/4ZA7cTlIME= +github.com/vbatts/tar-split v0.11.2/go.mod h1:vV3ZuO2yWSVsz+pfFzDG/upWH1JhjOiEaWq6kXyQ3VI= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a h1:DcqTD9SDLc+1P/r1EmRBwnVsrOwW+kk2vWf9n+1sGhs= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/vendor/github.com/containerd/stargz-snapshotter/estargz/gzip.go b/vendor/github.com/containerd/stargz-snapshotter/estargz/gzip.go new file mode 100644 index 0000000000..88e1283d85 --- /dev/null +++ b/vendor/github.com/containerd/stargz-snapshotter/estargz/gzip.go @@ -0,0 +1,216 @@ +/* + Copyright The containerd Authors. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +/* + Copyright 2019 The Go Authors. All rights reserved. + Use of this source code is governed by a BSD-style + license that can be found in the LICENSE file. +*/ + +package estargz + +import ( + "archive/tar" + "bytes" + "compress/gzip" + "encoding/binary" + "encoding/json" + "fmt" + "hash" + "io" + "strconv" + + digest "github.com/opencontainers/go-digest" + "github.com/pkg/errors" +) + +type gzipCompression struct { + *gzipCompressor + *GzipDecompressor +} + +func newGzipCompressionWithLevel(level int) Compression { + return &gzipCompression{ + &gzipCompressor{level}, + &GzipDecompressor{}, + } +} + +func NewGzipCompressorWithLevel(level int) Compressor { + return &gzipCompressor{level} +} + +type gzipCompressor struct { + compressionLevel int +} + +func (gc *gzipCompressor) Writer(w io.Writer) (io.WriteCloser, error) { + return gzip.NewWriterLevel(w, gc.compressionLevel) +} + +func (gc *gzipCompressor) WriteTOCAndFooter(w io.Writer, off int64, toc *JTOC, diffHash hash.Hash) (digest.Digest, error) { + tocJSON, err := json.MarshalIndent(toc, "", "\t") + if err != nil { + return "", err + } + gz, _ := gzip.NewWriterLevel(w, gc.compressionLevel) + gw := io.Writer(gz) + if diffHash != nil { + gw = io.MultiWriter(gz, diffHash) + } + tw := tar.NewWriter(gw) + if err := tw.WriteHeader(&tar.Header{ + Typeflag: tar.TypeReg, + Name: TOCTarName, + Size: int64(len(tocJSON)), + }); err != nil { + return "", err + } + if _, err := tw.Write(tocJSON); err != nil { + return "", err + } + + if err := tw.Close(); err != nil { + return "", err + } + if err := gz.Close(); err != nil { + return "", err + } + if _, err := w.Write(gzipFooterBytes(off)); err != nil { + return "", err + } + return digest.FromBytes(tocJSON), nil +} + +// gzipFooterBytes returns the 51 bytes footer. +func gzipFooterBytes(tocOff int64) []byte { + buf := bytes.NewBuffer(make([]byte, 0, FooterSize)) + gz, _ := gzip.NewWriterLevel(buf, gzip.NoCompression) // MUST be NoCompression to keep 51 bytes + + // Extra header indicating the offset of TOCJSON + // https://tools.ietf.org/html/rfc1952#section-2.3.1.1 + header := make([]byte, 4) + header[0], header[1] = 'S', 'G' + subfield := fmt.Sprintf("%016xSTARGZ", tocOff) + binary.LittleEndian.PutUint16(header[2:4], uint16(len(subfield))) // little-endian per RFC1952 + gz.Header.Extra = append(header, []byte(subfield)...) + gz.Close() + if buf.Len() != FooterSize { + panic(fmt.Sprintf("footer buffer = %d, not %d", buf.Len(), FooterSize)) + } + return buf.Bytes() +} + +type GzipDecompressor struct{} + +func (gz *GzipDecompressor) Reader(r io.Reader) (io.ReadCloser, error) { + return gzip.NewReader(r) +} + +func (gz *GzipDecompressor) ParseTOC(r io.Reader) (toc *JTOC, tocDgst digest.Digest, err error) { + return parseTOCEStargz(r) +} + +func (gz *GzipDecompressor) ParseFooter(p []byte) (blobPayloadSize, tocOffset, tocSize int64, err error) { + if len(p) != FooterSize { + return 0, 0, 0, fmt.Errorf("invalid length %d cannot be parsed", len(p)) + } + zr, err := gzip.NewReader(bytes.NewReader(p)) + if err != nil { + return 0, 0, 0, err + } + defer zr.Close() + extra := zr.Header.Extra + si1, si2, subfieldlen, subfield := extra[0], extra[1], extra[2:4], extra[4:] + if si1 != 'S' || si2 != 'G' { + return 0, 0, 0, fmt.Errorf("invalid subfield IDs: %q, %q; want E, S", si1, si2) + } + if slen := binary.LittleEndian.Uint16(subfieldlen); slen != uint16(16+len("STARGZ")) { + return 0, 0, 0, fmt.Errorf("invalid length of subfield %d; want %d", slen, 16+len("STARGZ")) + } + if string(subfield[16:]) != "STARGZ" { + return 0, 0, 0, fmt.Errorf("STARGZ magic string must be included in the footer subfield") + } + tocOffset, err = strconv.ParseInt(string(subfield[:16]), 16, 64) + if err != nil { + return 0, 0, 0, errors.Wrapf(err, "legacy: failed to parse toc offset") + } + return tocOffset, tocOffset, 0, nil +} + +func (gz *GzipDecompressor) FooterSize() int64 { + return FooterSize +} + +type legacyGzipDecompressor struct{} + +func (gz *legacyGzipDecompressor) Reader(r io.Reader) (io.ReadCloser, error) { + return gzip.NewReader(r) +} + +func (gz *legacyGzipDecompressor) ParseTOC(r io.Reader) (toc *JTOC, tocDgst digest.Digest, err error) { + return parseTOCEStargz(r) +} + +func (gz *legacyGzipDecompressor) ParseFooter(p []byte) (blobPayloadSize, tocOffset, tocSize int64, err error) { + if len(p) != legacyFooterSize { + return 0, 0, 0, fmt.Errorf("legacy: invalid length %d cannot be parsed", len(p)) + } + zr, err := gzip.NewReader(bytes.NewReader(p)) + if err != nil { + return 0, 0, 0, errors.Wrapf(err, "legacy: failed to get footer gzip reader") + } + defer zr.Close() + extra := zr.Header.Extra + if len(extra) != 16+len("STARGZ") { + return 0, 0, 0, fmt.Errorf("legacy: invalid stargz's extra field size") + } + if string(extra[16:]) != "STARGZ" { + return 0, 0, 0, fmt.Errorf("legacy: magic string STARGZ not found") + } + tocOffset, err = strconv.ParseInt(string(extra[:16]), 16, 64) + if err != nil { + return 0, 0, 0, errors.Wrapf(err, "legacy: failed to parse toc offset") + } + return tocOffset, tocOffset, 0, nil +} + +func (gz *legacyGzipDecompressor) FooterSize() int64 { + return legacyFooterSize +} + +func parseTOCEStargz(r io.Reader) (toc *JTOC, tocDgst digest.Digest, err error) { + zr, err := gzip.NewReader(r) + if err != nil { + return nil, "", fmt.Errorf("malformed TOC gzip header: %v", err) + } + defer zr.Close() + zr.Multistream(false) + tr := tar.NewReader(zr) + h, err := tr.Next() + if err != nil { + return nil, "", fmt.Errorf("failed to find tar header in TOC gzip stream: %v", err) + } + if h.Name != TOCTarName { + return nil, "", fmt.Errorf("TOC tar entry had name %q; expected %q", h.Name, TOCTarName) + } + dgstr := digest.Canonical.Digester() + toc = new(JTOC) + if err := json.NewDecoder(io.TeeReader(tr, dgstr.Hash())).Decode(&toc); err != nil { + return nil, "", fmt.Errorf("error decoding TOC JSON: %v", err) + } + return toc, dgstr.Digest(), nil +} diff --git a/vendor/github.com/containerd/stargz-snapshotter/estargz/testutil.go b/vendor/github.com/containerd/stargz-snapshotter/estargz/testutil.go new file mode 100644 index 0000000000..9224e456dd --- /dev/null +++ b/vendor/github.com/containerd/stargz-snapshotter/estargz/testutil.go @@ -0,0 +1,2009 @@ +/* + Copyright The containerd Authors. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +/* + Copyright 2019 The Go Authors. All rights reserved. + Use of this source code is governed by a BSD-style + license that can be found in the LICENSE file. +*/ + +package estargz + +import ( + "archive/tar" + "bytes" + "compress/gzip" + "crypto/sha256" + "encoding/json" + "fmt" + "io" + "io/ioutil" + "os" + "reflect" + "sort" + "strings" + "testing" + "time" + + "github.com/containerd/stargz-snapshotter/estargz/errorutil" + "github.com/klauspost/compress/zstd" + digest "github.com/opencontainers/go-digest" + "github.com/pkg/errors" +) + +// TestingController is Compression with some helper methods necessary for testing. +type TestingController interface { + Compression + CountStreams(*testing.T, []byte) int + DiffIDOf(*testing.T, []byte) string + String() string +} + +// CompressionTestSuite tests this pkg with controllers can build valid eStargz blobs and parse them. +func CompressionTestSuite(t *testing.T, controllers ...TestingController) { + t.Run("testBuild", func(t *testing.T) { t.Parallel(); testBuild(t, controllers...) }) + t.Run("testDigestAndVerify", func(t *testing.T) { t.Parallel(); testDigestAndVerify(t, controllers...) }) + t.Run("testWriteAndOpen", func(t *testing.T) { t.Parallel(); testWriteAndOpen(t, controllers...) }) +} + +const ( + uncompressedType int = iota + gzipType + zstdType +) + +var srcCompressions = []int{ + uncompressedType, + gzipType, + zstdType, +} + +var allowedPrefix = [4]string{"", "./", "/", "../"} + +// testBuild tests the resulting stargz blob built by this pkg has the same +// contents as the normal stargz blob. +func testBuild(t *testing.T, controllers ...TestingController) { + tests := []struct { + name string + chunkSize int + in []tarEntry + }{ + { + name: "regfiles and directories", + chunkSize: 4, + in: tarOf( + file("foo", "test1"), + dir("foo2/"), + file("foo2/bar", "test2", xAttr(map[string]string{"test": "sample"})), + ), + }, + { + name: "empty files", + chunkSize: 4, + in: tarOf( + file("foo", "tttttt"), + file("foo_empty", ""), + file("foo2", "tttttt"), + file("foo_empty2", ""), + file("foo3", "tttttt"), + file("foo_empty3", ""), + file("foo4", "tttttt"), + file("foo_empty4", ""), + file("foo5", "tttttt"), + file("foo_empty5", ""), + file("foo6", "tttttt"), + ), + }, + { + name: "various files", + chunkSize: 4, + in: tarOf( + file("baz.txt", "bazbazbazbazbazbazbaz"), + file("foo.txt", "a"), + symlink("barlink", "test/bar.txt"), + dir("test/"), + dir("dev/"), + blockdev("dev/testblock", 3, 4), + fifo("dev/testfifo"), + chardev("dev/testchar1", 5, 6), + file("test/bar.txt", "testbartestbar", xAttr(map[string]string{"test2": "sample2"})), + dir("test2/"), + link("test2/bazlink", "baz.txt"), + chardev("dev/testchar2", 1, 2), + ), + }, + { + name: "no contents", + chunkSize: 4, + in: tarOf( + file("baz.txt", ""), + symlink("barlink", "test/bar.txt"), + dir("test/"), + dir("dev/"), + blockdev("dev/testblock", 3, 4), + fifo("dev/testfifo"), + chardev("dev/testchar1", 5, 6), + file("test/bar.txt", "", xAttr(map[string]string{"test2": "sample2"})), + dir("test2/"), + link("test2/bazlink", "baz.txt"), + chardev("dev/testchar2", 1, 2), + ), + }, + } + for _, tt := range tests { + for _, srcCompression := range srcCompressions { + srcCompression := srcCompression + for _, cl := range controllers { + cl := cl + for _, srcTarFormat := range []tar.Format{tar.FormatUSTAR, tar.FormatPAX, tar.FormatGNU} { + srcTarFormat := srcTarFormat + for _, prefix := range allowedPrefix { + prefix := prefix + t.Run(tt.name+"-"+fmt.Sprintf("compression=%v,prefix=%q,src=%d,format=%s", cl, prefix, srcCompression, srcTarFormat), func(t *testing.T) { + tarBlob := buildTar(t, tt.in, prefix, srcTarFormat) + // Test divideEntries() + entries, err := sortEntries(tarBlob, nil, nil) // identical order + if err != nil { + t.Fatalf("failed to parse tar: %v", err) + } + var merged []*entry + for _, part := range divideEntries(entries, 4) { + merged = append(merged, part...) + } + if !reflect.DeepEqual(entries, merged) { + for _, e := range entries { + t.Logf("Original: %v", e.header) + } + for _, e := range merged { + t.Logf("Merged: %v", e.header) + } + t.Errorf("divided entries couldn't be merged") + return + } + + // Prepare sample data + wantBuf := new(bytes.Buffer) + sw := NewWriterWithCompressor(wantBuf, cl) + sw.ChunkSize = tt.chunkSize + if err := sw.AppendTar(tarBlob); err != nil { + t.Fatalf("failed to append tar to want stargz: %v", err) + } + if _, err := sw.Close(); err != nil { + t.Fatalf("failed to prepare want stargz: %v", err) + } + wantData := wantBuf.Bytes() + want, err := Open(io.NewSectionReader( + bytes.NewReader(wantData), 0, int64(len(wantData))), + WithDecompressors(cl), + ) + if err != nil { + t.Fatalf("failed to parse the want stargz: %v", err) + } + + // Prepare testing data + rc, err := Build(compressBlob(t, tarBlob, srcCompression), + WithChunkSize(tt.chunkSize), WithCompression(cl)) + if err != nil { + t.Fatalf("failed to build stargz: %v", err) + } + defer rc.Close() + gotBuf := new(bytes.Buffer) + if _, err := io.Copy(gotBuf, rc); err != nil { + t.Fatalf("failed to copy built stargz blob: %v", err) + } + gotData := gotBuf.Bytes() + got, err := Open(io.NewSectionReader( + bytes.NewReader(gotBuf.Bytes()), 0, int64(len(gotData))), + WithDecompressors(cl), + ) + if err != nil { + t.Fatalf("failed to parse the got stargz: %v", err) + } + + // Check DiffID is properly calculated + rc.Close() + diffID := rc.DiffID() + wantDiffID := cl.DiffIDOf(t, gotData) + if diffID.String() != wantDiffID { + t.Errorf("DiffID = %q; want %q", diffID, wantDiffID) + } + + // Compare as stargz + if !isSameVersion(t, cl, wantData, gotData) { + t.Errorf("built stargz hasn't same json") + return + } + if !isSameEntries(t, want, got) { + t.Errorf("built stargz isn't same as the original") + return + } + + // Compare as tar.gz + if !isSameTarGz(t, cl, wantData, gotData) { + t.Errorf("built stargz isn't same tar.gz") + return + } + }) + } + } + } + } + } +} + +func isSameTarGz(t *testing.T, controller TestingController, a, b []byte) bool { + aGz, err := controller.Reader(bytes.NewReader(a)) + if err != nil { + t.Fatalf("failed to read A") + } + defer aGz.Close() + bGz, err := controller.Reader(bytes.NewReader(b)) + if err != nil { + t.Fatalf("failed to read B") + } + defer bGz.Close() + + // Same as tar's Next() method but ignores landmarks and TOCJSON file + next := func(r *tar.Reader) (h *tar.Header, err error) { + for { + if h, err = r.Next(); err != nil { + return + } + if h.Name != PrefetchLandmark && + h.Name != NoPrefetchLandmark && + h.Name != TOCTarName { + return + } + } + } + + aTar := tar.NewReader(aGz) + bTar := tar.NewReader(bGz) + for { + // Fetch and parse next header. + aH, aErr := next(aTar) + bH, bErr := next(bTar) + if aErr != nil || bErr != nil { + if aErr == io.EOF && bErr == io.EOF { + break + } + t.Fatalf("Failed to parse tar file: A: %v, B: %v", aErr, bErr) + } + if !reflect.DeepEqual(aH, bH) { + t.Logf("different header (A = %v; B = %v)", aH, bH) + return false + + } + aFile, err := ioutil.ReadAll(aTar) + if err != nil { + t.Fatal("failed to read tar payload of A") + } + bFile, err := ioutil.ReadAll(bTar) + if err != nil { + t.Fatal("failed to read tar payload of B") + } + if !bytes.Equal(aFile, bFile) { + t.Logf("different tar payload (A = %q; B = %q)", string(a), string(b)) + return false + } + } + + return true +} + +func isSameVersion(t *testing.T, controller TestingController, a, b []byte) bool { + aJTOC, _, err := parseStargz(io.NewSectionReader(bytes.NewReader(a), 0, int64(len(a))), controller) + if err != nil { + t.Fatalf("failed to parse A: %v", err) + } + bJTOC, _, err := parseStargz(io.NewSectionReader(bytes.NewReader(b), 0, int64(len(b))), controller) + if err != nil { + t.Fatalf("failed to parse B: %v", err) + } + t.Logf("A: TOCJSON: %v", dumpTOCJSON(t, aJTOC)) + t.Logf("B: TOCJSON: %v", dumpTOCJSON(t, bJTOC)) + return aJTOC.Version == bJTOC.Version +} + +func isSameEntries(t *testing.T, a, b *Reader) bool { + aroot, ok := a.Lookup("") + if !ok { + t.Fatalf("failed to get root of A") + } + broot, ok := b.Lookup("") + if !ok { + t.Fatalf("failed to get root of B") + } + aEntry := stargzEntry{aroot, a} + bEntry := stargzEntry{broot, b} + return contains(t, aEntry, bEntry) && contains(t, bEntry, aEntry) +} + +func compressBlob(t *testing.T, src *io.SectionReader, srcCompression int) *io.SectionReader { + buf := new(bytes.Buffer) + var w io.WriteCloser + var err error + if srcCompression == gzipType { + w = gzip.NewWriter(buf) + } else if srcCompression == zstdType { + w, err = zstd.NewWriter(buf) + if err != nil { + t.Fatalf("failed to init zstd writer: %v", err) + } + } else { + return src + } + src.Seek(0, io.SeekStart) + if _, err := io.Copy(w, src); err != nil { + t.Fatalf("failed to compress source") + } + if err := w.Close(); err != nil { + t.Fatalf("failed to finalize compress source") + } + data := buf.Bytes() + return io.NewSectionReader(bytes.NewReader(data), 0, int64(len(data))) + +} + +type stargzEntry struct { + e *TOCEntry + r *Reader +} + +// contains checks if all child entries in "b" are also contained in "a". +// This function also checks if the files/chunks contain the same contents among "a" and "b". +func contains(t *testing.T, a, b stargzEntry) bool { + ae, ar := a.e, a.r + be, br := b.e, b.r + t.Logf("Comparing: %q vs %q", ae.Name, be.Name) + if !equalEntry(ae, be) { + t.Logf("%q != %q: entry: a: %v, b: %v", ae.Name, be.Name, ae, be) + return false + } + if ae.Type == "dir" { + t.Logf("Directory: %q vs %q: %v vs %v", ae.Name, be.Name, + allChildrenName(ae), allChildrenName(be)) + iscontain := true + ae.ForeachChild(func(aBaseName string, aChild *TOCEntry) bool { + // Walk through all files on this stargz file. + + if aChild.Name == PrefetchLandmark || + aChild.Name == NoPrefetchLandmark { + return true // Ignore landmarks + } + + // Ignore a TOCEntry of "./" (formated as "" by stargz lib) on root directory + // because this points to the root directory itself. + if aChild.Name == "" && ae.Name == "" { + return true + } + + bChild, ok := be.LookupChild(aBaseName) + if !ok { + t.Logf("%q (base: %q): not found in b: %v", + ae.Name, aBaseName, allChildrenName(be)) + iscontain = false + return false + } + + childcontain := contains(t, stargzEntry{aChild, a.r}, stargzEntry{bChild, b.r}) + if !childcontain { + t.Logf("%q != %q: non-equal dir", ae.Name, be.Name) + iscontain = false + return false + } + return true + }) + return iscontain + } else if ae.Type == "reg" { + af, err := ar.OpenFile(ae.Name) + if err != nil { + t.Fatalf("failed to open file %q on A: %v", ae.Name, err) + } + bf, err := br.OpenFile(be.Name) + if err != nil { + t.Fatalf("failed to open file %q on B: %v", be.Name, err) + } + + var nr int64 + for nr < ae.Size { + abytes, anext, aok := readOffset(t, af, nr, a) + bbytes, bnext, bok := readOffset(t, bf, nr, b) + if !aok && !bok { + break + } else if !(aok && bok) || anext != bnext { + t.Logf("%q != %q (offset=%d): chunk existence a=%v vs b=%v, anext=%v vs bnext=%v", + ae.Name, be.Name, nr, aok, bok, anext, bnext) + return false + } + nr = anext + if !bytes.Equal(abytes, bbytes) { + t.Logf("%q != %q: different contents %v vs %v", + ae.Name, be.Name, string(abytes), string(bbytes)) + return false + } + } + return true + } + + return true +} + +func allChildrenName(e *TOCEntry) (children []string) { + e.ForeachChild(func(baseName string, _ *TOCEntry) bool { + children = append(children, baseName) + return true + }) + return +} + +func equalEntry(a, b *TOCEntry) bool { + // Here, we selectively compare fileds that we are interested in. + return a.Name == b.Name && + a.Type == b.Type && + a.Size == b.Size && + a.ModTime3339 == b.ModTime3339 && + a.Stat().ModTime().Equal(b.Stat().ModTime()) && // modTime time.Time + a.LinkName == b.LinkName && + a.Mode == b.Mode && + a.UID == b.UID && + a.GID == b.GID && + a.Uname == b.Uname && + a.Gname == b.Gname && + (a.Offset > 0) == (b.Offset > 0) && + (a.NextOffset() > 0) == (b.NextOffset() > 0) && + a.DevMajor == b.DevMajor && + a.DevMinor == b.DevMinor && + a.NumLink == b.NumLink && + reflect.DeepEqual(a.Xattrs, b.Xattrs) && + // chunk-related infomations aren't compared in this function. + // ChunkOffset int64 `json:"chunkOffset,omitempty"` + // ChunkSize int64 `json:"chunkSize,omitempty"` + // children map[string]*TOCEntry + a.Digest == b.Digest +} + +func readOffset(t *testing.T, r *io.SectionReader, offset int64, e stargzEntry) ([]byte, int64, bool) { + ce, ok := e.r.ChunkEntryForOffset(e.e.Name, offset) + if !ok { + return nil, 0, false + } + data := make([]byte, ce.ChunkSize) + t.Logf("Offset: %v, NextOffset: %v", ce.Offset, ce.NextOffset()) + n, err := r.ReadAt(data, ce.ChunkOffset) + if err != nil { + t.Fatalf("failed to read file payload of %q (offset:%d,size:%d): %v", + e.e.Name, ce.ChunkOffset, ce.ChunkSize, err) + } + if int64(n) != ce.ChunkSize { + t.Fatalf("unexpected copied data size %d; want %d", + n, ce.ChunkSize) + } + return data[:n], offset + ce.ChunkSize, true +} + +func dumpTOCJSON(t *testing.T, tocJSON *JTOC) string { + jtocData, err := json.Marshal(*tocJSON) + if err != nil { + t.Fatalf("failed to marshal TOC JSON: %v", err) + } + buf := new(bytes.Buffer) + if _, err := io.Copy(buf, bytes.NewReader(jtocData)); err != nil { + t.Fatalf("failed to read toc json blob: %v", err) + } + return buf.String() +} + +const chunkSize = 3 + +// type check func(t *testing.T, sgzData []byte, tocDigest digest.Digest, dgstMap map[string]digest.Digest, compressionLevel int) +type check func(t *testing.T, sgzData []byte, tocDigest digest.Digest, dgstMap map[string]digest.Digest, controller TestingController) + +// testDigestAndVerify runs specified checks against sample stargz blobs. +func testDigestAndVerify(t *testing.T, controllers ...TestingController) { + tests := []struct { + name string + tarInit func(t *testing.T, dgstMap map[string]digest.Digest) (blob []tarEntry) + checks []check + }{ + { + name: "no-regfile", + tarInit: func(t *testing.T, dgstMap map[string]digest.Digest) (blob []tarEntry) { + return tarOf( + dir("test/"), + ) + }, + checks: []check{ + checkStargzTOC, + checkVerifyTOC, + checkVerifyInvalidStargzFail(buildTar(t, tarOf( + dir("test2/"), // modified + ), allowedPrefix[0])), + }, + }, + { + name: "small-files", + tarInit: func(t *testing.T, dgstMap map[string]digest.Digest) (blob []tarEntry) { + return tarOf( + regDigest(t, "baz.txt", "", dgstMap), + regDigest(t, "foo.txt", "a", dgstMap), + dir("test/"), + regDigest(t, "test/bar.txt", "bbb", dgstMap), + ) + }, + checks: []check{ + checkStargzTOC, + checkVerifyTOC, + checkVerifyInvalidStargzFail(buildTar(t, tarOf( + file("baz.txt", ""), + file("foo.txt", "M"), // modified + dir("test/"), + file("test/bar.txt", "bbb"), + ), allowedPrefix[0])), + // checkVerifyInvalidTOCEntryFail("foo.txt"), // TODO + checkVerifyBrokenContentFail("foo.txt"), + }, + }, + { + name: "big-files", + tarInit: func(t *testing.T, dgstMap map[string]digest.Digest) (blob []tarEntry) { + return tarOf( + regDigest(t, "baz.txt", "bazbazbazbazbazbazbaz", dgstMap), + regDigest(t, "foo.txt", "a", dgstMap), + dir("test/"), + regDigest(t, "test/bar.txt", "testbartestbar", dgstMap), + ) + }, + checks: []check{ + checkStargzTOC, + checkVerifyTOC, + checkVerifyInvalidStargzFail(buildTar(t, tarOf( + file("baz.txt", "bazbazbazMMMbazbazbaz"), // modified + file("foo.txt", "a"), + dir("test/"), + file("test/bar.txt", "testbartestbar"), + ), allowedPrefix[0])), + checkVerifyInvalidTOCEntryFail("test/bar.txt"), + checkVerifyBrokenContentFail("test/bar.txt"), + }, + }, + { + name: "with-non-regfiles", + tarInit: func(t *testing.T, dgstMap map[string]digest.Digest) (blob []tarEntry) { + return tarOf( + regDigest(t, "baz.txt", "bazbazbazbazbazbazbaz", dgstMap), + regDigest(t, "foo.txt", "a", dgstMap), + symlink("barlink", "test/bar.txt"), + dir("test/"), + regDigest(t, "test/bar.txt", "testbartestbar", dgstMap), + dir("test2/"), + link("test2/bazlink", "baz.txt"), + ) + }, + checks: []check{ + checkStargzTOC, + checkVerifyTOC, + checkVerifyInvalidStargzFail(buildTar(t, tarOf( + file("baz.txt", "bazbazbazbazbazbazbaz"), + file("foo.txt", "a"), + symlink("barlink", "test/bar.txt"), + dir("test/"), + file("test/bar.txt", "testbartestbar"), + dir("test2/"), + link("test2/bazlink", "foo.txt"), // modified + ), allowedPrefix[0])), + checkVerifyInvalidTOCEntryFail("test/bar.txt"), + checkVerifyBrokenContentFail("test/bar.txt"), + }, + }, + } + + for _, tt := range tests { + for _, srcCompression := range srcCompressions { + srcCompression := srcCompression + for _, cl := range controllers { + cl := cl + for _, prefix := range allowedPrefix { + prefix := prefix + for _, srcTarFormat := range []tar.Format{tar.FormatUSTAR, tar.FormatPAX, tar.FormatGNU} { + srcTarFormat := srcTarFormat + t.Run(tt.name+"-"+fmt.Sprintf("compression=%v,prefix=%q,format=%s", cl, prefix, srcTarFormat), func(t *testing.T) { + // Get original tar file and chunk digests + dgstMap := make(map[string]digest.Digest) + tarBlob := buildTar(t, tt.tarInit(t, dgstMap), prefix, srcTarFormat) + + rc, err := Build(compressBlob(t, tarBlob, srcCompression), + WithChunkSize(chunkSize), WithCompression(cl)) + if err != nil { + t.Fatalf("failed to convert stargz: %v", err) + } + tocDigest := rc.TOCDigest() + defer rc.Close() + buf := new(bytes.Buffer) + if _, err := io.Copy(buf, rc); err != nil { + t.Fatalf("failed to copy built stargz blob: %v", err) + } + newStargz := buf.Bytes() + // NoPrefetchLandmark is added during `Bulid`, which is expected behaviour. + dgstMap[chunkID(NoPrefetchLandmark, 0, int64(len([]byte{landmarkContents})))] = digest.FromBytes([]byte{landmarkContents}) + + for _, check := range tt.checks { + check(t, newStargz, tocDigest, dgstMap, cl) + } + }) + } + } + } + } + } +} + +// checkStargzTOC checks the TOC JSON of the passed stargz has the expected +// digest and contains valid chunks. It walks all entries in the stargz and +// checks all chunk digests stored to the TOC JSON match the actual contents. +func checkStargzTOC(t *testing.T, sgzData []byte, tocDigest digest.Digest, dgstMap map[string]digest.Digest, controller TestingController) { + sgz, err := Open( + io.NewSectionReader(bytes.NewReader(sgzData), 0, int64(len(sgzData))), + WithDecompressors(controller), + ) + if err != nil { + t.Errorf("failed to parse converted stargz: %v", err) + return + } + digestMapTOC, err := listDigests(io.NewSectionReader( + bytes.NewReader(sgzData), 0, int64(len(sgzData))), + controller, + ) + if err != nil { + t.Fatalf("failed to list digest: %v", err) + } + found := make(map[string]bool) + for id := range dgstMap { + found[id] = false + } + zr, err := controller.Reader(bytes.NewReader(sgzData)) + if err != nil { + t.Fatalf("failed to decompress converted stargz: %v", err) + } + defer zr.Close() + tr := tar.NewReader(zr) + for { + h, err := tr.Next() + if err != nil { + if err != io.EOF { + t.Errorf("failed to read tar entry: %v", err) + return + } + break + } + if h.Name == TOCTarName { + // Check the digest of TOC JSON based on the actual contents + // It's sure that TOC JSON exists in this archive because + // Open succeeded. + dgstr := digest.Canonical.Digester() + if _, err := io.Copy(dgstr.Hash(), tr); err != nil { + t.Fatalf("failed to calculate digest of TOC JSON: %v", + err) + } + if dgstr.Digest() != tocDigest { + t.Errorf("invalid TOC JSON %q; want %q", tocDigest, dgstr.Digest()) + } + continue + } + if _, ok := sgz.Lookup(h.Name); !ok { + t.Errorf("lost stargz entry %q in the converted TOC", h.Name) + return + } + var n int64 + for n < h.Size { + ce, ok := sgz.ChunkEntryForOffset(h.Name, n) + if !ok { + t.Errorf("lost chunk %q(offset=%d) in the converted TOC", + h.Name, n) + return + } + + // Get the original digest to make sure the file contents are kept unchanged + // from the original tar, during the whole conversion steps. + id := chunkID(h.Name, n, ce.ChunkSize) + want, ok := dgstMap[id] + if !ok { + t.Errorf("Unexpected chunk %q(offset=%d,size=%d): %v", + h.Name, n, ce.ChunkSize, dgstMap) + return + } + found[id] = true + + // Check the file contents + dgstr := digest.Canonical.Digester() + if _, err := io.CopyN(dgstr.Hash(), tr, ce.ChunkSize); err != nil { + t.Fatalf("failed to calculate digest of %q (offset=%d,size=%d)", + h.Name, n, ce.ChunkSize) + } + if want != dgstr.Digest() { + t.Errorf("Invalid contents in converted stargz %q: %q; want %q", + h.Name, dgstr.Digest(), want) + return + } + + // Check the digest stored in TOC JSON + dgstTOC, ok := digestMapTOC[ce.Offset] + if !ok { + t.Errorf("digest of %q(offset=%d,size=%d,chunkOffset=%d) isn't registered", + h.Name, ce.Offset, ce.ChunkSize, ce.ChunkOffset) + } + if want != dgstTOC { + t.Errorf("Invalid digest in TOCEntry %q: %q; want %q", + h.Name, dgstTOC, want) + return + } + + n += ce.ChunkSize + } + } + + for id, ok := range found { + if !ok { + t.Errorf("required chunk %q not found in the converted stargz: %v", id, found) + } + } +} + +// checkVerifyTOC checks the verification works for the TOC JSON of the passed +// stargz. It walks all entries in the stargz and checks the verifications for +// all chunks work. +func checkVerifyTOC(t *testing.T, sgzData []byte, tocDigest digest.Digest, dgstMap map[string]digest.Digest, controller TestingController) { + sgz, err := Open( + io.NewSectionReader(bytes.NewReader(sgzData), 0, int64(len(sgzData))), + WithDecompressors(controller), + ) + if err != nil { + t.Errorf("failed to parse converted stargz: %v", err) + return + } + ev, err := sgz.VerifyTOC(tocDigest) + if err != nil { + t.Errorf("failed to verify stargz: %v", err) + return + } + + found := make(map[string]bool) + for id := range dgstMap { + found[id] = false + } + zr, err := controller.Reader(bytes.NewReader(sgzData)) + if err != nil { + t.Fatalf("failed to decompress converted stargz: %v", err) + } + defer zr.Close() + tr := tar.NewReader(zr) + for { + h, err := tr.Next() + if err != nil { + if err != io.EOF { + t.Errorf("failed to read tar entry: %v", err) + return + } + break + } + if h.Name == TOCTarName { + continue + } + if _, ok := sgz.Lookup(h.Name); !ok { + t.Errorf("lost stargz entry %q in the converted TOC", h.Name) + return + } + var n int64 + for n < h.Size { + ce, ok := sgz.ChunkEntryForOffset(h.Name, n) + if !ok { + t.Errorf("lost chunk %q(offset=%d) in the converted TOC", + h.Name, n) + return + } + + v, err := ev.Verifier(ce) + if err != nil { + t.Errorf("failed to get verifier for %q(offset=%d)", h.Name, n) + } + + found[chunkID(h.Name, n, ce.ChunkSize)] = true + + // Check the file contents + if _, err := io.CopyN(v, tr, ce.ChunkSize); err != nil { + t.Fatalf("failed to get chunk of %q (offset=%d,size=%d)", + h.Name, n, ce.ChunkSize) + } + if !v.Verified() { + t.Errorf("Invalid contents in converted stargz %q (should be succeeded)", + h.Name) + return + } + n += ce.ChunkSize + } + } + + for id, ok := range found { + if !ok { + t.Errorf("required chunk %q not found in the converted stargz: %v", id, found) + } + } +} + +// checkVerifyInvalidTOCEntryFail checks if misconfigured TOC JSON can be +// detected during the verification and the verification returns an error. +func checkVerifyInvalidTOCEntryFail(filename string) check { + return func(t *testing.T, sgzData []byte, tocDigest digest.Digest, dgstMap map[string]digest.Digest, controller TestingController) { + funcs := map[string]rewriteFunc{ + "lost digest in a entry": func(t *testing.T, toc *JTOC, sgz *io.SectionReader) { + var found bool + for _, e := range toc.Entries { + if cleanEntryName(e.Name) == filename { + if e.Type != "reg" && e.Type != "chunk" { + t.Fatalf("entry %q to break must be regfile or chunk", filename) + } + if e.ChunkDigest == "" { + t.Fatalf("entry %q is already invalid", filename) + } + e.ChunkDigest = "" + found = true + } + } + if !found { + t.Fatalf("rewrite target not found") + } + }, + "duplicated entry offset": func(t *testing.T, toc *JTOC, sgz *io.SectionReader) { + var ( + sampleEntry *TOCEntry + targetEntry *TOCEntry + ) + for _, e := range toc.Entries { + if e.Type == "reg" || e.Type == "chunk" { + if cleanEntryName(e.Name) == filename { + targetEntry = e + } else { + sampleEntry = e + } + } + } + if sampleEntry == nil { + t.Fatalf("TOC must contain at least one regfile or chunk entry other than the rewrite target") + } + if targetEntry == nil { + t.Fatalf("rewrite target not found") + } + targetEntry.Offset = sampleEntry.Offset + }, + } + + for name, rFunc := range funcs { + t.Run(name, func(t *testing.T) { + newSgz, newTocDigest := rewriteTOCJSON(t, io.NewSectionReader(bytes.NewReader(sgzData), 0, int64(len(sgzData))), rFunc, controller) + buf := new(bytes.Buffer) + if _, err := io.Copy(buf, newSgz); err != nil { + t.Fatalf("failed to get converted stargz") + } + isgz := buf.Bytes() + + sgz, err := Open( + io.NewSectionReader(bytes.NewReader(isgz), 0, int64(len(isgz))), + WithDecompressors(controller), + ) + if err != nil { + t.Fatalf("failed to parse converted stargz: %v", err) + return + } + _, err = sgz.VerifyTOC(newTocDigest) + if err == nil { + t.Errorf("must fail for invalid TOC") + return + } + }) + } + } +} + +// checkVerifyInvalidStargzFail checks if the verification detects that the +// given stargz file doesn't match to the expected digest and returns error. +func checkVerifyInvalidStargzFail(invalid *io.SectionReader) check { + return func(t *testing.T, sgzData []byte, tocDigest digest.Digest, dgstMap map[string]digest.Digest, controller TestingController) { + rc, err := Build(invalid, WithChunkSize(chunkSize), WithCompression(controller)) + if err != nil { + t.Fatalf("failed to convert stargz: %v", err) + } + defer rc.Close() + buf := new(bytes.Buffer) + if _, err := io.Copy(buf, rc); err != nil { + t.Fatalf("failed to copy built stargz blob: %v", err) + } + mStargz := buf.Bytes() + + sgz, err := Open( + io.NewSectionReader(bytes.NewReader(mStargz), 0, int64(len(mStargz))), + WithDecompressors(controller), + ) + if err != nil { + t.Fatalf("failed to parse converted stargz: %v", err) + return + } + _, err = sgz.VerifyTOC(tocDigest) + if err == nil { + t.Errorf("must fail for invalid TOC") + return + } + } +} + +// checkVerifyBrokenContentFail checks if the verifier detects broken contents +// that doesn't match to the expected digest and returns error. +func checkVerifyBrokenContentFail(filename string) check { + return func(t *testing.T, sgzData []byte, tocDigest digest.Digest, dgstMap map[string]digest.Digest, controller TestingController) { + // Parse stargz file + sgz, err := Open( + io.NewSectionReader(bytes.NewReader(sgzData), 0, int64(len(sgzData))), + WithDecompressors(controller), + ) + if err != nil { + t.Fatalf("failed to parse converted stargz: %v", err) + return + } + ev, err := sgz.VerifyTOC(tocDigest) + if err != nil { + t.Fatalf("failed to verify stargz: %v", err) + return + } + + // Open the target file + sr, err := sgz.OpenFile(filename) + if err != nil { + t.Fatalf("failed to open file %q", filename) + } + ce, ok := sgz.ChunkEntryForOffset(filename, 0) + if !ok { + t.Fatalf("lost chunk %q(offset=%d) in the converted TOC", filename, 0) + return + } + if ce.ChunkSize == 0 { + t.Fatalf("file mustn't be empty") + return + } + data := make([]byte, ce.ChunkSize) + if _, err := sr.ReadAt(data, ce.ChunkOffset); err != nil { + t.Errorf("failed to get data of a chunk of %q(offset=%q)", + filename, ce.ChunkOffset) + } + + // Check the broken chunk (must fail) + v, err := ev.Verifier(ce) + if err != nil { + t.Fatalf("failed to get verifier for %q", filename) + } + broken := append([]byte{^data[0]}, data[1:]...) + if _, err := io.CopyN(v, bytes.NewReader(broken), ce.ChunkSize); err != nil { + t.Fatalf("failed to get chunk of %q (offset=%d,size=%d)", + filename, ce.ChunkOffset, ce.ChunkSize) + } + if v.Verified() { + t.Errorf("verification must fail for broken file chunk %q(org:%q,broken:%q)", + filename, data, broken) + } + } +} + +func chunkID(name string, offset, size int64) string { + return fmt.Sprintf("%s-%d-%d", cleanEntryName(name), offset, size) +} + +type rewriteFunc func(t *testing.T, toc *JTOC, sgz *io.SectionReader) + +func rewriteTOCJSON(t *testing.T, sgz *io.SectionReader, rewrite rewriteFunc, controller TestingController) (newSgz io.Reader, tocDigest digest.Digest) { + decodedJTOC, jtocOffset, err := parseStargz(sgz, controller) + if err != nil { + t.Fatalf("failed to extract TOC JSON: %v", err) + } + + rewrite(t, decodedJTOC, sgz) + + tocFooter, tocDigest, err := tocAndFooter(controller, decodedJTOC, jtocOffset) + if err != nil { + t.Fatalf("failed to create toc and footer: %v", err) + } + + // Reconstruct stargz file with the modified TOC JSON + if _, err := sgz.Seek(0, io.SeekStart); err != nil { + t.Fatalf("failed to reset the seek position of stargz: %v", err) + } + return io.MultiReader( + io.LimitReader(sgz, jtocOffset), // Original stargz (before TOC JSON) + tocFooter, // Rewritten TOC and footer + ), tocDigest +} + +func listDigests(sgz *io.SectionReader, controller TestingController) (map[int64]digest.Digest, error) { + decodedJTOC, _, err := parseStargz(sgz, controller) + if err != nil { + return nil, err + } + digestMap := make(map[int64]digest.Digest) + for _, e := range decodedJTOC.Entries { + if e.Type == "reg" || e.Type == "chunk" { + if e.Type == "reg" && e.Size == 0 { + continue // ignores empty file + } + if e.ChunkDigest == "" { + return nil, fmt.Errorf("ChunkDigest of %q(off=%d) not found in TOC JSON", + e.Name, e.Offset) + } + d, err := digest.Parse(e.ChunkDigest) + if err != nil { + return nil, err + } + digestMap[e.Offset] = d + } + } + return digestMap, nil +} + +func parseStargz(sgz *io.SectionReader, controller TestingController) (decodedJTOC *JTOC, jtocOffset int64, err error) { + fSize := controller.FooterSize() + footer := make([]byte, fSize) + if _, err := sgz.ReadAt(footer, sgz.Size()-fSize); err != nil { + return nil, 0, errors.Wrap(err, "error reading footer") + } + _, tocOffset, _, err := controller.ParseFooter(footer[positive(int64(len(footer))-fSize):]) + if err != nil { + return nil, 0, errors.Wrapf(err, "failed to parse footer") + } + + // Decode the TOC JSON + tocReader := io.NewSectionReader(sgz, tocOffset, sgz.Size()-tocOffset-fSize) + decodedJTOC, _, err = controller.ParseTOC(tocReader) + if err != nil { + return nil, 0, errors.Wrap(err, "failed to parse TOC") + } + return decodedJTOC, tocOffset, nil +} + +func testWriteAndOpen(t *testing.T, controllers ...TestingController) { + const content = "Some contents" + invalidUtf8 := "\xff\xfe\xfd" + + xAttrFile := xAttr{"foo": "bar", "invalid-utf8": invalidUtf8} + sampleOwner := owner{uid: 50, gid: 100} + + tests := []struct { + name string + chunkSize int + in []tarEntry + want []stargzCheck + wantNumGz int // expected number of streams + + wantNumGzLossLess int // expected number of streams (> 0) in lossless mode if it's different from wantNumGz + wantFailOnLossLess bool + }{ + { + name: "empty", + in: tarOf(), + wantNumGz: 2, // empty tar + TOC + footer + wantNumGzLossLess: 3, // empty tar + TOC + footer + want: checks( + numTOCEntries(0), + ), + }, + { + name: "1dir_1empty_file", + in: tarOf( + dir("foo/"), + file("foo/bar.txt", ""), + ), + wantNumGz: 3, // dir, TOC, footer + want: checks( + numTOCEntries(2), + hasDir("foo/"), + hasFileLen("foo/bar.txt", 0), + entryHasChildren("foo", "bar.txt"), + hasFileDigest("foo/bar.txt", digestFor("")), + ), + }, + { + name: "1dir_1file", + in: tarOf( + dir("foo/"), + file("foo/bar.txt", content, xAttrFile), + ), + wantNumGz: 4, // var dir, foo.txt alone, TOC, footer + want: checks( + numTOCEntries(2), + hasDir("foo/"), + hasFileLen("foo/bar.txt", len(content)), + hasFileDigest("foo/bar.txt", digestFor(content)), + hasFileContentsRange("foo/bar.txt", 0, content), + hasFileContentsRange("foo/bar.txt", 1, content[1:]), + entryHasChildren("", "foo"), + entryHasChildren("foo", "bar.txt"), + hasFileXattrs("foo/bar.txt", "foo", "bar"), + hasFileXattrs("foo/bar.txt", "invalid-utf8", invalidUtf8), + ), + }, + { + name: "2meta_2file", + in: tarOf( + dir("bar/", sampleOwner), + dir("foo/", sampleOwner), + file("foo/bar.txt", content, sampleOwner), + ), + wantNumGz: 4, // both dirs, foo.txt alone, TOC, footer + want: checks( + numTOCEntries(3), + hasDir("bar/"), + hasDir("foo/"), + hasFileLen("foo/bar.txt", len(content)), + entryHasChildren("", "bar", "foo"), + entryHasChildren("foo", "bar.txt"), + hasChunkEntries("foo/bar.txt", 1), + hasEntryOwner("bar/", sampleOwner), + hasEntryOwner("foo/", sampleOwner), + hasEntryOwner("foo/bar.txt", sampleOwner), + ), + }, + { + name: "3dir", + in: tarOf( + dir("bar/"), + dir("foo/"), + dir("foo/bar/"), + ), + wantNumGz: 3, // 3 dirs, TOC, footer + want: checks( + hasDirLinkCount("bar/", 2), + hasDirLinkCount("foo/", 3), + hasDirLinkCount("foo/bar/", 2), + ), + }, + { + name: "symlink", + in: tarOf( + dir("foo/"), + symlink("foo/bar", "../../x"), + ), + wantNumGz: 3, // metas + TOC + footer + want: checks( + numTOCEntries(2), + hasSymlink("foo/bar", "../../x"), + entryHasChildren("", "foo"), + entryHasChildren("foo", "bar"), + ), + }, + { + name: "chunked_file", + chunkSize: 4, + in: tarOf( + dir("foo/"), + file("foo/big.txt", "This "+"is s"+"uch "+"a bi"+"g fi"+"le"), + ), + wantNumGz: 9, + want: checks( + numTOCEntries(7), // 1 for foo dir, 6 for the foo/big.txt file + hasDir("foo/"), + hasFileLen("foo/big.txt", len("This is such a big file")), + hasFileDigest("foo/big.txt", digestFor("This is such a big file")), + hasFileContentsRange("foo/big.txt", 0, "This is such a big file"), + hasFileContentsRange("foo/big.txt", 1, "his is such a big file"), + hasFileContentsRange("foo/big.txt", 2, "is is such a big file"), + hasFileContentsRange("foo/big.txt", 3, "s is such a big file"), + hasFileContentsRange("foo/big.txt", 4, " is such a big file"), + hasFileContentsRange("foo/big.txt", 5, "is such a big file"), + hasFileContentsRange("foo/big.txt", 6, "s such a big file"), + hasFileContentsRange("foo/big.txt", 7, " such a big file"), + hasFileContentsRange("foo/big.txt", 8, "such a big file"), + hasFileContentsRange("foo/big.txt", 9, "uch a big file"), + hasFileContentsRange("foo/big.txt", 10, "ch a big file"), + hasFileContentsRange("foo/big.txt", 11, "h a big file"), + hasFileContentsRange("foo/big.txt", 12, " a big file"), + hasFileContentsRange("foo/big.txt", len("This is such a big file")-1, ""), + hasChunkEntries("foo/big.txt", 6), + ), + }, + { + name: "recursive", + in: tarOf( + dir("/", sampleOwner), + dir("bar/", sampleOwner), + dir("foo/", sampleOwner), + file("foo/bar.txt", content, sampleOwner), + ), + wantNumGz: 4, // dirs, bar.txt alone, TOC, footer + want: checks( + maxDepth(2), // 0: root directory, 1: "foo/", 2: "bar.txt" + ), + }, + { + name: "block_char_fifo", + in: tarOf( + tarEntryFunc(func(w *tar.Writer, prefix string, format tar.Format) error { + return w.WriteHeader(&tar.Header{ + Name: prefix + "b", + Typeflag: tar.TypeBlock, + Devmajor: 123, + Devminor: 456, + Format: format, + }) + }), + tarEntryFunc(func(w *tar.Writer, prefix string, format tar.Format) error { + return w.WriteHeader(&tar.Header{ + Name: prefix + "c", + Typeflag: tar.TypeChar, + Devmajor: 111, + Devminor: 222, + Format: format, + }) + }), + tarEntryFunc(func(w *tar.Writer, prefix string, format tar.Format) error { + return w.WriteHeader(&tar.Header{ + Name: prefix + "f", + Typeflag: tar.TypeFifo, + Format: format, + }) + }), + ), + wantNumGz: 3, + want: checks( + lookupMatch("b", &TOCEntry{Name: "b", Type: "block", DevMajor: 123, DevMinor: 456, NumLink: 1}), + lookupMatch("c", &TOCEntry{Name: "c", Type: "char", DevMajor: 111, DevMinor: 222, NumLink: 1}), + lookupMatch("f", &TOCEntry{Name: "f", Type: "fifo", NumLink: 1}), + ), + }, + { + name: "modes", + in: tarOf( + dir("foo1/", 0755|os.ModeDir|os.ModeSetgid), + file("foo1/bar1", content, 0700|os.ModeSetuid), + file("foo1/bar2", content, 0755|os.ModeSetgid), + dir("foo2/", 0755|os.ModeDir|os.ModeSticky), + file("foo2/bar3", content, 0755|os.ModeSticky), + dir("foo3/", 0755|os.ModeDir), + file("foo3/bar4", content, os.FileMode(0700)), + file("foo3/bar5", content, os.FileMode(0755)), + ), + wantNumGz: 8, // dir, bar1 alone, bar2 alone + dir, bar3 alone + dir, bar4 alone, bar5 alone, TOC, footer + want: checks( + hasMode("foo1/", 0755|os.ModeDir|os.ModeSetgid), + hasMode("foo1/bar1", 0700|os.ModeSetuid), + hasMode("foo1/bar2", 0755|os.ModeSetgid), + hasMode("foo2/", 0755|os.ModeDir|os.ModeSticky), + hasMode("foo2/bar3", 0755|os.ModeSticky), + hasMode("foo3/", 0755|os.ModeDir), + hasMode("foo3/bar4", os.FileMode(0700)), + hasMode("foo3/bar5", os.FileMode(0755)), + ), + }, + { + name: "lossy", + in: tarOf( + dir("bar/", sampleOwner), + dir("foo/", sampleOwner), + file("foo/bar.txt", content, sampleOwner), + file(TOCTarName, "dummy"), // ignored by the writer. (lossless write returns error) + ), + wantNumGz: 4, // both dirs, foo.txt alone, TOC, footer + want: checks( + numTOCEntries(3), + hasDir("bar/"), + hasDir("foo/"), + hasFileLen("foo/bar.txt", len(content)), + entryHasChildren("", "bar", "foo"), + entryHasChildren("foo", "bar.txt"), + hasChunkEntries("foo/bar.txt", 1), + hasEntryOwner("bar/", sampleOwner), + hasEntryOwner("foo/", sampleOwner), + hasEntryOwner("foo/bar.txt", sampleOwner), + ), + wantFailOnLossLess: true, + }, + } + + for _, tt := range tests { + for _, cl := range controllers { + cl := cl + for _, prefix := range allowedPrefix { + prefix := prefix + for _, srcTarFormat := range []tar.Format{tar.FormatUSTAR, tar.FormatPAX, tar.FormatGNU} { + srcTarFormat := srcTarFormat + for _, lossless := range []bool{true, false} { + t.Run(tt.name+"-"+fmt.Sprintf("compression=%v,prefix=%q,lossless=%v,format=%s", cl, prefix, lossless, srcTarFormat), func(t *testing.T) { + var tr io.Reader = buildTar(t, tt.in, prefix, srcTarFormat) + origTarDgstr := digest.Canonical.Digester() + tr = io.TeeReader(tr, origTarDgstr.Hash()) + var stargzBuf bytes.Buffer + w := NewWriterWithCompressor(&stargzBuf, cl) + w.ChunkSize = tt.chunkSize + if lossless { + err := w.AppendTarLossLess(tr) + if tt.wantFailOnLossLess { + if err != nil { + return // expected to fail + } + t.Fatalf("Append wanted to fail on lossless") + } + if err != nil { + t.Fatalf("Append(lossless): %v", err) + } + } else { + if err := w.AppendTar(tr); err != nil { + t.Fatalf("Append: %v", err) + } + } + if _, err := w.Close(); err != nil { + t.Fatalf("Writer.Close: %v", err) + } + b := stargzBuf.Bytes() + + if lossless { + // Check if the result blob reserves original tar metadata + rc, err := Unpack(io.NewSectionReader(bytes.NewReader(b), 0, int64(len(b))), cl) + if err != nil { + t.Errorf("failed to decompress blob: %v", err) + return + } + defer rc.Close() + resultDgstr := digest.Canonical.Digester() + if _, err := io.Copy(resultDgstr.Hash(), rc); err != nil { + t.Errorf("failed to read result decompressed blob: %v", err) + return + } + if resultDgstr.Digest() != origTarDgstr.Digest() { + t.Errorf("lossy compression occurred: digest=%v; want %v", + resultDgstr.Digest(), origTarDgstr.Digest()) + return + } + } + + diffID := w.DiffID() + wantDiffID := cl.DiffIDOf(t, b) + if diffID != wantDiffID { + t.Errorf("DiffID = %q; want %q", diffID, wantDiffID) + } + + got := cl.CountStreams(t, b) + wantNumGz := tt.wantNumGz + if lossless && tt.wantNumGzLossLess > 0 { + wantNumGz = tt.wantNumGzLossLess + } + if got != wantNumGz { + t.Errorf("number of streams = %d; want %d", got, wantNumGz) + } + + telemetry, checkCalled := newCalledTelemetry() + r, err := Open( + io.NewSectionReader(bytes.NewReader(b), 0, int64(len(b))), + WithDecompressors(cl), + WithTelemetry(telemetry), + ) + if err != nil { + t.Fatalf("stargz.Open: %v", err) + } + if err := checkCalled(); err != nil { + t.Errorf("telemetry failure: %v", err) + } + for _, want := range tt.want { + want.check(t, r) + } + }) + } + } + } + } + } +} + +func newCalledTelemetry() (telemetry *Telemetry, check func() error) { + var getFooterLatencyCalled bool + var getTocLatencyCalled bool + var deserializeTocLatencyCalled bool + return &Telemetry{ + func(time.Time) { getFooterLatencyCalled = true }, + func(time.Time) { getTocLatencyCalled = true }, + func(time.Time) { deserializeTocLatencyCalled = true }, + }, func() error { + var allErr []error + if !getFooterLatencyCalled { + allErr = append(allErr, fmt.Errorf("metrics GetFooterLatency isn't called")) + } + if !getTocLatencyCalled { + allErr = append(allErr, fmt.Errorf("metrics GetTocLatency isn't called")) + } + if !deserializeTocLatencyCalled { + allErr = append(allErr, fmt.Errorf("metrics DeserializeTocLatency isn't called")) + } + return errorutil.Aggregate(allErr) + } +} + +func digestFor(content string) string { + sum := sha256.Sum256([]byte(content)) + return fmt.Sprintf("sha256:%x", sum) +} + +type numTOCEntries int + +func (n numTOCEntries) check(t *testing.T, r *Reader) { + if r.toc == nil { + t.Fatal("nil TOC") + } + if got, want := len(r.toc.Entries), int(n); got != want { + t.Errorf("got %d TOC entries; want %d", got, want) + } + t.Logf("got TOC entries:") + for i, ent := range r.toc.Entries { + entj, _ := json.Marshal(ent) + t.Logf(" [%d]: %s\n", i, entj) + } + if t.Failed() { + t.FailNow() + } +} + +func checks(s ...stargzCheck) []stargzCheck { return s } + +type stargzCheck interface { + check(t *testing.T, r *Reader) +} + +type stargzCheckFn func(*testing.T, *Reader) + +func (f stargzCheckFn) check(t *testing.T, r *Reader) { f(t, r) } + +func maxDepth(max int) stargzCheck { + return stargzCheckFn(func(t *testing.T, r *Reader) { + e, ok := r.Lookup("") + if !ok { + t.Fatal("root directory not found") + } + d, err := getMaxDepth(t, e, 0, 10*max) + if err != nil { + t.Errorf("failed to get max depth (wanted %d): %v", max, err) + return + } + if d != max { + t.Errorf("invalid depth %d; want %d", d, max) + return + } + }) +} + +func getMaxDepth(t *testing.T, e *TOCEntry, current, limit int) (max int, rErr error) { + if current > limit { + return -1, fmt.Errorf("walkMaxDepth: exceeds limit: current:%d > limit:%d", + current, limit) + } + max = current + e.ForeachChild(func(baseName string, ent *TOCEntry) bool { + t.Logf("%q(basename:%q) is child of %q\n", ent.Name, baseName, e.Name) + d, err := getMaxDepth(t, ent, current+1, limit) + if err != nil { + rErr = err + return false + } + if d > max { + max = d + } + return true + }) + return +} + +func hasFileLen(file string, wantLen int) stargzCheck { + return stargzCheckFn(func(t *testing.T, r *Reader) { + for _, ent := range r.toc.Entries { + if ent.Name == file { + if ent.Type != "reg" { + t.Errorf("file type of %q is %q; want \"reg\"", file, ent.Type) + } else if ent.Size != int64(wantLen) { + t.Errorf("file size of %q = %d; want %d", file, ent.Size, wantLen) + } + return + } + } + t.Errorf("file %q not found", file) + }) +} + +func hasFileXattrs(file, name, value string) stargzCheck { + return stargzCheckFn(func(t *testing.T, r *Reader) { + for _, ent := range r.toc.Entries { + if ent.Name == file { + if ent.Type != "reg" { + t.Errorf("file type of %q is %q; want \"reg\"", file, ent.Type) + } + if ent.Xattrs == nil { + t.Errorf("file %q has no xattrs", file) + return + } + valueFound, found := ent.Xattrs[name] + if !found { + t.Errorf("file %q has no xattr %q", file, name) + return + } + if string(valueFound) != value { + t.Errorf("file %q has xattr %q with value %q instead of %q", file, name, valueFound, value) + } + + return + } + } + t.Errorf("file %q not found", file) + }) +} + +func hasFileDigest(file string, digest string) stargzCheck { + return stargzCheckFn(func(t *testing.T, r *Reader) { + ent, ok := r.Lookup(file) + if !ok { + t.Fatalf("didn't find TOCEntry for file %q", file) + } + if ent.Digest != digest { + t.Fatalf("Digest(%q) = %q, want %q", file, ent.Digest, digest) + } + }) +} + +func hasFileContentsRange(file string, offset int, want string) stargzCheck { + return stargzCheckFn(func(t *testing.T, r *Reader) { + f, err := r.OpenFile(file) + if err != nil { + t.Fatal(err) + } + got := make([]byte, len(want)) + n, err := f.ReadAt(got, int64(offset)) + if err != nil { + t.Fatalf("ReadAt(len %d, offset %d) = %v, %v", len(got), offset, n, err) + } + if string(got) != want { + t.Fatalf("ReadAt(len %d, offset %d) = %q, want %q", len(got), offset, got, want) + } + }) +} + +func hasChunkEntries(file string, wantChunks int) stargzCheck { + return stargzCheckFn(func(t *testing.T, r *Reader) { + ent, ok := r.Lookup(file) + if !ok { + t.Fatalf("no file for %q", file) + } + if ent.Type != "reg" { + t.Fatalf("file %q has unexpected type %q; want reg", file, ent.Type) + } + chunks := r.getChunks(ent) + if len(chunks) != wantChunks { + t.Errorf("len(r.getChunks(%q)) = %d; want %d", file, len(chunks), wantChunks) + return + } + f := chunks[0] + + var gotChunks []*TOCEntry + var last *TOCEntry + for off := int64(0); off < f.Size; off++ { + e, ok := r.ChunkEntryForOffset(file, off) + if !ok { + t.Errorf("no ChunkEntryForOffset at %d", off) + return + } + if last != e { + gotChunks = append(gotChunks, e) + last = e + } + } + if !reflect.DeepEqual(chunks, gotChunks) { + t.Errorf("gotChunks=%d, want=%d; contents mismatch", len(gotChunks), wantChunks) + } + + // And verify the NextOffset + for i := 0; i < len(gotChunks)-1; i++ { + ci := gotChunks[i] + cnext := gotChunks[i+1] + if ci.NextOffset() != cnext.Offset { + t.Errorf("chunk %d NextOffset %d != next chunk's Offset of %d", i, ci.NextOffset(), cnext.Offset) + } + } + }) +} + +func entryHasChildren(dir string, want ...string) stargzCheck { + return stargzCheckFn(func(t *testing.T, r *Reader) { + want := append([]string(nil), want...) + var got []string + ent, ok := r.Lookup(dir) + if !ok { + t.Fatalf("didn't find TOCEntry for dir node %q", dir) + } + for baseName := range ent.children { + got = append(got, baseName) + } + sort.Strings(got) + sort.Strings(want) + if !reflect.DeepEqual(got, want) { + t.Errorf("children of %q = %q; want %q", dir, got, want) + } + }) +} + +func hasDir(file string) stargzCheck { + return stargzCheckFn(func(t *testing.T, r *Reader) { + for _, ent := range r.toc.Entries { + if ent.Name == cleanEntryName(file) { + if ent.Type != "dir" { + t.Errorf("file type of %q is %q; want \"dir\"", file, ent.Type) + } + return + } + } + t.Errorf("directory %q not found", file) + }) +} + +func hasDirLinkCount(file string, count int) stargzCheck { + return stargzCheckFn(func(t *testing.T, r *Reader) { + for _, ent := range r.toc.Entries { + if ent.Name == cleanEntryName(file) { + if ent.Type != "dir" { + t.Errorf("file type of %q is %q; want \"dir\"", file, ent.Type) + return + } + if ent.NumLink != count { + t.Errorf("link count of %q = %d; want %d", file, ent.NumLink, count) + } + return + } + } + t.Errorf("directory %q not found", file) + }) +} + +func hasMode(file string, mode os.FileMode) stargzCheck { + return stargzCheckFn(func(t *testing.T, r *Reader) { + for _, ent := range r.toc.Entries { + if ent.Name == cleanEntryName(file) { + if ent.Stat().Mode() != mode { + t.Errorf("invalid mode: got %v; want %v", ent.Stat().Mode(), mode) + return + } + return + } + } + t.Errorf("file %q not found", file) + }) +} + +func hasSymlink(file, target string) stargzCheck { + return stargzCheckFn(func(t *testing.T, r *Reader) { + for _, ent := range r.toc.Entries { + if ent.Name == file { + if ent.Type != "symlink" { + t.Errorf("file type of %q is %q; want \"symlink\"", file, ent.Type) + } else if ent.LinkName != target { + t.Errorf("link target of symlink %q is %q; want %q", file, ent.LinkName, target) + } + return + } + } + t.Errorf("symlink %q not found", file) + }) +} + +func lookupMatch(name string, want *TOCEntry) stargzCheck { + return stargzCheckFn(func(t *testing.T, r *Reader) { + e, ok := r.Lookup(name) + if !ok { + t.Fatalf("failed to Lookup entry %q", name) + } + if !reflect.DeepEqual(e, want) { + t.Errorf("entry %q mismatch.\n got: %+v\nwant: %+v\n", name, e, want) + } + + }) +} + +func hasEntryOwner(entry string, owner owner) stargzCheck { + return stargzCheckFn(func(t *testing.T, r *Reader) { + ent, ok := r.Lookup(strings.TrimSuffix(entry, "/")) + if !ok { + t.Errorf("entry %q not found", entry) + return + } + if ent.UID != owner.uid || ent.GID != owner.gid { + t.Errorf("entry %q has invalid owner (uid:%d, gid:%d) instead of (uid:%d, gid:%d)", entry, ent.UID, ent.GID, owner.uid, owner.gid) + return + } + }) +} + +func tarOf(s ...tarEntry) []tarEntry { return s } + +type tarEntry interface { + appendTar(tw *tar.Writer, prefix string, format tar.Format) error +} + +type tarEntryFunc func(*tar.Writer, string, tar.Format) error + +func (f tarEntryFunc) appendTar(tw *tar.Writer, prefix string, format tar.Format) error { + return f(tw, prefix, format) +} + +func buildTar(t *testing.T, ents []tarEntry, prefix string, opts ...interface{}) *io.SectionReader { + format := tar.FormatUnknown + for _, opt := range opts { + switch v := opt.(type) { + case tar.Format: + format = v + default: + panic(fmt.Errorf("unsupported opt for buildTar: %v", opt)) + } + } + buf := new(bytes.Buffer) + tw := tar.NewWriter(buf) + for _, ent := range ents { + if err := ent.appendTar(tw, prefix, format); err != nil { + t.Fatalf("building input tar: %v", err) + } + } + if err := tw.Close(); err != nil { + t.Errorf("closing write of input tar: %v", err) + } + data := append(buf.Bytes(), make([]byte, 100)...) // append empty bytes at the tail to see lossless works + return io.NewSectionReader(bytes.NewReader(data), 0, int64(len(data))) +} + +func dir(name string, opts ...interface{}) tarEntry { + return tarEntryFunc(func(tw *tar.Writer, prefix string, format tar.Format) error { + var o owner + mode := os.FileMode(0755) + for _, opt := range opts { + switch v := opt.(type) { + case owner: + o = v + case os.FileMode: + mode = v + default: + return errors.New("unsupported opt") + } + } + if !strings.HasSuffix(name, "/") { + panic(fmt.Sprintf("missing trailing slash in dir %q ", name)) + } + tm, err := fileModeToTarMode(mode) + if err != nil { + return err + } + return tw.WriteHeader(&tar.Header{ + Typeflag: tar.TypeDir, + Name: prefix + name, + Mode: tm, + Uid: o.uid, + Gid: o.gid, + Format: format, + }) + }) +} + +// xAttr are extended attributes to set on test files created with the file func. +type xAttr map[string]string + +// owner is owner ot set on test files and directories with the file and dir functions. +type owner struct { + uid int + gid int +} + +func file(name, contents string, opts ...interface{}) tarEntry { + return tarEntryFunc(func(tw *tar.Writer, prefix string, format tar.Format) error { + var xattrs xAttr + var o owner + mode := os.FileMode(0644) + for _, opt := range opts { + switch v := opt.(type) { + case xAttr: + xattrs = v + case owner: + o = v + case os.FileMode: + mode = v + default: + return errors.New("unsupported opt") + } + } + if strings.HasSuffix(name, "/") { + return fmt.Errorf("bogus trailing slash in file %q", name) + } + tm, err := fileModeToTarMode(mode) + if err != nil { + return err + } + if len(xattrs) > 0 { + format = tar.FormatPAX // only PAX supports xattrs + } + if err := tw.WriteHeader(&tar.Header{ + Typeflag: tar.TypeReg, + Name: prefix + name, + Mode: tm, + Xattrs: xattrs, + Size: int64(len(contents)), + Uid: o.uid, + Gid: o.gid, + Format: format, + }); err != nil { + return err + } + _, err = io.WriteString(tw, contents) + return err + }) +} + +func symlink(name, target string) tarEntry { + return tarEntryFunc(func(tw *tar.Writer, prefix string, format tar.Format) error { + return tw.WriteHeader(&tar.Header{ + Typeflag: tar.TypeSymlink, + Name: prefix + name, + Linkname: target, + Mode: 0644, + Format: format, + }) + }) +} + +func link(name string, linkname string) tarEntry { + now := time.Now() + return tarEntryFunc(func(w *tar.Writer, prefix string, format tar.Format) error { + return w.WriteHeader(&tar.Header{ + Typeflag: tar.TypeLink, + Name: prefix + name, + Linkname: linkname, + ModTime: now, + Format: format, + }) + }) +} + +func chardev(name string, major, minor int64) tarEntry { + now := time.Now() + return tarEntryFunc(func(w *tar.Writer, prefix string, format tar.Format) error { + return w.WriteHeader(&tar.Header{ + Typeflag: tar.TypeChar, + Name: prefix + name, + Devmajor: major, + Devminor: minor, + ModTime: now, + Format: format, + }) + }) +} + +func blockdev(name string, major, minor int64) tarEntry { + now := time.Now() + return tarEntryFunc(func(w *tar.Writer, prefix string, format tar.Format) error { + return w.WriteHeader(&tar.Header{ + Typeflag: tar.TypeBlock, + Name: prefix + name, + Devmajor: major, + Devminor: minor, + ModTime: now, + Format: format, + }) + }) +} +func fifo(name string) tarEntry { + now := time.Now() + return tarEntryFunc(func(w *tar.Writer, prefix string, format tar.Format) error { + return w.WriteHeader(&tar.Header{ + Typeflag: tar.TypeFifo, + Name: prefix + name, + ModTime: now, + Format: format, + }) + }) +} + +func prefetchLandmark() tarEntry { + return tarEntryFunc(func(w *tar.Writer, prefix string, format tar.Format) error { + if err := w.WriteHeader(&tar.Header{ + Name: PrefetchLandmark, + Typeflag: tar.TypeReg, + Size: int64(len([]byte{landmarkContents})), + Format: format, + }); err != nil { + return err + } + contents := []byte{landmarkContents} + if _, err := io.CopyN(w, bytes.NewReader(contents), int64(len(contents))); err != nil { + return err + } + return nil + }) +} + +func noPrefetchLandmark() tarEntry { + return tarEntryFunc(func(w *tar.Writer, prefix string, format tar.Format) error { + if err := w.WriteHeader(&tar.Header{ + Name: NoPrefetchLandmark, + Typeflag: tar.TypeReg, + Size: int64(len([]byte{landmarkContents})), + Format: format, + }); err != nil { + return err + } + contents := []byte{landmarkContents} + if _, err := io.CopyN(w, bytes.NewReader(contents), int64(len(contents))); err != nil { + return err + } + return nil + }) +} + +func regDigest(t *testing.T, name string, contentStr string, digestMap map[string]digest.Digest) tarEntry { + if digestMap == nil { + t.Fatalf("digest map mustn't be nil") + } + content := []byte(contentStr) + + var n int64 + for n < int64(len(content)) { + size := int64(chunkSize) + remain := int64(len(content)) - n + if remain < size { + size = remain + } + dgstr := digest.Canonical.Digester() + if _, err := io.CopyN(dgstr.Hash(), bytes.NewReader(content[n:n+size]), size); err != nil { + t.Fatalf("failed to calculate digest of %q (name=%q,offset=%d,size=%d)", + string(content[n:n+size]), name, n, size) + } + digestMap[chunkID(name, n, size)] = dgstr.Digest() + n += size + } + + return tarEntryFunc(func(w *tar.Writer, prefix string, format tar.Format) error { + if err := w.WriteHeader(&tar.Header{ + Typeflag: tar.TypeReg, + Name: prefix + name, + Size: int64(len(content)), + Format: format, + }); err != nil { + return err + } + if _, err := io.CopyN(w, bytes.NewReader(content), int64(len(content))); err != nil { + return err + } + return nil + }) +} + +func fileModeToTarMode(mode os.FileMode) (int64, error) { + h, err := tar.FileInfoHeader(fileInfoOnlyMode(mode), "") + if err != nil { + return 0, err + } + return h.Mode, nil +} + +// fileInfoOnlyMode is os.FileMode that populates only file mode. +type fileInfoOnlyMode os.FileMode + +func (f fileInfoOnlyMode) Name() string { return "" } +func (f fileInfoOnlyMode) Size() int64 { return 0 } +func (f fileInfoOnlyMode) Mode() os.FileMode { return os.FileMode(f) } +func (f fileInfoOnlyMode) ModTime() time.Time { return time.Now() } +func (f fileInfoOnlyMode) IsDir() bool { return os.FileMode(f).IsDir() } +func (f fileInfoOnlyMode) Sys() interface{} { return nil } diff --git a/vendor/github.com/containerd/stargz-snapshotter/estargz/types.go b/vendor/github.com/containerd/stargz-snapshotter/estargz/types.go index 680347a79c..384ff7fd7f 100644 --- a/vendor/github.com/containerd/stargz-snapshotter/estargz/types.go +++ b/vendor/github.com/containerd/stargz-snapshotter/estargz/types.go @@ -24,6 +24,8 @@ package estargz import ( "archive/tar" + "hash" + "io" "os" "path" "time" @@ -90,8 +92,8 @@ const ( landmarkContents = 0xf ) -// jtoc is the JSON-serialized table of contents index of the files in the stargz file. -type jtoc struct { +// JTOC is the JSON-serialized table of contents index of the files in the stargz file. +type JTOC struct { Version int `json:"version"` Entries []*TOCEntry `json:"entries"` } @@ -262,3 +264,53 @@ type TOCEntryVerifier interface { // contents of the specified TOCEntry. Verifier(ce *TOCEntry) (digest.Verifier, error) } + +// Compression provides the compression helper to be used creating and parsing eStargz. +// This package provides gzip-based Compression by default, but any compression +// algorithm (e.g. zstd) can be used as long as it implements Compression. +type Compression interface { + Compressor + Decompressor +} + +// Compressor represents the helper mothods to be used for creating eStargz. +type Compressor interface { + // Writer returns WriteCloser to be used for writing a chunk to eStargz. + // Everytime a chunk is written, the WriteCloser is closed and Writer is + // called again for writing the next chunk. + Writer(w io.Writer) (io.WriteCloser, error) + + // WriteTOCAndFooter is called to write JTOC to the passed Writer. + // diffHash calculates the DiffID (uncompressed sha256 hash) of the blob + // WriteTOCAndFooter can optionally write anything that affects DiffID calculation + // (e.g. uncompressed TOC JSON). + // + // This function returns tocDgst that represents the digest of TOC that will be used + // to verify this blob when it's parsed. + WriteTOCAndFooter(w io.Writer, off int64, toc *JTOC, diffHash hash.Hash) (tocDgst digest.Digest, err error) +} + +// Decompressor represents the helper mothods to be used for parsing eStargz. +type Decompressor interface { + // Reader returns ReadCloser to be used for decompressing file payload. + Reader(r io.Reader) (io.ReadCloser, error) + + // FooterSize returns the size of the footer of this blob. + FooterSize() int64 + + // ParseFooter parses the footer and returns the offset and (compressed) size of TOC. + // payloadBlobSize is the (compressed) size of the blob payload (i.e. the size between + // the top until the TOC JSON). + // + // Here, tocSize is optional. If tocSize <= 0, it's by default the size of the range + // from tocOffset until the beginning of the footer (blob size - tocOff - FooterSize). + ParseFooter(p []byte) (blobPayloadSize, tocOffset, tocSize int64, err error) + + // ParseTOC parses TOC from the passed reader. The reader provides the partial contents + // of the underlying blob that has the range specified by ParseFooter method. + // + // This function returns tocDgst that represents the digest of TOC that will be used + // to verify this blob. This must match to the value returned from + // Compressor.WriteTOCAndFooter that is used when creating this blob. + ParseTOC(r io.Reader) (toc *JTOC, tocDgst digest.Digest, err error) +} diff --git a/vendor/github.com/coreos/go-semver/LICENSE b/vendor/github.com/coreos/go-semver/LICENSE new file mode 100644 index 0000000000..d645695673 --- /dev/null +++ b/vendor/github.com/coreos/go-semver/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/vendor/github.com/coreos/go-semver/NOTICE b/vendor/github.com/coreos/go-semver/NOTICE new file mode 100644 index 0000000000..23a0ada2fb --- /dev/null +++ b/vendor/github.com/coreos/go-semver/NOTICE @@ -0,0 +1,5 @@ +CoreOS Project +Copyright 2018 CoreOS, Inc + +This product includes software developed at CoreOS, Inc. +(http://www.coreos.com/). diff --git a/vendor/github.com/coreos/go-semver/semver/semver.go b/vendor/github.com/coreos/go-semver/semver/semver.go new file mode 100644 index 0000000000..76cf4852c7 --- /dev/null +++ b/vendor/github.com/coreos/go-semver/semver/semver.go @@ -0,0 +1,296 @@ +// Copyright 2013-2015 CoreOS, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Semantic Versions http://semver.org +package semver + +import ( + "bytes" + "errors" + "fmt" + "regexp" + "strconv" + "strings" +) + +type Version struct { + Major int64 + Minor int64 + Patch int64 + PreRelease PreRelease + Metadata string +} + +type PreRelease string + +func splitOff(input *string, delim string) (val string) { + parts := strings.SplitN(*input, delim, 2) + + if len(parts) == 2 { + *input = parts[0] + val = parts[1] + } + + return val +} + +func New(version string) *Version { + return Must(NewVersion(version)) +} + +func NewVersion(version string) (*Version, error) { + v := Version{} + + if err := v.Set(version); err != nil { + return nil, err + } + + return &v, nil +} + +// Must is a helper for wrapping NewVersion and will panic if err is not nil. +func Must(v *Version, err error) *Version { + if err != nil { + panic(err) + } + return v +} + +// Set parses and updates v from the given version string. Implements flag.Value +func (v *Version) Set(version string) error { + metadata := splitOff(&version, "+") + preRelease := PreRelease(splitOff(&version, "-")) + dotParts := strings.SplitN(version, ".", 3) + + if len(dotParts) != 3 { + return fmt.Errorf("%s is not in dotted-tri format", version) + } + + if err := validateIdentifier(string(preRelease)); err != nil { + return fmt.Errorf("failed to validate pre-release: %v", err) + } + + if err := validateIdentifier(metadata); err != nil { + return fmt.Errorf("failed to validate metadata: %v", err) + } + + parsed := make([]int64, 3, 3) + + for i, v := range dotParts[:3] { + val, err := strconv.ParseInt(v, 10, 64) + parsed[i] = val + if err != nil { + return err + } + } + + v.Metadata = metadata + v.PreRelease = preRelease + v.Major = parsed[0] + v.Minor = parsed[1] + v.Patch = parsed[2] + return nil +} + +func (v Version) String() string { + var buffer bytes.Buffer + + fmt.Fprintf(&buffer, "%d.%d.%d", v.Major, v.Minor, v.Patch) + + if v.PreRelease != "" { + fmt.Fprintf(&buffer, "-%s", v.PreRelease) + } + + if v.Metadata != "" { + fmt.Fprintf(&buffer, "+%s", v.Metadata) + } + + return buffer.String() +} + +func (v *Version) UnmarshalYAML(unmarshal func(interface{}) error) error { + var data string + if err := unmarshal(&data); err != nil { + return err + } + return v.Set(data) +} + +func (v Version) MarshalJSON() ([]byte, error) { + return []byte(`"` + v.String() + `"`), nil +} + +func (v *Version) UnmarshalJSON(data []byte) error { + l := len(data) + if l == 0 || string(data) == `""` { + return nil + } + if l < 2 || data[0] != '"' || data[l-1] != '"' { + return errors.New("invalid semver string") + } + return v.Set(string(data[1 : l-1])) +} + +// Compare tests if v is less than, equal to, or greater than versionB, +// returning -1, 0, or +1 respectively. +func (v Version) Compare(versionB Version) int { + if cmp := recursiveCompare(v.Slice(), versionB.Slice()); cmp != 0 { + return cmp + } + return preReleaseCompare(v, versionB) +} + +// Equal tests if v is equal to versionB. +func (v Version) Equal(versionB Version) bool { + return v.Compare(versionB) == 0 +} + +// LessThan tests if v is less than versionB. +func (v Version) LessThan(versionB Version) bool { + return v.Compare(versionB) < 0 +} + +// Slice converts the comparable parts of the semver into a slice of integers. +func (v Version) Slice() []int64 { + return []int64{v.Major, v.Minor, v.Patch} +} + +func (p PreRelease) Slice() []string { + preRelease := string(p) + return strings.Split(preRelease, ".") +} + +func preReleaseCompare(versionA Version, versionB Version) int { + a := versionA.PreRelease + b := versionB.PreRelease + + /* Handle the case where if two versions are otherwise equal it is the + * one without a PreRelease that is greater */ + if len(a) == 0 && (len(b) > 0) { + return 1 + } else if len(b) == 0 && (len(a) > 0) { + return -1 + } + + // If there is a prerelease, check and compare each part. + return recursivePreReleaseCompare(a.Slice(), b.Slice()) +} + +func recursiveCompare(versionA []int64, versionB []int64) int { + if len(versionA) == 0 { + return 0 + } + + a := versionA[0] + b := versionB[0] + + if a > b { + return 1 + } else if a < b { + return -1 + } + + return recursiveCompare(versionA[1:], versionB[1:]) +} + +func recursivePreReleaseCompare(versionA []string, versionB []string) int { + // A larger set of pre-release fields has a higher precedence than a smaller set, + // if all of the preceding identifiers are equal. + if len(versionA) == 0 { + if len(versionB) > 0 { + return -1 + } + return 0 + } else if len(versionB) == 0 { + // We're longer than versionB so return 1. + return 1 + } + + a := versionA[0] + b := versionB[0] + + aInt := false + bInt := false + + aI, err := strconv.Atoi(versionA[0]) + if err == nil { + aInt = true + } + + bI, err := strconv.Atoi(versionB[0]) + if err == nil { + bInt = true + } + + // Numeric identifiers always have lower precedence than non-numeric identifiers. + if aInt && !bInt { + return -1 + } else if !aInt && bInt { + return 1 + } + + // Handle Integer Comparison + if aInt && bInt { + if aI > bI { + return 1 + } else if aI < bI { + return -1 + } + } + + // Handle String Comparison + if a > b { + return 1 + } else if a < b { + return -1 + } + + return recursivePreReleaseCompare(versionA[1:], versionB[1:]) +} + +// BumpMajor increments the Major field by 1 and resets all other fields to their default values +func (v *Version) BumpMajor() { + v.Major += 1 + v.Minor = 0 + v.Patch = 0 + v.PreRelease = PreRelease("") + v.Metadata = "" +} + +// BumpMinor increments the Minor field by 1 and resets all other fields to their default values +func (v *Version) BumpMinor() { + v.Minor += 1 + v.Patch = 0 + v.PreRelease = PreRelease("") + v.Metadata = "" +} + +// BumpPatch increments the Patch field by 1 and resets all other fields to their default values +func (v *Version) BumpPatch() { + v.Patch += 1 + v.PreRelease = PreRelease("") + v.Metadata = "" +} + +// validateIdentifier makes sure the provided identifier satisfies semver spec +func validateIdentifier(id string) error { + if id != "" && !reIdentifier.MatchString(id) { + return fmt.Errorf("%s is not a valid semver identifier", id) + } + return nil +} + +// reIdentifier is a regular expression used to check that pre-release and metadata +// identifiers satisfy the spec requirements +var reIdentifier = regexp.MustCompile(`^[0-9A-Za-z-]+(\.[0-9A-Za-z-]+)*$`) diff --git a/vendor/github.com/coreos/go-semver/semver/sort.go b/vendor/github.com/coreos/go-semver/semver/sort.go new file mode 100644 index 0000000000..e256b41a5d --- /dev/null +++ b/vendor/github.com/coreos/go-semver/semver/sort.go @@ -0,0 +1,38 @@ +// Copyright 2013-2015 CoreOS, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package semver + +import ( + "sort" +) + +type Versions []*Version + +func (s Versions) Len() int { + return len(s) +} + +func (s Versions) Swap(i, j int) { + s[i], s[j] = s[j], s[i] +} + +func (s Versions) Less(i, j int) bool { + return s[i].LessThan(*s[j]) +} + +// Sort sorts the given slice of Version +func Sort(versions []*Version) { + sort.Sort(Versions(versions)) +} diff --git a/vendor/github.com/cpuguy83/go-md2man/v2/md2man/roff.go b/vendor/github.com/cpuguy83/go-md2man/v2/md2man/roff.go index 0668a66cf7..be2b343606 100644 --- a/vendor/github.com/cpuguy83/go-md2man/v2/md2man/roff.go +++ b/vendor/github.com/cpuguy83/go-md2man/v2/md2man/roff.go @@ -15,7 +15,7 @@ type roffRenderer struct { extensions blackfriday.Extensions listCounters []int firstHeader bool - defineTerm bool + firstDD bool listDepth int } @@ -42,7 +42,8 @@ const ( quoteCloseTag = "\n.RE\n" listTag = "\n.RS\n" listCloseTag = "\n.RE\n" - arglistTag = "\n.TP\n" + dtTag = "\n.TP\n" + dd2Tag = "\n" tableStart = "\n.TS\nallbox;\n" tableEnd = ".TE\n" tableCellStart = "T{\n" @@ -90,7 +91,7 @@ func (r *roffRenderer) RenderNode(w io.Writer, node *blackfriday.Node, entering switch node.Type { case blackfriday.Text: - r.handleText(w, node, entering) + escapeSpecialChars(w, node.Literal) case blackfriday.Softbreak: out(w, crTag) case blackfriday.Hardbreak: @@ -150,40 +151,21 @@ func (r *roffRenderer) RenderNode(w io.Writer, node *blackfriday.Node, entering out(w, codeCloseTag) case blackfriday.Table: r.handleTable(w, node, entering) - case blackfriday.TableCell: - r.handleTableCell(w, node, entering) case blackfriday.TableHead: case blackfriday.TableBody: case blackfriday.TableRow: // no action as cell entries do all the nroff formatting return blackfriday.GoToNext + case blackfriday.TableCell: + r.handleTableCell(w, node, entering) + case blackfriday.HTMLSpan: + // ignore other HTML tags default: fmt.Fprintln(os.Stderr, "WARNING: go-md2man does not handle node type "+node.Type.String()) } return walkAction } -func (r *roffRenderer) handleText(w io.Writer, node *blackfriday.Node, entering bool) { - var ( - start, end string - ) - // handle special roff table cell text encapsulation - if node.Parent.Type == blackfriday.TableCell { - if len(node.Literal) > 30 { - start = tableCellStart - end = tableCellEnd - } else { - // end rows that aren't terminated by "tableCellEnd" with a cr if end of row - if node.Parent.Next == nil && !node.Parent.IsHeader { - end = crTag - } - } - } - out(w, start) - escapeSpecialChars(w, node.Literal) - out(w, end) -} - func (r *roffRenderer) handleHeading(w io.Writer, node *blackfriday.Node, entering bool) { if entering { switch node.Level { @@ -230,15 +212,20 @@ func (r *roffRenderer) handleItem(w io.Writer, node *blackfriday.Node, entering if node.ListFlags&blackfriday.ListTypeOrdered != 0 { out(w, fmt.Sprintf(".IP \"%3d.\" 5\n", r.listCounters[len(r.listCounters)-1])) r.listCounters[len(r.listCounters)-1]++ + } else if node.ListFlags&blackfriday.ListTypeTerm != 0 { + // DT (definition term): line just before DD (see below). + out(w, dtTag) + r.firstDD = true } else if node.ListFlags&blackfriday.ListTypeDefinition != 0 { - // state machine for handling terms and following definitions - // since blackfriday does not distinguish them properly, nor - // does it seperate them into separate lists as it should - if !r.defineTerm { - out(w, arglistTag) - r.defineTerm = true + // DD (definition description): line that starts with ": ". + // + // We have to distinguish between the first DD and the + // subsequent ones, as there should be no vertical + // whitespace between the DT and the first DD. + if r.firstDD { + r.firstDD = false } else { - r.defineTerm = false + out(w, dd2Tag) } } else { out(w, ".IP \\(bu 2\n") @@ -251,7 +238,7 @@ func (r *roffRenderer) handleItem(w io.Writer, node *blackfriday.Node, entering func (r *roffRenderer) handleTable(w io.Writer, node *blackfriday.Node, entering bool) { if entering { out(w, tableStart) - //call walker to count cells (and rows?) so format section can be produced + // call walker to count cells (and rows?) so format section can be produced columns := countColumns(node) out(w, strings.Repeat("l ", columns)+"\n") out(w, strings.Repeat("l ", columns)+".\n") @@ -261,28 +248,41 @@ func (r *roffRenderer) handleTable(w io.Writer, node *blackfriday.Node, entering } func (r *roffRenderer) handleTableCell(w io.Writer, node *blackfriday.Node, entering bool) { - var ( - start, end string - ) - if node.IsHeader { - start = codespanTag - end = codespanCloseTag - } if entering { + var start string if node.Prev != nil && node.Prev.Type == blackfriday.TableCell { - out(w, "\t"+start) - } else { - out(w, start) + start = "\t" + } + if node.IsHeader { + start += codespanTag + } else if nodeLiteralSize(node) > 30 { + start += tableCellStart } + out(w, start) } else { - // need to carriage return if we are at the end of the header row - if node.IsHeader && node.Next == nil { - end = end + crTag + var end string + if node.IsHeader { + end = codespanCloseTag + } else if nodeLiteralSize(node) > 30 { + end = tableCellEnd + } + if node.Next == nil && end != tableCellEnd { + // Last cell: need to carriage return if we are at the end of the + // header row and content isn't wrapped in a "tablecell" + end += crTag } out(w, end) } } +func nodeLiteralSize(node *blackfriday.Node) int { + total := 0 + for n := node.FirstChild; n != nil; n = n.FirstChild { + total += len(n.Literal) + } + return total +} + // because roff format requires knowing the column count before outputting any table // data we need to walk a table tree and count the columns func countColumns(node *blackfriday.Node) int { @@ -309,15 +309,6 @@ func out(w io.Writer, output string) { io.WriteString(w, output) // nolint: errcheck } -func needsBackslash(c byte) bool { - for _, r := range []byte("-_&\\~") { - if c == r { - return true - } - } - return false -} - func escapeSpecialChars(w io.Writer, text []byte) { for i := 0; i < len(text); i++ { // escape initial apostrophe or period @@ -328,7 +319,7 @@ func escapeSpecialChars(w io.Writer, text []byte) { // directly copy normal characters org := i - for i < len(text) && !needsBackslash(text[i]) { + for i < len(text) && text[i] != '\\' { i++ } if i > org { diff --git a/vendor/github.com/evanphx/json-patch/v5/patch.go b/vendor/github.com/evanphx/json-patch/v5/patch.go index f24e9d59c7..117f2c00df 100644 --- a/vendor/github.com/evanphx/json-patch/v5/patch.go +++ b/vendor/github.com/evanphx/json-patch/v5/patch.go @@ -766,9 +766,9 @@ func ensurePathExists(pd *container, path string, options *ApplyOptions) error { } } - // Check if the next part is a numeric index. + // Check if the next part is a numeric index or "-". // If yes, then create an array, otherwise, create an object. - if arrIndex, err = strconv.Atoi(parts[pi+1]); err == nil { + if arrIndex, err = strconv.Atoi(parts[pi+1]); err == nil || parts[pi+1] == "-" { if arrIndex < 0 { if !options.SupportNegativeIndices { @@ -845,6 +845,29 @@ func (p Patch) replace(doc *container, op Operation, options *ApplyOptions) erro return errors.Wrapf(err, "replace operation failed to decode path") } + if path == "" { + val := op.value() + + if val.which == eRaw { + if !val.tryDoc() { + if !val.tryAry() { + return errors.Wrapf(err, "replace operation value must be object or array") + } + } + } + + switch val.which { + case eAry: + *doc = &val.ary + case eDoc: + *doc = val.doc + case eRaw: + return errors.Wrapf(err, "replace operation hit impossible case") + } + + return nil + } + con, key := findObject(doc, path, options) if con == nil { @@ -911,6 +934,25 @@ func (p Patch) test(doc *container, op Operation, options *ApplyOptions) error { return errors.Wrapf(err, "test operation failed to decode path") } + if path == "" { + var self lazyNode + + switch sv := (*doc).(type) { + case *partialDoc: + self.doc = sv + self.which = eDoc + case *partialArray: + self.ary = *sv + self.which = eAry + } + + if self.equal(op.value()) { + return nil + } + + return errors.Wrapf(ErrTestFailed, "testing value %s failed", path) + } + con, key := findObject(doc, path, options) if con == nil { diff --git a/vendor/github.com/fsnotify/fsnotify/.mailmap b/vendor/github.com/fsnotify/fsnotify/.mailmap new file mode 100644 index 0000000000..a04f2907fe --- /dev/null +++ b/vendor/github.com/fsnotify/fsnotify/.mailmap @@ -0,0 +1,2 @@ +Chris Howey +Nathan Youngman <4566+nathany@users.noreply.github.com> diff --git a/vendor/github.com/fsnotify/fsnotify/.travis.yml b/vendor/github.com/fsnotify/fsnotify/.travis.yml deleted file mode 100644 index a9c30165cd..0000000000 --- a/vendor/github.com/fsnotify/fsnotify/.travis.yml +++ /dev/null @@ -1,36 +0,0 @@ -sudo: false -language: go - -go: - - "stable" - - "1.11.x" - - "1.10.x" - - "1.9.x" - -matrix: - include: - - go: "stable" - env: GOLINT=true - allow_failures: - - go: tip - fast_finish: true - - -before_install: - - if [ ! -z "${GOLINT}" ]; then go get -u golang.org/x/lint/golint; fi - -script: - - go test --race ./... - -after_script: - - test -z "$(gofmt -s -l -w . | tee /dev/stderr)" - - if [ ! -z "${GOLINT}" ]; then echo running golint; golint --set_exit_status ./...; else echo skipping golint; fi - - go vet ./... - -os: - - linux - - osx - - windows - -notifications: - email: false diff --git a/vendor/github.com/fsnotify/fsnotify/AUTHORS b/vendor/github.com/fsnotify/fsnotify/AUTHORS index 5ab5d41c54..6cbabe5ef5 100644 --- a/vendor/github.com/fsnotify/fsnotify/AUTHORS +++ b/vendor/github.com/fsnotify/fsnotify/AUTHORS @@ -4,35 +4,44 @@ # You can update this list using the following command: # -# $ git shortlog -se | awk '{print $2 " " $3 " " $4}' +# $ (head -n10 AUTHORS && git shortlog -se | sed -E 's/^\s+[0-9]+\t//') | tee AUTHORS # Please keep the list sorted. Aaron L Adrien Bustany +Alexey Kazakov Amit Krishnan Anmol Sethi Bjørn Erik Pedersen +Brian Goff Bruno Bigras Caleb Spare Case Nelson -Chris Howey +Chris Howey Christoffer Buchholz Daniel Wagner-Hall Dave Cheney +Eric Lin Evan Phoenix Francisco Souza +Gautam Dey Hari haran -John C Barstow +Ichinose Shogo +Johannes Ebke +John C Barstow Kelvin Fo Ken-ichirou MATSUZAWA Matt Layher +Matthias Stone Nathan Youngman Nickolai Zeldovich +Oliver Bristow Patrick Paul Hammond Pawel Knap Pieter Droogendijk +Pratik Shinde Pursuit92 Riku Voipio Rob Figueiredo @@ -41,6 +50,7 @@ Slawek Ligus Soge Zhang Tiffany Jernigan Tilak Sharma +Tobias Klauser Tom Payne Travis Cline Tudor Golubenco diff --git a/vendor/github.com/fsnotify/fsnotify/CHANGELOG.md b/vendor/github.com/fsnotify/fsnotify/CHANGELOG.md index be4d7ea2c1..a438fe4b4a 100644 --- a/vendor/github.com/fsnotify/fsnotify/CHANGELOG.md +++ b/vendor/github.com/fsnotify/fsnotify/CHANGELOG.md @@ -1,6 +1,28 @@ # Changelog -## v1.4.7 / 2018-01-09 +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## [Unreleased] + +## [1.5.1] - 2021-08-24 + +* Revert Add AddRaw to not follow symlinks + +## [1.5.0] - 2021-08-20 + +* Go: Increase minimum required version to Go 1.12 [#381](https://github.com/fsnotify/fsnotify/pull/381) +* Feature: Add AddRaw method which does not follow symlinks when adding a watch [#289](https://github.com/fsnotify/fsnotify/pull/298) +* Windows: Follow symlinks by default like on all other systems [#289](https://github.com/fsnotify/fsnotify/pull/289) +* CI: Use GitHub Actions for CI and cover go 1.12-1.17 + [#378](https://github.com/fsnotify/fsnotify/pull/378) + [#381](https://github.com/fsnotify/fsnotify/pull/381) + [#385](https://github.com/fsnotify/fsnotify/pull/385) +* Go 1.14+: Fix unsafe pointer conversion [#325](https://github.com/fsnotify/fsnotify/pull/325) + +## [1.4.7] - 2018-01-09 * BSD/macOS: Fix possible deadlock on closing the watcher on kqueue (thanks @nhooyr and @glycerine) * Tests: Fix missing verb on format string (thanks @rchiossi) @@ -10,62 +32,62 @@ * Linux: Properly handle inotify's IN_Q_OVERFLOW event (thanks @zeldovich) * Docs: replace references to OS X with macOS -## v1.4.2 / 2016-10-10 +## [1.4.2] - 2016-10-10 * Linux: use InotifyInit1 with IN_CLOEXEC to stop leaking a file descriptor to a child process when using fork/exec [#178](https://github.com/fsnotify/fsnotify/pull/178) (thanks @pattyshack) -## v1.4.1 / 2016-10-04 +## [1.4.1] - 2016-10-04 * Fix flaky inotify stress test on Linux [#177](https://github.com/fsnotify/fsnotify/pull/177) (thanks @pattyshack) -## v1.4.0 / 2016-10-01 +## [1.4.0] - 2016-10-01 * add a String() method to Event.Op [#165](https://github.com/fsnotify/fsnotify/pull/165) (thanks @oozie) -## v1.3.1 / 2016-06-28 +## [1.3.1] - 2016-06-28 * Windows: fix for double backslash when watching the root of a drive [#151](https://github.com/fsnotify/fsnotify/issues/151) (thanks @brunoqc) -## v1.3.0 / 2016-04-19 +## [1.3.0] - 2016-04-19 * Support linux/arm64 by [patching](https://go-review.googlesource.com/#/c/21971/) x/sys/unix and switching to to it from syscall (thanks @suihkulokki) [#135](https://github.com/fsnotify/fsnotify/pull/135) -## v1.2.10 / 2016-03-02 +## [1.2.10] - 2016-03-02 * Fix golint errors in windows.go [#121](https://github.com/fsnotify/fsnotify/pull/121) (thanks @tiffanyfj) -## v1.2.9 / 2016-01-13 +## [1.2.9] - 2016-01-13 kqueue: Fix logic for CREATE after REMOVE [#111](https://github.com/fsnotify/fsnotify/pull/111) (thanks @bep) -## v1.2.8 / 2015-12-17 +## [1.2.8] - 2015-12-17 * kqueue: fix race condition in Close [#105](https://github.com/fsnotify/fsnotify/pull/105) (thanks @djui for reporting the issue and @ppknap for writing a failing test) * inotify: fix race in test * enable race detection for continuous integration (Linux, Mac, Windows) -## v1.2.5 / 2015-10-17 +## [1.2.5] - 2015-10-17 * inotify: use epoll_create1 for arm64 support (requires Linux 2.6.27 or later) [#100](https://github.com/fsnotify/fsnotify/pull/100) (thanks @suihkulokki) * inotify: fix path leaks [#73](https://github.com/fsnotify/fsnotify/pull/73) (thanks @chamaken) * kqueue: watch for rename events on subdirectories [#83](https://github.com/fsnotify/fsnotify/pull/83) (thanks @guotie) * kqueue: avoid infinite loops from symlinks cycles [#101](https://github.com/fsnotify/fsnotify/pull/101) (thanks @illicitonion) -## v1.2.1 / 2015-10-14 +## [1.2.1] - 2015-10-14 * kqueue: don't watch named pipes [#98](https://github.com/fsnotify/fsnotify/pull/98) (thanks @evanphx) -## v1.2.0 / 2015-02-08 +## [1.2.0] - 2015-02-08 * inotify: use epoll to wake up readEvents [#66](https://github.com/fsnotify/fsnotify/pull/66) (thanks @PieterD) * inotify: closing watcher should now always shut down goroutine [#63](https://github.com/fsnotify/fsnotify/pull/63) (thanks @PieterD) * kqueue: close kqueue after removing watches, fixes [#59](https://github.com/fsnotify/fsnotify/issues/59) -## v1.1.1 / 2015-02-05 +## [1.1.1] - 2015-02-05 * inotify: Retry read on EINTR [#61](https://github.com/fsnotify/fsnotify/issues/61) (thanks @PieterD) -## v1.1.0 / 2014-12-12 +## [1.1.0] - 2014-12-12 * kqueue: rework internals [#43](https://github.com/fsnotify/fsnotify/pull/43) * add low-level functions @@ -77,22 +99,22 @@ kqueue: Fix logic for CREATE after REMOVE [#111](https://github.com/fsnotify/fsn * kqueue: fix regression in rework causing subdirectories to be watched [#48](https://github.com/fsnotify/fsnotify/issues/48) * kqueue: cleanup internal watch before sending remove event [#51](https://github.com/fsnotify/fsnotify/issues/51) -## v1.0.4 / 2014-09-07 +## [1.0.4] - 2014-09-07 * kqueue: add dragonfly to the build tags. * Rename source code files, rearrange code so exported APIs are at the top. * Add done channel to example code. [#37](https://github.com/fsnotify/fsnotify/pull/37) (thanks @chenyukang) -## v1.0.3 / 2014-08-19 +## [1.0.3] - 2014-08-19 * [Fix] Windows MOVED_TO now translates to Create like on BSD and Linux. [#36](https://github.com/fsnotify/fsnotify/issues/36) -## v1.0.2 / 2014-08-17 +## [1.0.2] - 2014-08-17 * [Fix] Missing create events on macOS. [#14](https://github.com/fsnotify/fsnotify/issues/14) (thanks @zhsso) * [Fix] Make ./path and path equivalent. (thanks @zhsso) -## v1.0.0 / 2014-08-15 +## [1.0.0] - 2014-08-15 * [API] Remove AddWatch on Windows, use Add. * Improve documentation for exported identifiers. [#30](https://github.com/fsnotify/fsnotify/issues/30) @@ -146,51 +168,51 @@ kqueue: Fix logic for CREATE after REMOVE [#111](https://github.com/fsnotify/fsn * no tests for the current implementation * not fully implemented on Windows [#93](https://github.com/howeyc/fsnotify/issues/93#issuecomment-39285195) -## v0.9.3 / 2014-12-31 +## [0.9.3] - 2014-12-31 * kqueue: cleanup internal watch before sending remove event [#51](https://github.com/fsnotify/fsnotify/issues/51) -## v0.9.2 / 2014-08-17 +## [0.9.2] - 2014-08-17 * [Backport] Fix missing create events on macOS. [#14](https://github.com/fsnotify/fsnotify/issues/14) (thanks @zhsso) -## v0.9.1 / 2014-06-12 +## [0.9.1] - 2014-06-12 * Fix data race on kevent buffer (thanks @tilaks) [#98](https://github.com/howeyc/fsnotify/pull/98) -## v0.9.0 / 2014-01-17 +## [0.9.0] - 2014-01-17 * IsAttrib() for events that only concern a file's metadata [#79][] (thanks @abustany) * [Fix] kqueue: fix deadlock [#77][] (thanks @cespare) * [NOTICE] Development has moved to `code.google.com/p/go.exp/fsnotify` in preparation for inclusion in the Go standard library. -## v0.8.12 / 2013-11-13 +## [0.8.12] - 2013-11-13 * [API] Remove FD_SET and friends from Linux adapter -## v0.8.11 / 2013-11-02 +## [0.8.11] - 2013-11-02 * [Doc] Add Changelog [#72][] (thanks @nathany) * [Doc] Spotlight and double modify events on macOS [#62][] (reported by @paulhammond) -## v0.8.10 / 2013-10-19 +## [0.8.10] - 2013-10-19 * [Fix] kqueue: remove file watches when parent directory is removed [#71][] (reported by @mdwhatcott) * [Fix] kqueue: race between Close and readEvents [#70][] (reported by @bernerdschaefer) * [Doc] specify OS-specific limits in README (thanks @debrando) -## v0.8.9 / 2013-09-08 +## [0.8.9] - 2013-09-08 * [Doc] Contributing (thanks @nathany) * [Doc] update package path in example code [#63][] (thanks @paulhammond) * [Doc] GoCI badge in README (Linux only) [#60][] * [Doc] Cross-platform testing with Vagrant [#59][] (thanks @nathany) -## v0.8.8 / 2013-06-17 +## [0.8.8] - 2013-06-17 * [Fix] Windows: handle `ERROR_MORE_DATA` on Windows [#49][] (thanks @jbowtie) -## v0.8.7 / 2013-06-03 +## [0.8.7] - 2013-06-03 * [API] Make syscall flags internal * [Fix] inotify: ignore event changes @@ -198,74 +220,74 @@ kqueue: Fix logic for CREATE after REMOVE [#111](https://github.com/fsnotify/fsn * [Fix] tests on Windows * lower case error messages -## v0.8.6 / 2013-05-23 +## [0.8.6] - 2013-05-23 * kqueue: Use EVT_ONLY flag on Darwin * [Doc] Update README with full example -## v0.8.5 / 2013-05-09 +## [0.8.5] - 2013-05-09 * [Fix] inotify: allow monitoring of "broken" symlinks (thanks @tsg) -## v0.8.4 / 2013-04-07 +## [0.8.4] - 2013-04-07 * [Fix] kqueue: watch all file events [#40][] (thanks @ChrisBuchholz) -## v0.8.3 / 2013-03-13 +## [0.8.3] - 2013-03-13 * [Fix] inoitfy/kqueue memory leak [#36][] (reported by @nbkolchin) * [Fix] kqueue: use fsnFlags for watching a directory [#33][] (reported by @nbkolchin) -## v0.8.2 / 2013-02-07 +## [0.8.2] - 2013-02-07 * [Doc] add Authors * [Fix] fix data races for map access [#29][] (thanks @fsouza) -## v0.8.1 / 2013-01-09 +## [0.8.1] - 2013-01-09 * [Fix] Windows path separators * [Doc] BSD License -## v0.8.0 / 2012-11-09 +## [0.8.0] - 2012-11-09 * kqueue: directory watching improvements (thanks @vmirage) * inotify: add `IN_MOVED_TO` [#25][] (requested by @cpisto) * [Fix] kqueue: deleting watched directory [#24][] (reported by @jakerr) -## v0.7.4 / 2012-10-09 +## [0.7.4] - 2012-10-09 * [Fix] inotify: fixes from https://codereview.appspot.com/5418045/ (ugorji) * [Fix] kqueue: preserve watch flags when watching for delete [#21][] (reported by @robfig) * [Fix] kqueue: watch the directory even if it isn't a new watch (thanks @robfig) * [Fix] kqueue: modify after recreation of file -## v0.7.3 / 2012-09-27 +## [0.7.3] - 2012-09-27 * [Fix] kqueue: watch with an existing folder inside the watched folder (thanks @vmirage) * [Fix] kqueue: no longer get duplicate CREATE events -## v0.7.2 / 2012-09-01 +## [0.7.2] - 2012-09-01 * kqueue: events for created directories -## v0.7.1 / 2012-07-14 +## [0.7.1] - 2012-07-14 * [Fix] for renaming files -## v0.7.0 / 2012-07-02 +## [0.7.0] - 2012-07-02 * [Feature] FSNotify flags * [Fix] inotify: Added file name back to event path -## v0.6.0 / 2012-06-06 +## [0.6.0] - 2012-06-06 * kqueue: watch files after directory created (thanks @tmc) -## v0.5.1 / 2012-05-22 +## [0.5.1] - 2012-05-22 * [Fix] inotify: remove all watches before Close() -## v0.5.0 / 2012-05-03 +## [0.5.0] - 2012-05-03 * [API] kqueue: return errors during watch instead of sending over channel * kqueue: match symlink behavior on Linux @@ -273,22 +295,22 @@ kqueue: Fix logic for CREATE after REMOVE [#111](https://github.com/fsnotify/fsn * [Fix] kqueue: handle EINTR (reported by @robfig) * [Doc] Godoc example [#1][] (thanks @davecheney) -## v0.4.0 / 2012-03-30 +## [0.4.0] - 2012-03-30 * Go 1 released: build with go tool * [Feature] Windows support using winfsnotify * Windows does not have attribute change notifications * Roll attribute notifications into IsModify -## v0.3.0 / 2012-02-19 +## [0.3.0] - 2012-02-19 * kqueue: add files when watch directory -## v0.2.0 / 2011-12-30 +## [0.2.0] - 2011-12-30 * update to latest Go weekly code -## v0.1.0 / 2011-10-19 +## [0.1.0] - 2011-10-19 * kqueue: add watch on file creation to match inotify * kqueue: create file event diff --git a/vendor/github.com/fsnotify/fsnotify/README.md b/vendor/github.com/fsnotify/fsnotify/README.md index b2629e5229..df57b1b282 100644 --- a/vendor/github.com/fsnotify/fsnotify/README.md +++ b/vendor/github.com/fsnotify/fsnotify/README.md @@ -12,9 +12,9 @@ Cross platform: Windows, Linux, BSD and macOS. | Adapter | OS | Status | | --------------------- | -------------------------------- | ------------------------------------------------------------------------------------------------------------------------------- | -| inotify | Linux 2.6.27 or later, Android\* | Supported [![Build Status](https://travis-ci.org/fsnotify/fsnotify.svg?branch=master)](https://travis-ci.org/fsnotify/fsnotify) | -| kqueue | BSD, macOS, iOS\* | Supported [![Build Status](https://travis-ci.org/fsnotify/fsnotify.svg?branch=master)](https://travis-ci.org/fsnotify/fsnotify) | -| ReadDirectoryChangesW | Windows | Supported [![Build Status](https://travis-ci.org/fsnotify/fsnotify.svg?branch=master)](https://travis-ci.org/fsnotify/fsnotify) | +| inotify | Linux 2.6.27 or later, Android\* | Supported | +| kqueue | BSD, macOS, iOS\* | Supported | +| ReadDirectoryChangesW | Windows | Supported | | FSEvents | macOS | [Planned](https://github.com/fsnotify/fsnotify/issues/11) | | FEN | Solaris 11 | [In Progress](https://github.com/fsnotify/fsnotify/issues/12) | | fanotify | Linux 2.6.37+ | [Planned](https://github.com/fsnotify/fsnotify/issues/114) | diff --git a/vendor/github.com/fsnotify/fsnotify/fen.go b/vendor/github.com/fsnotify/fsnotify/fen.go index ced39cb881..b3ac3d8f55 100644 --- a/vendor/github.com/fsnotify/fsnotify/fen.go +++ b/vendor/github.com/fsnotify/fsnotify/fen.go @@ -2,6 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. +//go:build solaris // +build solaris package fsnotify diff --git a/vendor/github.com/fsnotify/fsnotify/fsnotify.go b/vendor/github.com/fsnotify/fsnotify/fsnotify.go index 89cab046d1..0f4ee52e8a 100644 --- a/vendor/github.com/fsnotify/fsnotify/fsnotify.go +++ b/vendor/github.com/fsnotify/fsnotify/fsnotify.go @@ -2,6 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. +//go:build !plan9 // +build !plan9 // Package fsnotify provides a platform-independent interface for file system notifications. diff --git a/vendor/github.com/fsnotify/fsnotify/go.mod b/vendor/github.com/fsnotify/fsnotify/go.mod index ff11e13f22..54089e48b7 100644 --- a/vendor/github.com/fsnotify/fsnotify/go.mod +++ b/vendor/github.com/fsnotify/fsnotify/go.mod @@ -2,4 +2,6 @@ module github.com/fsnotify/fsnotify go 1.13 -require golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9 +require golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c + +retract v1.5.0 diff --git a/vendor/github.com/fsnotify/fsnotify/go.sum b/vendor/github.com/fsnotify/fsnotify/go.sum index f60af9855d..0f478630ca 100644 --- a/vendor/github.com/fsnotify/fsnotify/go.sum +++ b/vendor/github.com/fsnotify/fsnotify/go.sum @@ -1,2 +1,2 @@ -golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9 h1:L2auWcuQIvxz9xSEqzESnV/QN/gNRXNApHi3fYwl2w0= -golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c h1:F1jZWGFhYfh0Ci55sIpILtKKK8p3i2/krTr0H1rg74I= +golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= diff --git a/vendor/github.com/fsnotify/fsnotify/inotify.go b/vendor/github.com/fsnotify/fsnotify/inotify.go index d9fd1b88a0..eb87699b5b 100644 --- a/vendor/github.com/fsnotify/fsnotify/inotify.go +++ b/vendor/github.com/fsnotify/fsnotify/inotify.go @@ -2,6 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. +//go:build linux // +build linux package fsnotify @@ -272,7 +273,7 @@ func (w *Watcher) readEvents() { if nameLen > 0 { // Point "bytes" at the first byte of the filename - bytes := (*[unix.PathMax]byte)(unsafe.Pointer(&buf[offset+unix.SizeofInotifyEvent])) + bytes := (*[unix.PathMax]byte)(unsafe.Pointer(&buf[offset+unix.SizeofInotifyEvent]))[:nameLen:nameLen] // The filename is padded with NULL bytes. TrimRight() gets rid of those. name += "/" + strings.TrimRight(string(bytes[0:nameLen]), "\000") } diff --git a/vendor/github.com/fsnotify/fsnotify/inotify_poller.go b/vendor/github.com/fsnotify/fsnotify/inotify_poller.go index b33f2b4d4b..e9ff9439f7 100644 --- a/vendor/github.com/fsnotify/fsnotify/inotify_poller.go +++ b/vendor/github.com/fsnotify/fsnotify/inotify_poller.go @@ -2,6 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. +//go:build linux // +build linux package fsnotify diff --git a/vendor/github.com/fsnotify/fsnotify/kqueue.go b/vendor/github.com/fsnotify/fsnotify/kqueue.go index 86e76a3d67..368f5b790d 100644 --- a/vendor/github.com/fsnotify/fsnotify/kqueue.go +++ b/vendor/github.com/fsnotify/fsnotify/kqueue.go @@ -2,6 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. +//go:build freebsd || openbsd || netbsd || dragonfly || darwin // +build freebsd openbsd netbsd dragonfly darwin package fsnotify diff --git a/vendor/github.com/fsnotify/fsnotify/open_mode_bsd.go b/vendor/github.com/fsnotify/fsnotify/open_mode_bsd.go index 2306c4620b..36cc3845b6 100644 --- a/vendor/github.com/fsnotify/fsnotify/open_mode_bsd.go +++ b/vendor/github.com/fsnotify/fsnotify/open_mode_bsd.go @@ -2,6 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. +//go:build freebsd || openbsd || netbsd || dragonfly // +build freebsd openbsd netbsd dragonfly package fsnotify diff --git a/vendor/github.com/fsnotify/fsnotify/open_mode_darwin.go b/vendor/github.com/fsnotify/fsnotify/open_mode_darwin.go index 870c4d6d18..98cd8476ff 100644 --- a/vendor/github.com/fsnotify/fsnotify/open_mode_darwin.go +++ b/vendor/github.com/fsnotify/fsnotify/open_mode_darwin.go @@ -2,6 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. +//go:build darwin // +build darwin package fsnotify diff --git a/vendor/github.com/fsnotify/fsnotify/windows.go b/vendor/github.com/fsnotify/fsnotify/windows.go index 09436f31d8..c02b75f7c3 100644 --- a/vendor/github.com/fsnotify/fsnotify/windows.go +++ b/vendor/github.com/fsnotify/fsnotify/windows.go @@ -2,6 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. +//go:build windows // +build windows package fsnotify diff --git a/vendor/github.com/ghodss/yaml/.gitignore b/vendor/github.com/ghodss/yaml/.gitignore new file mode 100644 index 0000000000..e256a31e00 --- /dev/null +++ b/vendor/github.com/ghodss/yaml/.gitignore @@ -0,0 +1,20 @@ +# OSX leaves these everywhere on SMB shares +._* + +# Eclipse files +.classpath +.project +.settings/** + +# Emacs save files +*~ + +# Vim-related files +[._]*.s[a-w][a-z] +[._]s[a-w][a-z] +*.un~ +Session.vim +.netrwhist + +# Go test binaries +*.test diff --git a/vendor/github.com/ghodss/yaml/.travis.yml b/vendor/github.com/ghodss/yaml/.travis.yml new file mode 100644 index 0000000000..0e9d6edc01 --- /dev/null +++ b/vendor/github.com/ghodss/yaml/.travis.yml @@ -0,0 +1,7 @@ +language: go +go: + - 1.3 + - 1.4 +script: + - go test + - go build diff --git a/vendor/github.com/ghodss/yaml/LICENSE b/vendor/github.com/ghodss/yaml/LICENSE new file mode 100644 index 0000000000..7805d36de7 --- /dev/null +++ b/vendor/github.com/ghodss/yaml/LICENSE @@ -0,0 +1,50 @@ +The MIT License (MIT) + +Copyright (c) 2014 Sam Ghods + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + + +Copyright (c) 2012 The Go Authors. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/github.com/ghodss/yaml/README.md b/vendor/github.com/ghodss/yaml/README.md new file mode 100644 index 0000000000..0200f75b4d --- /dev/null +++ b/vendor/github.com/ghodss/yaml/README.md @@ -0,0 +1,121 @@ +# YAML marshaling and unmarshaling support for Go + +[![Build Status](https://travis-ci.org/ghodss/yaml.svg)](https://travis-ci.org/ghodss/yaml) + +## Introduction + +A wrapper around [go-yaml](https://github.com/go-yaml/yaml) designed to enable a better way of handling YAML when marshaling to and from structs. + +In short, this library first converts YAML to JSON using go-yaml and then uses `json.Marshal` and `json.Unmarshal` to convert to or from the struct. This means that it effectively reuses the JSON struct tags as well as the custom JSON methods `MarshalJSON` and `UnmarshalJSON` unlike go-yaml. For a detailed overview of the rationale behind this method, [see this blog post](http://ghodss.com/2014/the-right-way-to-handle-yaml-in-golang/). + +## Compatibility + +This package uses [go-yaml](https://github.com/go-yaml/yaml) and therefore supports [everything go-yaml supports](https://github.com/go-yaml/yaml#compatibility). + +## Caveats + +**Caveat #1:** When using `yaml.Marshal` and `yaml.Unmarshal`, binary data should NOT be preceded with the `!!binary` YAML tag. If you do, go-yaml will convert the binary data from base64 to native binary data, which is not compatible with JSON. You can still use binary in your YAML files though - just store them without the `!!binary` tag and decode the base64 in your code (e.g. in the custom JSON methods `MarshalJSON` and `UnmarshalJSON`). This also has the benefit that your YAML and your JSON binary data will be decoded exactly the same way. As an example: + +``` +BAD: + exampleKey: !!binary gIGC + +GOOD: + exampleKey: gIGC +... and decode the base64 data in your code. +``` + +**Caveat #2:** When using `YAMLToJSON` directly, maps with keys that are maps will result in an error since this is not supported by JSON. This error will occur in `Unmarshal` as well since you can't unmarshal map keys anyways since struct fields can't be keys. + +## Installation and usage + +To install, run: + +``` +$ go get github.com/ghodss/yaml +``` + +And import using: + +``` +import "github.com/ghodss/yaml" +``` + +Usage is very similar to the JSON library: + +```go +package main + +import ( + "fmt" + + "github.com/ghodss/yaml" +) + +type Person struct { + Name string `json:"name"` // Affects YAML field names too. + Age int `json:"age"` +} + +func main() { + // Marshal a Person struct to YAML. + p := Person{"John", 30} + y, err := yaml.Marshal(p) + if err != nil { + fmt.Printf("err: %v\n", err) + return + } + fmt.Println(string(y)) + /* Output: + age: 30 + name: John + */ + + // Unmarshal the YAML back into a Person struct. + var p2 Person + err = yaml.Unmarshal(y, &p2) + if err != nil { + fmt.Printf("err: %v\n", err) + return + } + fmt.Println(p2) + /* Output: + {John 30} + */ +} +``` + +`yaml.YAMLToJSON` and `yaml.JSONToYAML` methods are also available: + +```go +package main + +import ( + "fmt" + + "github.com/ghodss/yaml" +) + +func main() { + j := []byte(`{"name": "John", "age": 30}`) + y, err := yaml.JSONToYAML(j) + if err != nil { + fmt.Printf("err: %v\n", err) + return + } + fmt.Println(string(y)) + /* Output: + name: John + age: 30 + */ + j2, err := yaml.YAMLToJSON(y) + if err != nil { + fmt.Printf("err: %v\n", err) + return + } + fmt.Println(string(j2)) + /* Output: + {"age":30,"name":"John"} + */ +} +``` diff --git a/vendor/github.com/ghodss/yaml/fields.go b/vendor/github.com/ghodss/yaml/fields.go new file mode 100644 index 0000000000..5860074026 --- /dev/null +++ b/vendor/github.com/ghodss/yaml/fields.go @@ -0,0 +1,501 @@ +// Copyright 2013 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. +package yaml + +import ( + "bytes" + "encoding" + "encoding/json" + "reflect" + "sort" + "strings" + "sync" + "unicode" + "unicode/utf8" +) + +// indirect walks down v allocating pointers as needed, +// until it gets to a non-pointer. +// if it encounters an Unmarshaler, indirect stops and returns that. +// if decodingNull is true, indirect stops at the last pointer so it can be set to nil. +func indirect(v reflect.Value, decodingNull bool) (json.Unmarshaler, encoding.TextUnmarshaler, reflect.Value) { + // If v is a named type and is addressable, + // start with its address, so that if the type has pointer methods, + // we find them. + if v.Kind() != reflect.Ptr && v.Type().Name() != "" && v.CanAddr() { + v = v.Addr() + } + for { + // Load value from interface, but only if the result will be + // usefully addressable. + if v.Kind() == reflect.Interface && !v.IsNil() { + e := v.Elem() + if e.Kind() == reflect.Ptr && !e.IsNil() && (!decodingNull || e.Elem().Kind() == reflect.Ptr) { + v = e + continue + } + } + + if v.Kind() != reflect.Ptr { + break + } + + if v.Elem().Kind() != reflect.Ptr && decodingNull && v.CanSet() { + break + } + if v.IsNil() { + if v.CanSet() { + v.Set(reflect.New(v.Type().Elem())) + } else { + v = reflect.New(v.Type().Elem()) + } + } + if v.Type().NumMethod() > 0 { + if u, ok := v.Interface().(json.Unmarshaler); ok { + return u, nil, reflect.Value{} + } + if u, ok := v.Interface().(encoding.TextUnmarshaler); ok { + return nil, u, reflect.Value{} + } + } + v = v.Elem() + } + return nil, nil, v +} + +// A field represents a single field found in a struct. +type field struct { + name string + nameBytes []byte // []byte(name) + equalFold func(s, t []byte) bool // bytes.EqualFold or equivalent + + tag bool + index []int + typ reflect.Type + omitEmpty bool + quoted bool +} + +func fillField(f field) field { + f.nameBytes = []byte(f.name) + f.equalFold = foldFunc(f.nameBytes) + return f +} + +// byName sorts field by name, breaking ties with depth, +// then breaking ties with "name came from json tag", then +// breaking ties with index sequence. +type byName []field + +func (x byName) Len() int { return len(x) } + +func (x byName) Swap(i, j int) { x[i], x[j] = x[j], x[i] } + +func (x byName) Less(i, j int) bool { + if x[i].name != x[j].name { + return x[i].name < x[j].name + } + if len(x[i].index) != len(x[j].index) { + return len(x[i].index) < len(x[j].index) + } + if x[i].tag != x[j].tag { + return x[i].tag + } + return byIndex(x).Less(i, j) +} + +// byIndex sorts field by index sequence. +type byIndex []field + +func (x byIndex) Len() int { return len(x) } + +func (x byIndex) Swap(i, j int) { x[i], x[j] = x[j], x[i] } + +func (x byIndex) Less(i, j int) bool { + for k, xik := range x[i].index { + if k >= len(x[j].index) { + return false + } + if xik != x[j].index[k] { + return xik < x[j].index[k] + } + } + return len(x[i].index) < len(x[j].index) +} + +// typeFields returns a list of fields that JSON should recognize for the given type. +// The algorithm is breadth-first search over the set of structs to include - the top struct +// and then any reachable anonymous structs. +func typeFields(t reflect.Type) []field { + // Anonymous fields to explore at the current level and the next. + current := []field{} + next := []field{{typ: t}} + + // Count of queued names for current level and the next. + count := map[reflect.Type]int{} + nextCount := map[reflect.Type]int{} + + // Types already visited at an earlier level. + visited := map[reflect.Type]bool{} + + // Fields found. + var fields []field + + for len(next) > 0 { + current, next = next, current[:0] + count, nextCount = nextCount, map[reflect.Type]int{} + + for _, f := range current { + if visited[f.typ] { + continue + } + visited[f.typ] = true + + // Scan f.typ for fields to include. + for i := 0; i < f.typ.NumField(); i++ { + sf := f.typ.Field(i) + if sf.PkgPath != "" { // unexported + continue + } + tag := sf.Tag.Get("json") + if tag == "-" { + continue + } + name, opts := parseTag(tag) + if !isValidTag(name) { + name = "" + } + index := make([]int, len(f.index)+1) + copy(index, f.index) + index[len(f.index)] = i + + ft := sf.Type + if ft.Name() == "" && ft.Kind() == reflect.Ptr { + // Follow pointer. + ft = ft.Elem() + } + + // Record found field and index sequence. + if name != "" || !sf.Anonymous || ft.Kind() != reflect.Struct { + tagged := name != "" + if name == "" { + name = sf.Name + } + fields = append(fields, fillField(field{ + name: name, + tag: tagged, + index: index, + typ: ft, + omitEmpty: opts.Contains("omitempty"), + quoted: opts.Contains("string"), + })) + if count[f.typ] > 1 { + // If there were multiple instances, add a second, + // so that the annihilation code will see a duplicate. + // It only cares about the distinction between 1 or 2, + // so don't bother generating any more copies. + fields = append(fields, fields[len(fields)-1]) + } + continue + } + + // Record new anonymous struct to explore in next round. + nextCount[ft]++ + if nextCount[ft] == 1 { + next = append(next, fillField(field{name: ft.Name(), index: index, typ: ft})) + } + } + } + } + + sort.Sort(byName(fields)) + + // Delete all fields that are hidden by the Go rules for embedded fields, + // except that fields with JSON tags are promoted. + + // The fields are sorted in primary order of name, secondary order + // of field index length. Loop over names; for each name, delete + // hidden fields by choosing the one dominant field that survives. + out := fields[:0] + for advance, i := 0, 0; i < len(fields); i += advance { + // One iteration per name. + // Find the sequence of fields with the name of this first field. + fi := fields[i] + name := fi.name + for advance = 1; i+advance < len(fields); advance++ { + fj := fields[i+advance] + if fj.name != name { + break + } + } + if advance == 1 { // Only one field with this name + out = append(out, fi) + continue + } + dominant, ok := dominantField(fields[i : i+advance]) + if ok { + out = append(out, dominant) + } + } + + fields = out + sort.Sort(byIndex(fields)) + + return fields +} + +// dominantField looks through the fields, all of which are known to +// have the same name, to find the single field that dominates the +// others using Go's embedding rules, modified by the presence of +// JSON tags. If there are multiple top-level fields, the boolean +// will be false: This condition is an error in Go and we skip all +// the fields. +func dominantField(fields []field) (field, bool) { + // The fields are sorted in increasing index-length order. The winner + // must therefore be one with the shortest index length. Drop all + // longer entries, which is easy: just truncate the slice. + length := len(fields[0].index) + tagged := -1 // Index of first tagged field. + for i, f := range fields { + if len(f.index) > length { + fields = fields[:i] + break + } + if f.tag { + if tagged >= 0 { + // Multiple tagged fields at the same level: conflict. + // Return no field. + return field{}, false + } + tagged = i + } + } + if tagged >= 0 { + return fields[tagged], true + } + // All remaining fields have the same length. If there's more than one, + // we have a conflict (two fields named "X" at the same level) and we + // return no field. + if len(fields) > 1 { + return field{}, false + } + return fields[0], true +} + +var fieldCache struct { + sync.RWMutex + m map[reflect.Type][]field +} + +// cachedTypeFields is like typeFields but uses a cache to avoid repeated work. +func cachedTypeFields(t reflect.Type) []field { + fieldCache.RLock() + f := fieldCache.m[t] + fieldCache.RUnlock() + if f != nil { + return f + } + + // Compute fields without lock. + // Might duplicate effort but won't hold other computations back. + f = typeFields(t) + if f == nil { + f = []field{} + } + + fieldCache.Lock() + if fieldCache.m == nil { + fieldCache.m = map[reflect.Type][]field{} + } + fieldCache.m[t] = f + fieldCache.Unlock() + return f +} + +func isValidTag(s string) bool { + if s == "" { + return false + } + for _, c := range s { + switch { + case strings.ContainsRune("!#$%&()*+-./:<=>?@[]^_{|}~ ", c): + // Backslash and quote chars are reserved, but + // otherwise any punctuation chars are allowed + // in a tag name. + default: + if !unicode.IsLetter(c) && !unicode.IsDigit(c) { + return false + } + } + } + return true +} + +const ( + caseMask = ^byte(0x20) // Mask to ignore case in ASCII. + kelvin = '\u212a' + smallLongEss = '\u017f' +) + +// foldFunc returns one of four different case folding equivalence +// functions, from most general (and slow) to fastest: +// +// 1) bytes.EqualFold, if the key s contains any non-ASCII UTF-8 +// 2) equalFoldRight, if s contains special folding ASCII ('k', 'K', 's', 'S') +// 3) asciiEqualFold, no special, but includes non-letters (including _) +// 4) simpleLetterEqualFold, no specials, no non-letters. +// +// The letters S and K are special because they map to 3 runes, not just 2: +// * S maps to s and to U+017F 'ſ' Latin small letter long s +// * k maps to K and to U+212A 'K' Kelvin sign +// See http://play.golang.org/p/tTxjOc0OGo +// +// The returned function is specialized for matching against s and +// should only be given s. It's not curried for performance reasons. +func foldFunc(s []byte) func(s, t []byte) bool { + nonLetter := false + special := false // special letter + for _, b := range s { + if b >= utf8.RuneSelf { + return bytes.EqualFold + } + upper := b & caseMask + if upper < 'A' || upper > 'Z' { + nonLetter = true + } else if upper == 'K' || upper == 'S' { + // See above for why these letters are special. + special = true + } + } + if special { + return equalFoldRight + } + if nonLetter { + return asciiEqualFold + } + return simpleLetterEqualFold +} + +// equalFoldRight is a specialization of bytes.EqualFold when s is +// known to be all ASCII (including punctuation), but contains an 's', +// 'S', 'k', or 'K', requiring a Unicode fold on the bytes in t. +// See comments on foldFunc. +func equalFoldRight(s, t []byte) bool { + for _, sb := range s { + if len(t) == 0 { + return false + } + tb := t[0] + if tb < utf8.RuneSelf { + if sb != tb { + sbUpper := sb & caseMask + if 'A' <= sbUpper && sbUpper <= 'Z' { + if sbUpper != tb&caseMask { + return false + } + } else { + return false + } + } + t = t[1:] + continue + } + // sb is ASCII and t is not. t must be either kelvin + // sign or long s; sb must be s, S, k, or K. + tr, size := utf8.DecodeRune(t) + switch sb { + case 's', 'S': + if tr != smallLongEss { + return false + } + case 'k', 'K': + if tr != kelvin { + return false + } + default: + return false + } + t = t[size:] + + } + if len(t) > 0 { + return false + } + return true +} + +// asciiEqualFold is a specialization of bytes.EqualFold for use when +// s is all ASCII (but may contain non-letters) and contains no +// special-folding letters. +// See comments on foldFunc. +func asciiEqualFold(s, t []byte) bool { + if len(s) != len(t) { + return false + } + for i, sb := range s { + tb := t[i] + if sb == tb { + continue + } + if ('a' <= sb && sb <= 'z') || ('A' <= sb && sb <= 'Z') { + if sb&caseMask != tb&caseMask { + return false + } + } else { + return false + } + } + return true +} + +// simpleLetterEqualFold is a specialization of bytes.EqualFold for +// use when s is all ASCII letters (no underscores, etc) and also +// doesn't contain 'k', 'K', 's', or 'S'. +// See comments on foldFunc. +func simpleLetterEqualFold(s, t []byte) bool { + if len(s) != len(t) { + return false + } + for i, b := range s { + if b&caseMask != t[i]&caseMask { + return false + } + } + return true +} + +// tagOptions is the string following a comma in a struct field's "json" +// tag, or the empty string. It does not include the leading comma. +type tagOptions string + +// parseTag splits a struct field's json tag into its name and +// comma-separated options. +func parseTag(tag string) (string, tagOptions) { + if idx := strings.Index(tag, ","); idx != -1 { + return tag[:idx], tagOptions(tag[idx+1:]) + } + return tag, tagOptions("") +} + +// Contains reports whether a comma-separated list of options +// contains a particular substr flag. substr must be surrounded by a +// string boundary or commas. +func (o tagOptions) Contains(optionName string) bool { + if len(o) == 0 { + return false + } + s := string(o) + for s != "" { + var next string + i := strings.Index(s, ",") + if i >= 0 { + s, next = s[:i], s[i+1:] + } + if s == optionName { + return true + } + s = next + } + return false +} diff --git a/vendor/github.com/ghodss/yaml/yaml.go b/vendor/github.com/ghodss/yaml/yaml.go new file mode 100644 index 0000000000..4fb4054a8b --- /dev/null +++ b/vendor/github.com/ghodss/yaml/yaml.go @@ -0,0 +1,277 @@ +package yaml + +import ( + "bytes" + "encoding/json" + "fmt" + "reflect" + "strconv" + + "gopkg.in/yaml.v2" +) + +// Marshals the object into JSON then converts JSON to YAML and returns the +// YAML. +func Marshal(o interface{}) ([]byte, error) { + j, err := json.Marshal(o) + if err != nil { + return nil, fmt.Errorf("error marshaling into JSON: %v", err) + } + + y, err := JSONToYAML(j) + if err != nil { + return nil, fmt.Errorf("error converting JSON to YAML: %v", err) + } + + return y, nil +} + +// Converts YAML to JSON then uses JSON to unmarshal into an object. +func Unmarshal(y []byte, o interface{}) error { + vo := reflect.ValueOf(o) + j, err := yamlToJSON(y, &vo) + if err != nil { + return fmt.Errorf("error converting YAML to JSON: %v", err) + } + + err = json.Unmarshal(j, o) + if err != nil { + return fmt.Errorf("error unmarshaling JSON: %v", err) + } + + return nil +} + +// Convert JSON to YAML. +func JSONToYAML(j []byte) ([]byte, error) { + // Convert the JSON to an object. + var jsonObj interface{} + // We are using yaml.Unmarshal here (instead of json.Unmarshal) because the + // Go JSON library doesn't try to pick the right number type (int, float, + // etc.) when unmarshalling to interface{}, it just picks float64 + // universally. go-yaml does go through the effort of picking the right + // number type, so we can preserve number type throughout this process. + err := yaml.Unmarshal(j, &jsonObj) + if err != nil { + return nil, err + } + + // Marshal this object into YAML. + return yaml.Marshal(jsonObj) +} + +// Convert YAML to JSON. Since JSON is a subset of YAML, passing JSON through +// this method should be a no-op. +// +// Things YAML can do that are not supported by JSON: +// * In YAML you can have binary and null keys in your maps. These are invalid +// in JSON. (int and float keys are converted to strings.) +// * Binary data in YAML with the !!binary tag is not supported. If you want to +// use binary data with this library, encode the data as base64 as usual but do +// not use the !!binary tag in your YAML. This will ensure the original base64 +// encoded data makes it all the way through to the JSON. +func YAMLToJSON(y []byte) ([]byte, error) { + return yamlToJSON(y, nil) +} + +func yamlToJSON(y []byte, jsonTarget *reflect.Value) ([]byte, error) { + // Convert the YAML to an object. + var yamlObj interface{} + err := yaml.Unmarshal(y, &yamlObj) + if err != nil { + return nil, err + } + + // YAML objects are not completely compatible with JSON objects (e.g. you + // can have non-string keys in YAML). So, convert the YAML-compatible object + // to a JSON-compatible object, failing with an error if irrecoverable + // incompatibilties happen along the way. + jsonObj, err := convertToJSONableObject(yamlObj, jsonTarget) + if err != nil { + return nil, err + } + + // Convert this object to JSON and return the data. + return json.Marshal(jsonObj) +} + +func convertToJSONableObject(yamlObj interface{}, jsonTarget *reflect.Value) (interface{}, error) { + var err error + + // Resolve jsonTarget to a concrete value (i.e. not a pointer or an + // interface). We pass decodingNull as false because we're not actually + // decoding into the value, we're just checking if the ultimate target is a + // string. + if jsonTarget != nil { + ju, tu, pv := indirect(*jsonTarget, false) + // We have a JSON or Text Umarshaler at this level, so we can't be trying + // to decode into a string. + if ju != nil || tu != nil { + jsonTarget = nil + } else { + jsonTarget = &pv + } + } + + // If yamlObj is a number or a boolean, check if jsonTarget is a string - + // if so, coerce. Else return normal. + // If yamlObj is a map or array, find the field that each key is + // unmarshaling to, and when you recurse pass the reflect.Value for that + // field back into this function. + switch typedYAMLObj := yamlObj.(type) { + case map[interface{}]interface{}: + // JSON does not support arbitrary keys in a map, so we must convert + // these keys to strings. + // + // From my reading of go-yaml v2 (specifically the resolve function), + // keys can only have the types string, int, int64, float64, binary + // (unsupported), or null (unsupported). + strMap := make(map[string]interface{}) + for k, v := range typedYAMLObj { + // Resolve the key to a string first. + var keyString string + switch typedKey := k.(type) { + case string: + keyString = typedKey + case int: + keyString = strconv.Itoa(typedKey) + case int64: + // go-yaml will only return an int64 as a key if the system + // architecture is 32-bit and the key's value is between 32-bit + // and 64-bit. Otherwise the key type will simply be int. + keyString = strconv.FormatInt(typedKey, 10) + case float64: + // Stolen from go-yaml to use the same conversion to string as + // the go-yaml library uses to convert float to string when + // Marshaling. + s := strconv.FormatFloat(typedKey, 'g', -1, 32) + switch s { + case "+Inf": + s = ".inf" + case "-Inf": + s = "-.inf" + case "NaN": + s = ".nan" + } + keyString = s + case bool: + if typedKey { + keyString = "true" + } else { + keyString = "false" + } + default: + return nil, fmt.Errorf("Unsupported map key of type: %s, key: %+#v, value: %+#v", + reflect.TypeOf(k), k, v) + } + + // jsonTarget should be a struct or a map. If it's a struct, find + // the field it's going to map to and pass its reflect.Value. If + // it's a map, find the element type of the map and pass the + // reflect.Value created from that type. If it's neither, just pass + // nil - JSON conversion will error for us if it's a real issue. + if jsonTarget != nil { + t := *jsonTarget + if t.Kind() == reflect.Struct { + keyBytes := []byte(keyString) + // Find the field that the JSON library would use. + var f *field + fields := cachedTypeFields(t.Type()) + for i := range fields { + ff := &fields[i] + if bytes.Equal(ff.nameBytes, keyBytes) { + f = ff + break + } + // Do case-insensitive comparison. + if f == nil && ff.equalFold(ff.nameBytes, keyBytes) { + f = ff + } + } + if f != nil { + // Find the reflect.Value of the most preferential + // struct field. + jtf := t.Field(f.index[0]) + strMap[keyString], err = convertToJSONableObject(v, &jtf) + if err != nil { + return nil, err + } + continue + } + } else if t.Kind() == reflect.Map { + // Create a zero value of the map's element type to use as + // the JSON target. + jtv := reflect.Zero(t.Type().Elem()) + strMap[keyString], err = convertToJSONableObject(v, &jtv) + if err != nil { + return nil, err + } + continue + } + } + strMap[keyString], err = convertToJSONableObject(v, nil) + if err != nil { + return nil, err + } + } + return strMap, nil + case []interface{}: + // We need to recurse into arrays in case there are any + // map[interface{}]interface{}'s inside and to convert any + // numbers to strings. + + // If jsonTarget is a slice (which it really should be), find the + // thing it's going to map to. If it's not a slice, just pass nil + // - JSON conversion will error for us if it's a real issue. + var jsonSliceElemValue *reflect.Value + if jsonTarget != nil { + t := *jsonTarget + if t.Kind() == reflect.Slice { + // By default slices point to nil, but we need a reflect.Value + // pointing to a value of the slice type, so we create one here. + ev := reflect.Indirect(reflect.New(t.Type().Elem())) + jsonSliceElemValue = &ev + } + } + + // Make and use a new array. + arr := make([]interface{}, len(typedYAMLObj)) + for i, v := range typedYAMLObj { + arr[i], err = convertToJSONableObject(v, jsonSliceElemValue) + if err != nil { + return nil, err + } + } + return arr, nil + default: + // If the target type is a string and the YAML type is a number, + // convert the YAML type to a string. + if jsonTarget != nil && (*jsonTarget).Kind() == reflect.String { + // Based on my reading of go-yaml, it may return int, int64, + // float64, or uint64. + var s string + switch typedVal := typedYAMLObj.(type) { + case int: + s = strconv.FormatInt(int64(typedVal), 10) + case int64: + s = strconv.FormatInt(typedVal, 10) + case float64: + s = strconv.FormatFloat(typedVal, 'g', -1, 32) + case uint64: + s = strconv.FormatUint(typedVal, 10) + case bool: + if typedVal { + s = "true" + } else { + s = "false" + } + } + if len(s) > 0 { + yamlObj = interface{}(s) + } + } + return yamlObj, nil + } + + return nil, nil +} diff --git a/vendor/github.com/go-logr/logr/.golangci.yaml b/vendor/github.com/go-logr/logr/.golangci.yaml new file mode 100644 index 0000000000..94ff801df1 --- /dev/null +++ b/vendor/github.com/go-logr/logr/.golangci.yaml @@ -0,0 +1,29 @@ +run: + timeout: 1m + tests: true + +linters: + disable-all: true + enable: + - asciicheck + - deadcode + - errcheck + - forcetypeassert + - gocritic + - gofmt + - goimports + - gosimple + - govet + - ineffassign + - misspell + - revive + - staticcheck + - structcheck + - typecheck + - unused + - varcheck + +issues: + exclude-use-default: false + max-issues-per-linter: 0 + max-same-issues: 10 diff --git a/vendor/github.com/go-logr/logr/CHANGELOG.md b/vendor/github.com/go-logr/logr/CHANGELOG.md new file mode 100644 index 0000000000..c356960046 --- /dev/null +++ b/vendor/github.com/go-logr/logr/CHANGELOG.md @@ -0,0 +1,6 @@ +# CHANGELOG + +## v1.0.0-rc1 + +This is the first logged release. Major changes (including breaking changes) +have occurred since earlier tags. diff --git a/vendor/github.com/go-logr/logr/CONTRIBUTING.md b/vendor/github.com/go-logr/logr/CONTRIBUTING.md new file mode 100644 index 0000000000..5d37e294c5 --- /dev/null +++ b/vendor/github.com/go-logr/logr/CONTRIBUTING.md @@ -0,0 +1,17 @@ +# Contributing + +Logr is open to pull-requests, provided they fit within the intended scope of +the project. Specifically, this library aims to be VERY small and minimalist, +with no external dependencies. + +## Compatibility + +This project intends to follow [semantic versioning](http://semver.org) and +is very strict about compatibility. Any proposed changes MUST follow those +rules. + +## Performance + +As a logging library, logr must be as light-weight as possible. Any proposed +code change must include results of running the [benchmark](./benchmark) +before and after the change. diff --git a/vendor/github.com/go-logr/logr/README.md b/vendor/github.com/go-logr/logr/README.md index e9b5520a1c..ad825f5f0a 100644 --- a/vendor/github.com/go-logr/logr/README.md +++ b/vendor/github.com/go-logr/logr/README.md @@ -1,112 +1,182 @@ -# A more minimal logging API for Go +# A minimal logging API for Go -Before you consider this package, please read [this blog post by the -inimitable Dave Cheney][warning-makes-no-sense]. I really appreciate what -he has to say, and it largely aligns with my own experiences. Too many -choices of levels means inconsistent logs. +[![Go Reference](https://pkg.go.dev/badge/github.com/go-logr/logr.svg)](https://pkg.go.dev/github.com/go-logr/logr) + +logr offers an(other) opinion on how Go programs and libraries can do logging +without becoming coupled to a particular logging implementation. This is not +an implementation of logging - it is an API. In fact it is two APIs with two +different sets of users. + +The `Logger` type is intended for application and library authors. It provides +a relatively small API which can be used everywhere you want to emit logs. It +defers the actual act of writing logs (to files, to stdout, or whatever) to the +`LogSink` interface. + +The `LogSink` interface is intended for logging library implementers. It is a +pure interface which can be implemented by logging frameworks to provide the actual logging +functionality. + +This decoupling allows application and library developers to write code in +terms of `logr.Logger` (which has very low dependency fan-out) while the +implementation of logging is managed "up stack" (e.g. in or near `main()`.) +Application developers can then switch out implementations as necessary. + +Many people assert that libraries should not be logging, and as such efforts +like this are pointless. Those people are welcome to convince the authors of +the tens-of-thousands of libraries that *DO* write logs that they are all +wrong. In the meantime, logr takes a more practical approach. + +## Typical usage + +Somewhere, early in an application's life, it will make a decision about which +logging library (implementation) it actually wants to use. Something like: + +``` + func main() { + // ... other setup code ... + + // Create the "root" logger. We have chosen the "logimpl" implementation, + // which takes some initial parameters and returns a logr.Logger. + logger := logimpl.New(param1, param2) + + // ... other setup code ... +``` + +Most apps will call into other libraries, create structures to govern the flow, +etc. The `logr.Logger` object can be passed to these other libraries, stored +in structs, or even used as a package-global variable, if needed. For example: + +``` + app := createTheAppObject(logger) + app.Run() +``` + +Outside of this early setup, no other packages need to know about the choice of +implementation. They write logs in terms of the `logr.Logger` that they +received: -This package offers a purely abstract interface, based on these ideas but with -a few twists. Code can depend on just this interface and have the actual -logging implementation be injected from callers. Ideally only `main()` knows -what logging implementation is being used. +``` + type appObject struct { + // ... other fields ... + logger logr.Logger + // ... other fields ... + } -# Differences from Dave's ideas + func (app *appObject) Run() { + app.logger.Info("starting up", "timestamp", time.Now()) + + // ... app code ... +``` + +## Background + +If the Go standard library had defined an interface for logging, this project +probably would not be needed. Alas, here we are. + +### Inspiration + +Before you consider this package, please read [this blog post by the +inimitable Dave Cheney][warning-makes-no-sense]. We really appreciate what +he has to say, and it largely aligns with our own experiences. + +### Differences from Dave's ideas The main differences are: -1) Dave basically proposes doing away with the notion of a logging API in favor -of `fmt.Printf()`. I disagree, especially when you consider things like output -locations, timestamps, file and line decorations, and structured logging. I -restrict the API to just 2 types of logs: info and error. +1. Dave basically proposes doing away with the notion of a logging API in favor +of `fmt.Printf()`. We disagree, especially when you consider things like output +locations, timestamps, file and line decorations, and structured logging. This +package restricts the logging API to just 2 types of logs: info and error. Info logs are things you want to tell the user which are not errors. Error logs are, well, errors. If your code receives an `error` from a subordinate function call and is logging that `error` *and not returning it*, use error logs. -2) Verbosity-levels on info logs. This gives developers a chance to indicate +2. Verbosity-levels on info logs. This gives developers a chance to indicate arbitrary grades of importance for info logs, without assigning names with -semantic meaning such as "warning", "trace", and "debug". Superficially this +semantic meaning such as "warning", "trace", and "debug." Superficially this may feel very similar, but the primary difference is the lack of semantics. Because verbosity is a numerical value, it's safe to assume that an app running with higher verbosity means more (and less important) logs will be generated. -This is a BETA grade API. +## Implementations (non-exhaustive) There are implementations for the following logging libraries: +- **a function** (can bridge to non-structured libraries): [funcr](https://github.com/go-logr/logr/tree/master/funcr) - **github.com/google/glog**: [glogr](https://github.com/go-logr/glogr) -- **k8s.io/klog**: [klogr](https://git.k8s.io/klog/klogr) +- **k8s.io/klog** (for Kubernetes): [klogr](https://git.k8s.io/klog/klogr) - **go.uber.org/zap**: [zapr](https://github.com/go-logr/zapr) -- **log** (the Go standard library logger): - [stdr](https://github.com/go-logr/stdr) +- **log** (the Go standard library logger): [stdr](https://github.com/go-logr/stdr) - **github.com/sirupsen/logrus**: [logrusr](https://github.com/bombsimon/logrusr) - **github.com/wojas/genericr**: [genericr](https://github.com/wojas/genericr) (makes it easy to implement your own backend) - **logfmt** (Heroku style [logging](https://www.brandur.org/logfmt)): [logfmtr](https://github.com/iand/logfmtr) +- **github.com/rs/zerolog**: [zerologr](https://github.com/go-logr/zerologr) -# FAQ +## FAQ -## Conceptual +### Conceptual -## Why structured logging? +#### Why structured logging? -- **Structured logs are more easily queriable**: Since you've got +- **Structured logs are more easily queryable**: Since you've got key-value pairs, it's much easier to query your structured logs for particular values by filtering on the contents of a particular key -- think searching request logs for error codes, Kubernetes reconcilers for - the name and namespace of the reconciled object, etc + the name and namespace of the reconciled object, etc. -- **Structured logging makes it easier to have cross-referencable logs**: +- **Structured logging makes it easier to have cross-referenceable logs**: Similarly to searchability, if you maintain conventions around your keys, it becomes easy to gather all log lines related to a particular concept. - + - **Structured logs allow better dimensions of filtering**: if you have structure to your logs, you've got more precise control over how much information is logged -- you might choose in a particular configuration to log certain keys but not others, only log lines where a certain key - matches a certain value, etc, instead of just having v-levels and names + matches a certain value, etc., instead of just having v-levels and names to key off of. - **Structured logs better represent structured data**: sometimes, the data that you want to log is inherently structured (think tuple-link - objects). Structured logs allow you to preserve that structure when + objects.) Structured logs allow you to preserve that structure when outputting. -## Why V-levels? +#### Why V-levels? **V-levels give operators an easy way to control the chattiness of log operations**. V-levels provide a way for a given package to distinguish the relative importance or verbosity of a given log message. Then, if a particular logger or package is logging too many messages, the user -of the package can simply change the v-levels for that library. +of the package can simply change the v-levels for that library. -## Why not more named levels, like Warning? +#### Why not named levels, like Info/Warning/Error? Read [Dave Cheney's post][warning-makes-no-sense]. Then read [Differences from Dave's ideas](#differences-from-daves-ideas). -## Why not allow format strings, too? +#### Why not allow format strings, too? **Format strings negate many of the benefits of structured logs**: - They're not easily searchable without resorting to fuzzy searching, - regular expressions, etc + regular expressions, etc. - They don't store structured data well, since contents are flattened into - a string + a string. -- They're not cross-referencable +- They're not cross-referenceable. -- They don't compress easily, since the message is not constant +- They don't compress easily, since the message is not constant. -(unless you turn positional parameters into key-value pairs with numerical +(Unless you turn positional parameters into key-value pairs with numerical keys, at which point you've gotten key-value logging with meaningless -keys) +keys.) -## Practical +### Practical -## Why key-value pairs, and not a map? +#### Why key-value pairs, and not a map? Key-value pairs are *much* easier to optimize, especially around allocations. Zap (a structured logger that inspired logr's interface) has @@ -117,26 +187,26 @@ While the interface ends up being a little less obvious, you get potentially better performance, plus avoid making users type `map[string]string{}` every time they want to log. -## What if my V-levels differ between libraries? +#### What if my V-levels differ between libraries? That's fine. Control your V-levels on a per-logger basis, and use the -`WithName` function to pass different loggers to different libraries. +`WithName` method to pass different loggers to different libraries. Generally, you should take care to ensure that you have relatively consistent V-levels within a given logger, however, as this makes deciding on what verbosity of logs to request easier. -## But I *really* want to use a format string! +#### But I really want to use a format string! That's not actually a question. Assuming your question is "how do I convert my mental model of logging with format strings to logging with constant messages": -1. figure out what the error actually is, as you'd write in a TL;DR style, - and use that as a message +1. Figure out what the error actually is, as you'd write in a TL;DR style, + and use that as a message. 2. For every place you'd write a format specifier, look to the word before - it, and add that as a key value pair + it, and add that as a key value pair. For instance, consider the following examples (all taken from spots in the Kubernetes codebase): @@ -150,34 +220,59 @@ Kubernetes codebase): response when requesting url", "attempt", retries, "after seconds", seconds, "url", url)` -If you *really* must use a format string, place it as a key value, and -call `fmt.Sprintf` yourself -- for instance, `log.Printf("unable to +If you *really* must use a format string, use it in a key's value, and +call `fmt.Sprintf` yourself. For instance: `log.Printf("unable to reflect over type %T")` becomes `logger.Info("unable to reflect over type", "type", fmt.Sprintf("%T"))`. In general though, the cases where this is necessary should be few and far between. -## How do I choose my V-levels? +#### How do I choose my V-levels? This is basically the only hard constraint: increase V-levels to denote more verbose or more debug-y logs. Otherwise, you can start out with `0` as "you always want to see this", `1` as "common logging that you might *possibly* want to turn off", and -`10` as "I would like to performance-test your log collection stack". +`10` as "I would like to performance-test your log collection stack." Then gradually choose levels in between as you need them, working your way down from 10 (for debug and trace style logs) and up from 1 (for chattier -info-type logs). +info-type logs.) + +#### How do I choose my keys? -## How do I choose my keys +Keys are fairly flexible, and can hold more or less any string +value. For best compatibility with implementations and consistency +with existing code in other projects, there are a few conventions you +should consider. -- make your keys human-readable -- constant keys are generally a good idea -- be consistent across your codebase -- keys should naturally match parts of the message string +- Make your keys human-readable. +- Constant keys are generally a good idea. +- Be consistent across your codebase. +- Keys should naturally match parts of the message string. +- Use lower case for simple keys and + [lowerCamelCase](https://en.wiktionary.org/wiki/lowerCamelCase) for + more complex ones. Kubernetes is one example of a project that has + [adopted that + convention](https://github.com/kubernetes/community/blob/HEAD/contributors/devel/sig-instrumentation/migration-to-structured-logging.md#name-arguments). While key names are mostly unrestricted (and spaces are acceptable), it's generally a good idea to stick to printable ascii characters, or at least match the general character set of your log lines. +#### Why should keys be constant values? + +The point of structured logging is to make later log processing easier. Your +keys are, effectively, the schema of each log message. If you use different +keys across instances of the same log line, you will make your structured logs +much harder to use. `Sprintf()` is for values, not for keys! + +#### Why is this not a pure interface? + +The Logger type is implemented as a struct in order to allow the Go compiler to +optimize things like high-V `Info` logs that are not triggered. Not all of +these implementations are implemented yet, but this structure was suggested as +a way to ensure they *can* be implemented. All of the real work is behind the +`LogSink` interface. + [warning-makes-no-sense]: http://dave.cheney.net/2015/11/05/lets-talk-about-logging diff --git a/vendor/github.com/go-logr/logr/discard.go b/vendor/github.com/go-logr/logr/discard.go index 2bafb13d15..9d92a38f1d 100644 --- a/vendor/github.com/go-logr/logr/discard.go +++ b/vendor/github.com/go-logr/logr/discard.go @@ -16,36 +16,39 @@ limitations under the License. package logr -// Discard returns a valid Logger that discards all messages logged to it. -// It can be used whenever the caller is not interested in the logs. +// Discard returns a Logger that discards all messages logged to it. It can be +// used whenever the caller is not interested in the logs. Logger instances +// produced by this function always compare as equal. func Discard() Logger { - return DiscardLogger{} + return Logger{ + level: 0, + sink: discardLogSink{}, + } } -// DiscardLogger is a Logger that discards all messages. -type DiscardLogger struct{} +// discardLogSink is a LogSink that discards all messages. +type discardLogSink struct{} -func (l DiscardLogger) Enabled() bool { - return false +// Verify that it actually implements the interface +var _ LogSink = discardLogSink{} + +func (l discardLogSink) Init(RuntimeInfo) { } -func (l DiscardLogger) Info(msg string, keysAndValues ...interface{}) { +func (l discardLogSink) Enabled(int) bool { + return false } -func (l DiscardLogger) Error(err error, msg string, keysAndValues ...interface{}) { +func (l discardLogSink) Info(int, string, ...interface{}) { } -func (l DiscardLogger) V(level int) Logger { - return l +func (l discardLogSink) Error(error, string, ...interface{}) { } -func (l DiscardLogger) WithValues(keysAndValues ...interface{}) Logger { +func (l discardLogSink) WithValues(...interface{}) LogSink { return l } -func (l DiscardLogger) WithName(name string) Logger { +func (l discardLogSink) WithName(string) LogSink { return l } - -// Verify that it actually implements the interface -var _ Logger = DiscardLogger{} diff --git a/vendor/github.com/go-logr/logr/go.mod b/vendor/github.com/go-logr/logr/go.mod index 591884e91f..7baec9b570 100644 --- a/vendor/github.com/go-logr/logr/go.mod +++ b/vendor/github.com/go-logr/logr/go.mod @@ -1,3 +1,3 @@ module github.com/go-logr/logr -go 1.14 +go 1.16 diff --git a/vendor/github.com/go-logr/logr/logr.go b/vendor/github.com/go-logr/logr/logr.go index 842428bd3a..44cd398c9f 100644 --- a/vendor/github.com/go-logr/logr/logr.go +++ b/vendor/github.com/go-logr/logr/logr.go @@ -16,83 +16,101 @@ limitations under the License. // This design derives from Dave Cheney's blog: // http://dave.cheney.net/2015/11/05/lets-talk-about-logging -// -// This is a BETA grade API. Until there is a significant 2nd implementation, -// I don't really know how it will change. -// Package logr defines abstract interfaces for logging. Packages can depend on -// these interfaces and callers can implement logging in whatever way is -// appropriate. +// Package logr defines a general-purpose logging API and abstract interfaces +// to back that API. Packages in the Go ecosystem can depend on this package, +// while callers can implement logging with whatever backend is appropriate. // // Usage // -// Logging is done using a Logger. Loggers can have name prefixes and named -// values attached, so that all log messages logged with that Logger have some -// base context associated. +// Logging is done using a Logger instance. Logger is a concrete type with +// methods, which defers the actual logging to a LogSink interface. The main +// methods of Logger are Info() and Error(). Arguments to Info() and Error() +// are key/value pairs rather than printf-style formatted strings, emphasizing +// "structured logging". // -// The term "key" is used to refer to the name associated with a particular -// value, to disambiguate it from the general Logger name. +// With Go's standard log package, we might write: +// log.Printf("setting target value %s", targetValue) // -// For instance, suppose we're trying to reconcile the state of an object, and -// we want to log that we've made some decision. +// With logr's structured logging, we'd write: +// logger.Info("setting target", "value", targetValue) // -// With the traditional log package, we might write: -// log.Printf("decided to set field foo to value %q for object %s/%s", -// targetValue, object.Namespace, object.Name) +// Errors are much the same. Instead of: +// log.Printf("failed to open the pod bay door for user %s: %v", user, err) // -// With logr's structured logging, we'd write: -// // elsewhere in the file, set up the logger to log with the prefix of -// // "reconcilers", and the named value target-type=Foo, for extra context. -// log := mainLogger.WithName("reconcilers").WithValues("target-type", "Foo") +// We'd write: +// logger.Error(err, "failed to open the pod bay door", "user", user) // -// // later on... -// log.Info("setting foo on object", "value", targetValue, "object", object) +// Info() and Error() are very similar, but they are separate methods so that +// LogSink implementations can choose to do things like attach additional +// information (such as stack traces) on calls to Error(). +// +// Verbosity +// +// Often we want to log information only when the application in "verbose +// mode". To write log lines that are more verbose, Logger has a V() method. +// The higher the V-level of a log line, the less critical it is considered. +// Log-lines with V-levels that are not enabled (as per the LogSink) will not +// be written. Level V(0) is the default, and logger.V(0).Info() has the same +// meaning as logger.Info(). Negative V-levels have the same meaning as V(0). +// +// Where we might have written: +// if flVerbose >= 2 { +// log.Printf("an unusual thing happened") +// } +// +// We can write: +// logger.V(2).Info("an unusual thing happened") +// +// Logger Names +// +// Logger instances can have name strings so that all messages logged through +// that instance have additional context. For example, you might want to add +// a subsystem name: // -// Depending on our logging implementation, we could then make logging decisions -// based on field values (like only logging such events for objects in a certain -// namespace), or copy the structured information into a structured log store. +// logger.WithName("compactor").Info("started", "time", time.Now()) // -// For logging errors, Logger has a method called Error. Suppose we wanted to -// log an error while reconciling. With the traditional log package, we might -// write: -// log.Errorf("unable to reconcile object %s/%s: %v", object.Namespace, object.Name, err) +// The WithName() method returns a new Logger, which can be passed to +// constructors or other functions for further use. Repeated use of WithName() +// will accumulate name "segments". These name segments will be joined in some +// way by the LogSink implementation. It is strongly recommended that name +// segments contain simple identifiers (letters, digits, and hyphen), and do +// not contain characters that could muddle the log output or confuse the +// joining operation (e.g. whitespace, commas, periods, slashes, brackets, +// quotes, etc). // -// With logr, we'd instead write: -// // assuming the above setup for log -// log.Error(err, "unable to reconcile object", "object", object) +// Saved Values // -// This functions similarly to: -// log.Info("unable to reconcile object", "error", err, "object", object) +// Logger instances can store any number of key/value pairs, which will be +// logged alongside all messages logged through that instance. For example, +// you might want to create a Logger instance per managed object: // -// However, it ensures that a standard key for the error value ("error") is used -// across all error logging. Furthermore, certain implementations may choose to -// attach additional information (such as stack traces) on calls to Error, so -// it's preferred to use Error to log errors. +// With the standard log package, we might write: +// log.Printf("decided to set field foo to value %q for object %s/%s", +// targetValue, object.Namespace, object.Name) // -// Parts of a log line +// With logr we'd write: +// // Elsewhere: set up the logger to log the object name. +// obj.logger = mainLogger.WithValues( +// "name", obj.name, "namespace", obj.namespace) // -// Each log message from a Logger has four types of context: -// logger name, log verbosity, log message, and the named values. +// // later on... +// obj.logger.Info("setting foo", "value", targetValue) // -// The Logger name consists of a series of name "segments" added by successive -// calls to WithName. These name segments will be joined in some way by the -// underlying implementation. It is strongly recommended that name segments -// contain simple identifiers (letters, digits, and hyphen), and do not contain -// characters that could muddle the log output or confuse the joining operation -// (e.g. whitespace, commas, periods, slashes, brackets, quotes, etc). +// Best Practices // -// Log verbosity represents how little a log matters. Level zero, the default, -// matters most. Increasing levels matter less and less. Try to avoid lots of -// different verbosity levels, and instead provide useful keys, logger names, -// and log messages for users to filter on. It's illegal to pass a log level -// below zero. +// Logger has very few hard rules, with the goal that LogSink implementations +// might have a lot of freedom to differentiate. There are, however, some +// things to consider. // // The log message consists of a constant message attached to the log line. // This should generally be a simple description of what's occurring, and should -// never be a format string. +// never be a format string. Variable information can then be attached using +// named values. // -// Variable information can then be attached using named values (key/value -// pairs). Keys are arbitrary strings, while values may be any Go value. +// Keys are arbitrary strings, but should generally be constant values. Values +// may be any Go value, but how the value is formatted is determined by the +// LogSink implementation. // // Key Naming Conventions // @@ -102,6 +120,7 @@ limitations under the License. // * be constant (not dependent on input data) // * contain only printable characters // * not contain whitespace or punctuation +// * use lower case for simple keys and lowerCamelCase for more complex ones // // These guidelines help ensure that log data is processed properly regardless // of the log implementation. For example, log implementations will try to @@ -110,21 +129,22 @@ limitations under the License. // While users are generally free to use key names of their choice, it's // generally best to avoid using the following keys, as they're frequently used // by implementations: -// -// * `"caller"`: the calling information (file/line) of a particular log line. -// * `"error"`: the underlying error value in the `Error` method. -// * `"level"`: the log level. -// * `"logger"`: the name of the associated logger. -// * `"msg"`: the log message. -// * `"stacktrace"`: the stack trace associated with a particular log line or -// error (often from the `Error` message). -// * `"ts"`: the timestamp for a log line. +// * "caller": the calling information (file/line) of a particular log line +// * "error": the underlying error value in the `Error` method +// * "level": the log level +// * "logger": the name of the associated logger +// * "msg": the log message +// * "stacktrace": the stack trace associated with a particular log line or +// error (often from the `Error` message) +// * "ts": the timestamp for a log line // // Implementations are encouraged to make use of these keys to represent the // above concepts, when necessary (for example, in a pure-JSON output form, it // would be necessary to represent at least message and timestamp as ordinary // named values). // +// Break Glass +// // Implementations may choose to give callers access to the underlying // logging implementation. The recommended pattern for this is: // // Underlier exposes access to the underlying logging implementation. @@ -134,81 +154,220 @@ limitations under the License. // type Underlier interface { // GetUnderlying() // } +// +// Logger grants access to the sink to enable type assertions like this: +// func DoSomethingWithImpl(log logr.Logger) { +// if underlier, ok := log.GetSink()(impl.Underlier) { +// implLogger := underlier.GetUnderlying() +// ... +// } +// } +// +// Custom `With*` functions can be implemented by copying the complete +// Logger struct and replacing the sink in the copy: +// // WithFooBar changes the foobar parameter in the log sink and returns a +// // new logger with that modified sink. It does nothing for loggers where +// // the sink doesn't support that parameter. +// func WithFoobar(log logr.Logger, foobar int) logr.Logger { +// if foobarLogSink, ok := log.GetSink()(FoobarSink); ok { +// log = log.WithSink(foobarLogSink.WithFooBar(foobar)) +// } +// return log +// } +// +// Don't use New to construct a new Logger with a LogSink retrieved from an +// existing Logger. Source code attribution might not work correctly and +// unexported fields in Logger get lost. +// +// Beware that the same LogSink instance may be shared by different logger +// instances. Calling functions that modify the LogSink will affect all of +// those. package logr import ( "context" ) -// TODO: consider adding back in format strings if they're really needed -// TODO: consider other bits of zap/zapcore functionality like ObjectMarshaller (for arbitrary objects) -// TODO: consider other bits of glog functionality like Flush, OutputStats +// New returns a new Logger instance. This is primarily used by libraries +// implementing LogSink, rather than end users. +func New(sink LogSink) Logger { + logger := Logger{} + logger.setSink(sink) + sink.Init(runtimeInfo) + return logger +} -// Logger represents the ability to log messages, both errors and not. -type Logger interface { - // Enabled tests whether this Logger is enabled. For example, commandline - // flags might be used to set the logging verbosity and disable some info - // logs. - Enabled() bool +// setSink stores the sink and updates any related fields. It mutates the +// logger and thus is only safe to use for loggers that are not currently being +// used concurrently. +func (l *Logger) setSink(sink LogSink) { + l.sink = sink +} - // Info logs a non-error message with the given key/value pairs as context. - // - // The msg argument should be used to add some constant description to - // the log line. The key/value pairs can then be used to add additional - // variable information. The key/value pairs should alternate string - // keys and arbitrary values. - Info(msg string, keysAndValues ...interface{}) - - // Error logs an error, with the given message and key/value pairs as context. - // It functions similarly to calling Info with the "error" named value, but may - // have unique behavior, and should be preferred for logging errors (see the - // package documentations for more information). - // - // The msg field should be used to add context to any underlying error, - // while the err field should be used to attach the actual error that - // triggered this log line, if present. - Error(err error, msg string, keysAndValues ...interface{}) +// GetSink returns the stored sink. +func (l Logger) GetSink() LogSink { + return l.sink +} + +// WithSink returns a copy of the logger with the new sink. +func (l Logger) WithSink(sink LogSink) Logger { + l.setSink(sink) + return l +} + +// Logger is an interface to an abstract logging implementation. This is a +// concrete type for performance reasons, but all the real work is passed on to +// a LogSink. Implementations of LogSink should provide their own constructors +// that return Logger, not LogSink. +// +// The underlying sink can be accessed through GetSink and be modified through +// WithSink. This enables the implementation of custom extensions (see "Break +// Glass" in the package documentation). Normally the sink should be used only +// indirectly. +type Logger struct { + sink LogSink + level int +} + +// Enabled tests whether this Logger is enabled. For example, commandline +// flags might be used to set the logging verbosity and disable some info logs. +func (l Logger) Enabled() bool { + return l.sink.Enabled(l.level) +} + +// Info logs a non-error message with the given key/value pairs as context. +// +// The msg argument should be used to add some constant description to the log +// line. The key/value pairs can then be used to add additional variable +// information. The key/value pairs must alternate string keys and arbitrary +// values. +func (l Logger) Info(msg string, keysAndValues ...interface{}) { + if l.Enabled() { + if withHelper, ok := l.sink.(CallStackHelperLogSink); ok { + withHelper.GetCallStackHelper()() + } + l.sink.Info(l.level, msg, keysAndValues...) + } +} + +// Error logs an error, with the given message and key/value pairs as context. +// It functions similarly to Info, but may have unique behavior, and should be +// preferred for logging errors (see the package documentations for more +// information). +// +// The msg argument should be used to add context to any underlying error, +// while the err argument should be used to attach the actual error that +// triggered this log line, if present. +func (l Logger) Error(err error, msg string, keysAndValues ...interface{}) { + if withHelper, ok := l.sink.(CallStackHelperLogSink); ok { + withHelper.GetCallStackHelper()() + } + l.sink.Error(err, msg, keysAndValues...) +} + +// V returns a new Logger instance for a specific verbosity level, relative to +// this Logger. In other words, V-levels are additive. A higher verbosity +// level means a log message is less important. Negative V-levels are treated +// as 0. +func (l Logger) V(level int) Logger { + if level < 0 { + level = 0 + } + l.level += level + return l +} + +// WithValues returns a new Logger instance with additional key/value pairs. +// See Info for documentation on how key/value pairs work. +func (l Logger) WithValues(keysAndValues ...interface{}) Logger { + l.setSink(l.sink.WithValues(keysAndValues...)) + return l +} - // V returns an Logger value for a specific verbosity level, relative to - // this Logger. In other words, V values are additive. V higher verbosity - // level means a log message is less important. It's illegal to pass a log - // level less than zero. - V(level int) Logger - - // WithValues adds some key-value pairs of context to a logger. - // See Info for documentation on how key/value pairs work. - WithValues(keysAndValues ...interface{}) Logger - - // WithName adds a new element to the logger's name. - // Successive calls with WithName continue to append - // suffixes to the logger's name. It's strongly recommended - // that name segments contain only letters, digits, and hyphens - // (see the package documentation for more information). - WithName(name string) Logger +// WithName returns a new Logger instance with the specified name element added +// to the Logger's name. Successive calls with WithName append additional +// suffixes to the Logger's name. It's strongly recommended that name segments +// contain only letters, digits, and hyphens (see the package documentation for +// more information). +func (l Logger) WithName(name string) Logger { + l.setSink(l.sink.WithName(name)) + return l } -// InfoLogger provides compatibility with code that relies on the v0.1.0 -// interface. +// WithCallDepth returns a Logger instance that offsets the call stack by the +// specified number of frames when logging call site information, if possible. +// This is useful for users who have helper functions between the "real" call +// site and the actual calls to Logger methods. If depth is 0 the attribution +// should be to the direct caller of this function. If depth is 1 the +// attribution should skip 1 call frame, and so on. Successive calls to this +// are additive. +// +// If the underlying log implementation supports a WithCallDepth(int) method, +// it will be called and the result returned. If the implementation does not +// support CallDepthLogSink, the original Logger will be returned. +// +// To skip one level, WithCallStackHelper() should be used instead of +// WithCallDepth(1) because it works with implementions that support the +// CallDepthLogSink and/or CallStackHelperLogSink interfaces. +func (l Logger) WithCallDepth(depth int) Logger { + if withCallDepth, ok := l.sink.(CallDepthLogSink); ok { + l.setSink(withCallDepth.WithCallDepth(depth)) + } + return l +} + +// WithCallStackHelper returns a new Logger instance that skips the direct +// caller when logging call site information, if possible. This is useful for +// users who have helper functions between the "real" call site and the actual +// calls to Logger methods and want to support loggers which depend on marking +// each individual helper function, like loggers based on testing.T. +// +// In addition to using that new logger instance, callers also must call the +// returned function. // -// Deprecated: InfoLogger is an artifact of early versions of this API. New -// users should never use it and existing users should use Logger instead. This -// will be removed in a future release. -type InfoLogger = Logger +// If the underlying log implementation supports a WithCallDepth(int) method, +// WithCallDepth(1) will be called to produce a new logger. If it supports a +// WithCallStackHelper() method, that will be also called. If the +// implementation does not support either of these, the original Logger will be +// returned. +func (l Logger) WithCallStackHelper() (func(), Logger) { + var helper func() + if withCallDepth, ok := l.sink.(CallDepthLogSink); ok { + l.setSink(withCallDepth.WithCallDepth(1)) + } + if withHelper, ok := l.sink.(CallStackHelperLogSink); ok { + helper = withHelper.GetCallStackHelper() + } else { + helper = func() {} + } + return helper, l +} +// contextKey is how we find Loggers in a context.Context. type contextKey struct{} -// FromContext returns a Logger constructed from ctx or nil if no -// logger details are found. -func FromContext(ctx context.Context) Logger { +// FromContext returns a Logger from ctx or an error if no Logger is found. +func FromContext(ctx context.Context) (Logger, error) { if v, ok := ctx.Value(contextKey{}).(Logger); ok { - return v + return v, nil } - return nil + return Logger{}, notFoundError{} } -// FromContextOrDiscard returns a Logger constructed from ctx or a Logger -// that discards all messages if no logger details are found. +// notFoundError exists to carry an IsNotFound method. +type notFoundError struct{} + +func (notFoundError) Error() string { + return "no logr.Logger was present" +} + +func (notFoundError) IsNotFound() bool { + return true +} + +// FromContextOrDiscard returns a Logger from ctx. If no Logger is found, this +// returns a Logger that discards all log messages. func FromContextOrDiscard(ctx context.Context) Logger { if v, ok := ctx.Value(contextKey{}).(Logger); ok { return v @@ -217,12 +376,59 @@ func FromContextOrDiscard(ctx context.Context) Logger { return Discard() } -// NewContext returns a new context derived from ctx that embeds the Logger. -func NewContext(ctx context.Context, l Logger) context.Context { - return context.WithValue(ctx, contextKey{}, l) +// NewContext returns a new Context, derived from ctx, which carries the +// provided Logger. +func NewContext(ctx context.Context, logger Logger) context.Context { + return context.WithValue(ctx, contextKey{}, logger) } -// CallDepthLogger represents a Logger that knows how to climb the call stack +// RuntimeInfo holds information that the logr "core" library knows which +// LogSinks might want to know. +type RuntimeInfo struct { + // CallDepth is the number of call frames the logr library adds between the + // end-user and the LogSink. LogSink implementations which choose to print + // the original logging site (e.g. file & line) should climb this many + // additional frames to find it. + CallDepth int +} + +// runtimeInfo is a static global. It must not be changed at run time. +var runtimeInfo = RuntimeInfo{ + CallDepth: 1, +} + +// LogSink represents a logging implementation. End-users will generally not +// interact with this type. +type LogSink interface { + // Init receives optional information about the logr library for LogSink + // implementations that need it. + Init(info RuntimeInfo) + + // Enabled tests whether this LogSink is enabled at the specified V-level. + // For example, commandline flags might be used to set the logging + // verbosity and disable some info logs. + Enabled(level int) bool + + // Info logs a non-error message with the given key/value pairs as context. + // The level argument is provided for optional logging. This method will + // only be called when Enabled(level) is true. See Logger.Info for more + // details. + Info(level int, msg string, keysAndValues ...interface{}) + + // Error logs an error, with the given message and key/value pairs as + // context. See Logger.Error for more details. + Error(err error, msg string, keysAndValues ...interface{}) + + // WithValues returns a new LogSink with additional key/value pairs. See + // Logger.WithValues for more details. + WithValues(keysAndValues ...interface{}) LogSink + + // WithName returns a new LogSink with the specified name appended. See + // Logger.WithName for more details. + WithName(name string) LogSink +} + +// CallDepthLogSink represents a Logger that knows how to climb the call stack // to identify the original call site and can offset the depth by a specified // number of frames. This is useful for users who have helper functions // between the "real" call site and the actual calls to Logger methods. @@ -232,35 +438,59 @@ func NewContext(ctx context.Context, l Logger) context.Context { // // This is an optional interface and implementations are not required to // support it. -type CallDepthLogger interface { - Logger - - // WithCallDepth returns a Logger that will offset the call stack by the - // specified number of frames when logging call site information. If depth - // is 0 the attribution should be to the direct caller of this method. If - // depth is 1 the attribution should skip 1 call frame, and so on. +type CallDepthLogSink interface { + // WithCallDepth returns a LogSink that will offset the call + // stack by the specified number of frames when logging call + // site information. + // + // If depth is 0, the LogSink should skip exactly the number + // of call frames defined in RuntimeInfo.CallDepth when Info + // or Error are called, i.e. the attribution should be to the + // direct caller of Logger.Info or Logger.Error. + // + // If depth is 1 the attribution should skip 1 call frame, and so on. // Successive calls to this are additive. - WithCallDepth(depth int) Logger + WithCallDepth(depth int) LogSink } -// WithCallDepth returns a Logger that will offset the call stack by the -// specified number of frames when logging call site information, if possible. -// This is useful for users who have helper functions between the "real" call -// site and the actual calls to Logger methods. If depth is 0 the attribution -// should be to the direct caller of this function. If depth is 1 the -// attribution should skip 1 call frame, and so on. Successive calls to this -// are additive. +// CallStackHelperLogSink represents a Logger that knows how to climb +// the call stack to identify the original call site and can skip +// intermediate helper functions if they mark themselves as +// helper. Go's testing package uses that approach. // -// If the underlying log implementation supports the CallDepthLogger interface, -// the WithCallDepth method will be called and the result returned. If the -// implementation does not support CallDepthLogger, the original Logger will be -// returned. +// This is useful for users who have helper functions between the +// "real" call site and the actual calls to Logger methods. +// Implementations that log information about the call site (such as +// file, function, or line) would otherwise log information about the +// intermediate helper functions. // -// Callers which care about whether this was supported or not should test for -// CallDepthLogger support themselves. -func WithCallDepth(logger Logger, depth int) Logger { - if decorator, ok := logger.(CallDepthLogger); ok { - return decorator.WithCallDepth(depth) - } - return logger +// This is an optional interface and implementations are not required +// to support it. Implementations that choose to support this must not +// simply implement it as WithCallDepth(1), because +// Logger.WithCallStackHelper will call both methods if they are +// present. This should only be implemented for LogSinks that actually +// need it, as with testing.T. +type CallStackHelperLogSink interface { + // GetCallStackHelper returns a function that must be called + // to mark the direct caller as helper function when logging + // call site information. + GetCallStackHelper() func() +} + +// Marshaler is an optional interface that logged values may choose to +// implement. Loggers with structured output, such as JSON, should +// log the object return by the MarshalLog method instead of the +// original value. +type Marshaler interface { + // MarshalLog can be used to: + // - ensure that structs are not logged as strings when the original + // value has a String method: return a different type without a + // String method + // - select which fields of a complex type should get logged: + // return a simpler struct with fewer fields + // - log unexported fields: return a different struct + // with exported fields + // + // It may return any value of any type. + MarshalLog() interface{} } diff --git a/vendor/github.com/klauspost/compress/.gitattributes b/vendor/github.com/klauspost/compress/.gitattributes new file mode 100644 index 0000000000..402433593c --- /dev/null +++ b/vendor/github.com/klauspost/compress/.gitattributes @@ -0,0 +1,2 @@ +* -text +*.bin -text -diff diff --git a/vendor/github.com/klauspost/compress/.gitignore b/vendor/github.com/klauspost/compress/.gitignore new file mode 100644 index 0000000000..b35f8449bf --- /dev/null +++ b/vendor/github.com/klauspost/compress/.gitignore @@ -0,0 +1,25 @@ +# Compiled Object files, Static and Dynamic libs (Shared Objects) +*.o +*.a +*.so + +# Folders +_obj +_test + +# Architecture specific extensions/prefixes +*.[568vq] +[568vq].out + +*.cgo1.go +*.cgo2.c +_cgo_defun.c +_cgo_gotypes.go +_cgo_export.* + +_testmain.go + +*.exe +*.test +*.prof +/s2/cmd/_s2sx/sfx-exe diff --git a/vendor/github.com/klauspost/compress/.goreleaser.yml b/vendor/github.com/klauspost/compress/.goreleaser.yml new file mode 100644 index 0000000000..c9014ce1da --- /dev/null +++ b/vendor/github.com/klauspost/compress/.goreleaser.yml @@ -0,0 +1,137 @@ +# This is an example goreleaser.yaml file with some sane defaults. +# Make sure to check the documentation at http://goreleaser.com +before: + hooks: + - ./gen.sh + +builds: + - + id: "s2c" + binary: s2c + main: ./s2/cmd/s2c/main.go + flags: + - -trimpath + env: + - CGO_ENABLED=0 + goos: + - aix + - linux + - freebsd + - netbsd + - windows + - darwin + goarch: + - 386 + - amd64 + - arm + - arm64 + - ppc64 + - ppc64le + - mips64 + - mips64le + goarm: + - 7 + - + id: "s2d" + binary: s2d + main: ./s2/cmd/s2d/main.go + flags: + - -trimpath + env: + - CGO_ENABLED=0 + goos: + - aix + - linux + - freebsd + - netbsd + - windows + - darwin + goarch: + - 386 + - amd64 + - arm + - arm64 + - ppc64 + - ppc64le + - mips64 + - mips64le + goarm: + - 7 + - + id: "s2sx" + binary: s2sx + main: ./s2/cmd/_s2sx/main.go + flags: + - -modfile=s2sx.mod + - -trimpath + env: + - CGO_ENABLED=0 + goos: + - aix + - linux + - freebsd + - netbsd + - windows + - darwin + goarch: + - 386 + - amd64 + - arm + - arm64 + - ppc64 + - ppc64le + - mips64 + - mips64le + goarm: + - 7 + +archives: + - + id: s2-binaries + name_template: "s2-{{ .Os }}_{{ .Arch }}_{{ .Version }}" + replacements: + aix: AIX + darwin: OSX + linux: Linux + windows: Windows + 386: i386 + amd64: x86_64 + freebsd: FreeBSD + netbsd: NetBSD + format_overrides: + - goos: windows + format: zip + files: + - unpack/* + - s2/LICENSE + - s2/README.md +checksum: + name_template: 'checksums.txt' +snapshot: + name_template: "{{ .Tag }}-next" +changelog: + sort: asc + filters: + exclude: + - '^doc:' + - '^docs:' + - '^test:' + - '^tests:' + - '^Update\sREADME.md' + +nfpms: + - + file_name_template: "s2_package_{{ .Version }}_{{ .Os }}_{{ .Arch }}" + vendor: Klaus Post + homepage: https://github.com/klauspost/compress + maintainer: Klaus Post + description: S2 Compression Tool + license: BSD 3-Clause + formats: + - deb + - rpm + replacements: + darwin: Darwin + linux: Linux + freebsd: FreeBSD + amd64: x86_64 diff --git a/vendor/github.com/klauspost/compress/LICENSE b/vendor/github.com/klauspost/compress/LICENSE index 1eb75ef68e..87d5574777 100644 --- a/vendor/github.com/klauspost/compress/LICENSE +++ b/vendor/github.com/klauspost/compress/LICENSE @@ -26,3 +26,279 @@ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +------------------ + +Files: gzhttp/* + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2016-2017 The New York Times Company + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +------------------ + +Files: s2/cmd/internal/readahead/* + +The MIT License (MIT) + +Copyright (c) 2015 Klaus Post + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +--------------------- +Files: snappy/* +Files: internal/snapref/* + +Copyright (c) 2011 The Snappy-Go Authors. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +----------------- + +Files: s2/cmd/internal/filepathx/* + +Copyright 2016 The filepathx Authors + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/vendor/github.com/klauspost/compress/README.md b/vendor/github.com/klauspost/compress/README.md new file mode 100644 index 0000000000..3429879eb6 --- /dev/null +++ b/vendor/github.com/klauspost/compress/README.md @@ -0,0 +1,438 @@ +# compress + +This package provides various compression algorithms. + +* [zstandard](https://github.com/klauspost/compress/tree/master/zstd#zstd) compression and decompression in pure Go. +* [S2](https://github.com/klauspost/compress/tree/master/s2#s2-compression) is a high performance replacement for Snappy. +* Optimized [deflate](https://godoc.org/github.com/klauspost/compress/flate) packages which can be used as a dropin replacement for [gzip](https://godoc.org/github.com/klauspost/compress/gzip), [zip](https://godoc.org/github.com/klauspost/compress/zip) and [zlib](https://godoc.org/github.com/klauspost/compress/zlib). +* [snappy](https://github.com/klauspost/compress/tree/master/snappy) is a drop-in replacement for `github.com/golang/snappy` offering better compression and concurrent streams. +* [huff0](https://github.com/klauspost/compress/tree/master/huff0) and [FSE](https://github.com/klauspost/compress/tree/master/fse) implementations for raw entropy encoding. +* [gzhttp](https://github.com/klauspost/compress/tree/master/gzhttp) Provides client and server wrappers for handling gzipped requests efficiently. +* [pgzip](https://github.com/klauspost/pgzip) is a separate package that provides a very fast parallel gzip implementation. +* [fuzz package](https://github.com/klauspost/compress-fuzz) for fuzz testing all compressors/decompressors here. + +[![Go Reference](https://pkg.go.dev/badge/klauspost/compress.svg)](https://pkg.go.dev/github.com/klauspost/compress?tab=subdirectories) +[![Go](https://github.com/klauspost/compress/actions/workflows/go.yml/badge.svg)](https://github.com/klauspost/compress/actions/workflows/go.yml) +[![Sourcegraph Badge](https://sourcegraph.com/github.com/klauspost/compress/-/badge.svg)](https://sourcegraph.com/github.com/klauspost/compress?badge) + +# changelog + +* Aug 30, 2021 (v1.13.5) + * gz/zlib/flate: Alias stdlib errors [#425](https://github.com/klauspost/compress/pull/425) + * s2: Add block support to commandline tools [#413](https://github.com/klauspost/compress/pull/413) + * zstd: pooledZipWriter should return Writers to the same pool [#426](https://github.com/klauspost/compress/pull/426) + * Removed golang/snappy as external dependency for tests [#421](https://github.com/klauspost/compress/pull/421) + +* Aug 12, 2021 (v1.13.4) + * Add [snappy replacement package](https://github.com/klauspost/compress/tree/master/snappy). + * zstd: Fix incorrect encoding in "best" mode [#415](https://github.com/klauspost/compress/pull/415) + +* Aug 3, 2021 (v1.13.3) + * zstd: Improve Best compression [#404](https://github.com/klauspost/compress/pull/404) + * zstd: Fix WriteTo error forwarding [#411](https://github.com/klauspost/compress/pull/411) + * gzhttp: Return http.HandlerFunc instead of http.Handler. Unlikely breaking change. [#406](https://github.com/klauspost/compress/pull/406) + * s2sx: Fix max size error [#399](https://github.com/klauspost/compress/pull/399) + * zstd: Add optional stream content size on reset [#401](https://github.com/klauspost/compress/pull/401) + * zstd: use SpeedBestCompression for level >= 10 [#410](https://github.com/klauspost/compress/pull/410) + +* Jun 14, 2021 (v1.13.1) + * s2: Add full Snappy output support [#396](https://github.com/klauspost/compress/pull/396) + * zstd: Add configurable [Decoder window](https://pkg.go.dev/github.com/klauspost/compress/zstd#WithDecoderMaxWindow) size [#394](https://github.com/klauspost/compress/pull/394) + * gzhttp: Add header to skip compression [#389](https://github.com/klauspost/compress/pull/389) + * s2: Improve speed with bigger output margin [#395](https://github.com/klauspost/compress/pull/395) + +* Jun 3, 2021 (v1.13.0) + * Added [gzhttp](https://github.com/klauspost/compress/tree/master/gzhttp#gzip-handler) which allows wrapping HTTP servers and clients with GZIP compressors. + * zstd: Detect short invalid signatures [#382](https://github.com/klauspost/compress/pull/382) + * zstd: Spawn decoder goroutine only if needed. [#380](https://github.com/klauspost/compress/pull/380) + +* May 25, 2021 (v1.12.3) + * deflate: Better/faster Huffman encoding [#374](https://github.com/klauspost/compress/pull/374) + * deflate: Allocate less for history. [#375](https://github.com/klauspost/compress/pull/375) + * zstd: Forward read errors [#373](https://github.com/klauspost/compress/pull/373) + +* Apr 27, 2021 (v1.12.2) + * zstd: Improve better/best compression [#360](https://github.com/klauspost/compress/pull/360) [#364](https://github.com/klauspost/compress/pull/364) [#365](https://github.com/klauspost/compress/pull/365) + * zstd: Add helpers to compress/decompress zstd inside zip files [#363](https://github.com/klauspost/compress/pull/363) + * deflate: Improve level 5+6 compression [#367](https://github.com/klauspost/compress/pull/367) + * s2: Improve better/best compression [#358](https://github.com/klauspost/compress/pull/358) [#359](https://github.com/klauspost/compress/pull/358) + * s2: Load after checking src limit on amd64. [#362](https://github.com/klauspost/compress/pull/362) + * s2sx: Limit max executable size [#368](https://github.com/klauspost/compress/pull/368) + +* Apr 14, 2021 (v1.12.1) + * snappy package removed. Upstream added as dependency. + * s2: Better compression in "best" mode [#353](https://github.com/klauspost/compress/pull/353) + * s2sx: Add stdin input and detect pre-compressed from signature [#352](https://github.com/klauspost/compress/pull/352) + * s2c/s2d: Add http as possible input [#348](https://github.com/klauspost/compress/pull/348) + * s2c/s2d/s2sx: Always truncate when writing files [#352](https://github.com/klauspost/compress/pull/352) + * zstd: Reduce memory usage further when using [WithLowerEncoderMem](https://pkg.go.dev/github.com/klauspost/compress/zstd#WithLowerEncoderMem) [#346](https://github.com/klauspost/compress/pull/346) + * s2: Fix potential problem with amd64 assembly and profilers [#349](https://github.com/klauspost/compress/pull/349) + +
+ See changes prior to v1.12.1 + +* Mar 26, 2021 (v1.11.13) + * zstd: Big speedup on small dictionary encodes [#344](https://github.com/klauspost/compress/pull/344) [#345](https://github.com/klauspost/compress/pull/345) + * zstd: Add [WithLowerEncoderMem](https://pkg.go.dev/github.com/klauspost/compress/zstd#WithLowerEncoderMem) encoder option [#336](https://github.com/klauspost/compress/pull/336) + * deflate: Improve entropy compression [#338](https://github.com/klauspost/compress/pull/338) + * s2: Clean up and minor performance improvement in best [#341](https://github.com/klauspost/compress/pull/341) + +* Mar 5, 2021 (v1.11.12) + * s2: Add `s2sx` binary that creates [self extracting archives](https://github.com/klauspost/compress/tree/master/s2#s2sx-self-extracting-archives). + * s2: Speed up decompression on non-assembly platforms [#328](https://github.com/klauspost/compress/pull/328) + +* Mar 1, 2021 (v1.11.9) + * s2: Add ARM64 decompression assembly. Around 2x output speed. [#324](https://github.com/klauspost/compress/pull/324) + * s2: Improve "better" speed and efficiency. [#325](https://github.com/klauspost/compress/pull/325) + * s2: Fix binaries. + +* Feb 25, 2021 (v1.11.8) + * s2: Fixed occational out-of-bounds write on amd64. Upgrade recommended. + * s2: Add AMD64 assembly for better mode. 25-50% faster. [#315](https://github.com/klauspost/compress/pull/315) + * s2: Less upfront decoder allocation. [#322](https://github.com/klauspost/compress/pull/322) + * zstd: Faster "compression" of incompressible data. [#314](https://github.com/klauspost/compress/pull/314) + * zip: Fix zip64 headers. [#313](https://github.com/klauspost/compress/pull/313) + +* Jan 14, 2021 (v1.11.7) + * Use Bytes() interface to get bytes across packages. [#309](https://github.com/klauspost/compress/pull/309) + * s2: Add 'best' compression option. [#310](https://github.com/klauspost/compress/pull/310) + * s2: Add ReaderMaxBlockSize, changes `s2.NewReader` signature to include varargs. [#311](https://github.com/klauspost/compress/pull/311) + * s2: Fix crash on small better buffers. [#308](https://github.com/klauspost/compress/pull/308) + * s2: Clean up decoder. [#312](https://github.com/klauspost/compress/pull/312) + +* Jan 7, 2021 (v1.11.6) + * zstd: Make decoder allocations smaller [#306](https://github.com/klauspost/compress/pull/306) + * zstd: Free Decoder resources when Reset is called with a nil io.Reader [#305](https://github.com/klauspost/compress/pull/305) + +* Dec 20, 2020 (v1.11.4) + * zstd: Add Best compression mode [#304](https://github.com/klauspost/compress/pull/304) + * Add header decoder [#299](https://github.com/klauspost/compress/pull/299) + * s2: Add uncompressed stream option [#297](https://github.com/klauspost/compress/pull/297) + * Simplify/speed up small blocks with known max size. [#300](https://github.com/klauspost/compress/pull/300) + * zstd: Always reset literal dict encoder [#303](https://github.com/klauspost/compress/pull/303) + +* Nov 15, 2020 (v1.11.3) + * inflate: 10-15% faster decompression [#293](https://github.com/klauspost/compress/pull/293) + * zstd: Tweak DecodeAll default allocation [#295](https://github.com/klauspost/compress/pull/295) + +* Oct 11, 2020 (v1.11.2) + * s2: Fix out of bounds read in "better" block compression [#291](https://github.com/klauspost/compress/pull/291) + +* Oct 1, 2020 (v1.11.1) + * zstd: Set allLitEntropy true in default configuration [#286](https://github.com/klauspost/compress/pull/286) + +* Sept 8, 2020 (v1.11.0) + * zstd: Add experimental compression [dictionaries](https://github.com/klauspost/compress/tree/master/zstd#dictionaries) [#281](https://github.com/klauspost/compress/pull/281) + * zstd: Fix mixed Write and ReadFrom calls [#282](https://github.com/klauspost/compress/pull/282) + * inflate/gz: Limit variable shifts, ~5% faster decompression [#274](https://github.com/klauspost/compress/pull/274) +
+ +
+ See changes prior to v1.11.0 + +* July 8, 2020 (v1.10.11) + * zstd: Fix extra block when compressing with ReadFrom. [#278](https://github.com/klauspost/compress/pull/278) + * huff0: Also populate compression table when reading decoding table. [#275](https://github.com/klauspost/compress/pull/275) + +* June 23, 2020 (v1.10.10) + * zstd: Skip entropy compression in fastest mode when no matches. [#270](https://github.com/klauspost/compress/pull/270) + +* June 16, 2020 (v1.10.9): + * zstd: API change for specifying dictionaries. See [#268](https://github.com/klauspost/compress/pull/268) + * zip: update CreateHeaderRaw to handle zip64 fields. [#266](https://github.com/klauspost/compress/pull/266) + * Fuzzit tests removed. The service has been purchased and is no longer available. + +* June 5, 2020 (v1.10.8): + * 1.15x faster zstd block decompression. [#265](https://github.com/klauspost/compress/pull/265) + +* June 1, 2020 (v1.10.7): + * Added zstd decompression [dictionary support](https://github.com/klauspost/compress/tree/master/zstd#dictionaries) + * Increase zstd decompression speed up to 1.19x. [#259](https://github.com/klauspost/compress/pull/259) + * Remove internal reset call in zstd compression and reduce allocations. [#263](https://github.com/klauspost/compress/pull/263) + +* May 21, 2020: (v1.10.6) + * zstd: Reduce allocations while decoding. [#258](https://github.com/klauspost/compress/pull/258), [#252](https://github.com/klauspost/compress/pull/252) + * zstd: Stricter decompression checks. + +* April 12, 2020: (v1.10.5) + * s2-commands: Flush output when receiving SIGINT. [#239](https://github.com/klauspost/compress/pull/239) + +* Apr 8, 2020: (v1.10.4) + * zstd: Minor/special case optimizations. [#251](https://github.com/klauspost/compress/pull/251), [#250](https://github.com/klauspost/compress/pull/250), [#249](https://github.com/klauspost/compress/pull/249), [#247](https://github.com/klauspost/compress/pull/247) +* Mar 11, 2020: (v1.10.3) + * s2: Use S2 encoder in pure Go mode for Snappy output as well. [#245](https://github.com/klauspost/compress/pull/245) + * s2: Fix pure Go block encoder. [#244](https://github.com/klauspost/compress/pull/244) + * zstd: Added "better compression" mode. [#240](https://github.com/klauspost/compress/pull/240) + * zstd: Improve speed of fastest compression mode by 5-10% [#241](https://github.com/klauspost/compress/pull/241) + * zstd: Skip creating encoders when not needed. [#238](https://github.com/klauspost/compress/pull/238) + +* Feb 27, 2020: (v1.10.2) + * Close to 50% speedup in inflate (gzip/zip decompression). [#236](https://github.com/klauspost/compress/pull/236) [#234](https://github.com/klauspost/compress/pull/234) [#232](https://github.com/klauspost/compress/pull/232) + * Reduce deflate level 1-6 memory usage up to 59%. [#227](https://github.com/klauspost/compress/pull/227) + +* Feb 18, 2020: (v1.10.1) + * Fix zstd crash when resetting multiple times without sending data. [#226](https://github.com/klauspost/compress/pull/226) + * deflate: Fix dictionary use on level 1-6. [#224](https://github.com/klauspost/compress/pull/224) + * Remove deflate writer reference when closing. [#224](https://github.com/klauspost/compress/pull/224) + +* Feb 4, 2020: (v1.10.0) + * Add optional dictionary to [stateless deflate](https://pkg.go.dev/github.com/klauspost/compress/flate?tab=doc#StatelessDeflate). Breaking change, send `nil` for previous behaviour. [#216](https://github.com/klauspost/compress/pull/216) + * Fix buffer overflow on repeated small block deflate. [#218](https://github.com/klauspost/compress/pull/218) + * Allow copying content from an existing ZIP file without decompressing+compressing. [#214](https://github.com/klauspost/compress/pull/214) + * Added [S2](https://github.com/klauspost/compress/tree/master/s2#s2-compression) AMD64 assembler and various optimizations. Stream speed >10GB/s. [#186](https://github.com/klauspost/compress/pull/186) + +
+ +
+ See changes prior to v1.10.0 + +* Jan 20,2020 (v1.9.8) Optimize gzip/deflate with better size estimates and faster table generation. [#207](https://github.com/klauspost/compress/pull/207) by [luyu6056](https://github.com/luyu6056), [#206](https://github.com/klauspost/compress/pull/206). +* Jan 11, 2020: S2 Encode/Decode will use provided buffer if capacity is big enough. [#204](https://github.com/klauspost/compress/pull/204) +* Jan 5, 2020: (v1.9.7) Fix another zstd regression in v1.9.5 - v1.9.6 removed. +* Jan 4, 2020: (v1.9.6) Regression in v1.9.5 fixed causing corrupt zstd encodes in rare cases. +* Jan 4, 2020: Faster IO in [s2c + s2d commandline tools](https://github.com/klauspost/compress/tree/master/s2#commandline-tools) compression/decompression. [#192](https://github.com/klauspost/compress/pull/192) +* Dec 29, 2019: Removed v1.9.5 since fuzz tests showed a compatibility problem with the reference zstandard decoder. +* Dec 29, 2019: (v1.9.5) zstd: 10-20% faster block compression. [#199](https://github.com/klauspost/compress/pull/199) +* Dec 29, 2019: [zip](https://godoc.org/github.com/klauspost/compress/zip) package updated with latest Go features +* Dec 29, 2019: zstd: Single segment flag condintions tweaked. [#197](https://github.com/klauspost/compress/pull/197) +* Dec 18, 2019: s2: Faster compression when ReadFrom is used. [#198](https://github.com/klauspost/compress/pull/198) +* Dec 10, 2019: s2: Fix repeat length output when just above at 16MB limit. +* Dec 10, 2019: zstd: Add function to get decoder as io.ReadCloser. [#191](https://github.com/klauspost/compress/pull/191) +* Dec 3, 2019: (v1.9.4) S2: limit max repeat length. [#188](https://github.com/klauspost/compress/pull/188) +* Dec 3, 2019: Add [WithNoEntropyCompression](https://godoc.org/github.com/klauspost/compress/zstd#WithNoEntropyCompression) to zstd [#187](https://github.com/klauspost/compress/pull/187) +* Dec 3, 2019: Reduce memory use for tests. Check for leaked goroutines. +* Nov 28, 2019 (v1.9.3) Less allocations in stateless deflate. +* Nov 28, 2019: 5-20% Faster huff0 decode. Impacts zstd as well. [#184](https://github.com/klauspost/compress/pull/184) +* Nov 12, 2019 (v1.9.2) Added [Stateless Compression](#stateless-compression) for gzip/deflate. +* Nov 12, 2019: Fixed zstd decompression of large single blocks. [#180](https://github.com/klauspost/compress/pull/180) +* Nov 11, 2019: Set default [s2c](https://github.com/klauspost/compress/tree/master/s2#commandline-tools) block size to 4MB. +* Nov 11, 2019: Reduce inflate memory use by 1KB. +* Nov 10, 2019: Less allocations in deflate bit writer. +* Nov 10, 2019: Fix inconsistent error returned by zstd decoder. +* Oct 28, 2019 (v1.9.1) ztsd: Fix crash when compressing blocks. [#174](https://github.com/klauspost/compress/pull/174) +* Oct 24, 2019 (v1.9.0) zstd: Fix rare data corruption [#173](https://github.com/klauspost/compress/pull/173) +* Oct 24, 2019 zstd: Fix huff0 out of buffer write [#171](https://github.com/klauspost/compress/pull/171) and always return errors [#172](https://github.com/klauspost/compress/pull/172) +* Oct 10, 2019: Big deflate rewrite, 30-40% faster with better compression [#105](https://github.com/klauspost/compress/pull/105) + +
+ +
+ See changes prior to v1.9.0 + +* Oct 10, 2019: (v1.8.6) zstd: Allow partial reads to get flushed data. [#169](https://github.com/klauspost/compress/pull/169) +* Oct 3, 2019: Fix inconsistent results on broken zstd streams. +* Sep 25, 2019: Added `-rm` (remove source files) and `-q` (no output except errors) to `s2c` and `s2d` [commands](https://github.com/klauspost/compress/tree/master/s2#commandline-tools) +* Sep 16, 2019: (v1.8.4) Add `s2c` and `s2d` [commandline tools](https://github.com/klauspost/compress/tree/master/s2#commandline-tools). +* Sep 10, 2019: (v1.8.3) Fix s2 decoder [Skip](https://godoc.org/github.com/klauspost/compress/s2#Reader.Skip). +* Sep 7, 2019: zstd: Added [WithWindowSize](https://godoc.org/github.com/klauspost/compress/zstd#WithWindowSize), contributed by [ianwilkes](https://github.com/ianwilkes). +* Sep 5, 2019: (v1.8.2) Add [WithZeroFrames](https://godoc.org/github.com/klauspost/compress/zstd#WithZeroFrames) which adds full zero payload block encoding option. +* Sep 5, 2019: Lazy initialization of zstandard predefined en/decoder tables. +* Aug 26, 2019: (v1.8.1) S2: 1-2% compression increase in "better" compression mode. +* Aug 26, 2019: zstd: Check maximum size of Huffman 1X compressed literals while decoding. +* Aug 24, 2019: (v1.8.0) Added [S2 compression](https://github.com/klauspost/compress/tree/master/s2#s2-compression), a high performance replacement for Snappy. +* Aug 21, 2019: (v1.7.6) Fixed minor issues found by fuzzer. One could lead to zstd not decompressing. +* Aug 18, 2019: Add [fuzzit](https://fuzzit.dev/) continuous fuzzing. +* Aug 14, 2019: zstd: Skip incompressible data 2x faster. [#147](https://github.com/klauspost/compress/pull/147) +* Aug 4, 2019 (v1.7.5): Better literal compression. [#146](https://github.com/klauspost/compress/pull/146) +* Aug 4, 2019: Faster zstd compression. [#143](https://github.com/klauspost/compress/pull/143) [#144](https://github.com/klauspost/compress/pull/144) +* Aug 4, 2019: Faster zstd decompression. [#145](https://github.com/klauspost/compress/pull/145) [#143](https://github.com/klauspost/compress/pull/143) [#142](https://github.com/klauspost/compress/pull/142) +* July 15, 2019 (v1.7.4): Fix double EOF block in rare cases on zstd encoder. +* July 15, 2019 (v1.7.3): Minor speedup/compression increase in default zstd encoder. +* July 14, 2019: zstd decoder: Fix decompression error on multiple uses with mixed content. +* July 7, 2019 (v1.7.2): Snappy update, zstd decoder potential race fix. +* June 17, 2019: zstd decompression bugfix. +* June 17, 2019: fix 32 bit builds. +* June 17, 2019: Easier use in modules (less dependencies). +* June 9, 2019: New stronger "default" [zstd](https://github.com/klauspost/compress/tree/master/zstd#zstd) compression mode. Matches zstd default compression ratio. +* June 5, 2019: 20-40% throughput in [zstandard](https://github.com/klauspost/compress/tree/master/zstd#zstd) compression and better compression. +* June 5, 2019: deflate/gzip compression: Reduce memory usage of lower compression levels. +* June 2, 2019: Added [zstandard](https://github.com/klauspost/compress/tree/master/zstd#zstd) compression! +* May 25, 2019: deflate/gzip: 10% faster bit writer, mostly visible in lower levels. +* Apr 22, 2019: [zstd](https://github.com/klauspost/compress/tree/master/zstd#zstd) decompression added. +* Aug 1, 2018: Added [huff0 README](https://github.com/klauspost/compress/tree/master/huff0#huff0-entropy-compression). +* Jul 8, 2018: Added [Performance Update 2018](#performance-update-2018) below. +* Jun 23, 2018: Merged [Go 1.11 inflate optimizations](https://go-review.googlesource.com/c/go/+/102235). Go 1.9 is now required. Backwards compatible version tagged with [v1.3.0](https://github.com/klauspost/compress/releases/tag/v1.3.0). +* Apr 2, 2018: Added [huff0](https://godoc.org/github.com/klauspost/compress/huff0) en/decoder. Experimental for now, API may change. +* Mar 4, 2018: Added [FSE Entropy](https://godoc.org/github.com/klauspost/compress/fse) en/decoder. Experimental for now, API may change. +* Nov 3, 2017: Add compression [Estimate](https://godoc.org/github.com/klauspost/compress#Estimate) function. +* May 28, 2017: Reduce allocations when resetting decoder. +* Apr 02, 2017: Change back to official crc32, since changes were merged in Go 1.7. +* Jan 14, 2017: Reduce stack pressure due to array copies. See [Issue #18625](https://github.com/golang/go/issues/18625). +* Oct 25, 2016: Level 2-4 have been rewritten and now offers significantly better performance than before. +* Oct 20, 2016: Port zlib changes from Go 1.7 to fix zlib writer issue. Please update. +* Oct 16, 2016: Go 1.7 changes merged. Apples to apples this package is a few percent faster, but has a significantly better balance between speed and compression per level. +* Mar 24, 2016: Always attempt Huffman encoding on level 4-7. This improves base 64 encoded data compression. +* Mar 24, 2016: Small speedup for level 1-3. +* Feb 19, 2016: Faster bit writer, level -2 is 15% faster, level 1 is 4% faster. +* Feb 19, 2016: Handle small payloads faster in level 1-3. +* Feb 19, 2016: Added faster level 2 + 3 compression modes. +* Feb 19, 2016: [Rebalanced compression levels](https://blog.klauspost.com/rebalancing-deflate-compression-levels/), so there is a more even progresssion in terms of compression. New default level is 5. +* Feb 14, 2016: Snappy: Merge upstream changes. +* Feb 14, 2016: Snappy: Fix aggressive skipping. +* Feb 14, 2016: Snappy: Update benchmark. +* Feb 13, 2016: Deflate: Fixed assembler problem that could lead to sub-optimal compression. +* Feb 12, 2016: Snappy: Added AMD64 SSE 4.2 optimizations to matching, which makes easy to compress material run faster. Typical speedup is around 25%. +* Feb 9, 2016: Added Snappy package fork. This version is 5-7% faster, much more on hard to compress content. +* Jan 30, 2016: Optimize level 1 to 3 by not considering static dictionary or storing uncompressed. ~4-5% speedup. +* Jan 16, 2016: Optimization on deflate level 1,2,3 compression. +* Jan 8 2016: Merge [CL 18317](https://go-review.googlesource.com/#/c/18317): fix reading, writing of zip64 archives. +* Dec 8 2015: Make level 1 and -2 deterministic even if write size differs. +* Dec 8 2015: Split encoding functions, so hashing and matching can potentially be inlined. 1-3% faster on AMD64. 5% faster on other platforms. +* Dec 8 2015: Fixed rare [one byte out-of bounds read](https://github.com/klauspost/compress/issues/20). Please update! +* Nov 23 2015: Optimization on token writer. ~2-4% faster. Contributed by [@dsnet](https://github.com/dsnet). +* Nov 20 2015: Small optimization to bit writer on 64 bit systems. +* Nov 17 2015: Fixed out-of-bound errors if the underlying Writer returned an error. See [#15](https://github.com/klauspost/compress/issues/15). +* Nov 12 2015: Added [io.WriterTo](https://golang.org/pkg/io/#WriterTo) support to gzip/inflate. +* Nov 11 2015: Merged [CL 16669](https://go-review.googlesource.com/#/c/16669/4): archive/zip: enable overriding (de)compressors per file +* Oct 15 2015: Added skipping on uncompressible data. Random data speed up >5x. + +
+ +# deflate usage + +* [High Throughput Benchmark](http://blog.klauspost.com/go-gzipdeflate-benchmarks/). +* [Small Payload/Webserver Benchmarks](http://blog.klauspost.com/gzip-performance-for-go-webservers/). +* [Linear Time Compression](http://blog.klauspost.com/constant-time-gzipzip-compression/). +* [Re-balancing Deflate Compression Levels](https://blog.klauspost.com/rebalancing-deflate-compression-levels/) + +The packages are drop-in replacements for standard libraries. Simply replace the import path to use them: + +| old import | new import | Documentation +|--------------------|-----------------------------------------|--------------------| +| `compress/gzip` | `github.com/klauspost/compress/gzip` | [gzip](https://pkg.go.dev/github.com/klauspost/compress/gzip?tab=doc) +| `compress/zlib` | `github.com/klauspost/compress/zlib` | [zlib](https://pkg.go.dev/github.com/klauspost/compress/zlib?tab=doc) +| `archive/zip` | `github.com/klauspost/compress/zip` | [zip](https://pkg.go.dev/github.com/klauspost/compress/zip?tab=doc) +| `compress/flate` | `github.com/klauspost/compress/flate` | [flate](https://pkg.go.dev/github.com/klauspost/compress/flate?tab=doc) + +* Optimized [deflate](https://godoc.org/github.com/klauspost/compress/flate) packages which can be used as a dropin replacement for [gzip](https://godoc.org/github.com/klauspost/compress/gzip), [zip](https://godoc.org/github.com/klauspost/compress/zip) and [zlib](https://godoc.org/github.com/klauspost/compress/zlib). + +You may also be interested in [pgzip](https://github.com/klauspost/pgzip), which is a drop in replacement for gzip, which support multithreaded compression on big files and the optimized [crc32](https://github.com/klauspost/crc32) package used by these packages. + +The packages contains the same as the standard library, so you can use the godoc for that: [gzip](http://golang.org/pkg/compress/gzip/), [zip](http://golang.org/pkg/archive/zip/), [zlib](http://golang.org/pkg/compress/zlib/), [flate](http://golang.org/pkg/compress/flate/). + +Currently there is only minor speedup on decompression (mostly CRC32 calculation). + +Memory usage is typically 1MB for a Writer. stdlib is in the same range. +If you expect to have a lot of concurrently allocated Writers consider using +the stateless compress described below. + +# Stateless compression + +This package offers stateless compression as a special option for gzip/deflate. +It will do compression but without maintaining any state between Write calls. + +This means there will be no memory kept between Write calls, but compression and speed will be suboptimal. + +This is only relevant in cases where you expect to run many thousands of compressors concurrently, +but with very little activity. This is *not* intended for regular web servers serving individual requests. + +Because of this, the size of actual Write calls will affect output size. + +In gzip, specify level `-3` / `gzip.StatelessCompression` to enable. + +For direct deflate use, NewStatelessWriter and StatelessDeflate are available. See [documentation](https://godoc.org/github.com/klauspost/compress/flate#NewStatelessWriter) + +A `bufio.Writer` can of course be used to control write sizes. For example, to use a 4KB buffer: + +``` + // replace 'ioutil.Discard' with your output. + gzw, err := gzip.NewWriterLevel(ioutil.Discard, gzip.StatelessCompression) + if err != nil { + return err + } + defer gzw.Close() + + w := bufio.NewWriterSize(gzw, 4096) + defer w.Flush() + + // Write to 'w' +``` + +This will only use up to 4KB in memory when the writer is idle. + +Compression is almost always worse than the fastest compression level +and each write will allocate (a little) memory. + +# Performance Update 2018 + +It has been a while since we have been looking at the speed of this package compared to the standard library, so I thought I would re-do my tests and give some overall recommendations based on the current state. All benchmarks have been performed with Go 1.10 on my Desktop Intel(R) Core(TM) i7-2600 CPU @3.40GHz. Since I last ran the tests, I have gotten more RAM, which means tests with big files are no longer limited by my SSD. + +The raw results are in my [updated spreadsheet](https://docs.google.com/spreadsheets/d/1nuNE2nPfuINCZJRMt6wFWhKpToF95I47XjSsc-1rbPQ/edit?usp=sharing). Due to cgo changes and upstream updates i could not get the cgo version of gzip to compile. Instead I included the [zstd](https://github.com/datadog/zstd) cgo implementation. If I get cgo gzip to work again, I might replace the results in the sheet. + +The columns to take note of are: *MB/s* - the throughput. *Reduction* - the data size reduction in percent of the original. *Rel Speed* relative speed compared to the standard library at the same level. *Smaller* - how many percent smaller is the compressed output compared to stdlib. Negative means the output was bigger. *Loss* means the loss (or gain) in compression as a percentage difference of the input. + +The `gzstd` (standard library gzip) and `gzkp` (this package gzip) only uses one CPU core. [`pgzip`](https://github.com/klauspost/pgzip), [`bgzf`](https://github.com/biogo/hts/tree/master/bgzf) uses all 4 cores. [`zstd`](https://github.com/DataDog/zstd) uses one core, and is a beast (but not Go, yet). + + +## Overall differences. + +There appears to be a roughly 5-10% speed advantage over the standard library when comparing at similar compression levels. + +The biggest difference you will see is the result of [re-balancing](https://blog.klauspost.com/rebalancing-deflate-compression-levels/) the compression levels. I wanted by library to give a smoother transition between the compression levels than the standard library. + +This package attempts to provide a more smooth transition, where "1" is taking a lot of shortcuts, "5" is the reasonable trade-off and "9" is the "give me the best compression", and the values in between gives something reasonable in between. The standard library has big differences in levels 1-4, but levels 5-9 having no significant gains - often spending a lot more time than can be justified by the achieved compression. + +There are links to all the test data in the [spreadsheet](https://docs.google.com/spreadsheets/d/1nuNE2nPfuINCZJRMt6wFWhKpToF95I47XjSsc-1rbPQ/edit?usp=sharing) in the top left field on each tab. + +## Web Content + +This test set aims to emulate typical use in a web server. The test-set is 4GB data in 53k files, and is a mixture of (mostly) HTML, JS, CSS. + +Since level 1 and 9 are close to being the same code, they are quite close. But looking at the levels in-between the differences are quite big. + +Looking at level 6, this package is 88% faster, but will output about 6% more data. For a web server, this means you can serve 88% more data, but have to pay for 6% more bandwidth. You can draw your own conclusions on what would be the most expensive for your case. + +## Object files + +This test is for typical data files stored on a server. In this case it is a collection of Go precompiled objects. They are very compressible. + +The picture is similar to the web content, but with small differences since this is very compressible. Levels 2-3 offer good speed, but is sacrificing quite a bit of compression. + +The standard library seems suboptimal on level 3 and 4 - offering both worse compression and speed than level 6 & 7 of this package respectively. + +## Highly Compressible File + +This is a JSON file with very high redundancy. The reduction starts at 95% on level 1, so in real life terms we are dealing with something like a highly redundant stream of data, etc. + +It is definitely visible that we are dealing with specialized content here, so the results are very scattered. This package does not do very well at levels 1-4, but picks up significantly at level 5 and levels 7 and 8 offering great speed for the achieved compression. + +So if you know you content is extremely compressible you might want to go slightly higher than the defaults. The standard library has a huge gap between levels 3 and 4 in terms of speed (2.75x slowdown), so it offers little "middle ground". + +## Medium-High Compressible + +This is a pretty common test corpus: [enwik9](http://mattmahoney.net/dc/textdata.html). It contains the first 10^9 bytes of the English Wikipedia dump on Mar. 3, 2006. This is a very good test of typical text based compression and more data heavy streams. + +We see a similar picture here as in "Web Content". On equal levels some compression is sacrificed for more speed. Level 5 seems to be the best trade-off between speed and size, beating stdlib level 3 in both. + +## Medium Compressible + +I will combine two test sets, one [10GB file set](http://mattmahoney.net/dc/10gb.html) and a VM disk image (~8GB). Both contain different data types and represent a typical backup scenario. + +The most notable thing is how quickly the standard library drops to very low compression speeds around level 5-6 without any big gains in compression. Since this type of data is fairly common, this does not seem like good behavior. + + +## Un-compressible Content + +This is mainly a test of how good the algorithms are at detecting un-compressible input. The standard library only offers this feature with very conservative settings at level 1. Obviously there is no reason for the algorithms to try to compress input that cannot be compressed. The only downside is that it might skip some compressible data on false detections. + + +## Huffman only compression + +This compression library adds a special compression level, named `HuffmanOnly`, which allows near linear time compression. This is done by completely disabling matching of previous data, and only reduce the number of bits to represent each character. + +This means that often used characters, like 'e' and ' ' (space) in text use the fewest bits to represent, and rare characters like '¤' takes more bits to represent. For more information see [wikipedia](https://en.wikipedia.org/wiki/Huffman_coding) or this nice [video](https://youtu.be/ZdooBTdW5bM). + +Since this type of compression has much less variance, the compression speed is mostly unaffected by the input data, and is usually more than *180MB/s* for a single core. + +The downside is that the compression ratio is usually considerably worse than even the fastest conventional compression. The compression ratio can never be better than 8:1 (12.5%). + +The linear time compression can be used as a "better than nothing" mode, where you cannot risk the encoder to slow down on some content. For comparison, the size of the "Twain" text is *233460 bytes* (+29% vs. level 1) and encode speed is 144MB/s (4.5x level 1). So in this case you trade a 30% size increase for a 4 times speedup. + +For more information see my blog post on [Fast Linear Time Compression](http://blog.klauspost.com/constant-time-gzipzip-compression/). + +This is implemented on Go 1.7 as "Huffman Only" mode, though not exposed for gzip. + + +# license + +This code is licensed under the same conditions as the original Go code. See LICENSE file. diff --git a/vendor/github.com/klauspost/compress/compressible.go b/vendor/github.com/klauspost/compress/compressible.go new file mode 100644 index 0000000000..ea5a692d51 --- /dev/null +++ b/vendor/github.com/klauspost/compress/compressible.go @@ -0,0 +1,85 @@ +package compress + +import "math" + +// Estimate returns a normalized compressibility estimate of block b. +// Values close to zero are likely uncompressible. +// Values above 0.1 are likely to be compressible. +// Values above 0.5 are very compressible. +// Very small lengths will return 0. +func Estimate(b []byte) float64 { + if len(b) < 16 { + return 0 + } + + // Correctly predicted order 1 + hits := 0 + lastMatch := false + var o1 [256]byte + var hist [256]int + c1 := byte(0) + for _, c := range b { + if c == o1[c1] { + // We only count a hit if there was two correct predictions in a row. + if lastMatch { + hits++ + } + lastMatch = true + } else { + lastMatch = false + } + o1[c1] = c + c1 = c + hist[c]++ + } + + // Use x^0.6 to give better spread + prediction := math.Pow(float64(hits)/float64(len(b)), 0.6) + + // Calculate histogram distribution + variance := float64(0) + avg := float64(len(b)) / 256 + + for _, v := range hist { + Δ := float64(v) - avg + variance += Δ * Δ + } + + stddev := math.Sqrt(float64(variance)) / float64(len(b)) + exp := math.Sqrt(1 / float64(len(b))) + + // Subtract expected stddev + stddev -= exp + if stddev < 0 { + stddev = 0 + } + stddev *= 1 + exp + + // Use x^0.4 to give better spread + entropy := math.Pow(stddev, 0.4) + + // 50/50 weight between prediction and histogram distribution + return math.Pow((prediction+entropy)/2, 0.9) +} + +// ShannonEntropyBits returns the number of bits minimum required to represent +// an entropy encoding of the input bytes. +// https://en.wiktionary.org/wiki/Shannon_entropy +func ShannonEntropyBits(b []byte) int { + if len(b) == 0 { + return 0 + } + var hist [256]int + for _, c := range b { + hist[c]++ + } + shannon := float64(0) + invTotal := 1.0 / float64(len(b)) + for _, v := range hist[:] { + if v > 0 { + n := float64(v) + shannon += math.Ceil(-math.Log2(n*invTotal) * n) + } + } + return int(math.Ceil(shannon)) +} diff --git a/vendor/github.com/klauspost/compress/gen.sh b/vendor/github.com/klauspost/compress/gen.sh new file mode 100644 index 0000000000..aff942205f --- /dev/null +++ b/vendor/github.com/klauspost/compress/gen.sh @@ -0,0 +1,4 @@ +#!/bin/sh + +cd s2/cmd/_s2sx/ || exit 1 +go generate . diff --git a/vendor/github.com/klauspost/compress/go.mod b/vendor/github.com/klauspost/compress/go.mod new file mode 100644 index 0000000000..5aa64a436a --- /dev/null +++ b/vendor/github.com/klauspost/compress/go.mod @@ -0,0 +1,3 @@ +module github.com/klauspost/compress + +go 1.15 diff --git a/vendor/github.com/klauspost/compress/go.sum b/vendor/github.com/klauspost/compress/go.sum new file mode 100644 index 0000000000..e69de29bb2 diff --git a/vendor/github.com/klauspost/compress/huff0/compress.go b/vendor/github.com/klauspost/compress/huff0/compress.go index 0823c928ce..8323dc0538 100644 --- a/vendor/github.com/klauspost/compress/huff0/compress.go +++ b/vendor/github.com/klauspost/compress/huff0/compress.go @@ -161,6 +161,70 @@ func compress(in []byte, s *Scratch, compressor func(src []byte) ([]byte, error) return s.Out, false, nil } +// EstimateSizes will estimate the data sizes +func EstimateSizes(in []byte, s *Scratch) (tableSz, dataSz, reuseSz int, err error) { + s, err = s.prepare(in) + if err != nil { + return 0, 0, 0, err + } + + // Create histogram, if none was provided. + tableSz, dataSz, reuseSz = -1, -1, -1 + maxCount := s.maxCount + var canReuse = false + if maxCount == 0 { + maxCount, canReuse = s.countSimple(in) + } else { + canReuse = s.canUseTable(s.prevTable) + } + + // We want the output size to be less than this: + wantSize := len(in) + if s.WantLogLess > 0 { + wantSize -= wantSize >> s.WantLogLess + } + + // Reset for next run. + s.clearCount = true + s.maxCount = 0 + if maxCount >= len(in) { + if maxCount > len(in) { + return 0, 0, 0, fmt.Errorf("maxCount (%d) > length (%d)", maxCount, len(in)) + } + if len(in) == 1 { + return 0, 0, 0, ErrIncompressible + } + // One symbol, use RLE + return 0, 0, 0, ErrUseRLE + } + if maxCount == 1 || maxCount < (len(in)>>7) { + // Each symbol present maximum once or too well distributed. + return 0, 0, 0, ErrIncompressible + } + + // Calculate new table. + err = s.buildCTable() + if err != nil { + return 0, 0, 0, err + } + + if false && !s.canUseTable(s.cTable) { + panic("invalid table generated") + } + + tableSz, err = s.cTable.estTableSize(s) + if err != nil { + return 0, 0, 0, err + } + if canReuse { + reuseSz = s.prevTable.estimateSize(s.count[:s.symbolLen]) + } + dataSz = s.cTable.estimateSize(s.count[:s.symbolLen]) + + // Restore + return tableSz, dataSz, reuseSz, nil +} + func (s *Scratch) compress1X(src []byte) ([]byte, error) { return s.compress1xDo(s.Out, src) } diff --git a/vendor/github.com/klauspost/compress/huff0/decompress.go b/vendor/github.com/klauspost/compress/huff0/decompress.go index 41703bba4d..9b7cc8e97b 100644 --- a/vendor/github.com/klauspost/compress/huff0/decompress.go +++ b/vendor/github.com/klauspost/compress/huff0/decompress.go @@ -344,35 +344,241 @@ func (d *Decoder) decompress1X8Bit(dst, src []byte) ([]byte, error) { var buf [256]byte var off uint8 - shift := (8 - d.actualTableLog) & 7 - - //fmt.Printf("mask: %b, tl:%d\n", mask, d.actualTableLog) - for br.off >= 4 { - br.fillFast() - v := dt[br.peekByteFast()>>shift] - br.advance(uint8(v.entry)) - buf[off+0] = uint8(v.entry >> 8) - - v = dt[br.peekByteFast()>>shift] - br.advance(uint8(v.entry)) - buf[off+1] = uint8(v.entry >> 8) - - v = dt[br.peekByteFast()>>shift] - br.advance(uint8(v.entry)) - buf[off+2] = uint8(v.entry >> 8) - - v = dt[br.peekByteFast()>>shift] - br.advance(uint8(v.entry)) - buf[off+3] = uint8(v.entry >> 8) - - off += 4 - if off == 0 { - if len(dst)+256 > maxDecodedSize { - br.close() - return nil, ErrMaxDecodedSizeExceeded + switch d.actualTableLog { + case 8: + const shift = 8 - 8 + for br.off >= 4 { + br.fillFast() + v := dt[uint8(br.value>>(56+shift))] + br.advance(uint8(v.entry)) + buf[off+0] = uint8(v.entry >> 8) + + v = dt[uint8(br.value>>(56+shift))] + br.advance(uint8(v.entry)) + buf[off+1] = uint8(v.entry >> 8) + + v = dt[uint8(br.value>>(56+shift))] + br.advance(uint8(v.entry)) + buf[off+2] = uint8(v.entry >> 8) + + v = dt[uint8(br.value>>(56+shift))] + br.advance(uint8(v.entry)) + buf[off+3] = uint8(v.entry >> 8) + + off += 4 + if off == 0 { + if len(dst)+256 > maxDecodedSize { + br.close() + return nil, ErrMaxDecodedSizeExceeded + } + dst = append(dst, buf[:]...) + } + } + case 7: + const shift = 8 - 7 + for br.off >= 4 { + br.fillFast() + v := dt[uint8(br.value>>(56+shift))] + br.advance(uint8(v.entry)) + buf[off+0] = uint8(v.entry >> 8) + + v = dt[uint8(br.value>>(56+shift))] + br.advance(uint8(v.entry)) + buf[off+1] = uint8(v.entry >> 8) + + v = dt[uint8(br.value>>(56+shift))] + br.advance(uint8(v.entry)) + buf[off+2] = uint8(v.entry >> 8) + + v = dt[uint8(br.value>>(56+shift))] + br.advance(uint8(v.entry)) + buf[off+3] = uint8(v.entry >> 8) + + off += 4 + if off == 0 { + if len(dst)+256 > maxDecodedSize { + br.close() + return nil, ErrMaxDecodedSizeExceeded + } + dst = append(dst, buf[:]...) + } + } + case 6: + const shift = 8 - 6 + for br.off >= 4 { + br.fillFast() + v := dt[uint8(br.value>>(56+shift))] + br.advance(uint8(v.entry)) + buf[off+0] = uint8(v.entry >> 8) + + v = dt[uint8(br.value>>(56+shift))] + br.advance(uint8(v.entry)) + buf[off+1] = uint8(v.entry >> 8) + + v = dt[uint8(br.value>>(56+shift))] + br.advance(uint8(v.entry)) + buf[off+2] = uint8(v.entry >> 8) + + v = dt[uint8(br.value>>(56+shift))] + br.advance(uint8(v.entry)) + buf[off+3] = uint8(v.entry >> 8) + + off += 4 + if off == 0 { + if len(dst)+256 > maxDecodedSize { + br.close() + return nil, ErrMaxDecodedSizeExceeded + } + dst = append(dst, buf[:]...) + } + } + case 5: + const shift = 8 - 5 + for br.off >= 4 { + br.fillFast() + v := dt[uint8(br.value>>(56+shift))] + br.advance(uint8(v.entry)) + buf[off+0] = uint8(v.entry >> 8) + + v = dt[uint8(br.value>>(56+shift))] + br.advance(uint8(v.entry)) + buf[off+1] = uint8(v.entry >> 8) + + v = dt[uint8(br.value>>(56+shift))] + br.advance(uint8(v.entry)) + buf[off+2] = uint8(v.entry >> 8) + + v = dt[uint8(br.value>>(56+shift))] + br.advance(uint8(v.entry)) + buf[off+3] = uint8(v.entry >> 8) + + off += 4 + if off == 0 { + if len(dst)+256 > maxDecodedSize { + br.close() + return nil, ErrMaxDecodedSizeExceeded + } + dst = append(dst, buf[:]...) + } + } + case 4: + const shift = 8 - 4 + for br.off >= 4 { + br.fillFast() + v := dt[uint8(br.value>>(56+shift))] + br.advance(uint8(v.entry)) + buf[off+0] = uint8(v.entry >> 8) + + v = dt[uint8(br.value>>(56+shift))] + br.advance(uint8(v.entry)) + buf[off+1] = uint8(v.entry >> 8) + + v = dt[uint8(br.value>>(56+shift))] + br.advance(uint8(v.entry)) + buf[off+2] = uint8(v.entry >> 8) + + v = dt[uint8(br.value>>(56+shift))] + br.advance(uint8(v.entry)) + buf[off+3] = uint8(v.entry >> 8) + + off += 4 + if off == 0 { + if len(dst)+256 > maxDecodedSize { + br.close() + return nil, ErrMaxDecodedSizeExceeded + } + dst = append(dst, buf[:]...) + } + } + case 3: + const shift = 8 - 3 + for br.off >= 4 { + br.fillFast() + v := dt[uint8(br.value>>(56+shift))] + br.advance(uint8(v.entry)) + buf[off+0] = uint8(v.entry >> 8) + + v = dt[uint8(br.value>>(56+shift))] + br.advance(uint8(v.entry)) + buf[off+1] = uint8(v.entry >> 8) + + v = dt[uint8(br.value>>(56+shift))] + br.advance(uint8(v.entry)) + buf[off+2] = uint8(v.entry >> 8) + + v = dt[uint8(br.value>>(56+shift))] + br.advance(uint8(v.entry)) + buf[off+3] = uint8(v.entry >> 8) + + off += 4 + if off == 0 { + if len(dst)+256 > maxDecodedSize { + br.close() + return nil, ErrMaxDecodedSizeExceeded + } + dst = append(dst, buf[:]...) + } + } + case 2: + const shift = 8 - 2 + for br.off >= 4 { + br.fillFast() + v := dt[uint8(br.value>>(56+shift))] + br.advance(uint8(v.entry)) + buf[off+0] = uint8(v.entry >> 8) + + v = dt[uint8(br.value>>(56+shift))] + br.advance(uint8(v.entry)) + buf[off+1] = uint8(v.entry >> 8) + + v = dt[uint8(br.value>>(56+shift))] + br.advance(uint8(v.entry)) + buf[off+2] = uint8(v.entry >> 8) + + v = dt[uint8(br.value>>(56+shift))] + br.advance(uint8(v.entry)) + buf[off+3] = uint8(v.entry >> 8) + + off += 4 + if off == 0 { + if len(dst)+256 > maxDecodedSize { + br.close() + return nil, ErrMaxDecodedSizeExceeded + } + dst = append(dst, buf[:]...) + } + } + case 1: + const shift = 8 - 1 + for br.off >= 4 { + br.fillFast() + v := dt[uint8(br.value>>(56+shift))] + br.advance(uint8(v.entry)) + buf[off+0] = uint8(v.entry >> 8) + + v = dt[uint8(br.value>>(56+shift))] + br.advance(uint8(v.entry)) + buf[off+1] = uint8(v.entry >> 8) + + v = dt[uint8(br.value>>(56+shift))] + br.advance(uint8(v.entry)) + buf[off+2] = uint8(v.entry >> 8) + + v = dt[uint8(br.value>>(56+shift))] + br.advance(uint8(v.entry)) + buf[off+3] = uint8(v.entry >> 8) + + off += 4 + if off == 0 { + if len(dst)+256 > maxDecodedSize { + br.close() + return nil, ErrMaxDecodedSizeExceeded + } + dst = append(dst, buf[:]...) } - dst = append(dst, buf[:]...) } + default: + return nil, fmt.Errorf("invalid tablelog: %d", d.actualTableLog) } if len(dst)+int(off) > maxDecodedSize { @@ -383,6 +589,8 @@ func (d *Decoder) decompress1X8Bit(dst, src []byte) ([]byte, error) { // br < 4, so uint8 is fine bitsLeft := int8(uint8(br.off)*8 + (64 - br.bitsRead)) + shift := (8 - d.actualTableLog) & 7 + for bitsLeft > 0 { if br.bitsRead >= 64-8 { for br.off > 0 { @@ -423,24 +631,24 @@ func (d *Decoder) decompress1X8BitExactly(dst, src []byte) ([]byte, error) { var buf [256]byte var off uint8 - const shift = 0 + const shift = 56 //fmt.Printf("mask: %b, tl:%d\n", mask, d.actualTableLog) for br.off >= 4 { br.fillFast() - v := dt[br.peekByteFast()>>shift] + v := dt[uint8(br.value>>shift)] br.advance(uint8(v.entry)) buf[off+0] = uint8(v.entry >> 8) - v = dt[br.peekByteFast()>>shift] + v = dt[uint8(br.value>>shift)] br.advance(uint8(v.entry)) buf[off+1] = uint8(v.entry >> 8) - v = dt[br.peekByteFast()>>shift] + v = dt[uint8(br.value>>shift)] br.advance(uint8(v.entry)) buf[off+2] = uint8(v.entry >> 8) - v = dt[br.peekByteFast()>>shift] + v = dt[uint8(br.value>>shift)] br.advance(uint8(v.entry)) buf[off+3] = uint8(v.entry >> 8) @@ -474,7 +682,7 @@ func (d *Decoder) decompress1X8BitExactly(dst, src []byte) ([]byte, error) { br.close() return nil, ErrMaxDecodedSizeExceeded } - v := dt[br.peekByteFast()>>shift] + v := dt[br.peekByteFast()] nBits := uint8(v.entry) br.advance(nBits) bitsLeft -= int8(nBits) @@ -709,7 +917,6 @@ func (d *Decoder) decompress4X8bit(dst, src []byte) ([]byte, error) { shift := (8 - d.actualTableLog) & 7 const tlSize = 1 << 8 - const tlMask = tlSize - 1 single := d.dt.single[:tlSize] // Use temp table to avoid bound checks/append penalty. diff --git a/vendor/github.com/klauspost/compress/huff0/huff0.go b/vendor/github.com/klauspost/compress/huff0/huff0.go index 7ec2022b65..3ee00ecb47 100644 --- a/vendor/github.com/klauspost/compress/huff0/huff0.go +++ b/vendor/github.com/klauspost/compress/huff0/huff0.go @@ -245,6 +245,68 @@ func (c cTable) write(s *Scratch) error { return nil } +func (c cTable) estTableSize(s *Scratch) (sz int, err error) { + var ( + // precomputed conversion table + bitsToWeight [tableLogMax + 1]byte + huffLog = s.actualTableLog + // last weight is not saved. + maxSymbolValue = uint8(s.symbolLen - 1) + huffWeight = s.huffWeight[:256] + ) + const ( + maxFSETableLog = 6 + ) + // convert to weight + bitsToWeight[0] = 0 + for n := uint8(1); n < huffLog+1; n++ { + bitsToWeight[n] = huffLog + 1 - n + } + + // Acquire histogram for FSE. + hist := s.fse.Histogram() + hist = hist[:256] + for i := range hist[:16] { + hist[i] = 0 + } + for n := uint8(0); n < maxSymbolValue; n++ { + v := bitsToWeight[c[n].nBits] & 15 + huffWeight[n] = v + hist[v]++ + } + + // FSE compress if feasible. + if maxSymbolValue >= 2 { + huffMaxCnt := uint32(0) + huffMax := uint8(0) + for i, v := range hist[:16] { + if v == 0 { + continue + } + huffMax = byte(i) + if v > huffMaxCnt { + huffMaxCnt = v + } + } + s.fse.HistogramFinished(huffMax, int(huffMaxCnt)) + s.fse.TableLog = maxFSETableLog + b, err := fse.Compress(huffWeight[:maxSymbolValue], s.fse) + if err == nil && len(b) < int(s.symbolLen>>1) { + sz += 1 + len(b) + return sz, nil + } + // Unable to compress (RLE/uncompressible) + } + // write raw values as 4-bits (max : 15) + if maxSymbolValue > (256 - 128) { + // should not happen : likely means source cannot be compressed + return 0, ErrIncompressible + } + // special case, pack weights 4 bits/weight. + sz += 1 + int(maxSymbolValue/2) + return sz, nil +} + // estimateSize returns the estimated size in bytes of the input represented in the // histogram supplied. func (c cTable) estimateSize(hist []uint32) int { diff --git a/vendor/github.com/klauspost/compress/internal/snapref/LICENSE b/vendor/github.com/klauspost/compress/internal/snapref/LICENSE new file mode 100644 index 0000000000..6050c10f4c --- /dev/null +++ b/vendor/github.com/klauspost/compress/internal/snapref/LICENSE @@ -0,0 +1,27 @@ +Copyright (c) 2011 The Snappy-Go Authors. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/github.com/klauspost/compress/internal/snapref/decode.go b/vendor/github.com/klauspost/compress/internal/snapref/decode.go new file mode 100644 index 0000000000..40796a49d6 --- /dev/null +++ b/vendor/github.com/klauspost/compress/internal/snapref/decode.go @@ -0,0 +1,264 @@ +// Copyright 2011 The Snappy-Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package snapref + +import ( + "encoding/binary" + "errors" + "io" +) + +var ( + // ErrCorrupt reports that the input is invalid. + ErrCorrupt = errors.New("snappy: corrupt input") + // ErrTooLarge reports that the uncompressed length is too large. + ErrTooLarge = errors.New("snappy: decoded block is too large") + // ErrUnsupported reports that the input isn't supported. + ErrUnsupported = errors.New("snappy: unsupported input") + + errUnsupportedLiteralLength = errors.New("snappy: unsupported literal length") +) + +// DecodedLen returns the length of the decoded block. +func DecodedLen(src []byte) (int, error) { + v, _, err := decodedLen(src) + return v, err +} + +// decodedLen returns the length of the decoded block and the number of bytes +// that the length header occupied. +func decodedLen(src []byte) (blockLen, headerLen int, err error) { + v, n := binary.Uvarint(src) + if n <= 0 || v > 0xffffffff { + return 0, 0, ErrCorrupt + } + + const wordSize = 32 << (^uint(0) >> 32 & 1) + if wordSize == 32 && v > 0x7fffffff { + return 0, 0, ErrTooLarge + } + return int(v), n, nil +} + +const ( + decodeErrCodeCorrupt = 1 + decodeErrCodeUnsupportedLiteralLength = 2 +) + +// Decode returns the decoded form of src. The returned slice may be a sub- +// slice of dst if dst was large enough to hold the entire decoded block. +// Otherwise, a newly allocated slice will be returned. +// +// The dst and src must not overlap. It is valid to pass a nil dst. +// +// Decode handles the Snappy block format, not the Snappy stream format. +func Decode(dst, src []byte) ([]byte, error) { + dLen, s, err := decodedLen(src) + if err != nil { + return nil, err + } + if dLen <= len(dst) { + dst = dst[:dLen] + } else { + dst = make([]byte, dLen) + } + switch decode(dst, src[s:]) { + case 0: + return dst, nil + case decodeErrCodeUnsupportedLiteralLength: + return nil, errUnsupportedLiteralLength + } + return nil, ErrCorrupt +} + +// NewReader returns a new Reader that decompresses from r, using the framing +// format described at +// https://github.com/google/snappy/blob/master/framing_format.txt +func NewReader(r io.Reader) *Reader { + return &Reader{ + r: r, + decoded: make([]byte, maxBlockSize), + buf: make([]byte, maxEncodedLenOfMaxBlockSize+checksumSize), + } +} + +// Reader is an io.Reader that can read Snappy-compressed bytes. +// +// Reader handles the Snappy stream format, not the Snappy block format. +type Reader struct { + r io.Reader + err error + decoded []byte + buf []byte + // decoded[i:j] contains decoded bytes that have not yet been passed on. + i, j int + readHeader bool +} + +// Reset discards any buffered data, resets all state, and switches the Snappy +// reader to read from r. This permits reusing a Reader rather than allocating +// a new one. +func (r *Reader) Reset(reader io.Reader) { + r.r = reader + r.err = nil + r.i = 0 + r.j = 0 + r.readHeader = false +} + +func (r *Reader) readFull(p []byte, allowEOF bool) (ok bool) { + if _, r.err = io.ReadFull(r.r, p); r.err != nil { + if r.err == io.ErrUnexpectedEOF || (r.err == io.EOF && !allowEOF) { + r.err = ErrCorrupt + } + return false + } + return true +} + +func (r *Reader) fill() error { + for r.i >= r.j { + if !r.readFull(r.buf[:4], true) { + return r.err + } + chunkType := r.buf[0] + if !r.readHeader { + if chunkType != chunkTypeStreamIdentifier { + r.err = ErrCorrupt + return r.err + } + r.readHeader = true + } + chunkLen := int(r.buf[1]) | int(r.buf[2])<<8 | int(r.buf[3])<<16 + if chunkLen > len(r.buf) { + r.err = ErrUnsupported + return r.err + } + + // The chunk types are specified at + // https://github.com/google/snappy/blob/master/framing_format.txt + switch chunkType { + case chunkTypeCompressedData: + // Section 4.2. Compressed data (chunk type 0x00). + if chunkLen < checksumSize { + r.err = ErrCorrupt + return r.err + } + buf := r.buf[:chunkLen] + if !r.readFull(buf, false) { + return r.err + } + checksum := uint32(buf[0]) | uint32(buf[1])<<8 | uint32(buf[2])<<16 | uint32(buf[3])<<24 + buf = buf[checksumSize:] + + n, err := DecodedLen(buf) + if err != nil { + r.err = err + return r.err + } + if n > len(r.decoded) { + r.err = ErrCorrupt + return r.err + } + if _, err := Decode(r.decoded, buf); err != nil { + r.err = err + return r.err + } + if crc(r.decoded[:n]) != checksum { + r.err = ErrCorrupt + return r.err + } + r.i, r.j = 0, n + continue + + case chunkTypeUncompressedData: + // Section 4.3. Uncompressed data (chunk type 0x01). + if chunkLen < checksumSize { + r.err = ErrCorrupt + return r.err + } + buf := r.buf[:checksumSize] + if !r.readFull(buf, false) { + return r.err + } + checksum := uint32(buf[0]) | uint32(buf[1])<<8 | uint32(buf[2])<<16 | uint32(buf[3])<<24 + // Read directly into r.decoded instead of via r.buf. + n := chunkLen - checksumSize + if n > len(r.decoded) { + r.err = ErrCorrupt + return r.err + } + if !r.readFull(r.decoded[:n], false) { + return r.err + } + if crc(r.decoded[:n]) != checksum { + r.err = ErrCorrupt + return r.err + } + r.i, r.j = 0, n + continue + + case chunkTypeStreamIdentifier: + // Section 4.1. Stream identifier (chunk type 0xff). + if chunkLen != len(magicBody) { + r.err = ErrCorrupt + return r.err + } + if !r.readFull(r.buf[:len(magicBody)], false) { + return r.err + } + for i := 0; i < len(magicBody); i++ { + if r.buf[i] != magicBody[i] { + r.err = ErrCorrupt + return r.err + } + } + continue + } + + if chunkType <= 0x7f { + // Section 4.5. Reserved unskippable chunks (chunk types 0x02-0x7f). + r.err = ErrUnsupported + return r.err + } + // Section 4.4 Padding (chunk type 0xfe). + // Section 4.6. Reserved skippable chunks (chunk types 0x80-0xfd). + if !r.readFull(r.buf[:chunkLen], false) { + return r.err + } + } + + return nil +} + +// Read satisfies the io.Reader interface. +func (r *Reader) Read(p []byte) (int, error) { + if r.err != nil { + return 0, r.err + } + + if err := r.fill(); err != nil { + return 0, err + } + + n := copy(p, r.decoded[r.i:r.j]) + r.i += n + return n, nil +} + +// ReadByte satisfies the io.ByteReader interface. +func (r *Reader) ReadByte() (byte, error) { + if r.err != nil { + return 0, r.err + } + + if err := r.fill(); err != nil { + return 0, err + } + + c := r.decoded[r.i] + r.i++ + return c, nil +} diff --git a/vendor/github.com/klauspost/compress/internal/snapref/decode_other.go b/vendor/github.com/klauspost/compress/internal/snapref/decode_other.go new file mode 100644 index 0000000000..77395a6b8b --- /dev/null +++ b/vendor/github.com/klauspost/compress/internal/snapref/decode_other.go @@ -0,0 +1,113 @@ +// Copyright 2016 The Snappy-Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package snapref + +// decode writes the decoding of src to dst. It assumes that the varint-encoded +// length of the decompressed bytes has already been read, and that len(dst) +// equals that length. +// +// It returns 0 on success or a decodeErrCodeXxx error code on failure. +func decode(dst, src []byte) int { + var d, s, offset, length int + for s < len(src) { + switch src[s] & 0x03 { + case tagLiteral: + x := uint32(src[s] >> 2) + switch { + case x < 60: + s++ + case x == 60: + s += 2 + if uint(s) > uint(len(src)) { // The uint conversions catch overflow from the previous line. + return decodeErrCodeCorrupt + } + x = uint32(src[s-1]) + case x == 61: + s += 3 + if uint(s) > uint(len(src)) { // The uint conversions catch overflow from the previous line. + return decodeErrCodeCorrupt + } + x = uint32(src[s-2]) | uint32(src[s-1])<<8 + case x == 62: + s += 4 + if uint(s) > uint(len(src)) { // The uint conversions catch overflow from the previous line. + return decodeErrCodeCorrupt + } + x = uint32(src[s-3]) | uint32(src[s-2])<<8 | uint32(src[s-1])<<16 + case x == 63: + s += 5 + if uint(s) > uint(len(src)) { // The uint conversions catch overflow from the previous line. + return decodeErrCodeCorrupt + } + x = uint32(src[s-4]) | uint32(src[s-3])<<8 | uint32(src[s-2])<<16 | uint32(src[s-1])<<24 + } + length = int(x) + 1 + if length <= 0 { + return decodeErrCodeUnsupportedLiteralLength + } + if length > len(dst)-d || length > len(src)-s { + return decodeErrCodeCorrupt + } + copy(dst[d:], src[s:s+length]) + d += length + s += length + continue + + case tagCopy1: + s += 2 + if uint(s) > uint(len(src)) { // The uint conversions catch overflow from the previous line. + return decodeErrCodeCorrupt + } + length = 4 + int(src[s-2])>>2&0x7 + offset = int(uint32(src[s-2])&0xe0<<3 | uint32(src[s-1])) + + case tagCopy2: + s += 3 + if uint(s) > uint(len(src)) { // The uint conversions catch overflow from the previous line. + return decodeErrCodeCorrupt + } + length = 1 + int(src[s-3])>>2 + offset = int(uint32(src[s-2]) | uint32(src[s-1])<<8) + + case tagCopy4: + s += 5 + if uint(s) > uint(len(src)) { // The uint conversions catch overflow from the previous line. + return decodeErrCodeCorrupt + } + length = 1 + int(src[s-5])>>2 + offset = int(uint32(src[s-4]) | uint32(src[s-3])<<8 | uint32(src[s-2])<<16 | uint32(src[s-1])<<24) + } + + if offset <= 0 || d < offset || length > len(dst)-d { + return decodeErrCodeCorrupt + } + // Copy from an earlier sub-slice of dst to a later sub-slice. + // If no overlap, use the built-in copy: + if offset >= length { + copy(dst[d:d+length], dst[d-offset:]) + d += length + continue + } + + // Unlike the built-in copy function, this byte-by-byte copy always runs + // forwards, even if the slices overlap. Conceptually, this is: + // + // d += forwardCopy(dst[d:d+length], dst[d-offset:]) + // + // We align the slices into a and b and show the compiler they are the same size. + // This allows the loop to run without bounds checks. + a := dst[d : d+length] + b := dst[d-offset:] + b = b[:len(a)] + for i := range a { + a[i] = b[i] + } + d += length + } + if d != len(dst) { + return decodeErrCodeCorrupt + } + return 0 +} diff --git a/vendor/github.com/klauspost/compress/internal/snapref/encode.go b/vendor/github.com/klauspost/compress/internal/snapref/encode.go new file mode 100644 index 0000000000..13c6040a5d --- /dev/null +++ b/vendor/github.com/klauspost/compress/internal/snapref/encode.go @@ -0,0 +1,289 @@ +// Copyright 2011 The Snappy-Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package snapref + +import ( + "encoding/binary" + "errors" + "io" +) + +// Encode returns the encoded form of src. The returned slice may be a sub- +// slice of dst if dst was large enough to hold the entire encoded block. +// Otherwise, a newly allocated slice will be returned. +// +// The dst and src must not overlap. It is valid to pass a nil dst. +// +// Encode handles the Snappy block format, not the Snappy stream format. +func Encode(dst, src []byte) []byte { + if n := MaxEncodedLen(len(src)); n < 0 { + panic(ErrTooLarge) + } else if len(dst) < n { + dst = make([]byte, n) + } + + // The block starts with the varint-encoded length of the decompressed bytes. + d := binary.PutUvarint(dst, uint64(len(src))) + + for len(src) > 0 { + p := src + src = nil + if len(p) > maxBlockSize { + p, src = p[:maxBlockSize], p[maxBlockSize:] + } + if len(p) < minNonLiteralBlockSize { + d += emitLiteral(dst[d:], p) + } else { + d += encodeBlock(dst[d:], p) + } + } + return dst[:d] +} + +// inputMargin is the minimum number of extra input bytes to keep, inside +// encodeBlock's inner loop. On some architectures, this margin lets us +// implement a fast path for emitLiteral, where the copy of short (<= 16 byte) +// literals can be implemented as a single load to and store from a 16-byte +// register. That literal's actual length can be as short as 1 byte, so this +// can copy up to 15 bytes too much, but that's OK as subsequent iterations of +// the encoding loop will fix up the copy overrun, and this inputMargin ensures +// that we don't overrun the dst and src buffers. +const inputMargin = 16 - 1 + +// minNonLiteralBlockSize is the minimum size of the input to encodeBlock that +// could be encoded with a copy tag. This is the minimum with respect to the +// algorithm used by encodeBlock, not a minimum enforced by the file format. +// +// The encoded output must start with at least a 1 byte literal, as there are +// no previous bytes to copy. A minimal (1 byte) copy after that, generated +// from an emitCopy call in encodeBlock's main loop, would require at least +// another inputMargin bytes, for the reason above: we want any emitLiteral +// calls inside encodeBlock's main loop to use the fast path if possible, which +// requires being able to overrun by inputMargin bytes. Thus, +// minNonLiteralBlockSize equals 1 + 1 + inputMargin. +// +// The C++ code doesn't use this exact threshold, but it could, as discussed at +// https://groups.google.com/d/topic/snappy-compression/oGbhsdIJSJ8/discussion +// The difference between Go (2+inputMargin) and C++ (inputMargin) is purely an +// optimization. It should not affect the encoded form. This is tested by +// TestSameEncodingAsCppShortCopies. +const minNonLiteralBlockSize = 1 + 1 + inputMargin + +// MaxEncodedLen returns the maximum length of a snappy block, given its +// uncompressed length. +// +// It will return a negative value if srcLen is too large to encode. +func MaxEncodedLen(srcLen int) int { + n := uint64(srcLen) + if n > 0xffffffff { + return -1 + } + // Compressed data can be defined as: + // compressed := item* literal* + // item := literal* copy + // + // The trailing literal sequence has a space blowup of at most 62/60 + // since a literal of length 60 needs one tag byte + one extra byte + // for length information. + // + // Item blowup is trickier to measure. Suppose the "copy" op copies + // 4 bytes of data. Because of a special check in the encoding code, + // we produce a 4-byte copy only if the offset is < 65536. Therefore + // the copy op takes 3 bytes to encode, and this type of item leads + // to at most the 62/60 blowup for representing literals. + // + // Suppose the "copy" op copies 5 bytes of data. If the offset is big + // enough, it will take 5 bytes to encode the copy op. Therefore the + // worst case here is a one-byte literal followed by a five-byte copy. + // That is, 6 bytes of input turn into 7 bytes of "compressed" data. + // + // This last factor dominates the blowup, so the final estimate is: + n = 32 + n + n/6 + if n > 0xffffffff { + return -1 + } + return int(n) +} + +var errClosed = errors.New("snappy: Writer is closed") + +// NewWriter returns a new Writer that compresses to w. +// +// The Writer returned does not buffer writes. There is no need to Flush or +// Close such a Writer. +// +// Deprecated: the Writer returned is not suitable for many small writes, only +// for few large writes. Use NewBufferedWriter instead, which is efficient +// regardless of the frequency and shape of the writes, and remember to Close +// that Writer when done. +func NewWriter(w io.Writer) *Writer { + return &Writer{ + w: w, + obuf: make([]byte, obufLen), + } +} + +// NewBufferedWriter returns a new Writer that compresses to w, using the +// framing format described at +// https://github.com/google/snappy/blob/master/framing_format.txt +// +// The Writer returned buffers writes. Users must call Close to guarantee all +// data has been forwarded to the underlying io.Writer. They may also call +// Flush zero or more times before calling Close. +func NewBufferedWriter(w io.Writer) *Writer { + return &Writer{ + w: w, + ibuf: make([]byte, 0, maxBlockSize), + obuf: make([]byte, obufLen), + } +} + +// Writer is an io.Writer that can write Snappy-compressed bytes. +// +// Writer handles the Snappy stream format, not the Snappy block format. +type Writer struct { + w io.Writer + err error + + // ibuf is a buffer for the incoming (uncompressed) bytes. + // + // Its use is optional. For backwards compatibility, Writers created by the + // NewWriter function have ibuf == nil, do not buffer incoming bytes, and + // therefore do not need to be Flush'ed or Close'd. + ibuf []byte + + // obuf is a buffer for the outgoing (compressed) bytes. + obuf []byte + + // wroteStreamHeader is whether we have written the stream header. + wroteStreamHeader bool +} + +// Reset discards the writer's state and switches the Snappy writer to write to +// w. This permits reusing a Writer rather than allocating a new one. +func (w *Writer) Reset(writer io.Writer) { + w.w = writer + w.err = nil + if w.ibuf != nil { + w.ibuf = w.ibuf[:0] + } + w.wroteStreamHeader = false +} + +// Write satisfies the io.Writer interface. +func (w *Writer) Write(p []byte) (nRet int, errRet error) { + if w.ibuf == nil { + // Do not buffer incoming bytes. This does not perform or compress well + // if the caller of Writer.Write writes many small slices. This + // behavior is therefore deprecated, but still supported for backwards + // compatibility with code that doesn't explicitly Flush or Close. + return w.write(p) + } + + // The remainder of this method is based on bufio.Writer.Write from the + // standard library. + + for len(p) > (cap(w.ibuf)-len(w.ibuf)) && w.err == nil { + var n int + if len(w.ibuf) == 0 { + // Large write, empty buffer. + // Write directly from p to avoid copy. + n, _ = w.write(p) + } else { + n = copy(w.ibuf[len(w.ibuf):cap(w.ibuf)], p) + w.ibuf = w.ibuf[:len(w.ibuf)+n] + w.Flush() + } + nRet += n + p = p[n:] + } + if w.err != nil { + return nRet, w.err + } + n := copy(w.ibuf[len(w.ibuf):cap(w.ibuf)], p) + w.ibuf = w.ibuf[:len(w.ibuf)+n] + nRet += n + return nRet, nil +} + +func (w *Writer) write(p []byte) (nRet int, errRet error) { + if w.err != nil { + return 0, w.err + } + for len(p) > 0 { + obufStart := len(magicChunk) + if !w.wroteStreamHeader { + w.wroteStreamHeader = true + copy(w.obuf, magicChunk) + obufStart = 0 + } + + var uncompressed []byte + if len(p) > maxBlockSize { + uncompressed, p = p[:maxBlockSize], p[maxBlockSize:] + } else { + uncompressed, p = p, nil + } + checksum := crc(uncompressed) + + // Compress the buffer, discarding the result if the improvement + // isn't at least 12.5%. + compressed := Encode(w.obuf[obufHeaderLen:], uncompressed) + chunkType := uint8(chunkTypeCompressedData) + chunkLen := 4 + len(compressed) + obufEnd := obufHeaderLen + len(compressed) + if len(compressed) >= len(uncompressed)-len(uncompressed)/8 { + chunkType = chunkTypeUncompressedData + chunkLen = 4 + len(uncompressed) + obufEnd = obufHeaderLen + } + + // Fill in the per-chunk header that comes before the body. + w.obuf[len(magicChunk)+0] = chunkType + w.obuf[len(magicChunk)+1] = uint8(chunkLen >> 0) + w.obuf[len(magicChunk)+2] = uint8(chunkLen >> 8) + w.obuf[len(magicChunk)+3] = uint8(chunkLen >> 16) + w.obuf[len(magicChunk)+4] = uint8(checksum >> 0) + w.obuf[len(magicChunk)+5] = uint8(checksum >> 8) + w.obuf[len(magicChunk)+6] = uint8(checksum >> 16) + w.obuf[len(magicChunk)+7] = uint8(checksum >> 24) + + if _, err := w.w.Write(w.obuf[obufStart:obufEnd]); err != nil { + w.err = err + return nRet, err + } + if chunkType == chunkTypeUncompressedData { + if _, err := w.w.Write(uncompressed); err != nil { + w.err = err + return nRet, err + } + } + nRet += len(uncompressed) + } + return nRet, nil +} + +// Flush flushes the Writer to its underlying io.Writer. +func (w *Writer) Flush() error { + if w.err != nil { + return w.err + } + if len(w.ibuf) == 0 { + return nil + } + w.write(w.ibuf) + w.ibuf = w.ibuf[:0] + return w.err +} + +// Close calls Flush and then closes the Writer. +func (w *Writer) Close() error { + w.Flush() + ret := w.err + if w.err == nil { + w.err = errClosed + } + return ret +} diff --git a/vendor/github.com/klauspost/compress/internal/snapref/encode_other.go b/vendor/github.com/klauspost/compress/internal/snapref/encode_other.go new file mode 100644 index 0000000000..511bba65db --- /dev/null +++ b/vendor/github.com/klauspost/compress/internal/snapref/encode_other.go @@ -0,0 +1,236 @@ +// Copyright 2016 The Snappy-Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package snapref + +func load32(b []byte, i int) uint32 { + b = b[i : i+4 : len(b)] // Help the compiler eliminate bounds checks on the next line. + return uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24 +} + +func load64(b []byte, i int) uint64 { + b = b[i : i+8 : len(b)] // Help the compiler eliminate bounds checks on the next line. + return uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 | + uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56 +} + +// emitLiteral writes a literal chunk and returns the number of bytes written. +// +// It assumes that: +// dst is long enough to hold the encoded bytes +// 1 <= len(lit) && len(lit) <= 65536 +func emitLiteral(dst, lit []byte) int { + i, n := 0, uint(len(lit)-1) + switch { + case n < 60: + dst[0] = uint8(n)<<2 | tagLiteral + i = 1 + case n < 1<<8: + dst[0] = 60<<2 | tagLiteral + dst[1] = uint8(n) + i = 2 + default: + dst[0] = 61<<2 | tagLiteral + dst[1] = uint8(n) + dst[2] = uint8(n >> 8) + i = 3 + } + return i + copy(dst[i:], lit) +} + +// emitCopy writes a copy chunk and returns the number of bytes written. +// +// It assumes that: +// dst is long enough to hold the encoded bytes +// 1 <= offset && offset <= 65535 +// 4 <= length && length <= 65535 +func emitCopy(dst []byte, offset, length int) int { + i := 0 + // The maximum length for a single tagCopy1 or tagCopy2 op is 64 bytes. The + // threshold for this loop is a little higher (at 68 = 64 + 4), and the + // length emitted down below is is a little lower (at 60 = 64 - 4), because + // it's shorter to encode a length 67 copy as a length 60 tagCopy2 followed + // by a length 7 tagCopy1 (which encodes as 3+2 bytes) than to encode it as + // a length 64 tagCopy2 followed by a length 3 tagCopy2 (which encodes as + // 3+3 bytes). The magic 4 in the 64±4 is because the minimum length for a + // tagCopy1 op is 4 bytes, which is why a length 3 copy has to be an + // encodes-as-3-bytes tagCopy2 instead of an encodes-as-2-bytes tagCopy1. + for length >= 68 { + // Emit a length 64 copy, encoded as 3 bytes. + dst[i+0] = 63<<2 | tagCopy2 + dst[i+1] = uint8(offset) + dst[i+2] = uint8(offset >> 8) + i += 3 + length -= 64 + } + if length > 64 { + // Emit a length 60 copy, encoded as 3 bytes. + dst[i+0] = 59<<2 | tagCopy2 + dst[i+1] = uint8(offset) + dst[i+2] = uint8(offset >> 8) + i += 3 + length -= 60 + } + if length >= 12 || offset >= 2048 { + // Emit the remaining copy, encoded as 3 bytes. + dst[i+0] = uint8(length-1)<<2 | tagCopy2 + dst[i+1] = uint8(offset) + dst[i+2] = uint8(offset >> 8) + return i + 3 + } + // Emit the remaining copy, encoded as 2 bytes. + dst[i+0] = uint8(offset>>8)<<5 | uint8(length-4)<<2 | tagCopy1 + dst[i+1] = uint8(offset) + return i + 2 +} + +// extendMatch returns the largest k such that k <= len(src) and that +// src[i:i+k-j] and src[j:k] have the same contents. +// +// It assumes that: +// 0 <= i && i < j && j <= len(src) +func extendMatch(src []byte, i, j int) int { + for ; j < len(src) && src[i] == src[j]; i, j = i+1, j+1 { + } + return j +} + +func hash(u, shift uint32) uint32 { + return (u * 0x1e35a7bd) >> shift +} + +// encodeBlock encodes a non-empty src to a guaranteed-large-enough dst. It +// assumes that the varint-encoded length of the decompressed bytes has already +// been written. +// +// It also assumes that: +// len(dst) >= MaxEncodedLen(len(src)) && +// minNonLiteralBlockSize <= len(src) && len(src) <= maxBlockSize +func encodeBlock(dst, src []byte) (d int) { + // Initialize the hash table. Its size ranges from 1<<8 to 1<<14 inclusive. + // The table element type is uint16, as s < sLimit and sLimit < len(src) + // and len(src) <= maxBlockSize and maxBlockSize == 65536. + const ( + maxTableSize = 1 << 14 + // tableMask is redundant, but helps the compiler eliminate bounds + // checks. + tableMask = maxTableSize - 1 + ) + shift := uint32(32 - 8) + for tableSize := 1 << 8; tableSize < maxTableSize && tableSize < len(src); tableSize *= 2 { + shift-- + } + // In Go, all array elements are zero-initialized, so there is no advantage + // to a smaller tableSize per se. However, it matches the C++ algorithm, + // and in the asm versions of this code, we can get away with zeroing only + // the first tableSize elements. + var table [maxTableSize]uint16 + + // sLimit is when to stop looking for offset/length copies. The inputMargin + // lets us use a fast path for emitLiteral in the main loop, while we are + // looking for copies. + sLimit := len(src) - inputMargin + + // nextEmit is where in src the next emitLiteral should start from. + nextEmit := 0 + + // The encoded form must start with a literal, as there are no previous + // bytes to copy, so we start looking for hash matches at s == 1. + s := 1 + nextHash := hash(load32(src, s), shift) + + for { + // Copied from the C++ snappy implementation: + // + // Heuristic match skipping: If 32 bytes are scanned with no matches + // found, start looking only at every other byte. If 32 more bytes are + // scanned (or skipped), look at every third byte, etc.. When a match + // is found, immediately go back to looking at every byte. This is a + // small loss (~5% performance, ~0.1% density) for compressible data + // due to more bookkeeping, but for non-compressible data (such as + // JPEG) it's a huge win since the compressor quickly "realizes" the + // data is incompressible and doesn't bother looking for matches + // everywhere. + // + // The "skip" variable keeps track of how many bytes there are since + // the last match; dividing it by 32 (ie. right-shifting by five) gives + // the number of bytes to move ahead for each iteration. + skip := 32 + + nextS := s + candidate := 0 + for { + s = nextS + bytesBetweenHashLookups := skip >> 5 + nextS = s + bytesBetweenHashLookups + skip += bytesBetweenHashLookups + if nextS > sLimit { + goto emitRemainder + } + candidate = int(table[nextHash&tableMask]) + table[nextHash&tableMask] = uint16(s) + nextHash = hash(load32(src, nextS), shift) + if load32(src, s) == load32(src, candidate) { + break + } + } + + // A 4-byte match has been found. We'll later see if more than 4 bytes + // match. But, prior to the match, src[nextEmit:s] are unmatched. Emit + // them as literal bytes. + d += emitLiteral(dst[d:], src[nextEmit:s]) + + // Call emitCopy, and then see if another emitCopy could be our next + // move. Repeat until we find no match for the input immediately after + // what was consumed by the last emitCopy call. + // + // If we exit this loop normally then we need to call emitLiteral next, + // though we don't yet know how big the literal will be. We handle that + // by proceeding to the next iteration of the main loop. We also can + // exit this loop via goto if we get close to exhausting the input. + for { + // Invariant: we have a 4-byte match at s, and no need to emit any + // literal bytes prior to s. + base := s + + // Extend the 4-byte match as long as possible. + // + // This is an inlined version of: + // s = extendMatch(src, candidate+4, s+4) + s += 4 + for i := candidate + 4; s < len(src) && src[i] == src[s]; i, s = i+1, s+1 { + } + + d += emitCopy(dst[d:], base-candidate, s-base) + nextEmit = s + if s >= sLimit { + goto emitRemainder + } + + // We could immediately start working at s now, but to improve + // compression we first update the hash table at s-1 and at s. If + // another emitCopy is not our next move, also calculate nextHash + // at s+1. At least on GOARCH=amd64, these three hash calculations + // are faster as one load64 call (with some shifts) instead of + // three load32 calls. + x := load64(src, s-1) + prevHash := hash(uint32(x>>0), shift) + table[prevHash&tableMask] = uint16(s - 1) + currHash := hash(uint32(x>>8), shift) + candidate = int(table[currHash&tableMask]) + table[currHash&tableMask] = uint16(s) + if uint32(x>>8) != load32(src, candidate) { + nextHash = hash(uint32(x>>16), shift) + s++ + break + } + } + } + +emitRemainder: + if nextEmit < len(src) { + d += emitLiteral(dst[d:], src[nextEmit:]) + } + return d +} diff --git a/vendor/github.com/klauspost/compress/internal/snapref/snappy.go b/vendor/github.com/klauspost/compress/internal/snapref/snappy.go new file mode 100644 index 0000000000..34d01f4aa6 --- /dev/null +++ b/vendor/github.com/klauspost/compress/internal/snapref/snappy.go @@ -0,0 +1,98 @@ +// Copyright 2011 The Snappy-Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package snapref implements the Snappy compression format. It aims for very +// high speeds and reasonable compression. +// +// There are actually two Snappy formats: block and stream. They are related, +// but different: trying to decompress block-compressed data as a Snappy stream +// will fail, and vice versa. The block format is the Decode and Encode +// functions and the stream format is the Reader and Writer types. +// +// The block format, the more common case, is used when the complete size (the +// number of bytes) of the original data is known upfront, at the time +// compression starts. The stream format, also known as the framing format, is +// for when that isn't always true. +// +// The canonical, C++ implementation is at https://github.com/google/snappy and +// it only implements the block format. +package snapref + +import ( + "hash/crc32" +) + +/* +Each encoded block begins with the varint-encoded length of the decoded data, +followed by a sequence of chunks. Chunks begin and end on byte boundaries. The +first byte of each chunk is broken into its 2 least and 6 most significant bits +called l and m: l ranges in [0, 4) and m ranges in [0, 64). l is the chunk tag. +Zero means a literal tag. All other values mean a copy tag. + +For literal tags: + - If m < 60, the next 1 + m bytes are literal bytes. + - Otherwise, let n be the little-endian unsigned integer denoted by the next + m - 59 bytes. The next 1 + n bytes after that are literal bytes. + +For copy tags, length bytes are copied from offset bytes ago, in the style of +Lempel-Ziv compression algorithms. In particular: + - For l == 1, the offset ranges in [0, 1<<11) and the length in [4, 12). + The length is 4 + the low 3 bits of m. The high 3 bits of m form bits 8-10 + of the offset. The next byte is bits 0-7 of the offset. + - For l == 2, the offset ranges in [0, 1<<16) and the length in [1, 65). + The length is 1 + m. The offset is the little-endian unsigned integer + denoted by the next 2 bytes. + - For l == 3, this tag is a legacy format that is no longer issued by most + encoders. Nonetheless, the offset ranges in [0, 1<<32) and the length in + [1, 65). The length is 1 + m. The offset is the little-endian unsigned + integer denoted by the next 4 bytes. +*/ +const ( + tagLiteral = 0x00 + tagCopy1 = 0x01 + tagCopy2 = 0x02 + tagCopy4 = 0x03 +) + +const ( + checksumSize = 4 + chunkHeaderSize = 4 + magicChunk = "\xff\x06\x00\x00" + magicBody + magicBody = "sNaPpY" + + // maxBlockSize is the maximum size of the input to encodeBlock. It is not + // part of the wire format per se, but some parts of the encoder assume + // that an offset fits into a uint16. + // + // Also, for the framing format (Writer type instead of Encode function), + // https://github.com/google/snappy/blob/master/framing_format.txt says + // that "the uncompressed data in a chunk must be no longer than 65536 + // bytes". + maxBlockSize = 65536 + + // maxEncodedLenOfMaxBlockSize equals MaxEncodedLen(maxBlockSize), but is + // hard coded to be a const instead of a variable, so that obufLen can also + // be a const. Their equivalence is confirmed by + // TestMaxEncodedLenOfMaxBlockSize. + maxEncodedLenOfMaxBlockSize = 76490 + + obufHeaderLen = len(magicChunk) + checksumSize + chunkHeaderSize + obufLen = obufHeaderLen + maxEncodedLenOfMaxBlockSize +) + +const ( + chunkTypeCompressedData = 0x00 + chunkTypeUncompressedData = 0x01 + chunkTypePadding = 0xfe + chunkTypeStreamIdentifier = 0xff +) + +var crcTable = crc32.MakeTable(crc32.Castagnoli) + +// crc implements the checksum specified in section 3 of +// https://github.com/google/snappy/blob/master/framing_format.txt +func crc(b []byte) uint32 { + c := crc32.Update(0, crcTable, b) + return uint32(c>>15|c<<17) + 0xa282ead8 +} diff --git a/vendor/github.com/klauspost/compress/s2sx.mod b/vendor/github.com/klauspost/compress/s2sx.mod new file mode 100644 index 0000000000..2263853fca --- /dev/null +++ b/vendor/github.com/klauspost/compress/s2sx.mod @@ -0,0 +1,4 @@ +module github.com/klauspost/compress + +go 1.16 + diff --git a/vendor/github.com/klauspost/compress/s2sx.sum b/vendor/github.com/klauspost/compress/s2sx.sum new file mode 100644 index 0000000000..e69de29bb2 diff --git a/vendor/github.com/klauspost/compress/zstd/README.md b/vendor/github.com/klauspost/compress/zstd/README.md index 787813fa9e..c8f0f16fc1 100644 --- a/vendor/github.com/klauspost/compress/zstd/README.md +++ b/vendor/github.com/klauspost/compress/zstd/README.md @@ -152,7 +152,7 @@ file out level insize outsize millis mb/s silesia.tar zskp 1 211947520 73101992 643 313.87 silesia.tar zskp 2 211947520 67504318 969 208.38 silesia.tar zskp 3 211947520 64595893 2007 100.68 -silesia.tar zskp 4 211947520 60995370 7691 26.28 +silesia.tar zskp 4 211947520 60995370 8825 22.90 cgo zstd: silesia.tar zstd 1 211947520 73605392 543 371.56 @@ -162,7 +162,7 @@ silesia.tar zstd 9 211947520 60212393 5063 39.92 gzip, stdlib/this package: silesia.tar gzstd 1 211947520 80007735 1654 122.21 -silesia.tar gzkp 1 211947520 80369488 1168 173.06 +silesia.tar gzkp 1 211947520 80136201 1152 175.45 GOB stream of binary data. Highly compressible. https://files.klauspost.com/compress/gob-stream.7z @@ -171,13 +171,15 @@ file out level insize outsize millis mb/s gob-stream zskp 1 1911399616 235022249 3088 590.30 gob-stream zskp 2 1911399616 205669791 3786 481.34 gob-stream zskp 3 1911399616 175034659 9636 189.17 -gob-stream zskp 4 1911399616 167273881 29337 62.13 +gob-stream zskp 4 1911399616 165609838 50369 36.19 + gob-stream zstd 1 1911399616 249810424 2637 691.26 gob-stream zstd 3 1911399616 208192146 3490 522.31 gob-stream zstd 6 1911399616 193632038 6687 272.56 gob-stream zstd 9 1911399616 177620386 16175 112.70 + gob-stream gzstd 1 1911399616 357382641 10251 177.82 -gob-stream gzkp 1 1911399616 362156523 5695 320.08 +gob-stream gzkp 1 1911399616 359753026 5438 335.20 The test data for the Large Text Compression Benchmark is the first 10^9 bytes of the English Wikipedia dump on Mar. 3, 2006. @@ -187,11 +189,13 @@ file out level insize outsize millis mb/s enwik9 zskp 1 1000000000 343848582 3609 264.18 enwik9 zskp 2 1000000000 317276632 5746 165.97 enwik9 zskp 3 1000000000 292243069 12162 78.41 -enwik9 zskp 4 1000000000 275241169 36430 26.18 +enwik9 zskp 4 1000000000 262183768 82837 11.51 + enwik9 zstd 1 1000000000 358072021 3110 306.65 enwik9 zstd 3 1000000000 313734672 4784 199.35 enwik9 zstd 6 1000000000 295138875 10290 92.68 enwik9 zstd 9 1000000000 278348700 28549 33.40 + enwik9 gzstd 1 1000000000 382578136 9604 99.30 enwik9 gzkp 1 1000000000 383825945 6544 145.73 @@ -202,13 +206,15 @@ file out level insize outsize millis mb/s github-june-2days-2019.json zskp 1 6273951764 699045015 10620 563.40 github-june-2days-2019.json zskp 2 6273951764 617881763 11687 511.96 github-june-2days-2019.json zskp 3 6273951764 524340691 34043 175.75 -github-june-2days-2019.json zskp 4 6273951764 503314661 93811 63.78 +github-june-2days-2019.json zskp 4 6273951764 470320075 170190 35.16 + github-june-2days-2019.json zstd 1 6273951764 766284037 8450 708.00 github-june-2days-2019.json zstd 3 6273951764 661889476 10927 547.57 github-june-2days-2019.json zstd 6 6273951764 642756859 22996 260.18 github-june-2days-2019.json zstd 9 6273951764 601974523 52413 114.16 + github-june-2days-2019.json gzstd 1 6273951764 1164400847 29948 199.79 -github-june-2days-2019.json gzkp 1 6273951764 1128755542 19236 311.03 +github-june-2days-2019.json gzkp 1 6273951764 1125417694 21788 274.61 VM Image, Linux mint with a few installed applications: https://files.klauspost.com/compress/rawstudio-mint14.7z @@ -217,13 +223,15 @@ file out level insize outsize millis mb/s rawstudio-mint14.tar zskp 1 8558382592 3667489370 20210 403.84 rawstudio-mint14.tar zskp 2 8558382592 3364592300 31873 256.07 rawstudio-mint14.tar zskp 3 8558382592 3158085214 77675 105.08 -rawstudio-mint14.tar zskp 4 8558382592 3020370044 404956 20.16 +rawstudio-mint14.tar zskp 4 8558382592 2965110639 857750 9.52 + rawstudio-mint14.tar zstd 1 8558382592 3609250104 17136 476.27 rawstudio-mint14.tar zstd 3 8558382592 3341679997 29262 278.92 rawstudio-mint14.tar zstd 6 8558382592 3235846406 77904 104.77 rawstudio-mint14.tar zstd 9 8558382592 3160778861 140946 57.91 + rawstudio-mint14.tar gzstd 1 8558382592 3926257486 57722 141.40 -rawstudio-mint14.tar gzkp 1 8558382592 3970463184 41749 195.49 +rawstudio-mint14.tar gzkp 1 8558382592 3962605659 45113 180.92 CSV data: https://files.klauspost.com/compress/nyc-taxi-data-10M.csv.zst @@ -232,13 +240,15 @@ file out level insize outsize millis mb/s nyc-taxi-data-10M.csv zskp 1 3325605752 641339945 8925 355.35 nyc-taxi-data-10M.csv zskp 2 3325605752 591748091 11268 281.44 nyc-taxi-data-10M.csv zskp 3 3325605752 530289687 25239 125.66 -nyc-taxi-data-10M.csv zskp 4 3325605752 490907191 65939 48.10 +nyc-taxi-data-10M.csv zskp 4 3325605752 476268884 135958 23.33 + nyc-taxi-data-10M.csv zstd 1 3325605752 687399637 8233 385.18 nyc-taxi-data-10M.csv zstd 3 3325605752 598514411 10065 315.07 nyc-taxi-data-10M.csv zstd 6 3325605752 570522953 20038 158.27 nyc-taxi-data-10M.csv zstd 9 3325605752 517554797 64565 49.12 + nyc-taxi-data-10M.csv gzstd 1 3325605752 928656485 23876 132.83 -nyc-taxi-data-10M.csv gzkp 1 3325605752 924718719 16388 193.53 +nyc-taxi-data-10M.csv gzkp 1 3325605752 922257165 16780 189.00 ``` ## Decompressor diff --git a/vendor/github.com/klauspost/compress/zstd/blockdec.go b/vendor/github.com/klauspost/compress/zstd/blockdec.go index e30af505ca..8a98c4562e 100644 --- a/vendor/github.com/klauspost/compress/zstd/blockdec.go +++ b/vendor/github.com/klauspost/compress/zstd/blockdec.go @@ -168,10 +168,10 @@ func (b *blockDec) reset(br byteBuffer, windowSize uint64) error { // Read block data. if cap(b.dataStorage) < cSize { - if b.lowMem { + if b.lowMem || cSize > maxCompressedBlockSize { b.dataStorage = make([]byte, 0, cSize) } else { - b.dataStorage = make([]byte, 0, maxBlockSize) + b.dataStorage = make([]byte, 0, maxCompressedBlockSize) } } if cap(b.dst) <= maxSize { diff --git a/vendor/github.com/klauspost/compress/zstd/decoder.go b/vendor/github.com/klauspost/compress/zstd/decoder.go index 4d984c3b26..f430f58b57 100644 --- a/vendor/github.com/klauspost/compress/zstd/decoder.go +++ b/vendor/github.com/klauspost/compress/zstd/decoder.go @@ -260,9 +260,10 @@ func (d *Decoder) WriteTo(w io.Writer) (int64, error) { if len(d.current.b) > 0 { n2, err2 := w.Write(d.current.b) n += int64(n2) - if err2 != nil && d.current.err == nil { + if err2 != nil && (d.current.err == nil || d.current.err == io.EOF) { d.current.err = err2 - break + } else if n2 != len(d.current.b) { + d.current.err = io.ErrShortWrite } } if d.current.err != nil { diff --git a/vendor/github.com/klauspost/compress/zstd/decoder_options.go b/vendor/github.com/klauspost/compress/zstd/decoder_options.go index c0fd058c28..95cc9b8b81 100644 --- a/vendor/github.com/klauspost/compress/zstd/decoder_options.go +++ b/vendor/github.com/klauspost/compress/zstd/decoder_options.go @@ -17,14 +17,16 @@ type decoderOptions struct { lowMem bool concurrent int maxDecodedSize uint64 + maxWindowSize uint64 dicts []dict } func (o *decoderOptions) setDefault() { *o = decoderOptions{ // use less ram: true for now, but may change. - lowMem: true, - concurrent: runtime.GOMAXPROCS(0), + lowMem: true, + concurrent: runtime.GOMAXPROCS(0), + maxWindowSize: MaxWindowSize, } o.maxDecodedSize = 1 << 63 } @@ -52,7 +54,6 @@ func WithDecoderConcurrency(n int) DOption { // WithDecoderMaxMemory allows to set a maximum decoded size for in-memory // non-streaming operations or maximum window size for streaming operations. // This can be used to control memory usage of potentially hostile content. -// For streaming operations, the maximum window size is capped at 1<<30 bytes. // Maximum and default is 1 << 63 bytes. func WithDecoderMaxMemory(n uint64) DOption { return func(o *decoderOptions) error { @@ -81,3 +82,21 @@ func WithDecoderDicts(dicts ...[]byte) DOption { return nil } } + +// WithDecoderMaxWindow allows to set a maximum window size for decodes. +// This allows rejecting packets that will cause big memory usage. +// The Decoder will likely allocate more memory based on the WithDecoderLowmem setting. +// If WithDecoderMaxMemory is set to a lower value, that will be used. +// Default is 512MB, Maximum is ~3.75 TB as per zstandard spec. +func WithDecoderMaxWindow(size uint64) DOption { + return func(o *decoderOptions) error { + if size < MinWindowSize { + return errors.New("WithMaxWindowSize must be at least 1KB, 1024 bytes") + } + if size > (1<<41)+7*(1<<38) { + return errors.New("WithMaxWindowSize must be less than (1<<41) + 7*(1<<38) ~ 3.75TB") + } + o.maxWindowSize = size + return nil + } +} diff --git a/vendor/github.com/klauspost/compress/zstd/enc_base.go b/vendor/github.com/klauspost/compress/zstd/enc_base.go index 60f2986486..295cd602a4 100644 --- a/vendor/github.com/klauspost/compress/zstd/enc_base.go +++ b/vendor/github.com/klauspost/compress/zstd/enc_base.go @@ -38,8 +38,8 @@ func (e *fastBase) AppendCRC(dst []byte) []byte { // WindowSize returns the window size of the encoder, // or a window size small enough to contain the input size, if > 0. -func (e *fastBase) WindowSize(size int) int32 { - if size > 0 && size < int(e.maxMatchOff) { +func (e *fastBase) WindowSize(size int64) int32 { + if size > 0 && size < int64(e.maxMatchOff) { b := int32(1) << uint(bits.Len(uint(size))) // Keep minimum window. if b < 1024 { diff --git a/vendor/github.com/klauspost/compress/zstd/enc_best.go b/vendor/github.com/klauspost/compress/zstd/enc_best.go index b7d4b90047..96028ecd83 100644 --- a/vendor/github.com/klauspost/compress/zstd/enc_best.go +++ b/vendor/github.com/klauspost/compress/zstd/enc_best.go @@ -5,22 +5,61 @@ package zstd import ( + "bytes" "fmt" - "math/bits" + + "github.com/klauspost/compress" ) const ( - bestLongTableBits = 20 // Bits used in the long match table + bestLongTableBits = 22 // Bits used in the long match table bestLongTableSize = 1 << bestLongTableBits // Size of the table + bestLongLen = 8 // Bytes used for table hash // Note: Increasing the short table bits or making the hash shorter // can actually lead to compression degradation since it will 'steal' more from the // long match table and match offsets are quite big. // This greatly depends on the type of input. - bestShortTableBits = 16 // Bits used in the short match table + bestShortTableBits = 18 // Bits used in the short match table bestShortTableSize = 1 << bestShortTableBits // Size of the table + bestShortLen = 4 // Bytes used for table hash + ) +type match struct { + offset int32 + s int32 + length int32 + rep int32 + est int32 +} + +const highScore = 25000 + +// estBits will estimate output bits from predefined tables. +func (m *match) estBits(bitsPerByte int32) { + mlc := mlCode(uint32(m.length - zstdMinMatch)) + var ofc uint8 + if m.rep < 0 { + ofc = ofCode(uint32(m.s-m.offset) + 3) + } else { + ofc = ofCode(uint32(m.rep)) + } + // Cost, excluding + ofTT, mlTT := fsePredefEnc[tableOffsets].ct.symbolTT[ofc], fsePredefEnc[tableMatchLengths].ct.symbolTT[mlc] + + // Add cost of match encoding... + m.est = int32(ofTT.outBits + mlTT.outBits) + m.est += int32(ofTT.deltaNbBits>>16 + mlTT.deltaNbBits>>16) + // Subtract savings compared to literal encoding... + m.est -= (m.length * bitsPerByte) >> 10 + if m.est > 0 { + // Unlikely gain.. + m.length = 0 + m.est = highScore + } +} + // bestFastEncoder uses 2 tables, one for short matches (5 bytes) and one for long matches. // The long match table contains the previous entry with the same hash, // effectively making it a "chain" of length 2. @@ -109,6 +148,14 @@ func (e *bestFastEncoder) Encode(blk *blockEnc, src []byte) { return } + // Use this to estimate literal cost. + // Scaled by 10 bits. + bitsPerByte := int32((compress.ShannonEntropyBits(src) * 1024) / len(src)) + // Huffman can never go < 1 bit/byte + if bitsPerByte < 1024 { + bitsPerByte = 1024 + } + // Override src src = e.hist sLimit := int32(len(src)) - inputMargin @@ -145,51 +192,49 @@ encodeLoop: panic("offset0 was 0") } - type match struct { - offset int32 - s int32 - length int32 - rep int32 - } - matchAt := func(offset int32, s int32, first uint32, rep int32) match { - if s-offset >= e.maxMatchOff || load3232(src, offset) != first { - return match{offset: offset, s: s} - } - return match{offset: offset, s: s, length: 4 + e.matchlen(s+4, offset+4, src), rep: rep} - } - bestOf := func(a, b match) match { - aScore := b.s - a.s + a.length - bScore := a.s - b.s + b.length - if a.rep < 0 { - aScore = aScore - int32(bits.Len32(uint32(a.offset)))/8 - } - if b.rep < 0 { - bScore = bScore - int32(bits.Len32(uint32(b.offset)))/8 - } - if aScore >= bScore { + if a.est+(a.s-b.s)*bitsPerByte>>10 < b.est+(b.s-a.s)*bitsPerByte>>10 { return a } return b } const goodEnough = 100 - nextHashL := hash8(cv, bestLongTableBits) - nextHashS := hash4x64(cv, bestShortTableBits) + nextHashL := hashLen(cv, bestLongTableBits, bestLongLen) + nextHashS := hashLen(cv, bestShortTableBits, bestShortLen) candidateL := e.longTable[nextHashL] candidateS := e.table[nextHashS] + matchAt := func(offset int32, s int32, first uint32, rep int32) match { + if s-offset >= e.maxMatchOff || load3232(src, offset) != first { + return match{s: s, est: highScore} + } + if debugAsserts { + if !bytes.Equal(src[s:s+4], src[offset:offset+4]) { + panic(fmt.Sprintf("first match mismatch: %v != %v, first: %08x", src[s:s+4], src[offset:offset+4], first)) + } + } + m := match{offset: offset, s: s, length: 4 + e.matchlen(s+4, offset+4, src), rep: rep} + m.estBits(bitsPerByte) + return m + } + best := bestOf(matchAt(candidateL.offset-e.cur, s, uint32(cv), -1), matchAt(candidateL.prev-e.cur, s, uint32(cv), -1)) best = bestOf(best, matchAt(candidateS.offset-e.cur, s, uint32(cv), -1)) best = bestOf(best, matchAt(candidateS.prev-e.cur, s, uint32(cv), -1)) + if canRepeat && best.length < goodEnough { - best = bestOf(best, matchAt(s-offset1+1, s+1, uint32(cv>>8), 1)) - best = bestOf(best, matchAt(s-offset2+1, s+1, uint32(cv>>8), 2)) - best = bestOf(best, matchAt(s-offset3+1, s+1, uint32(cv>>8), 3)) + cv32 := uint32(cv >> 8) + spp := s + 1 + best = bestOf(best, matchAt(spp-offset1, spp, cv32, 1)) + best = bestOf(best, matchAt(spp-offset2, spp, cv32, 2)) + best = bestOf(best, matchAt(spp-offset3, spp, cv32, 3)) if best.length > 0 { - best = bestOf(best, matchAt(s-offset1+3, s+3, uint32(cv>>24), 1)) - best = bestOf(best, matchAt(s-offset2+3, s+3, uint32(cv>>24), 2)) - best = bestOf(best, matchAt(s-offset3+3, s+3, uint32(cv>>24), 3)) + cv32 = uint32(cv >> 24) + spp += 2 + best = bestOf(best, matchAt(spp-offset1, spp, cv32, 1)) + best = bestOf(best, matchAt(spp-offset2, spp, cv32, 2)) + best = bestOf(best, matchAt(spp-offset3, spp, cv32, 3)) } } // Load next and check... @@ -209,22 +254,28 @@ encodeLoop: } s++ - candidateS = e.table[hash4x64(cv>>8, bestShortTableBits)] + candidateS = e.table[hashLen(cv>>8, bestShortTableBits, bestShortLen)] cv = load6432(src, s) cv2 := load6432(src, s+1) - candidateL = e.longTable[hash8(cv, bestLongTableBits)] - candidateL2 := e.longTable[hash8(cv2, bestLongTableBits)] + candidateL = e.longTable[hashLen(cv, bestLongTableBits, bestLongLen)] + candidateL2 := e.longTable[hashLen(cv2, bestLongTableBits, bestLongLen)] + // Short at s+1 best = bestOf(best, matchAt(candidateS.offset-e.cur, s, uint32(cv), -1)) + // Long at s+1, s+2 best = bestOf(best, matchAt(candidateL.offset-e.cur, s, uint32(cv), -1)) best = bestOf(best, matchAt(candidateL.prev-e.cur, s, uint32(cv), -1)) best = bestOf(best, matchAt(candidateL2.offset-e.cur, s+1, uint32(cv2), -1)) best = bestOf(best, matchAt(candidateL2.prev-e.cur, s+1, uint32(cv2), -1)) - + if false { + // Short at s+3. + // Too often worse... + best = bestOf(best, matchAt(e.table[hashLen(cv2>>8, bestShortTableBits, bestShortLen)].offset-e.cur, s+2, uint32(cv2>>8), -1)) + } // See if we can find a better match by checking where the current best ends. // Use that offset to see if we can find a better full match. if sAt := best.s + best.length; sAt < sLimit { - nextHashL := hash8(load6432(src, sAt), bestLongTableBits) + nextHashL := hashLen(load6432(src, sAt), bestLongTableBits, bestLongLen) candidateEnd := e.longTable[nextHashL] if pos := candidateEnd.offset - e.cur - best.length; pos >= 0 { bestEnd := bestOf(best, matchAt(pos, best.s, load3232(src, best.s), -1)) @@ -236,6 +287,12 @@ encodeLoop: } } + if debugAsserts { + if !bytes.Equal(src[best.s:best.s+best.length], src[best.offset:best.offset+best.length]) { + panic(fmt.Sprintf("match mismatch: %v != %v", src[best.s:best.s+best.length], src[best.offset:best.offset+best.length])) + } + } + // We have a match, we can store the forward value if best.rep > 0 { s = best.s @@ -284,8 +341,8 @@ encodeLoop: off := index0 + e.cur for index0 < s-1 { cv0 := load6432(src, index0) - h0 := hash8(cv0, bestLongTableBits) - h1 := hash4x64(cv0, bestShortTableBits) + h0 := hashLen(cv0, bestLongTableBits, bestLongLen) + h1 := hashLen(cv0, bestShortTableBits, bestShortLen) e.longTable[h0] = prevEntry{offset: off, prev: e.longTable[h0].offset} e.table[h1] = prevEntry{offset: off, prev: e.table[h1].offset} off++ @@ -311,7 +368,7 @@ encodeLoop: panic(fmt.Sprintf("s (%d) <= t (%d)", s, t)) } - if debugAsserts && canRepeat && int(offset1) > len(src) { + if debugAsserts && int(offset1) > len(src) { panic("invalid offset") } @@ -352,8 +409,8 @@ encodeLoop: // every entry for index0 < s-1 { cv0 := load6432(src, index0) - h0 := hash8(cv0, bestLongTableBits) - h1 := hash4x64(cv0, bestShortTableBits) + h0 := hashLen(cv0, bestLongTableBits, bestLongLen) + h1 := hashLen(cv0, bestShortTableBits, bestShortLen) off := index0 + e.cur e.longTable[h0] = prevEntry{offset: off, prev: e.longTable[h0].offset} e.table[h1] = prevEntry{offset: off, prev: e.table[h1].offset} @@ -374,8 +431,8 @@ encodeLoop: } // Store this, since we have it. - nextHashS := hash4x64(cv, bestShortTableBits) - nextHashL := hash8(cv, bestLongTableBits) + nextHashS := hashLen(cv, bestShortTableBits, bestShortLen) + nextHashL := hashLen(cv, bestLongTableBits, bestLongLen) // We have at least 4 byte match. // No need to check backwards. We come straight from a match @@ -425,7 +482,7 @@ func (e *bestFastEncoder) EncodeNoHist(blk *blockEnc, src []byte) { e.Encode(blk, src) } -// ResetDict will reset and set a dictionary if not nil +// Reset will reset and set a dictionary if not nil func (e *bestFastEncoder) Reset(d *dict, singleBlock bool) { e.resetBase(d, singleBlock) if d == nil { @@ -441,10 +498,10 @@ func (e *bestFastEncoder) Reset(d *dict, singleBlock bool) { const hashLog = bestShortTableBits cv := load6432(d.content, i-e.maxMatchOff) - nextHash := hash4x64(cv, hashLog) // 0 -> 4 - nextHash1 := hash4x64(cv>>8, hashLog) // 1 -> 5 - nextHash2 := hash4x64(cv>>16, hashLog) // 2 -> 6 - nextHash3 := hash4x64(cv>>24, hashLog) // 3 -> 7 + nextHash := hashLen(cv, hashLog, bestShortLen) // 0 -> 4 + nextHash1 := hashLen(cv>>8, hashLog, bestShortLen) // 1 -> 5 + nextHash2 := hashLen(cv>>16, hashLog, bestShortLen) // 2 -> 6 + nextHash3 := hashLen(cv>>24, hashLog, bestShortLen) // 3 -> 7 e.dictTable[nextHash] = prevEntry{ prev: e.dictTable[nextHash].offset, offset: i, @@ -472,7 +529,7 @@ func (e *bestFastEncoder) Reset(d *dict, singleBlock bool) { } if len(d.content) >= 8 { cv := load6432(d.content, 0) - h := hash8(cv, bestLongTableBits) + h := hashLen(cv, bestLongTableBits, bestLongLen) e.dictLongTable[h] = prevEntry{ offset: e.maxMatchOff, prev: e.dictLongTable[h].offset, @@ -482,7 +539,7 @@ func (e *bestFastEncoder) Reset(d *dict, singleBlock bool) { off := 8 // First to read for i := e.maxMatchOff + 1; i < end; i++ { cv = cv>>8 | (uint64(d.content[off]) << 56) - h := hash8(cv, bestLongTableBits) + h := hashLen(cv, bestLongTableBits, bestLongLen) e.dictLongTable[h] = prevEntry{ offset: i, prev: e.dictLongTable[h].offset, diff --git a/vendor/github.com/klauspost/compress/zstd/enc_better.go b/vendor/github.com/klauspost/compress/zstd/enc_better.go index eab7b5083e..602c05ee0c 100644 --- a/vendor/github.com/klauspost/compress/zstd/enc_better.go +++ b/vendor/github.com/klauspost/compress/zstd/enc_better.go @@ -9,6 +9,7 @@ import "fmt" const ( betterLongTableBits = 19 // Bits used in the long match table betterLongTableSize = 1 << betterLongTableBits // Size of the table + betterLongLen = 8 // Bytes used for table hash // Note: Increasing the short table bits or making the hash shorter // can actually lead to compression degradation since it will 'steal' more from the @@ -16,6 +17,7 @@ const ( // This greatly depends on the type of input. betterShortTableBits = 13 // Bits used in the short match table betterShortTableSize = 1 << betterShortTableBits // Size of the table + betterShortLen = 5 // Bytes used for table hash betterLongTableShardCnt = 1 << (betterLongTableBits - dictShardBits) // Number of shards in the table betterLongTableShardSize = betterLongTableSize / betterLongTableShardCnt // Size of an individual shard @@ -154,8 +156,8 @@ encodeLoop: panic("offset0 was 0") } - nextHashS := hash5(cv, betterShortTableBits) - nextHashL := hash8(cv, betterLongTableBits) + nextHashS := hashLen(cv, betterShortTableBits, betterShortLen) + nextHashL := hashLen(cv, betterLongTableBits, betterLongLen) candidateL := e.longTable[nextHashL] candidateS := e.table[nextHashS] @@ -214,10 +216,10 @@ encodeLoop: for index0 < s-1 { cv0 := load6432(src, index0) cv1 := cv0 >> 8 - h0 := hash8(cv0, betterLongTableBits) + h0 := hashLen(cv0, betterLongTableBits, betterLongLen) off := index0 + e.cur e.longTable[h0] = prevEntry{offset: off, prev: e.longTable[h0].offset} - e.table[hash5(cv1, betterShortTableBits)] = tableEntry{offset: off + 1, val: uint32(cv1)} + e.table[hashLen(cv1, betterShortTableBits, betterShortLen)] = tableEntry{offset: off + 1, val: uint32(cv1)} index0 += 2 } cv = load6432(src, s) @@ -275,10 +277,10 @@ encodeLoop: for index0 < s-1 { cv0 := load6432(src, index0) cv1 := cv0 >> 8 - h0 := hash8(cv0, betterLongTableBits) + h0 := hashLen(cv0, betterLongTableBits, betterLongLen) off := index0 + e.cur e.longTable[h0] = prevEntry{offset: off, prev: e.longTable[h0].offset} - e.table[hash5(cv1, betterShortTableBits)] = tableEntry{offset: off + 1, val: uint32(cv1)} + e.table[hashLen(cv1, betterShortTableBits, betterShortLen)] = tableEntry{offset: off + 1, val: uint32(cv1)} index0 += 2 } cv = load6432(src, s) @@ -353,7 +355,7 @@ encodeLoop: // See if we can find a long match at s+1 const checkAt = 1 cv := load6432(src, s+checkAt) - nextHashL = hash8(cv, betterLongTableBits) + nextHashL = hashLen(cv, betterLongTableBits, betterLongLen) candidateL = e.longTable[nextHashL] coffsetL = candidateL.offset - e.cur @@ -413,8 +415,8 @@ encodeLoop: } // Try to find a better match by searching for a long match at the end of the current best match - if true && s+matched < sLimit { - nextHashL := hash8(load6432(src, s+matched), betterLongTableBits) + if s+matched < sLimit { + nextHashL := hashLen(load6432(src, s+matched), betterLongTableBits, betterLongLen) cv := load3232(src, s) candidateL := e.longTable[nextHashL] coffsetL := candidateL.offset - e.cur - matched @@ -495,10 +497,10 @@ encodeLoop: for index0 < s-1 { cv0 := load6432(src, index0) cv1 := cv0 >> 8 - h0 := hash8(cv0, betterLongTableBits) + h0 := hashLen(cv0, betterLongTableBits, betterLongLen) off := index0 + e.cur e.longTable[h0] = prevEntry{offset: off, prev: e.longTable[h0].offset} - e.table[hash5(cv1, betterShortTableBits)] = tableEntry{offset: off + 1, val: uint32(cv1)} + e.table[hashLen(cv1, betterShortTableBits, betterShortLen)] = tableEntry{offset: off + 1, val: uint32(cv1)} index0 += 2 } @@ -516,8 +518,8 @@ encodeLoop: } // Store this, since we have it. - nextHashS := hash5(cv, betterShortTableBits) - nextHashL := hash8(cv, betterLongTableBits) + nextHashS := hashLen(cv, betterShortTableBits, betterShortLen) + nextHashL := hashLen(cv, betterLongTableBits, betterLongLen) // We have at least 4 byte match. // No need to check backwards. We come straight from a match @@ -672,8 +674,8 @@ encodeLoop: panic("offset0 was 0") } - nextHashS := hash5(cv, betterShortTableBits) - nextHashL := hash8(cv, betterLongTableBits) + nextHashS := hashLen(cv, betterShortTableBits, betterShortLen) + nextHashL := hashLen(cv, betterLongTableBits, betterLongLen) candidateL := e.longTable[nextHashL] candidateS := e.table[nextHashS] @@ -734,11 +736,11 @@ encodeLoop: for index0 < s-1 { cv0 := load6432(src, index0) cv1 := cv0 >> 8 - h0 := hash8(cv0, betterLongTableBits) + h0 := hashLen(cv0, betterLongTableBits, betterLongLen) off := index0 + e.cur e.longTable[h0] = prevEntry{offset: off, prev: e.longTable[h0].offset} e.markLongShardDirty(h0) - h1 := hash5(cv1, betterShortTableBits) + h1 := hashLen(cv1, betterShortTableBits, betterShortLen) e.table[h1] = tableEntry{offset: off + 1, val: uint32(cv1)} e.markShortShardDirty(h1) index0 += 2 @@ -798,11 +800,11 @@ encodeLoop: for index0 < s-1 { cv0 := load6432(src, index0) cv1 := cv0 >> 8 - h0 := hash8(cv0, betterLongTableBits) + h0 := hashLen(cv0, betterLongTableBits, betterLongLen) off := index0 + e.cur e.longTable[h0] = prevEntry{offset: off, prev: e.longTable[h0].offset} e.markLongShardDirty(h0) - h1 := hash5(cv1, betterShortTableBits) + h1 := hashLen(cv1, betterShortTableBits, betterShortLen) e.table[h1] = tableEntry{offset: off + 1, val: uint32(cv1)} e.markShortShardDirty(h1) index0 += 2 @@ -879,7 +881,7 @@ encodeLoop: // See if we can find a long match at s+1 const checkAt = 1 cv := load6432(src, s+checkAt) - nextHashL = hash8(cv, betterLongTableBits) + nextHashL = hashLen(cv, betterLongTableBits, betterLongLen) candidateL = e.longTable[nextHashL] coffsetL = candidateL.offset - e.cur @@ -940,7 +942,7 @@ encodeLoop: } // Try to find a better match by searching for a long match at the end of the current best match if s+matched < sLimit { - nextHashL := hash8(load6432(src, s+matched), betterLongTableBits) + nextHashL := hashLen(load6432(src, s+matched), betterLongTableBits, betterLongLen) cv := load3232(src, s) candidateL := e.longTable[nextHashL] coffsetL := candidateL.offset - e.cur - matched @@ -1021,11 +1023,11 @@ encodeLoop: for index0 < s-1 { cv0 := load6432(src, index0) cv1 := cv0 >> 8 - h0 := hash8(cv0, betterLongTableBits) + h0 := hashLen(cv0, betterLongTableBits, betterLongLen) off := index0 + e.cur e.longTable[h0] = prevEntry{offset: off, prev: e.longTable[h0].offset} e.markLongShardDirty(h0) - h1 := hash5(cv1, betterShortTableBits) + h1 := hashLen(cv1, betterShortTableBits, betterShortLen) e.table[h1] = tableEntry{offset: off + 1, val: uint32(cv1)} e.markShortShardDirty(h1) index0 += 2 @@ -1045,8 +1047,8 @@ encodeLoop: } // Store this, since we have it. - nextHashS := hash5(cv, betterShortTableBits) - nextHashL := hash8(cv, betterLongTableBits) + nextHashS := hashLen(cv, betterShortTableBits, betterShortLen) + nextHashL := hashLen(cv, betterLongTableBits, betterLongLen) // We have at least 4 byte match. // No need to check backwards. We come straight from a match @@ -1113,10 +1115,10 @@ func (e *betterFastEncoderDict) Reset(d *dict, singleBlock bool) { const hashLog = betterShortTableBits cv := load6432(d.content, i-e.maxMatchOff) - nextHash := hash5(cv, hashLog) // 0 -> 4 - nextHash1 := hash5(cv>>8, hashLog) // 1 -> 5 - nextHash2 := hash5(cv>>16, hashLog) // 2 -> 6 - nextHash3 := hash5(cv>>24, hashLog) // 3 -> 7 + nextHash := hashLen(cv, hashLog, betterShortLen) // 0 -> 4 + nextHash1 := hashLen(cv>>8, hashLog, betterShortLen) // 1 -> 5 + nextHash2 := hashLen(cv>>16, hashLog, betterShortLen) // 2 -> 6 + nextHash3 := hashLen(cv>>24, hashLog, betterShortLen) // 3 -> 7 e.dictTable[nextHash] = tableEntry{ val: uint32(cv), offset: i, @@ -1145,7 +1147,7 @@ func (e *betterFastEncoderDict) Reset(d *dict, singleBlock bool) { } if len(d.content) >= 8 { cv := load6432(d.content, 0) - h := hash8(cv, betterLongTableBits) + h := hashLen(cv, betterLongTableBits, betterLongLen) e.dictLongTable[h] = prevEntry{ offset: e.maxMatchOff, prev: e.dictLongTable[h].offset, @@ -1155,7 +1157,7 @@ func (e *betterFastEncoderDict) Reset(d *dict, singleBlock bool) { off := 8 // First to read for i := e.maxMatchOff + 1; i < end; i++ { cv = cv>>8 | (uint64(d.content[off]) << 56) - h := hash8(cv, betterLongTableBits) + h := hashLen(cv, betterLongTableBits, betterLongLen) e.dictLongTable[h] = prevEntry{ offset: i, prev: e.dictLongTable[h].offset, diff --git a/vendor/github.com/klauspost/compress/zstd/enc_dfast.go b/vendor/github.com/klauspost/compress/zstd/enc_dfast.go index 96b21b90e8..d6b3104240 100644 --- a/vendor/github.com/klauspost/compress/zstd/enc_dfast.go +++ b/vendor/github.com/klauspost/compress/zstd/enc_dfast.go @@ -10,6 +10,7 @@ const ( dFastLongTableBits = 17 // Bits used in the long match table dFastLongTableSize = 1 << dFastLongTableBits // Size of the table dFastLongTableMask = dFastLongTableSize - 1 // Mask for table indices. Redundant, but can eliminate bounds checks. + dFastLongLen = 8 // Bytes used for table hash dLongTableShardCnt = 1 << (dFastLongTableBits - dictShardBits) // Number of shards in the table dLongTableShardSize = dFastLongTableSize / tableShardCnt // Size of an individual shard @@ -17,6 +18,8 @@ const ( dFastShortTableBits = tableBits // Bits used in the short match table dFastShortTableSize = 1 << dFastShortTableBits // Size of the table dFastShortTableMask = dFastShortTableSize - 1 // Mask for table indices. Redundant, but can eliminate bounds checks. + dFastShortLen = 5 // Bytes used for table hash + ) type doubleFastEncoder struct { @@ -124,8 +127,8 @@ encodeLoop: panic("offset0 was 0") } - nextHashS := hash5(cv, dFastShortTableBits) - nextHashL := hash8(cv, dFastLongTableBits) + nextHashS := hashLen(cv, dFastShortTableBits, dFastShortLen) + nextHashL := hashLen(cv, dFastLongTableBits, dFastLongLen) candidateL := e.longTable[nextHashL] candidateS := e.table[nextHashS] @@ -208,7 +211,7 @@ encodeLoop: // See if we can find a long match at s+1 const checkAt = 1 cv := load6432(src, s+checkAt) - nextHashL = hash8(cv, dFastLongTableBits) + nextHashL = hashLen(cv, dFastLongTableBits, dFastLongLen) candidateL = e.longTable[nextHashL] coffsetL = s - (candidateL.offset - e.cur) + checkAt @@ -304,16 +307,16 @@ encodeLoop: cv1 := load6432(src, index1) te0 := tableEntry{offset: index0 + e.cur, val: uint32(cv0)} te1 := tableEntry{offset: index1 + e.cur, val: uint32(cv1)} - e.longTable[hash8(cv0, dFastLongTableBits)] = te0 - e.longTable[hash8(cv1, dFastLongTableBits)] = te1 + e.longTable[hashLen(cv0, dFastLongTableBits, dFastLongLen)] = te0 + e.longTable[hashLen(cv1, dFastLongTableBits, dFastLongLen)] = te1 cv0 >>= 8 cv1 >>= 8 te0.offset++ te1.offset++ te0.val = uint32(cv0) te1.val = uint32(cv1) - e.table[hash5(cv0, dFastShortTableBits)] = te0 - e.table[hash5(cv1, dFastShortTableBits)] = te1 + e.table[hashLen(cv0, dFastShortTableBits, dFastShortLen)] = te0 + e.table[hashLen(cv1, dFastShortTableBits, dFastShortLen)] = te1 cv = load6432(src, s) @@ -330,8 +333,8 @@ encodeLoop: } // Store this, since we have it. - nextHashS := hash5(cv, dFastShortTableBits) - nextHashL := hash8(cv, dFastLongTableBits) + nextHashS := hashLen(cv, dFastShortTableBits, dFastShortLen) + nextHashL := hashLen(cv, dFastLongTableBits, dFastLongLen) // We have at least 4 byte match. // No need to check backwards. We come straight from a match @@ -436,8 +439,8 @@ encodeLoop: var t int32 for { - nextHashS := hash5(cv, dFastShortTableBits) - nextHashL := hash8(cv, dFastLongTableBits) + nextHashS := hashLen(cv, dFastShortTableBits, dFastShortLen) + nextHashL := hashLen(cv, dFastLongTableBits, dFastLongLen) candidateL := e.longTable[nextHashL] candidateS := e.table[nextHashS] @@ -521,7 +524,7 @@ encodeLoop: // See if we can find a long match at s+1 const checkAt = 1 cv := load6432(src, s+checkAt) - nextHashL = hash8(cv, dFastLongTableBits) + nextHashL = hashLen(cv, dFastLongTableBits, dFastLongLen) candidateL = e.longTable[nextHashL] coffsetL = s - (candidateL.offset - e.cur) + checkAt @@ -614,16 +617,16 @@ encodeLoop: cv1 := load6432(src, index1) te0 := tableEntry{offset: index0 + e.cur, val: uint32(cv0)} te1 := tableEntry{offset: index1 + e.cur, val: uint32(cv1)} - e.longTable[hash8(cv0, dFastLongTableBits)] = te0 - e.longTable[hash8(cv1, dFastLongTableBits)] = te1 + e.longTable[hashLen(cv0, dFastLongTableBits, dFastLongLen)] = te0 + e.longTable[hashLen(cv1, dFastLongTableBits, dFastLongLen)] = te1 cv0 >>= 8 cv1 >>= 8 te0.offset++ te1.offset++ te0.val = uint32(cv0) te1.val = uint32(cv1) - e.table[hash5(cv0, dFastShortTableBits)] = te0 - e.table[hash5(cv1, dFastShortTableBits)] = te1 + e.table[hashLen(cv0, dFastShortTableBits, dFastShortLen)] = te0 + e.table[hashLen(cv1, dFastShortTableBits, dFastShortLen)] = te1 cv = load6432(src, s) @@ -640,8 +643,8 @@ encodeLoop: } // Store this, since we have it. - nextHashS := hash5(cv1>>8, dFastShortTableBits) - nextHashL := hash8(cv, dFastLongTableBits) + nextHashS := hashLen(cv1>>8, dFastShortTableBits, dFastShortLen) + nextHashL := hashLen(cv, dFastLongTableBits, dFastLongLen) // We have at least 4 byte match. // No need to check backwards. We come straight from a match @@ -782,8 +785,8 @@ encodeLoop: panic("offset0 was 0") } - nextHashS := hash5(cv, dFastShortTableBits) - nextHashL := hash8(cv, dFastLongTableBits) + nextHashS := hashLen(cv, dFastShortTableBits, dFastShortLen) + nextHashL := hashLen(cv, dFastLongTableBits, dFastLongLen) candidateL := e.longTable[nextHashL] candidateS := e.table[nextHashS] @@ -868,7 +871,7 @@ encodeLoop: // See if we can find a long match at s+1 const checkAt = 1 cv := load6432(src, s+checkAt) - nextHashL = hash8(cv, dFastLongTableBits) + nextHashL = hashLen(cv, dFastLongTableBits, dFastLongLen) candidateL = e.longTable[nextHashL] coffsetL = s - (candidateL.offset - e.cur) + checkAt @@ -965,8 +968,8 @@ encodeLoop: cv1 := load6432(src, index1) te0 := tableEntry{offset: index0 + e.cur, val: uint32(cv0)} te1 := tableEntry{offset: index1 + e.cur, val: uint32(cv1)} - longHash1 := hash8(cv0, dFastLongTableBits) - longHash2 := hash8(cv0, dFastLongTableBits) + longHash1 := hashLen(cv0, dFastLongTableBits, dFastLongLen) + longHash2 := hashLen(cv0, dFastLongTableBits, dFastLongLen) e.longTable[longHash1] = te0 e.longTable[longHash2] = te1 e.markLongShardDirty(longHash1) @@ -977,8 +980,8 @@ encodeLoop: te1.offset++ te0.val = uint32(cv0) te1.val = uint32(cv1) - hashVal1 := hash5(cv0, dFastShortTableBits) - hashVal2 := hash5(cv1, dFastShortTableBits) + hashVal1 := hashLen(cv0, dFastShortTableBits, dFastShortLen) + hashVal2 := hashLen(cv1, dFastShortTableBits, dFastShortLen) e.table[hashVal1] = te0 e.markShardDirty(hashVal1) e.table[hashVal2] = te1 @@ -999,8 +1002,8 @@ encodeLoop: } // Store this, since we have it. - nextHashS := hash5(cv, dFastShortTableBits) - nextHashL := hash8(cv, dFastLongTableBits) + nextHashS := hashLen(cv, dFastShortTableBits, dFastShortLen) + nextHashL := hashLen(cv, dFastLongTableBits, dFastLongLen) // We have at least 4 byte match. // No need to check backwards. We come straight from a match @@ -1071,14 +1074,14 @@ func (e *doubleFastEncoderDict) Reset(d *dict, singleBlock bool) { } if len(d.content) >= 8 { cv := load6432(d.content, 0) - e.dictLongTable[hash8(cv, dFastLongTableBits)] = tableEntry{ + e.dictLongTable[hashLen(cv, dFastLongTableBits, dFastLongLen)] = tableEntry{ val: uint32(cv), offset: e.maxMatchOff, } end := int32(len(d.content)) - 8 + e.maxMatchOff for i := e.maxMatchOff + 1; i < end; i++ { cv = cv>>8 | (uint64(d.content[i-e.maxMatchOff+7]) << 56) - e.dictLongTable[hash8(cv, dFastLongTableBits)] = tableEntry{ + e.dictLongTable[hashLen(cv, dFastLongTableBits, dFastLongLen)] = tableEntry{ val: uint32(cv), offset: i, } diff --git a/vendor/github.com/klauspost/compress/zstd/enc_fast.go b/vendor/github.com/klauspost/compress/zstd/enc_fast.go index 2246d286dc..f2502629bc 100644 --- a/vendor/github.com/klauspost/compress/zstd/enc_fast.go +++ b/vendor/github.com/klauspost/compress/zstd/enc_fast.go @@ -11,12 +11,13 @@ import ( ) const ( - tableBits = 15 // Bits used in the table - tableSize = 1 << tableBits // Size of the table - tableShardCnt = 1 << (tableBits - dictShardBits) // Number of shards in the table - tableShardSize = tableSize / tableShardCnt // Size of an individual shard - tableMask = tableSize - 1 // Mask for table indices. Redundant, but can eliminate bounds checks. - maxMatchLength = 131074 + tableBits = 15 // Bits used in the table + tableSize = 1 << tableBits // Size of the table + tableShardCnt = 1 << (tableBits - dictShardBits) // Number of shards in the table + tableShardSize = tableSize / tableShardCnt // Size of an individual shard + tableFastHashLen = 6 + tableMask = tableSize - 1 // Mask for table indices. Redundant, but can eliminate bounds checks. + maxMatchLength = 131074 ) type tableEntry struct { @@ -122,8 +123,8 @@ encodeLoop: panic("offset0 was 0") } - nextHash := hash6(cv, hashLog) - nextHash2 := hash6(cv>>8, hashLog) + nextHash := hashLen(cv, hashLog, tableFastHashLen) + nextHash2 := hashLen(cv>>8, hashLog, tableFastHashLen) candidate := e.table[nextHash] candidate2 := e.table[nextHash2] repIndex := s - offset1 + 2 @@ -301,7 +302,7 @@ encodeLoop: } // Store this, since we have it. - nextHash := hash6(cv, hashLog) + nextHash := hashLen(cv, hashLog, tableFastHashLen) e.table[nextHash] = tableEntry{offset: s + e.cur, val: uint32(cv)} seq.matchLen = uint32(l) - zstdMinMatch seq.litLen = 0 @@ -405,8 +406,8 @@ encodeLoop: // By not using them for the first 3 matches for { - nextHash := hash6(cv, hashLog) - nextHash2 := hash6(cv>>8, hashLog) + nextHash := hashLen(cv, hashLog, tableFastHashLen) + nextHash2 := hashLen(cv>>8, hashLog, tableFastHashLen) candidate := e.table[nextHash] candidate2 := e.table[nextHash2] repIndex := s - offset1 + 2 @@ -589,7 +590,7 @@ encodeLoop: } // Store this, since we have it. - nextHash := hash6(cv, hashLog) + nextHash := hashLen(cv, hashLog, tableFastHashLen) e.table[nextHash] = tableEntry{offset: s + e.cur, val: uint32(cv)} seq.matchLen = uint32(l) - zstdMinMatch seq.litLen = 0 @@ -715,8 +716,8 @@ encodeLoop: panic("offset0 was 0") } - nextHash := hash6(cv, hashLog) - nextHash2 := hash6(cv>>8, hashLog) + nextHash := hashLen(cv, hashLog, tableFastHashLen) + nextHash2 := hashLen(cv>>8, hashLog, tableFastHashLen) candidate := e.table[nextHash] candidate2 := e.table[nextHash2] repIndex := s - offset1 + 2 @@ -896,7 +897,7 @@ encodeLoop: } // Store this, since we have it. - nextHash := hash6(cv, hashLog) + nextHash := hashLen(cv, hashLog, tableFastHashLen) e.table[nextHash] = tableEntry{offset: s + e.cur, val: uint32(cv)} e.markShardDirty(nextHash) seq.matchLen = uint32(l) - zstdMinMatch @@ -957,9 +958,9 @@ func (e *fastEncoderDict) Reset(d *dict, singleBlock bool) { const hashLog = tableBits cv := load6432(d.content, i-e.maxMatchOff) - nextHash := hash6(cv, hashLog) // 0 -> 5 - nextHash1 := hash6(cv>>8, hashLog) // 1 -> 6 - nextHash2 := hash6(cv>>16, hashLog) // 2 -> 7 + nextHash := hashLen(cv, hashLog, tableFastHashLen) // 0 -> 5 + nextHash1 := hashLen(cv>>8, hashLog, tableFastHashLen) // 1 -> 6 + nextHash2 := hashLen(cv>>16, hashLog, tableFastHashLen) // 2 -> 7 e.dictTable[nextHash] = tableEntry{ val: uint32(cv), offset: i, diff --git a/vendor/github.com/klauspost/compress/zstd/encoder.go b/vendor/github.com/klauspost/compress/zstd/encoder.go index ea85548fc9..e6e315969b 100644 --- a/vendor/github.com/klauspost/compress/zstd/encoder.go +++ b/vendor/github.com/klauspost/compress/zstd/encoder.go @@ -33,7 +33,7 @@ type encoder interface { Block() *blockEnc CRC() *xxhash.Digest AppendCRC([]byte) []byte - WindowSize(size int) int32 + WindowSize(size int64) int32 UseBlock(*blockEnc) Reset(d *dict, singleBlock bool) } @@ -48,6 +48,8 @@ type encoderState struct { err error writeErr error nWritten int64 + nInput int64 + frameContentSize int64 headerWritten bool eofWritten bool fullFrameWritten bool @@ -120,7 +122,21 @@ func (e *Encoder) Reset(w io.Writer) { s.w = w s.err = nil s.nWritten = 0 + s.nInput = 0 s.writeErr = nil + s.frameContentSize = 0 +} + +// ResetContentSize will reset and set a content size for the next stream. +// If the bytes written does not match the size given an error will be returned +// when calling Close(). +// This is removed when Reset is called. +// Sizes <= 0 results in no content size set. +func (e *Encoder) ResetContentSize(w io.Writer, size int64) { + e.Reset(w) + if size >= 0 { + e.state.frameContentSize = size + } } // Write data to the encoder. @@ -190,6 +206,7 @@ func (e *Encoder) nextBlock(final bool) error { return s.err } s.nWritten += int64(n2) + s.nInput += int64(len(s.filling)) s.current = s.current[:0] s.filling = s.filling[:0] s.headerWritten = true @@ -200,8 +217,8 @@ func (e *Encoder) nextBlock(final bool) error { var tmp [maxHeaderSize]byte fh := frameHeader{ - ContentSize: 0, - WindowSize: uint32(s.encoder.WindowSize(0)), + ContentSize: uint64(s.frameContentSize), + WindowSize: uint32(s.encoder.WindowSize(s.frameContentSize)), SingleSegment: false, Checksum: e.o.crc, DictID: e.o.dict.ID(), @@ -243,6 +260,7 @@ func (e *Encoder) nextBlock(final bool) error { // Move blocks forward. s.filling, s.current, s.previous = s.previous[:0], s.filling, s.current + s.nInput += int64(len(s.current)) s.wg.Add(1) go func(src []byte) { if debugEncoder { @@ -394,6 +412,11 @@ func (e *Encoder) Close() error { if err != nil { return err } + if s.frameContentSize > 0 { + if s.nInput != s.frameContentSize { + return fmt.Errorf("frame content size %d given, but %d bytes was written", s.frameContentSize, s.nInput) + } + } if e.state.fullFrameWritten { return s.err } @@ -470,7 +493,7 @@ func (e *Encoder) EncodeAll(src, dst []byte) []byte { } fh := frameHeader{ ContentSize: uint64(len(src)), - WindowSize: uint32(enc.WindowSize(len(src))), + WindowSize: uint32(enc.WindowSize(int64(len(src)))), SingleSegment: single, Checksum: e.o.crc, DictID: e.o.dict.ID(), diff --git a/vendor/github.com/klauspost/compress/zstd/encoder_options.go b/vendor/github.com/klauspost/compress/zstd/encoder_options.go index 16d4ab63c1..7d29e1d689 100644 --- a/vendor/github.com/klauspost/compress/zstd/encoder_options.go +++ b/vendor/github.com/klauspost/compress/zstd/encoder_options.go @@ -189,7 +189,7 @@ func EncoderLevelFromZstd(level int) EncoderLevel { case level >= 6 && level < 10: return SpeedBetterCompression case level >= 10: - return SpeedBetterCompression + return SpeedBestCompression } return SpeedDefault } diff --git a/vendor/github.com/klauspost/compress/zstd/framedec.go b/vendor/github.com/klauspost/compress/zstd/framedec.go index e8cc9a2c22..989c79f8c3 100644 --- a/vendor/github.com/klauspost/compress/zstd/framedec.go +++ b/vendor/github.com/klauspost/compress/zstd/framedec.go @@ -22,10 +22,6 @@ type frameDec struct { WindowSize uint64 - // maxWindowSize is the maximum windows size to support. - // should never be bigger than max-int. - maxWindowSize uint64 - // In order queue of blocks being decoded. decoding chan *blockDec @@ -50,8 +46,11 @@ type frameDec struct { } const ( - // The minimum Window_Size is 1 KB. + // MinWindowSize is the minimum Window Size, which is 1 KB. MinWindowSize = 1 << 10 + + // MaxWindowSize is the maximum encoder window size + // and the default decoder maximum window size. MaxWindowSize = 1 << 29 ) @@ -61,12 +60,11 @@ var ( ) func newFrameDec(o decoderOptions) *frameDec { - d := frameDec{ - o: o, - maxWindowSize: MaxWindowSize, + if o.maxWindowSize > o.maxDecodedSize { + o.maxWindowSize = o.maxDecodedSize } - if d.maxWindowSize > o.maxDecodedSize { - d.maxWindowSize = o.maxDecodedSize + d := frameDec{ + o: o, } return &d } @@ -251,13 +249,17 @@ func (d *frameDec) reset(br byteBuffer) error { } } - if d.WindowSize > d.maxWindowSize { - printf("window size %d > max %d\n", d.WindowSize, d.maxWindowSize) + if d.WindowSize > uint64(d.o.maxWindowSize) { + if debugDecoder { + printf("window size %d > max %d\n", d.WindowSize, d.o.maxWindowSize) + } return ErrWindowSizeExceeded } // The minimum Window_Size is 1 KB. if d.WindowSize < MinWindowSize { - println("got window size: ", d.WindowSize) + if debugDecoder { + println("got window size: ", d.WindowSize) + } return ErrWindowSizeTooSmall } d.history.windowSize = int(d.WindowSize) @@ -352,8 +354,8 @@ func (d *frameDec) checkCRC() error { func (d *frameDec) initAsync() { if !d.o.lowMem && !d.SingleSegment { - // set max extra size history to 10MB. - d.history.maxSize = d.history.windowSize + maxBlockSize*5 + // set max extra size history to 2MB. + d.history.maxSize = d.history.windowSize + maxBlockSize } // re-alloc if more than one extra block size. if d.o.lowMem && cap(d.history.b) > d.history.maxSize+maxBlockSize { diff --git a/vendor/github.com/klauspost/compress/zstd/hash.go b/vendor/github.com/klauspost/compress/zstd/hash.go index 4a752067fc..cf33f29a1b 100644 --- a/vendor/github.com/klauspost/compress/zstd/hash.go +++ b/vendor/github.com/klauspost/compress/zstd/hash.go @@ -13,24 +13,24 @@ const ( prime8bytes = 0xcf1bbcdcb7a56463 ) -// hashLen returns a hash of the lowest l bytes of u for a size size of h bytes. -// l must be >=4 and <=8. Any other value will return hash for 4 bytes. -// h should always be <32. -// Preferably h and l should be a constant. -// FIXME: This does NOT get resolved, if 'mls' is constant, -// so this cannot be used. -func hashLen(u uint64, hashLog, mls uint8) uint32 { +// hashLen returns a hash of the lowest mls bytes of with length output bits. +// mls must be >=3 and <=8. Any other value will return hash for 4 bytes. +// length should always be < 32. +// Preferably length and mls should be a constant for inlining. +func hashLen(u uint64, length, mls uint8) uint32 { switch mls { + case 3: + return (uint32(u<<8) * prime3bytes) >> (32 - length) case 5: - return hash5(u, hashLog) + return uint32(((u << (64 - 40)) * prime5bytes) >> (64 - length)) case 6: - return hash6(u, hashLog) + return uint32(((u << (64 - 48)) * prime6bytes) >> (64 - length)) case 7: - return hash7(u, hashLog) + return uint32(((u << (64 - 56)) * prime7bytes) >> (64 - length)) case 8: - return hash8(u, hashLog) + return uint32((u * prime8bytes) >> (64 - length)) default: - return hash4x64(u, hashLog) + return (uint32(u) * prime4bytes) >> (32 - length) } } @@ -39,39 +39,3 @@ func hashLen(u uint64, hashLog, mls uint8) uint32 { func hash3(u uint32, h uint8) uint32 { return ((u << (32 - 24)) * prime3bytes) >> ((32 - h) & 31) } - -// hash4 returns the hash of u to fit in a hash table with h bits. -// Preferably h should be a constant and should always be <32. -func hash4(u uint32, h uint8) uint32 { - return (u * prime4bytes) >> ((32 - h) & 31) -} - -// hash4x64 returns the hash of the lowest 4 bytes of u to fit in a hash table with h bits. -// Preferably h should be a constant and should always be <32. -func hash4x64(u uint64, h uint8) uint32 { - return (uint32(u) * prime4bytes) >> ((32 - h) & 31) -} - -// hash5 returns the hash of the lowest 5 bytes of u to fit in a hash table with h bits. -// Preferably h should be a constant and should always be <64. -func hash5(u uint64, h uint8) uint32 { - return uint32(((u << (64 - 40)) * prime5bytes) >> ((64 - h) & 63)) -} - -// hash6 returns the hash of the lowest 6 bytes of u to fit in a hash table with h bits. -// Preferably h should be a constant and should always be <64. -func hash6(u uint64, h uint8) uint32 { - return uint32(((u << (64 - 48)) * prime6bytes) >> ((64 - h) & 63)) -} - -// hash7 returns the hash of the lowest 7 bytes of u to fit in a hash table with h bits. -// Preferably h should be a constant and should always be <64. -func hash7(u uint64, h uint8) uint32 { - return uint32(((u << (64 - 56)) * prime7bytes) >> ((64 - h) & 63)) -} - -// hash8 returns the hash of u to fit in a hash table with h bits. -// Preferably h should be a constant and should always be <64. -func hash8(u uint64, h uint8) uint32 { - return uint32((u * prime8bytes) >> ((64 - h) & 63)) -} diff --git a/vendor/github.com/klauspost/compress/zstd/internal/xxhash/xxhash.go b/vendor/github.com/klauspost/compress/zstd/internal/xxhash/xxhash.go index 426b9cac78..2c112a0ab1 100644 --- a/vendor/github.com/klauspost/compress/zstd/internal/xxhash/xxhash.go +++ b/vendor/github.com/klauspost/compress/zstd/internal/xxhash/xxhash.go @@ -195,7 +195,6 @@ func (d *Digest) UnmarshalBinary(b []byte) error { b, d.v4 = consumeUint64(b) b, d.total = consumeUint64(b) copy(d.mem[:], b) - b = b[len(d.mem):] d.n = int(d.total % uint64(len(d.mem))) return nil } diff --git a/vendor/github.com/klauspost/compress/zstd/internal/xxhash/xxhash_amd64.go b/vendor/github.com/klauspost/compress/zstd/internal/xxhash/xxhash_amd64.go index 35318d7c46..0ae847f75b 100644 --- a/vendor/github.com/klauspost/compress/zstd/internal/xxhash/xxhash_amd64.go +++ b/vendor/github.com/klauspost/compress/zstd/internal/xxhash/xxhash_amd64.go @@ -1,6 +1,5 @@ -// +build !appengine -// +build gc -// +build !purego +//go:build !appengine && gc && !purego +// +build !appengine,gc,!purego package xxhash @@ -10,4 +9,4 @@ package xxhash func Sum64(b []byte) uint64 //go:noescape -func writeBlocks(*Digest, []byte) int +func writeBlocks(d *Digest, b []byte) int diff --git a/vendor/github.com/klauspost/compress/zstd/internal/xxhash/xxhash_amd64.s b/vendor/github.com/klauspost/compress/zstd/internal/xxhash/xxhash_amd64.s index 2c9c5357a1..be8db5bf79 100644 --- a/vendor/github.com/klauspost/compress/zstd/internal/xxhash/xxhash_amd64.s +++ b/vendor/github.com/klauspost/compress/zstd/internal/xxhash/xxhash_amd64.s @@ -6,7 +6,7 @@ // Register allocation: // AX h -// CX pointer to advance through b +// SI pointer to advance through b // DX n // BX loop end // R8 v1, k1 @@ -16,39 +16,39 @@ // R12 tmp // R13 prime1v // R14 prime2v -// R15 prime4v +// DI prime4v -// round reads from and advances the buffer pointer in CX. +// round reads from and advances the buffer pointer in SI. // It assumes that R13 has prime1v and R14 has prime2v. #define round(r) \ - MOVQ (CX), R12 \ - ADDQ $8, CX \ + MOVQ (SI), R12 \ + ADDQ $8, SI \ IMULQ R14, R12 \ ADDQ R12, r \ ROLQ $31, r \ IMULQ R13, r // mergeRound applies a merge round on the two registers acc and val. -// It assumes that R13 has prime1v, R14 has prime2v, and R15 has prime4v. +// It assumes that R13 has prime1v, R14 has prime2v, and DI has prime4v. #define mergeRound(acc, val) \ IMULQ R14, val \ ROLQ $31, val \ IMULQ R13, val \ XORQ val, acc \ IMULQ R13, acc \ - ADDQ R15, acc + ADDQ DI, acc // func Sum64(b []byte) uint64 TEXT ·Sum64(SB), NOSPLIT, $0-32 // Load fixed primes. MOVQ ·prime1v(SB), R13 MOVQ ·prime2v(SB), R14 - MOVQ ·prime4v(SB), R15 + MOVQ ·prime4v(SB), DI // Load slice. - MOVQ b_base+0(FP), CX + MOVQ b_base+0(FP), SI MOVQ b_len+8(FP), DX - LEAQ (CX)(DX*1), BX + LEAQ (SI)(DX*1), BX // The first loop limit will be len(b)-32. SUBQ $32, BX @@ -65,14 +65,14 @@ TEXT ·Sum64(SB), NOSPLIT, $0-32 XORQ R11, R11 SUBQ R13, R11 - // Loop until CX > BX. + // Loop until SI > BX. blockLoop: round(R8) round(R9) round(R10) round(R11) - CMPQ CX, BX + CMPQ SI, BX JLE blockLoop MOVQ R8, AX @@ -100,16 +100,16 @@ noBlocks: afterBlocks: ADDQ DX, AX - // Right now BX has len(b)-32, and we want to loop until CX > len(b)-8. + // Right now BX has len(b)-32, and we want to loop until SI > len(b)-8. ADDQ $24, BX - CMPQ CX, BX + CMPQ SI, BX JG fourByte wordLoop: // Calculate k1. - MOVQ (CX), R8 - ADDQ $8, CX + MOVQ (SI), R8 + ADDQ $8, SI IMULQ R14, R8 ROLQ $31, R8 IMULQ R13, R8 @@ -117,18 +117,18 @@ wordLoop: XORQ R8, AX ROLQ $27, AX IMULQ R13, AX - ADDQ R15, AX + ADDQ DI, AX - CMPQ CX, BX + CMPQ SI, BX JLE wordLoop fourByte: ADDQ $4, BX - CMPQ CX, BX + CMPQ SI, BX JG singles - MOVL (CX), R8 - ADDQ $4, CX + MOVL (SI), R8 + ADDQ $4, SI IMULQ R13, R8 XORQ R8, AX @@ -138,19 +138,19 @@ fourByte: singles: ADDQ $4, BX - CMPQ CX, BX + CMPQ SI, BX JGE finalize singlesLoop: - MOVBQZX (CX), R12 - ADDQ $1, CX + MOVBQZX (SI), R12 + ADDQ $1, SI IMULQ ·prime5v(SB), R12 XORQ R12, AX ROLQ $11, AX IMULQ R13, AX - CMPQ CX, BX + CMPQ SI, BX JL singlesLoop finalize: @@ -179,13 +179,13 @@ TEXT ·writeBlocks(SB), NOSPLIT, $0-40 MOVQ ·prime2v(SB), R14 // Load slice. - MOVQ arg1_base+8(FP), CX - MOVQ arg1_len+16(FP), DX - LEAQ (CX)(DX*1), BX + MOVQ b_base+8(FP), SI + MOVQ b_len+16(FP), DX + LEAQ (SI)(DX*1), BX SUBQ $32, BX // Load vN from d. - MOVQ arg+0(FP), AX + MOVQ d+0(FP), AX MOVQ 0(AX), R8 // v1 MOVQ 8(AX), R9 // v2 MOVQ 16(AX), R10 // v3 @@ -199,7 +199,7 @@ blockLoop: round(R10) round(R11) - CMPQ CX, BX + CMPQ SI, BX JLE blockLoop // Copy vN back to d. @@ -208,8 +208,8 @@ blockLoop: MOVQ R10, 16(AX) MOVQ R11, 24(AX) - // The number of bytes written is CX minus the old base pointer. - SUBQ arg1_base+8(FP), CX - MOVQ CX, ret+32(FP) + // The number of bytes written is SI minus the old base pointer. + SUBQ b_base+8(FP), SI + MOVQ SI, ret+32(FP) RET diff --git a/vendor/github.com/klauspost/compress/zstd/internal/xxhash/xxhash_other.go b/vendor/github.com/klauspost/compress/zstd/internal/xxhash/xxhash_other.go index 4a5a821603..1f52f296e7 100644 --- a/vendor/github.com/klauspost/compress/zstd/internal/xxhash/xxhash_other.go +++ b/vendor/github.com/klauspost/compress/zstd/internal/xxhash/xxhash_other.go @@ -1,3 +1,4 @@ +//go:build !amd64 || appengine || !gc || purego // +build !amd64 appengine !gc purego package xxhash diff --git a/vendor/github.com/klauspost/compress/zstd/snappy.go b/vendor/github.com/klauspost/compress/zstd/snappy.go index 0372b1714a..9e1baad73b 100644 --- a/vendor/github.com/klauspost/compress/zstd/snappy.go +++ b/vendor/github.com/klauspost/compress/zstd/snappy.go @@ -10,8 +10,8 @@ import ( "hash/crc32" "io" - "github.com/golang/snappy" "github.com/klauspost/compress/huff0" + snappy "github.com/klauspost/compress/internal/snapref" ) const ( diff --git a/vendor/github.com/klauspost/compress/zstd/zip.go b/vendor/github.com/klauspost/compress/zstd/zip.go index 9325b928ae..967f29b312 100644 --- a/vendor/github.com/klauspost/compress/zstd/zip.go +++ b/vendor/github.com/klauspost/compress/zstd/zip.go @@ -64,8 +64,9 @@ func (r *pooledZipReader) Close() error { } type pooledZipWriter struct { - mu sync.Mutex // guards Close and Read - enc *Encoder + mu sync.Mutex // guards Close and Read + enc *Encoder + pool *sync.Pool } func (w *pooledZipWriter) Write(p []byte) (n int, err error) { @@ -83,7 +84,7 @@ func (w *pooledZipWriter) Close() error { var err error if w.enc != nil { err = w.enc.Close() - zipReaderPool.Put(w.enc) + w.pool.Put(w.enc) w.enc = nil } return err @@ -104,7 +105,7 @@ func ZipCompressor(opts ...EOption) func(w io.Writer) (io.WriteCloser, error) { return nil, err } } - return &pooledZipWriter{enc: enc}, nil + return &pooledZipWriter{enc: enc, pool: &pool}, nil } } diff --git a/vendor/github.com/mattn/go-colorable/.travis.yml b/vendor/github.com/mattn/go-colorable/.travis.yml deleted file mode 100644 index 7942c565ce..0000000000 --- a/vendor/github.com/mattn/go-colorable/.travis.yml +++ /dev/null @@ -1,15 +0,0 @@ -language: go -sudo: false -go: - - 1.13.x - - tip - -before_install: - - go get -t -v ./... - -script: - - ./go.test.sh - -after_success: - - bash <(curl -s https://codecov.io/bash) - diff --git a/vendor/github.com/mattn/go-colorable/README.md b/vendor/github.com/mattn/go-colorable/README.md index e055952b66..ca0483711c 100644 --- a/vendor/github.com/mattn/go-colorable/README.md +++ b/vendor/github.com/mattn/go-colorable/README.md @@ -1,6 +1,6 @@ # go-colorable -[![Build Status](https://travis-ci.org/mattn/go-colorable.svg?branch=master)](https://travis-ci.org/mattn/go-colorable) +[![Build Status](https://github.com/mattn/go-colorable/workflows/test/badge.svg)](https://github.com/mattn/go-colorable/actions?query=workflow%3Atest) [![Codecov](https://codecov.io/gh/mattn/go-colorable/branch/master/graph/badge.svg)](https://codecov.io/gh/mattn/go-colorable) [![GoDoc](https://godoc.org/github.com/mattn/go-colorable?status.svg)](http://godoc.org/github.com/mattn/go-colorable) [![Go Report Card](https://goreportcard.com/badge/mattn/go-colorable)](https://goreportcard.com/report/mattn/go-colorable) diff --git a/vendor/github.com/mattn/go-colorable/colorable_appengine.go b/vendor/github.com/mattn/go-colorable/colorable_appengine.go index 1f7806fe16..416d1bbbf8 100644 --- a/vendor/github.com/mattn/go-colorable/colorable_appengine.go +++ b/vendor/github.com/mattn/go-colorable/colorable_appengine.go @@ -1,3 +1,4 @@ +//go:build appengine // +build appengine package colorable diff --git a/vendor/github.com/mattn/go-colorable/colorable_others.go b/vendor/github.com/mattn/go-colorable/colorable_others.go index 08cbd1e0fa..766d94603a 100644 --- a/vendor/github.com/mattn/go-colorable/colorable_others.go +++ b/vendor/github.com/mattn/go-colorable/colorable_others.go @@ -1,5 +1,5 @@ -// +build !windows -// +build !appengine +//go:build !windows && !appengine +// +build !windows,!appengine package colorable diff --git a/vendor/github.com/mattn/go-colorable/colorable_windows.go b/vendor/github.com/mattn/go-colorable/colorable_windows.go index 41215d7fc4..1846ad5ab4 100644 --- a/vendor/github.com/mattn/go-colorable/colorable_windows.go +++ b/vendor/github.com/mattn/go-colorable/colorable_windows.go @@ -1,5 +1,5 @@ -// +build windows -// +build !appengine +//go:build windows && !appengine +// +build windows,!appengine package colorable @@ -452,18 +452,22 @@ func (w *Writer) Write(data []byte) (n int, err error) { } else { er = bytes.NewReader(data) } - var bw [1]byte + var plaintext bytes.Buffer loop: for { c1, err := er.ReadByte() if err != nil { + plaintext.WriteTo(w.out) break loop } if c1 != 0x1b { - bw[0] = c1 - w.out.Write(bw[:]) + plaintext.WriteByte(c1) continue } + _, err = plaintext.WriteTo(w.out) + if err != nil { + break loop + } c2, err := er.ReadByte() if err != nil { break loop diff --git a/vendor/github.com/mattn/go-colorable/go.mod b/vendor/github.com/mattn/go-colorable/go.mod index 1e590b8199..27351c0278 100644 --- a/vendor/github.com/mattn/go-colorable/go.mod +++ b/vendor/github.com/mattn/go-colorable/go.mod @@ -1,8 +1,8 @@ module github.com/mattn/go-colorable require ( - github.com/mattn/go-isatty v0.0.12 - golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae // indirect + github.com/mattn/go-isatty v0.0.14 + golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6 // indirect ) go 1.13 diff --git a/vendor/github.com/mattn/go-colorable/go.sum b/vendor/github.com/mattn/go-colorable/go.sum index cf5b95d97c..40c33b333c 100644 --- a/vendor/github.com/mattn/go-colorable/go.sum +++ b/vendor/github.com/mattn/go-colorable/go.sum @@ -1,5 +1,5 @@ -github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY= -github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= -golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae h1:/WDfKMnPU+m5M4xB+6x4kaepxRw6jWvR5iDRdvjHgy8= -golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y= +github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= +golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6 h1:foEbQz/B0Oz6YIqu/69kfXPYeFQAuuMYFkjaqXzl5Wo= +golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= diff --git a/vendor/github.com/mattn/go-colorable/noncolorable.go b/vendor/github.com/mattn/go-colorable/noncolorable.go index 95f2c6be25..3df68f360e 100644 --- a/vendor/github.com/mattn/go-colorable/noncolorable.go +++ b/vendor/github.com/mattn/go-colorable/noncolorable.go @@ -18,18 +18,22 @@ func NewNonColorable(w io.Writer) io.Writer { // Write writes data on console func (w *NonColorable) Write(data []byte) (n int, err error) { er := bytes.NewReader(data) - var bw [1]byte + var plaintext bytes.Buffer loop: for { c1, err := er.ReadByte() if err != nil { + plaintext.WriteTo(w.out) break loop } if c1 != 0x1b { - bw[0] = c1 - w.out.Write(bw[:]) + plaintext.WriteByte(c1) continue } + _, err = plaintext.WriteTo(w.out) + if err != nil { + break loop + } c2, err := er.ReadByte() if err != nil { break loop diff --git a/vendor/github.com/mattn/go-isatty/.travis.yml b/vendor/github.com/mattn/go-isatty/.travis.yml deleted file mode 100644 index 604314dd44..0000000000 --- a/vendor/github.com/mattn/go-isatty/.travis.yml +++ /dev/null @@ -1,14 +0,0 @@ -language: go -sudo: false -go: - - 1.13.x - - tip - -before_install: - - go get -t -v ./... - -script: - - ./go.test.sh - -after_success: - - bash <(curl -s https://codecov.io/bash) diff --git a/vendor/github.com/mattn/go-isatty/go.mod b/vendor/github.com/mattn/go-isatty/go.mod index 605c4c2210..c9a20b7f3f 100644 --- a/vendor/github.com/mattn/go-isatty/go.mod +++ b/vendor/github.com/mattn/go-isatty/go.mod @@ -2,4 +2,4 @@ module github.com/mattn/go-isatty go 1.12 -require golang.org/x/sys v0.0.0-20200116001909-b77594299b42 +require golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c diff --git a/vendor/github.com/mattn/go-isatty/isatty_bsd.go b/vendor/github.com/mattn/go-isatty/isatty_bsd.go index 711f288085..39bbcf00f0 100644 --- a/vendor/github.com/mattn/go-isatty/isatty_bsd.go +++ b/vendor/github.com/mattn/go-isatty/isatty_bsd.go @@ -1,3 +1,4 @@ +//go:build (darwin || freebsd || openbsd || netbsd || dragonfly) && !appengine // +build darwin freebsd openbsd netbsd dragonfly // +build !appengine diff --git a/vendor/github.com/mattn/go-isatty/isatty_others.go b/vendor/github.com/mattn/go-isatty/isatty_others.go index 3eba4cb34a..31503226f6 100644 --- a/vendor/github.com/mattn/go-isatty/isatty_others.go +++ b/vendor/github.com/mattn/go-isatty/isatty_others.go @@ -1,3 +1,4 @@ +//go:build appengine || js || nacl || wasm // +build appengine js nacl wasm package isatty diff --git a/vendor/github.com/mattn/go-isatty/isatty_plan9.go b/vendor/github.com/mattn/go-isatty/isatty_plan9.go index c5b6e0c084..bae7f9bb3d 100644 --- a/vendor/github.com/mattn/go-isatty/isatty_plan9.go +++ b/vendor/github.com/mattn/go-isatty/isatty_plan9.go @@ -1,3 +1,4 @@ +//go:build plan9 // +build plan9 package isatty diff --git a/vendor/github.com/mattn/go-isatty/isatty_solaris.go b/vendor/github.com/mattn/go-isatty/isatty_solaris.go index 3010670783..0c3acf2dc2 100644 --- a/vendor/github.com/mattn/go-isatty/isatty_solaris.go +++ b/vendor/github.com/mattn/go-isatty/isatty_solaris.go @@ -1,5 +1,5 @@ -// +build solaris -// +build !appengine +//go:build solaris && !appengine +// +build solaris,!appengine package isatty diff --git a/vendor/github.com/mattn/go-isatty/isatty_tcgets.go b/vendor/github.com/mattn/go-isatty/isatty_tcgets.go index 4e7b850ecf..67787657fb 100644 --- a/vendor/github.com/mattn/go-isatty/isatty_tcgets.go +++ b/vendor/github.com/mattn/go-isatty/isatty_tcgets.go @@ -1,3 +1,4 @@ +//go:build (linux || aix || zos) && !appengine // +build linux aix zos // +build !appengine diff --git a/vendor/github.com/mattn/go-isatty/isatty_windows.go b/vendor/github.com/mattn/go-isatty/isatty_windows.go index 1fa8691540..8e3c99171b 100644 --- a/vendor/github.com/mattn/go-isatty/isatty_windows.go +++ b/vendor/github.com/mattn/go-isatty/isatty_windows.go @@ -1,5 +1,5 @@ -// +build windows -// +build !appengine +//go:build windows && !appengine +// +build windows,!appengine package isatty @@ -76,7 +76,7 @@ func isCygwinPipeName(name string) bool { } // getFileNameByHandle use the undocomented ntdll NtQueryObject to get file full name from file handler -// since GetFileInformationByHandleEx is not avilable under windows Vista and still some old fashion +// since GetFileInformationByHandleEx is not available under windows Vista and still some old fashion // guys are using Windows XP, this is a workaround for those guys, it will also work on system from // Windows vista to 10 // see https://stackoverflow.com/a/18792477 for details diff --git a/vendor/github.com/mitchellh/mapstructure/CHANGELOG.md b/vendor/github.com/mitchellh/mapstructure/CHANGELOG.md index 1955f2878c..9fe803a5e9 100644 --- a/vendor/github.com/mitchellh/mapstructure/CHANGELOG.md +++ b/vendor/github.com/mitchellh/mapstructure/CHANGELOG.md @@ -1,6 +1,12 @@ -## unreleased +## 1.4.2 -* Fix regression where `*time.Time` value would be set to empty and not be sent +* Custom name matchers to support any sort of casing, formatting, etc. for + field names. [GH-250] +* Fix possible panic in ComposeDecodeHookFunc [GH-251] + +## 1.4.1 + +* Fix regression where `*time.Time` value would be set to empty and not be sent to decode hooks properly [GH-232] ## 1.4.0 diff --git a/vendor/github.com/mitchellh/mapstructure/decode_hooks.go b/vendor/github.com/mitchellh/mapstructure/decode_hooks.go index 92e6f76fff..4d4bbc733b 100644 --- a/vendor/github.com/mitchellh/mapstructure/decode_hooks.go +++ b/vendor/github.com/mitchellh/mapstructure/decode_hooks.go @@ -62,7 +62,8 @@ func DecodeHookExec( func ComposeDecodeHookFunc(fs ...DecodeHookFunc) DecodeHookFunc { return func(f reflect.Value, t reflect.Value) (interface{}, error) { var err error - var data interface{} + data := f.Interface() + newFrom := f for _, f1 := range fs { data, err = DecodeHookExec(f1, newFrom, t) diff --git a/vendor/github.com/mitchellh/mapstructure/mapstructure.go b/vendor/github.com/mitchellh/mapstructure/mapstructure.go index 3643901f55..dcee0f2d63 100644 --- a/vendor/github.com/mitchellh/mapstructure/mapstructure.go +++ b/vendor/github.com/mitchellh/mapstructure/mapstructure.go @@ -192,7 +192,7 @@ type DecodeHookFuncType func(reflect.Type, reflect.Type, interface{}) (interface // source and target types. type DecodeHookFuncKind func(reflect.Kind, reflect.Kind, interface{}) (interface{}, error) -// DecodeHookFuncRaw is a DecodeHookFunc which has complete access to both the source and target +// DecodeHookFuncValue is a DecodeHookFunc which has complete access to both the source and target // values. type DecodeHookFuncValue func(from reflect.Value, to reflect.Value) (interface{}, error) @@ -258,6 +258,11 @@ type DecoderConfig struct { // The tag name that mapstructure reads for field names. This // defaults to "mapstructure" TagName string + + // MatchName is the function used to match the map key to the struct + // field name or tag. Defaults to `strings.EqualFold`. This can be used + // to implement case-sensitive tag values, support snake casing, etc. + MatchName func(mapKey, fieldName string) bool } // A Decoder takes a raw interface value and turns it into structured @@ -376,6 +381,10 @@ func NewDecoder(config *DecoderConfig) (*Decoder, error) { config.TagName = "mapstructure" } + if config.MatchName == nil { + config.MatchName = strings.EqualFold + } + result := &Decoder{ config: config, } @@ -1340,7 +1349,7 @@ func (d *Decoder) decodeStructFromMap(name string, dataVal, val reflect.Value) e continue } - if strings.EqualFold(mK, fieldName) { + if d.config.MatchName(mK, fieldName) { rawMapKey = dataValKey rawMapVal = dataVal.MapIndex(dataValKey) break diff --git a/vendor/github.com/moby/spdystream/CONTRIBUTING.md b/vendor/github.com/moby/spdystream/CONTRIBUTING.md new file mode 100644 index 0000000000..d4eddcc539 --- /dev/null +++ b/vendor/github.com/moby/spdystream/CONTRIBUTING.md @@ -0,0 +1,13 @@ +# Contributing to SpdyStream + +Want to hack on spdystream? Awesome! Here are instructions to get you +started. + +SpdyStream is a part of the [Docker](https://docker.io) project, and follows +the same rules and principles. If you're already familiar with the way +Docker does things, you'll feel right at home. + +Otherwise, go read +[Docker's contributions guidelines](https://github.com/dotcloud/docker/blob/master/CONTRIBUTING.md). + +Happy hacking! diff --git a/vendor/github.com/moby/spdystream/LICENSE b/vendor/github.com/moby/spdystream/LICENSE new file mode 100644 index 0000000000..d645695673 --- /dev/null +++ b/vendor/github.com/moby/spdystream/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/vendor/github.com/moby/spdystream/MAINTAINERS b/vendor/github.com/moby/spdystream/MAINTAINERS new file mode 100644 index 0000000000..26e5ec828a --- /dev/null +++ b/vendor/github.com/moby/spdystream/MAINTAINERS @@ -0,0 +1,40 @@ +# Spdystream maintainers file +# +# This file describes who runs the moby/spdystream project and how. +# This is a living document - if you see something out of date or missing, speak up! +# +# It is structured to be consumable by both humans and programs. +# To extract its contents programmatically, use any TOML-compliant parser. +# +# This file is compiled into the MAINTAINERS file in docker/opensource. +# +[Org] + [Org."Core maintainers"] + people = [ + "adisky", + "dims", + "dmcgowan", + ] + +[people] + +# A reference list of all people associated with the project. +# All other sections should refer to people by their canonical key +# in the people section. + + # ADD YOURSELF HERE IN ALPHABETICAL ORDER + + [people.adisky] + Name = "Aditi Sharma" + Email = "adi.sky17@gmail.com" + GitHub = "adisky" + + [people.dims] + Name = "Davanum Srinivas" + Email = "davanum@gmail.com" + GitHub = "dims" + + [people.dmcgowan] + Name = "Derek McGowan" + Email = "derek@mcg.dev" + GitHub = "dmcgowan" diff --git a/vendor/github.com/moby/spdystream/NOTICE b/vendor/github.com/moby/spdystream/NOTICE new file mode 100644 index 0000000000..b9b11c9ab7 --- /dev/null +++ b/vendor/github.com/moby/spdystream/NOTICE @@ -0,0 +1,5 @@ +SpdyStream +Copyright 2014-2021 Docker Inc. + +This product includes software developed at +Docker Inc. (https://www.docker.com/). diff --git a/vendor/github.com/moby/spdystream/README.md b/vendor/github.com/moby/spdystream/README.md new file mode 100644 index 0000000000..b84e983439 --- /dev/null +++ b/vendor/github.com/moby/spdystream/README.md @@ -0,0 +1,77 @@ +# SpdyStream + +A multiplexed stream library using spdy + +## Usage + +Client example (connecting to mirroring server without auth) + +```go +package main + +import ( + "fmt" + "github.com/moby/spdystream" + "net" + "net/http" +) + +func main() { + conn, err := net.Dial("tcp", "localhost:8080") + if err != nil { + panic(err) + } + spdyConn, err := spdystream.NewConnection(conn, false) + if err != nil { + panic(err) + } + go spdyConn.Serve(spdystream.NoOpStreamHandler) + stream, err := spdyConn.CreateStream(http.Header{}, nil, false) + if err != nil { + panic(err) + } + + stream.Wait() + + fmt.Fprint(stream, "Writing to stream") + + buf := make([]byte, 25) + stream.Read(buf) + fmt.Println(string(buf)) + + stream.Close() +} +``` + +Server example (mirroring server without auth) + +```go +package main + +import ( + "github.com/moby/spdystream" + "net" +) + +func main() { + listener, err := net.Listen("tcp", "localhost:8080") + if err != nil { + panic(err) + } + for { + conn, err := listener.Accept() + if err != nil { + panic(err) + } + spdyConn, err := spdystream.NewConnection(conn, true) + if err != nil { + panic(err) + } + go spdyConn.Serve(spdystream.MirrorStreamHandler) + } +} +``` + +## Copyright and license + +Copyright 2013-2021 Docker, inc. Released under the [Apache 2.0 license](LICENSE). diff --git a/vendor/github.com/moby/spdystream/connection.go b/vendor/github.com/moby/spdystream/connection.go new file mode 100644 index 0000000000..d906bb05ce --- /dev/null +++ b/vendor/github.com/moby/spdystream/connection.go @@ -0,0 +1,972 @@ +/* + Copyright 2014-2021 Docker Inc. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package spdystream + +import ( + "errors" + "fmt" + "io" + "net" + "net/http" + "sync" + "time" + + "github.com/moby/spdystream/spdy" +) + +var ( + ErrInvalidStreamId = errors.New("Invalid stream id") + ErrTimeout = errors.New("Timeout occurred") + ErrReset = errors.New("Stream reset") + ErrWriteClosedStream = errors.New("Write on closed stream") +) + +const ( + FRAME_WORKERS = 5 + QUEUE_SIZE = 50 +) + +type StreamHandler func(stream *Stream) + +type AuthHandler func(header http.Header, slot uint8, parent uint32) bool + +type idleAwareFramer struct { + f *spdy.Framer + conn *Connection + writeLock sync.Mutex + resetChan chan struct{} + setTimeoutLock sync.Mutex + setTimeoutChan chan time.Duration + timeout time.Duration +} + +func newIdleAwareFramer(framer *spdy.Framer) *idleAwareFramer { + iaf := &idleAwareFramer{ + f: framer, + resetChan: make(chan struct{}, 2), + // setTimeoutChan needs to be buffered to avoid deadlocks when calling setIdleTimeout at about + // the same time the connection is being closed + setTimeoutChan: make(chan time.Duration, 1), + } + return iaf +} + +func (i *idleAwareFramer) monitor() { + var ( + timer *time.Timer + expired <-chan time.Time + resetChan = i.resetChan + setTimeoutChan = i.setTimeoutChan + ) +Loop: + for { + select { + case timeout := <-i.setTimeoutChan: + i.timeout = timeout + if timeout == 0 { + if timer != nil { + timer.Stop() + } + } else { + if timer == nil { + timer = time.NewTimer(timeout) + expired = timer.C + } else { + timer.Reset(timeout) + } + } + case <-resetChan: + if timer != nil && i.timeout > 0 { + timer.Reset(i.timeout) + } + case <-expired: + i.conn.streamCond.L.Lock() + streams := i.conn.streams + i.conn.streams = make(map[spdy.StreamId]*Stream) + i.conn.streamCond.Broadcast() + i.conn.streamCond.L.Unlock() + go func() { + for _, stream := range streams { + stream.resetStream() + } + i.conn.Close() + }() + case <-i.conn.closeChan: + if timer != nil { + timer.Stop() + } + + // Start a goroutine to drain resetChan. This is needed because we've seen + // some unit tests with large numbers of goroutines get into a situation + // where resetChan fills up, at least 1 call to Write() is still trying to + // send to resetChan, the connection gets closed, and this case statement + // attempts to grab the write lock that Write() already has, causing a + // deadlock. + // + // See https://github.com/moby/spdystream/issues/49 for more details. + go func() { + for range resetChan { + } + }() + + go func() { + for range setTimeoutChan { + } + }() + + i.writeLock.Lock() + close(resetChan) + i.resetChan = nil + i.writeLock.Unlock() + + i.setTimeoutLock.Lock() + close(i.setTimeoutChan) + i.setTimeoutChan = nil + i.setTimeoutLock.Unlock() + + break Loop + } + } + + // Drain resetChan + for range resetChan { + } +} + +func (i *idleAwareFramer) WriteFrame(frame spdy.Frame) error { + i.writeLock.Lock() + defer i.writeLock.Unlock() + if i.resetChan == nil { + return io.EOF + } + err := i.f.WriteFrame(frame) + if err != nil { + return err + } + + i.resetChan <- struct{}{} + + return nil +} + +func (i *idleAwareFramer) ReadFrame() (spdy.Frame, error) { + frame, err := i.f.ReadFrame() + if err != nil { + return nil, err + } + + // resetChan should never be closed since it is only closed + // when the connection has closed its closeChan. This closure + // only occurs after all Reads have finished + // TODO (dmcgowan): refactor relationship into connection + i.resetChan <- struct{}{} + + return frame, nil +} + +func (i *idleAwareFramer) setIdleTimeout(timeout time.Duration) { + i.setTimeoutLock.Lock() + defer i.setTimeoutLock.Unlock() + + if i.setTimeoutChan == nil { + return + } + + i.setTimeoutChan <- timeout +} + +type Connection struct { + conn net.Conn + framer *idleAwareFramer + + closeChan chan bool + goneAway bool + lastStreamChan chan<- *Stream + goAwayTimeout time.Duration + closeTimeout time.Duration + + streamLock *sync.RWMutex + streamCond *sync.Cond + streams map[spdy.StreamId]*Stream + + nextIdLock sync.Mutex + receiveIdLock sync.Mutex + nextStreamId spdy.StreamId + receivedStreamId spdy.StreamId + + pingIdLock sync.Mutex + pingId uint32 + pingChans map[uint32]chan error + + shutdownLock sync.Mutex + shutdownChan chan error + hasShutdown bool + + // for testing https://github.com/moby/spdystream/pull/56 + dataFrameHandler func(*spdy.DataFrame) error +} + +// NewConnection creates a new spdy connection from an existing +// network connection. +func NewConnection(conn net.Conn, server bool) (*Connection, error) { + framer, framerErr := spdy.NewFramer(conn, conn) + if framerErr != nil { + return nil, framerErr + } + idleAwareFramer := newIdleAwareFramer(framer) + var sid spdy.StreamId + var rid spdy.StreamId + var pid uint32 + if server { + sid = 2 + rid = 1 + pid = 2 + } else { + sid = 1 + rid = 2 + pid = 1 + } + + streamLock := new(sync.RWMutex) + streamCond := sync.NewCond(streamLock) + + session := &Connection{ + conn: conn, + framer: idleAwareFramer, + + closeChan: make(chan bool), + goAwayTimeout: time.Duration(0), + closeTimeout: time.Duration(0), + + streamLock: streamLock, + streamCond: streamCond, + streams: make(map[spdy.StreamId]*Stream), + nextStreamId: sid, + receivedStreamId: rid, + + pingId: pid, + pingChans: make(map[uint32]chan error), + + shutdownChan: make(chan error), + } + session.dataFrameHandler = session.handleDataFrame + idleAwareFramer.conn = session + go idleAwareFramer.monitor() + + return session, nil +} + +// Ping sends a ping frame across the connection and +// returns the response time +func (s *Connection) Ping() (time.Duration, error) { + pid := s.pingId + s.pingIdLock.Lock() + if s.pingId > 0x7ffffffe { + s.pingId = s.pingId - 0x7ffffffe + } else { + s.pingId = s.pingId + 2 + } + s.pingIdLock.Unlock() + pingChan := make(chan error) + s.pingChans[pid] = pingChan + defer delete(s.pingChans, pid) + + frame := &spdy.PingFrame{Id: pid} + startTime := time.Now() + writeErr := s.framer.WriteFrame(frame) + if writeErr != nil { + return time.Duration(0), writeErr + } + select { + case <-s.closeChan: + return time.Duration(0), errors.New("connection closed") + case err, ok := <-pingChan: + if ok && err != nil { + return time.Duration(0), err + } + break + } + return time.Since(startTime), nil +} + +// Serve handles frames sent from the server, including reply frames +// which are needed to fully initiate connections. Both clients and servers +// should call Serve in a separate goroutine before creating streams. +func (s *Connection) Serve(newHandler StreamHandler) { + // use a WaitGroup to wait for all frames to be drained after receiving + // go-away. + var wg sync.WaitGroup + + // Parition queues to ensure stream frames are handled + // by the same worker, ensuring order is maintained + frameQueues := make([]*PriorityFrameQueue, FRAME_WORKERS) + for i := 0; i < FRAME_WORKERS; i++ { + frameQueues[i] = NewPriorityFrameQueue(QUEUE_SIZE) + + // Ensure frame queue is drained when connection is closed + go func(frameQueue *PriorityFrameQueue) { + <-s.closeChan + frameQueue.Drain() + }(frameQueues[i]) + + wg.Add(1) + go func(frameQueue *PriorityFrameQueue) { + // let the WaitGroup know this worker is done + defer wg.Done() + + s.frameHandler(frameQueue, newHandler) + }(frameQueues[i]) + } + + var ( + partitionRoundRobin int + goAwayFrame *spdy.GoAwayFrame + ) +Loop: + for { + readFrame, err := s.framer.ReadFrame() + if err != nil { + if err != io.EOF { + debugMessage("frame read error: %s", err) + } else { + debugMessage("(%p) EOF received", s) + } + break + } + var priority uint8 + var partition int + switch frame := readFrame.(type) { + case *spdy.SynStreamFrame: + if s.checkStreamFrame(frame) { + priority = frame.Priority + partition = int(frame.StreamId % FRAME_WORKERS) + debugMessage("(%p) Add stream frame: %d ", s, frame.StreamId) + s.addStreamFrame(frame) + } else { + debugMessage("(%p) Rejected stream frame: %d ", s, frame.StreamId) + continue + } + case *spdy.SynReplyFrame: + priority = s.getStreamPriority(frame.StreamId) + partition = int(frame.StreamId % FRAME_WORKERS) + case *spdy.DataFrame: + priority = s.getStreamPriority(frame.StreamId) + partition = int(frame.StreamId % FRAME_WORKERS) + case *spdy.RstStreamFrame: + priority = s.getStreamPriority(frame.StreamId) + partition = int(frame.StreamId % FRAME_WORKERS) + case *spdy.HeadersFrame: + priority = s.getStreamPriority(frame.StreamId) + partition = int(frame.StreamId % FRAME_WORKERS) + case *spdy.PingFrame: + priority = 0 + partition = partitionRoundRobin + partitionRoundRobin = (partitionRoundRobin + 1) % FRAME_WORKERS + case *spdy.GoAwayFrame: + // hold on to the go away frame and exit the loop + goAwayFrame = frame + break Loop + default: + priority = 7 + partition = partitionRoundRobin + partitionRoundRobin = (partitionRoundRobin + 1) % FRAME_WORKERS + } + frameQueues[partition].Push(readFrame, priority) + } + close(s.closeChan) + + // wait for all frame handler workers to indicate they've drained their queues + // before handling the go away frame + wg.Wait() + + if goAwayFrame != nil { + s.handleGoAwayFrame(goAwayFrame) + } + + // now it's safe to close remote channels and empty s.streams + s.streamCond.L.Lock() + // notify streams that they're now closed, which will + // unblock any stream Read() calls + for _, stream := range s.streams { + stream.closeRemoteChannels() + } + s.streams = make(map[spdy.StreamId]*Stream) + s.streamCond.Broadcast() + s.streamCond.L.Unlock() +} + +func (s *Connection) frameHandler(frameQueue *PriorityFrameQueue, newHandler StreamHandler) { + for { + popFrame := frameQueue.Pop() + if popFrame == nil { + return + } + + var frameErr error + switch frame := popFrame.(type) { + case *spdy.SynStreamFrame: + frameErr = s.handleStreamFrame(frame, newHandler) + case *spdy.SynReplyFrame: + frameErr = s.handleReplyFrame(frame) + case *spdy.DataFrame: + frameErr = s.dataFrameHandler(frame) + case *spdy.RstStreamFrame: + frameErr = s.handleResetFrame(frame) + case *spdy.HeadersFrame: + frameErr = s.handleHeaderFrame(frame) + case *spdy.PingFrame: + frameErr = s.handlePingFrame(frame) + case *spdy.GoAwayFrame: + frameErr = s.handleGoAwayFrame(frame) + default: + frameErr = fmt.Errorf("unhandled frame type: %T", frame) + } + + if frameErr != nil { + debugMessage("frame handling error: %s", frameErr) + } + } +} + +func (s *Connection) getStreamPriority(streamId spdy.StreamId) uint8 { + stream, streamOk := s.getStream(streamId) + if !streamOk { + return 7 + } + return stream.priority +} + +func (s *Connection) addStreamFrame(frame *spdy.SynStreamFrame) { + var parent *Stream + if frame.AssociatedToStreamId != spdy.StreamId(0) { + parent, _ = s.getStream(frame.AssociatedToStreamId) + } + + stream := &Stream{ + streamId: frame.StreamId, + parent: parent, + conn: s, + startChan: make(chan error), + headers: frame.Headers, + finished: (frame.CFHeader.Flags & spdy.ControlFlagUnidirectional) != 0x00, + replyCond: sync.NewCond(new(sync.Mutex)), + dataChan: make(chan []byte), + headerChan: make(chan http.Header), + closeChan: make(chan bool), + priority: frame.Priority, + } + if frame.CFHeader.Flags&spdy.ControlFlagFin != 0x00 { + stream.closeRemoteChannels() + } + + s.addStream(stream) +} + +// checkStreamFrame checks to see if a stream frame is allowed. +// If the stream is invalid, then a reset frame with protocol error +// will be returned. +func (s *Connection) checkStreamFrame(frame *spdy.SynStreamFrame) bool { + s.receiveIdLock.Lock() + defer s.receiveIdLock.Unlock() + if s.goneAway { + return false + } + validationErr := s.validateStreamId(frame.StreamId) + if validationErr != nil { + go func() { + resetErr := s.sendResetFrame(spdy.ProtocolError, frame.StreamId) + if resetErr != nil { + debugMessage("reset error: %s", resetErr) + } + }() + return false + } + return true +} + +func (s *Connection) handleStreamFrame(frame *spdy.SynStreamFrame, newHandler StreamHandler) error { + stream, ok := s.getStream(frame.StreamId) + if !ok { + return fmt.Errorf("Missing stream: %d", frame.StreamId) + } + + newHandler(stream) + + return nil +} + +func (s *Connection) handleReplyFrame(frame *spdy.SynReplyFrame) error { + debugMessage("(%p) Reply frame received for %d", s, frame.StreamId) + stream, streamOk := s.getStream(frame.StreamId) + if !streamOk { + debugMessage("Reply frame gone away for %d", frame.StreamId) + // Stream has already gone away + return nil + } + if stream.replied { + // Stream has already received reply + return nil + } + stream.replied = true + + // TODO Check for error + if (frame.CFHeader.Flags & spdy.ControlFlagFin) != 0x00 { + s.remoteStreamFinish(stream) + } + + close(stream.startChan) + + return nil +} + +func (s *Connection) handleResetFrame(frame *spdy.RstStreamFrame) error { + stream, streamOk := s.getStream(frame.StreamId) + if !streamOk { + // Stream has already been removed + return nil + } + s.removeStream(stream) + stream.closeRemoteChannels() + + if !stream.replied { + stream.replied = true + stream.startChan <- ErrReset + close(stream.startChan) + } + + stream.finishLock.Lock() + stream.finished = true + stream.finishLock.Unlock() + + return nil +} + +func (s *Connection) handleHeaderFrame(frame *spdy.HeadersFrame) error { + stream, streamOk := s.getStream(frame.StreamId) + if !streamOk { + // Stream has already gone away + return nil + } + if !stream.replied { + // No reply received...Protocol error? + return nil + } + + // TODO limit headers while not blocking (use buffered chan or goroutine?) + select { + case <-stream.closeChan: + return nil + case stream.headerChan <- frame.Headers: + } + + if (frame.CFHeader.Flags & spdy.ControlFlagFin) != 0x00 { + s.remoteStreamFinish(stream) + } + + return nil +} + +func (s *Connection) handleDataFrame(frame *spdy.DataFrame) error { + debugMessage("(%p) Data frame received for %d", s, frame.StreamId) + stream, streamOk := s.getStream(frame.StreamId) + if !streamOk { + debugMessage("(%p) Data frame gone away for %d", s, frame.StreamId) + // Stream has already gone away + return nil + } + if !stream.replied { + debugMessage("(%p) Data frame not replied %d", s, frame.StreamId) + // No reply received...Protocol error? + return nil + } + + debugMessage("(%p) (%d) Data frame handling", stream, stream.streamId) + if len(frame.Data) > 0 { + stream.dataLock.RLock() + select { + case <-stream.closeChan: + debugMessage("(%p) (%d) Data frame not sent (stream shut down)", stream, stream.streamId) + case stream.dataChan <- frame.Data: + debugMessage("(%p) (%d) Data frame sent", stream, stream.streamId) + } + stream.dataLock.RUnlock() + } + if (frame.Flags & spdy.DataFlagFin) != 0x00 { + s.remoteStreamFinish(stream) + } + return nil +} + +func (s *Connection) handlePingFrame(frame *spdy.PingFrame) error { + if s.pingId&0x01 != frame.Id&0x01 { + return s.framer.WriteFrame(frame) + } + pingChan, pingOk := s.pingChans[frame.Id] + if pingOk { + close(pingChan) + } + return nil +} + +func (s *Connection) handleGoAwayFrame(frame *spdy.GoAwayFrame) error { + debugMessage("(%p) Go away received", s) + s.receiveIdLock.Lock() + if s.goneAway { + s.receiveIdLock.Unlock() + return nil + } + s.goneAway = true + s.receiveIdLock.Unlock() + + if s.lastStreamChan != nil { + stream, _ := s.getStream(frame.LastGoodStreamId) + go func() { + s.lastStreamChan <- stream + }() + } + + // Do not block frame handler waiting for closure + go s.shutdown(s.goAwayTimeout) + + return nil +} + +func (s *Connection) remoteStreamFinish(stream *Stream) { + stream.closeRemoteChannels() + + stream.finishLock.Lock() + if stream.finished { + // Stream is fully closed, cleanup + s.removeStream(stream) + } + stream.finishLock.Unlock() +} + +// CreateStream creates a new spdy stream using the parameters for +// creating the stream frame. The stream frame will be sent upon +// calling this function, however this function does not wait for +// the reply frame. If waiting for the reply is desired, use +// the stream Wait or WaitTimeout function on the stream returned +// by this function. +func (s *Connection) CreateStream(headers http.Header, parent *Stream, fin bool) (*Stream, error) { + // MUST synchronize stream creation (all the way to writing the frame) + // as stream IDs **MUST** increase monotonically. + s.nextIdLock.Lock() + defer s.nextIdLock.Unlock() + + streamId := s.getNextStreamId() + if streamId == 0 { + return nil, fmt.Errorf("Unable to get new stream id") + } + + stream := &Stream{ + streamId: streamId, + parent: parent, + conn: s, + startChan: make(chan error), + headers: headers, + dataChan: make(chan []byte), + headerChan: make(chan http.Header), + closeChan: make(chan bool), + } + + debugMessage("(%p) (%p) Create stream", s, stream) + + s.addStream(stream) + + return stream, s.sendStream(stream, fin) +} + +func (s *Connection) shutdown(closeTimeout time.Duration) { + // TODO Ensure this isn't called multiple times + s.shutdownLock.Lock() + if s.hasShutdown { + s.shutdownLock.Unlock() + return + } + s.hasShutdown = true + s.shutdownLock.Unlock() + + var timeout <-chan time.Time + if closeTimeout > time.Duration(0) { + timeout = time.After(closeTimeout) + } + streamsClosed := make(chan bool) + + go func() { + s.streamCond.L.Lock() + for len(s.streams) > 0 { + debugMessage("Streams opened: %d, %#v", len(s.streams), s.streams) + s.streamCond.Wait() + } + s.streamCond.L.Unlock() + close(streamsClosed) + }() + + var err error + select { + case <-streamsClosed: + // No active streams, close should be safe + err = s.conn.Close() + case <-timeout: + // Force ungraceful close + err = s.conn.Close() + // Wait for cleanup to clear active streams + <-streamsClosed + } + + if err != nil { + duration := 10 * time.Minute + time.AfterFunc(duration, func() { + select { + case err, ok := <-s.shutdownChan: + if ok { + debugMessage("Unhandled close error after %s: %s", duration, err) + } + default: + } + }) + s.shutdownChan <- err + } + close(s.shutdownChan) +} + +// Closes spdy connection by sending GoAway frame and initiating shutdown +func (s *Connection) Close() error { + s.receiveIdLock.Lock() + if s.goneAway { + s.receiveIdLock.Unlock() + return nil + } + s.goneAway = true + s.receiveIdLock.Unlock() + + var lastStreamId spdy.StreamId + if s.receivedStreamId > 2 { + lastStreamId = s.receivedStreamId - 2 + } + + goAwayFrame := &spdy.GoAwayFrame{ + LastGoodStreamId: lastStreamId, + Status: spdy.GoAwayOK, + } + + err := s.framer.WriteFrame(goAwayFrame) + go s.shutdown(s.closeTimeout) + if err != nil { + return err + } + + return nil +} + +// CloseWait closes the connection and waits for shutdown +// to finish. Note the underlying network Connection +// is not closed until the end of shutdown. +func (s *Connection) CloseWait() error { + closeErr := s.Close() + if closeErr != nil { + return closeErr + } + shutdownErr, ok := <-s.shutdownChan + if ok { + return shutdownErr + } + return nil +} + +// Wait waits for the connection to finish shutdown or for +// the wait timeout duration to expire. This needs to be +// called either after Close has been called or the GOAWAYFRAME +// has been received. If the wait timeout is 0, this function +// will block until shutdown finishes. If wait is never called +// and a shutdown error occurs, that error will be logged as an +// unhandled error. +func (s *Connection) Wait(waitTimeout time.Duration) error { + var timeout <-chan time.Time + if waitTimeout > time.Duration(0) { + timeout = time.After(waitTimeout) + } + + select { + case err, ok := <-s.shutdownChan: + if ok { + return err + } + case <-timeout: + return ErrTimeout + } + return nil +} + +// NotifyClose registers a channel to be called when the remote +// peer inidicates connection closure. The last stream to be +// received by the remote will be sent on the channel. The notify +// timeout will determine the duration between go away received +// and the connection being closed. +func (s *Connection) NotifyClose(c chan<- *Stream, timeout time.Duration) { + s.goAwayTimeout = timeout + s.lastStreamChan = c +} + +// SetCloseTimeout sets the amount of time close will wait for +// streams to finish before terminating the underlying network +// connection. Setting the timeout to 0 will cause close to +// wait forever, which is the default. +func (s *Connection) SetCloseTimeout(timeout time.Duration) { + s.closeTimeout = timeout +} + +// SetIdleTimeout sets the amount of time the connection may sit idle before +// it is forcefully terminated. +func (s *Connection) SetIdleTimeout(timeout time.Duration) { + s.framer.setIdleTimeout(timeout) +} + +func (s *Connection) sendHeaders(headers http.Header, stream *Stream, fin bool) error { + var flags spdy.ControlFlags + if fin { + flags = spdy.ControlFlagFin + } + + headerFrame := &spdy.HeadersFrame{ + StreamId: stream.streamId, + Headers: headers, + CFHeader: spdy.ControlFrameHeader{Flags: flags}, + } + + return s.framer.WriteFrame(headerFrame) +} + +func (s *Connection) sendReply(headers http.Header, stream *Stream, fin bool) error { + var flags spdy.ControlFlags + if fin { + flags = spdy.ControlFlagFin + } + + replyFrame := &spdy.SynReplyFrame{ + StreamId: stream.streamId, + Headers: headers, + CFHeader: spdy.ControlFrameHeader{Flags: flags}, + } + + return s.framer.WriteFrame(replyFrame) +} + +func (s *Connection) sendResetFrame(status spdy.RstStreamStatus, streamId spdy.StreamId) error { + resetFrame := &spdy.RstStreamFrame{ + StreamId: streamId, + Status: status, + } + + return s.framer.WriteFrame(resetFrame) +} + +func (s *Connection) sendReset(status spdy.RstStreamStatus, stream *Stream) error { + return s.sendResetFrame(status, stream.streamId) +} + +func (s *Connection) sendStream(stream *Stream, fin bool) error { + var flags spdy.ControlFlags + if fin { + flags = spdy.ControlFlagFin + stream.finished = true + } + + var parentId spdy.StreamId + if stream.parent != nil { + parentId = stream.parent.streamId + } + + streamFrame := &spdy.SynStreamFrame{ + StreamId: spdy.StreamId(stream.streamId), + AssociatedToStreamId: spdy.StreamId(parentId), + Headers: stream.headers, + CFHeader: spdy.ControlFrameHeader{Flags: flags}, + } + + return s.framer.WriteFrame(streamFrame) +} + +// getNextStreamId returns the next sequential id +// every call should produce a unique value or an error +func (s *Connection) getNextStreamId() spdy.StreamId { + sid := s.nextStreamId + if sid > 0x7fffffff { + return 0 + } + s.nextStreamId = s.nextStreamId + 2 + return sid +} + +// PeekNextStreamId returns the next sequential id and keeps the next id untouched +func (s *Connection) PeekNextStreamId() spdy.StreamId { + sid := s.nextStreamId + return sid +} + +func (s *Connection) validateStreamId(rid spdy.StreamId) error { + if rid > 0x7fffffff || rid < s.receivedStreamId { + return ErrInvalidStreamId + } + s.receivedStreamId = rid + 2 + return nil +} + +func (s *Connection) addStream(stream *Stream) { + s.streamCond.L.Lock() + s.streams[stream.streamId] = stream + debugMessage("(%p) (%p) Stream added, broadcasting: %d", s, stream, stream.streamId) + s.streamCond.Broadcast() + s.streamCond.L.Unlock() +} + +func (s *Connection) removeStream(stream *Stream) { + s.streamCond.L.Lock() + delete(s.streams, stream.streamId) + debugMessage("(%p) (%p) Stream removed, broadcasting: %d", s, stream, stream.streamId) + s.streamCond.Broadcast() + s.streamCond.L.Unlock() +} + +func (s *Connection) getStream(streamId spdy.StreamId) (stream *Stream, ok bool) { + s.streamLock.RLock() + stream, ok = s.streams[streamId] + s.streamLock.RUnlock() + return +} + +// FindStream looks up the given stream id and either waits for the +// stream to be found or returns nil if the stream id is no longer +// valid. +func (s *Connection) FindStream(streamId uint32) *Stream { + var stream *Stream + var ok bool + s.streamCond.L.Lock() + stream, ok = s.streams[spdy.StreamId(streamId)] + debugMessage("(%p) Found stream %d? %t", s, spdy.StreamId(streamId), ok) + for !ok && streamId >= uint32(s.receivedStreamId) { + s.streamCond.Wait() + stream, ok = s.streams[spdy.StreamId(streamId)] + } + s.streamCond.L.Unlock() + return stream +} + +func (s *Connection) CloseChan() <-chan bool { + return s.closeChan +} diff --git a/vendor/github.com/moby/spdystream/go.mod b/vendor/github.com/moby/spdystream/go.mod new file mode 100644 index 0000000000..d9b9ad59c7 --- /dev/null +++ b/vendor/github.com/moby/spdystream/go.mod @@ -0,0 +1,5 @@ +module github.com/moby/spdystream + +go 1.13 + +require github.com/gorilla/websocket v1.4.2 diff --git a/vendor/github.com/moby/spdystream/go.sum b/vendor/github.com/moby/spdystream/go.sum new file mode 100644 index 0000000000..85efffd996 --- /dev/null +++ b/vendor/github.com/moby/spdystream/go.sum @@ -0,0 +1,2 @@ +github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc= +github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= diff --git a/vendor/github.com/moby/spdystream/handlers.go b/vendor/github.com/moby/spdystream/handlers.go new file mode 100644 index 0000000000..d68f61f812 --- /dev/null +++ b/vendor/github.com/moby/spdystream/handlers.go @@ -0,0 +1,52 @@ +/* + Copyright 2014-2021 Docker Inc. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package spdystream + +import ( + "io" + "net/http" +) + +// MirrorStreamHandler mirrors all streams. +func MirrorStreamHandler(stream *Stream) { + replyErr := stream.SendReply(http.Header{}, false) + if replyErr != nil { + return + } + + go func() { + io.Copy(stream, stream) + stream.Close() + }() + go func() { + for { + header, receiveErr := stream.ReceiveHeader() + if receiveErr != nil { + return + } + sendErr := stream.SendHeader(header, false) + if sendErr != nil { + return + } + } + }() +} + +// NoopStreamHandler does nothing when stream connects. +func NoOpStreamHandler(stream *Stream) { + stream.SendReply(http.Header{}, false) +} diff --git a/vendor/github.com/moby/spdystream/priority.go b/vendor/github.com/moby/spdystream/priority.go new file mode 100644 index 0000000000..d8eb3516ca --- /dev/null +++ b/vendor/github.com/moby/spdystream/priority.go @@ -0,0 +1,114 @@ +/* + Copyright 2014-2021 Docker Inc. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package spdystream + +import ( + "container/heap" + "sync" + + "github.com/moby/spdystream/spdy" +) + +type prioritizedFrame struct { + frame spdy.Frame + priority uint8 + insertId uint64 +} + +type frameQueue []*prioritizedFrame + +func (fq frameQueue) Len() int { + return len(fq) +} + +func (fq frameQueue) Less(i, j int) bool { + if fq[i].priority == fq[j].priority { + return fq[i].insertId < fq[j].insertId + } + return fq[i].priority < fq[j].priority +} + +func (fq frameQueue) Swap(i, j int) { + fq[i], fq[j] = fq[j], fq[i] +} + +func (fq *frameQueue) Push(x interface{}) { + *fq = append(*fq, x.(*prioritizedFrame)) +} + +func (fq *frameQueue) Pop() interface{} { + old := *fq + n := len(old) + *fq = old[0 : n-1] + return old[n-1] +} + +type PriorityFrameQueue struct { + queue *frameQueue + c *sync.Cond + size int + nextInsertId uint64 + drain bool +} + +func NewPriorityFrameQueue(size int) *PriorityFrameQueue { + queue := make(frameQueue, 0, size) + heap.Init(&queue) + + return &PriorityFrameQueue{ + queue: &queue, + size: size, + c: sync.NewCond(&sync.Mutex{}), + } +} + +func (q *PriorityFrameQueue) Push(frame spdy.Frame, priority uint8) { + q.c.L.Lock() + defer q.c.L.Unlock() + for q.queue.Len() >= q.size { + q.c.Wait() + } + pFrame := &prioritizedFrame{ + frame: frame, + priority: priority, + insertId: q.nextInsertId, + } + q.nextInsertId = q.nextInsertId + 1 + heap.Push(q.queue, pFrame) + q.c.Signal() +} + +func (q *PriorityFrameQueue) Pop() spdy.Frame { + q.c.L.Lock() + defer q.c.L.Unlock() + for q.queue.Len() == 0 { + if q.drain { + return nil + } + q.c.Wait() + } + frame := heap.Pop(q.queue).(*prioritizedFrame).frame + q.c.Signal() + return frame +} + +func (q *PriorityFrameQueue) Drain() { + q.c.L.Lock() + defer q.c.L.Unlock() + q.drain = true + q.c.Broadcast() +} diff --git a/vendor/github.com/moby/spdystream/spdy/dictionary.go b/vendor/github.com/moby/spdystream/spdy/dictionary.go new file mode 100644 index 0000000000..392232f174 --- /dev/null +++ b/vendor/github.com/moby/spdystream/spdy/dictionary.go @@ -0,0 +1,203 @@ +/* + Copyright 2014-2021 Docker Inc. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +// Copyright 2013 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package spdy + +// headerDictionary is the dictionary sent to the zlib compressor/decompressor. +var headerDictionary = []byte{ + 0x00, 0x00, 0x00, 0x07, 0x6f, 0x70, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0x00, 0x00, 0x00, 0x04, 0x68, + 0x65, 0x61, 0x64, 0x00, 0x00, 0x00, 0x04, 0x70, + 0x6f, 0x73, 0x74, 0x00, 0x00, 0x00, 0x03, 0x70, + 0x75, 0x74, 0x00, 0x00, 0x00, 0x06, 0x64, 0x65, + 0x6c, 0x65, 0x74, 0x65, 0x00, 0x00, 0x00, 0x05, + 0x74, 0x72, 0x61, 0x63, 0x65, 0x00, 0x00, 0x00, + 0x06, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x00, + 0x00, 0x00, 0x0e, 0x61, 0x63, 0x63, 0x65, 0x70, + 0x74, 0x2d, 0x63, 0x68, 0x61, 0x72, 0x73, 0x65, + 0x74, 0x00, 0x00, 0x00, 0x0f, 0x61, 0x63, 0x63, + 0x65, 0x70, 0x74, 0x2d, 0x65, 0x6e, 0x63, 0x6f, + 0x64, 0x69, 0x6e, 0x67, 0x00, 0x00, 0x00, 0x0f, + 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d, 0x6c, + 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x00, + 0x00, 0x00, 0x0d, 0x61, 0x63, 0x63, 0x65, 0x70, + 0x74, 0x2d, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x73, + 0x00, 0x00, 0x00, 0x03, 0x61, 0x67, 0x65, 0x00, + 0x00, 0x00, 0x05, 0x61, 0x6c, 0x6c, 0x6f, 0x77, + 0x00, 0x00, 0x00, 0x0d, 0x61, 0x75, 0x74, 0x68, + 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x00, 0x00, 0x00, 0x0d, 0x63, 0x61, 0x63, + 0x68, 0x65, 0x2d, 0x63, 0x6f, 0x6e, 0x74, 0x72, + 0x6f, 0x6c, 0x00, 0x00, 0x00, 0x0a, 0x63, 0x6f, + 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x00, 0x00, 0x00, 0x0c, 0x63, 0x6f, 0x6e, 0x74, + 0x65, 0x6e, 0x74, 0x2d, 0x62, 0x61, 0x73, 0x65, + 0x00, 0x00, 0x00, 0x10, 0x63, 0x6f, 0x6e, 0x74, + 0x65, 0x6e, 0x74, 0x2d, 0x65, 0x6e, 0x63, 0x6f, + 0x64, 0x69, 0x6e, 0x67, 0x00, 0x00, 0x00, 0x10, + 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, + 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, + 0x00, 0x00, 0x00, 0x0e, 0x63, 0x6f, 0x6e, 0x74, + 0x65, 0x6e, 0x74, 0x2d, 0x6c, 0x65, 0x6e, 0x67, + 0x74, 0x68, 0x00, 0x00, 0x00, 0x10, 0x63, 0x6f, + 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x6c, 0x6f, + 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x00, + 0x00, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, + 0x74, 0x2d, 0x6d, 0x64, 0x35, 0x00, 0x00, 0x00, + 0x0d, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, + 0x2d, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x00, 0x00, + 0x00, 0x0c, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, + 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x00, 0x00, + 0x00, 0x04, 0x64, 0x61, 0x74, 0x65, 0x00, 0x00, + 0x00, 0x04, 0x65, 0x74, 0x61, 0x67, 0x00, 0x00, + 0x00, 0x06, 0x65, 0x78, 0x70, 0x65, 0x63, 0x74, + 0x00, 0x00, 0x00, 0x07, 0x65, 0x78, 0x70, 0x69, + 0x72, 0x65, 0x73, 0x00, 0x00, 0x00, 0x04, 0x66, + 0x72, 0x6f, 0x6d, 0x00, 0x00, 0x00, 0x04, 0x68, + 0x6f, 0x73, 0x74, 0x00, 0x00, 0x00, 0x08, 0x69, + 0x66, 0x2d, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x00, + 0x00, 0x00, 0x11, 0x69, 0x66, 0x2d, 0x6d, 0x6f, + 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x2d, 0x73, + 0x69, 0x6e, 0x63, 0x65, 0x00, 0x00, 0x00, 0x0d, + 0x69, 0x66, 0x2d, 0x6e, 0x6f, 0x6e, 0x65, 0x2d, + 0x6d, 0x61, 0x74, 0x63, 0x68, 0x00, 0x00, 0x00, + 0x08, 0x69, 0x66, 0x2d, 0x72, 0x61, 0x6e, 0x67, + 0x65, 0x00, 0x00, 0x00, 0x13, 0x69, 0x66, 0x2d, + 0x75, 0x6e, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x69, + 0x65, 0x64, 0x2d, 0x73, 0x69, 0x6e, 0x63, 0x65, + 0x00, 0x00, 0x00, 0x0d, 0x6c, 0x61, 0x73, 0x74, + 0x2d, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, + 0x64, 0x00, 0x00, 0x00, 0x08, 0x6c, 0x6f, 0x63, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x00, 0x00, + 0x0c, 0x6d, 0x61, 0x78, 0x2d, 0x66, 0x6f, 0x72, + 0x77, 0x61, 0x72, 0x64, 0x73, 0x00, 0x00, 0x00, + 0x06, 0x70, 0x72, 0x61, 0x67, 0x6d, 0x61, 0x00, + 0x00, 0x00, 0x12, 0x70, 0x72, 0x6f, 0x78, 0x79, + 0x2d, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, + 0x69, 0x63, 0x61, 0x74, 0x65, 0x00, 0x00, 0x00, + 0x13, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x2d, 0x61, + 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x00, 0x00, 0x05, + 0x72, 0x61, 0x6e, 0x67, 0x65, 0x00, 0x00, 0x00, + 0x07, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x72, + 0x00, 0x00, 0x00, 0x0b, 0x72, 0x65, 0x74, 0x72, + 0x79, 0x2d, 0x61, 0x66, 0x74, 0x65, 0x72, 0x00, + 0x00, 0x00, 0x06, 0x73, 0x65, 0x72, 0x76, 0x65, + 0x72, 0x00, 0x00, 0x00, 0x02, 0x74, 0x65, 0x00, + 0x00, 0x00, 0x07, 0x74, 0x72, 0x61, 0x69, 0x6c, + 0x65, 0x72, 0x00, 0x00, 0x00, 0x11, 0x74, 0x72, + 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x2d, 0x65, + 0x6e, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x00, + 0x00, 0x00, 0x07, 0x75, 0x70, 0x67, 0x72, 0x61, + 0x64, 0x65, 0x00, 0x00, 0x00, 0x0a, 0x75, 0x73, + 0x65, 0x72, 0x2d, 0x61, 0x67, 0x65, 0x6e, 0x74, + 0x00, 0x00, 0x00, 0x04, 0x76, 0x61, 0x72, 0x79, + 0x00, 0x00, 0x00, 0x03, 0x76, 0x69, 0x61, 0x00, + 0x00, 0x00, 0x07, 0x77, 0x61, 0x72, 0x6e, 0x69, + 0x6e, 0x67, 0x00, 0x00, 0x00, 0x10, 0x77, 0x77, + 0x77, 0x2d, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, + 0x74, 0x69, 0x63, 0x61, 0x74, 0x65, 0x00, 0x00, + 0x00, 0x06, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, + 0x00, 0x00, 0x00, 0x03, 0x67, 0x65, 0x74, 0x00, + 0x00, 0x00, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, + 0x73, 0x00, 0x00, 0x00, 0x06, 0x32, 0x30, 0x30, + 0x20, 0x4f, 0x4b, 0x00, 0x00, 0x00, 0x07, 0x76, + 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x00, 0x00, + 0x00, 0x08, 0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, + 0x2e, 0x31, 0x00, 0x00, 0x00, 0x03, 0x75, 0x72, + 0x6c, 0x00, 0x00, 0x00, 0x06, 0x70, 0x75, 0x62, + 0x6c, 0x69, 0x63, 0x00, 0x00, 0x00, 0x0a, 0x73, + 0x65, 0x74, 0x2d, 0x63, 0x6f, 0x6f, 0x6b, 0x69, + 0x65, 0x00, 0x00, 0x00, 0x0a, 0x6b, 0x65, 0x65, + 0x70, 0x2d, 0x61, 0x6c, 0x69, 0x76, 0x65, 0x00, + 0x00, 0x00, 0x06, 0x6f, 0x72, 0x69, 0x67, 0x69, + 0x6e, 0x31, 0x30, 0x30, 0x31, 0x30, 0x31, 0x32, + 0x30, 0x31, 0x32, 0x30, 0x32, 0x32, 0x30, 0x35, + 0x32, 0x30, 0x36, 0x33, 0x30, 0x30, 0x33, 0x30, + 0x32, 0x33, 0x30, 0x33, 0x33, 0x30, 0x34, 0x33, + 0x30, 0x35, 0x33, 0x30, 0x36, 0x33, 0x30, 0x37, + 0x34, 0x30, 0x32, 0x34, 0x30, 0x35, 0x34, 0x30, + 0x36, 0x34, 0x30, 0x37, 0x34, 0x30, 0x38, 0x34, + 0x30, 0x39, 0x34, 0x31, 0x30, 0x34, 0x31, 0x31, + 0x34, 0x31, 0x32, 0x34, 0x31, 0x33, 0x34, 0x31, + 0x34, 0x34, 0x31, 0x35, 0x34, 0x31, 0x36, 0x34, + 0x31, 0x37, 0x35, 0x30, 0x32, 0x35, 0x30, 0x34, + 0x35, 0x30, 0x35, 0x32, 0x30, 0x33, 0x20, 0x4e, + 0x6f, 0x6e, 0x2d, 0x41, 0x75, 0x74, 0x68, 0x6f, + 0x72, 0x69, 0x74, 0x61, 0x74, 0x69, 0x76, 0x65, + 0x20, 0x49, 0x6e, 0x66, 0x6f, 0x72, 0x6d, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x32, 0x30, 0x34, 0x20, + 0x4e, 0x6f, 0x20, 0x43, 0x6f, 0x6e, 0x74, 0x65, + 0x6e, 0x74, 0x33, 0x30, 0x31, 0x20, 0x4d, 0x6f, + 0x76, 0x65, 0x64, 0x20, 0x50, 0x65, 0x72, 0x6d, + 0x61, 0x6e, 0x65, 0x6e, 0x74, 0x6c, 0x79, 0x34, + 0x30, 0x30, 0x20, 0x42, 0x61, 0x64, 0x20, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x34, 0x30, + 0x31, 0x20, 0x55, 0x6e, 0x61, 0x75, 0x74, 0x68, + 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x34, 0x30, + 0x33, 0x20, 0x46, 0x6f, 0x72, 0x62, 0x69, 0x64, + 0x64, 0x65, 0x6e, 0x34, 0x30, 0x34, 0x20, 0x4e, + 0x6f, 0x74, 0x20, 0x46, 0x6f, 0x75, 0x6e, 0x64, + 0x35, 0x30, 0x30, 0x20, 0x49, 0x6e, 0x74, 0x65, + 0x72, 0x6e, 0x61, 0x6c, 0x20, 0x53, 0x65, 0x72, + 0x76, 0x65, 0x72, 0x20, 0x45, 0x72, 0x72, 0x6f, + 0x72, 0x35, 0x30, 0x31, 0x20, 0x4e, 0x6f, 0x74, + 0x20, 0x49, 0x6d, 0x70, 0x6c, 0x65, 0x6d, 0x65, + 0x6e, 0x74, 0x65, 0x64, 0x35, 0x30, 0x33, 0x20, + 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x20, + 0x55, 0x6e, 0x61, 0x76, 0x61, 0x69, 0x6c, 0x61, + 0x62, 0x6c, 0x65, 0x4a, 0x61, 0x6e, 0x20, 0x46, + 0x65, 0x62, 0x20, 0x4d, 0x61, 0x72, 0x20, 0x41, + 0x70, 0x72, 0x20, 0x4d, 0x61, 0x79, 0x20, 0x4a, + 0x75, 0x6e, 0x20, 0x4a, 0x75, 0x6c, 0x20, 0x41, + 0x75, 0x67, 0x20, 0x53, 0x65, 0x70, 0x74, 0x20, + 0x4f, 0x63, 0x74, 0x20, 0x4e, 0x6f, 0x76, 0x20, + 0x44, 0x65, 0x63, 0x20, 0x30, 0x30, 0x3a, 0x30, + 0x30, 0x3a, 0x30, 0x30, 0x20, 0x4d, 0x6f, 0x6e, + 0x2c, 0x20, 0x54, 0x75, 0x65, 0x2c, 0x20, 0x57, + 0x65, 0x64, 0x2c, 0x20, 0x54, 0x68, 0x75, 0x2c, + 0x20, 0x46, 0x72, 0x69, 0x2c, 0x20, 0x53, 0x61, + 0x74, 0x2c, 0x20, 0x53, 0x75, 0x6e, 0x2c, 0x20, + 0x47, 0x4d, 0x54, 0x63, 0x68, 0x75, 0x6e, 0x6b, + 0x65, 0x64, 0x2c, 0x74, 0x65, 0x78, 0x74, 0x2f, + 0x68, 0x74, 0x6d, 0x6c, 0x2c, 0x69, 0x6d, 0x61, + 0x67, 0x65, 0x2f, 0x70, 0x6e, 0x67, 0x2c, 0x69, + 0x6d, 0x61, 0x67, 0x65, 0x2f, 0x6a, 0x70, 0x67, + 0x2c, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2f, 0x67, + 0x69, 0x66, 0x2c, 0x61, 0x70, 0x70, 0x6c, 0x69, + 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x78, + 0x6d, 0x6c, 0x2c, 0x61, 0x70, 0x70, 0x6c, 0x69, + 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x78, + 0x68, 0x74, 0x6d, 0x6c, 0x2b, 0x78, 0x6d, 0x6c, + 0x2c, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x70, 0x6c, + 0x61, 0x69, 0x6e, 0x2c, 0x74, 0x65, 0x78, 0x74, + 0x2f, 0x6a, 0x61, 0x76, 0x61, 0x73, 0x63, 0x72, + 0x69, 0x70, 0x74, 0x2c, 0x70, 0x75, 0x62, 0x6c, + 0x69, 0x63, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, + 0x65, 0x6d, 0x61, 0x78, 0x2d, 0x61, 0x67, 0x65, + 0x3d, 0x67, 0x7a, 0x69, 0x70, 0x2c, 0x64, 0x65, + 0x66, 0x6c, 0x61, 0x74, 0x65, 0x2c, 0x73, 0x64, + 0x63, 0x68, 0x63, 0x68, 0x61, 0x72, 0x73, 0x65, + 0x74, 0x3d, 0x75, 0x74, 0x66, 0x2d, 0x38, 0x63, + 0x68, 0x61, 0x72, 0x73, 0x65, 0x74, 0x3d, 0x69, + 0x73, 0x6f, 0x2d, 0x38, 0x38, 0x35, 0x39, 0x2d, + 0x31, 0x2c, 0x75, 0x74, 0x66, 0x2d, 0x2c, 0x2a, + 0x2c, 0x65, 0x6e, 0x71, 0x3d, 0x30, 0x2e, +} diff --git a/vendor/github.com/moby/spdystream/spdy/read.go b/vendor/github.com/moby/spdystream/spdy/read.go new file mode 100644 index 0000000000..75ea045b8e --- /dev/null +++ b/vendor/github.com/moby/spdystream/spdy/read.go @@ -0,0 +1,364 @@ +/* + Copyright 2014-2021 Docker Inc. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +// Copyright 2011 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package spdy + +import ( + "compress/zlib" + "encoding/binary" + "io" + "net/http" + "strings" +) + +func (frame *SynStreamFrame) read(h ControlFrameHeader, f *Framer) error { + return f.readSynStreamFrame(h, frame) +} + +func (frame *SynReplyFrame) read(h ControlFrameHeader, f *Framer) error { + return f.readSynReplyFrame(h, frame) +} + +func (frame *RstStreamFrame) read(h ControlFrameHeader, f *Framer) error { + frame.CFHeader = h + if err := binary.Read(f.r, binary.BigEndian, &frame.StreamId); err != nil { + return err + } + if err := binary.Read(f.r, binary.BigEndian, &frame.Status); err != nil { + return err + } + if frame.Status == 0 { + return &Error{InvalidControlFrame, frame.StreamId} + } + if frame.StreamId == 0 { + return &Error{ZeroStreamId, 0} + } + return nil +} + +func (frame *SettingsFrame) read(h ControlFrameHeader, f *Framer) error { + frame.CFHeader = h + var numSettings uint32 + if err := binary.Read(f.r, binary.BigEndian, &numSettings); err != nil { + return err + } + frame.FlagIdValues = make([]SettingsFlagIdValue, numSettings) + for i := uint32(0); i < numSettings; i++ { + if err := binary.Read(f.r, binary.BigEndian, &frame.FlagIdValues[i].Id); err != nil { + return err + } + frame.FlagIdValues[i].Flag = SettingsFlag((frame.FlagIdValues[i].Id & 0xff000000) >> 24) + frame.FlagIdValues[i].Id &= 0xffffff + if err := binary.Read(f.r, binary.BigEndian, &frame.FlagIdValues[i].Value); err != nil { + return err + } + } + return nil +} + +func (frame *PingFrame) read(h ControlFrameHeader, f *Framer) error { + frame.CFHeader = h + if err := binary.Read(f.r, binary.BigEndian, &frame.Id); err != nil { + return err + } + if frame.Id == 0 { + return &Error{ZeroStreamId, 0} + } + if frame.CFHeader.Flags != 0 { + return &Error{InvalidControlFrame, StreamId(frame.Id)} + } + return nil +} + +func (frame *GoAwayFrame) read(h ControlFrameHeader, f *Framer) error { + frame.CFHeader = h + if err := binary.Read(f.r, binary.BigEndian, &frame.LastGoodStreamId); err != nil { + return err + } + if frame.CFHeader.Flags != 0 { + return &Error{InvalidControlFrame, frame.LastGoodStreamId} + } + if frame.CFHeader.length != 8 { + return &Error{InvalidControlFrame, frame.LastGoodStreamId} + } + if err := binary.Read(f.r, binary.BigEndian, &frame.Status); err != nil { + return err + } + return nil +} + +func (frame *HeadersFrame) read(h ControlFrameHeader, f *Framer) error { + return f.readHeadersFrame(h, frame) +} + +func (frame *WindowUpdateFrame) read(h ControlFrameHeader, f *Framer) error { + frame.CFHeader = h + if err := binary.Read(f.r, binary.BigEndian, &frame.StreamId); err != nil { + return err + } + if frame.CFHeader.Flags != 0 { + return &Error{InvalidControlFrame, frame.StreamId} + } + if frame.CFHeader.length != 8 { + return &Error{InvalidControlFrame, frame.StreamId} + } + if err := binary.Read(f.r, binary.BigEndian, &frame.DeltaWindowSize); err != nil { + return err + } + return nil +} + +func newControlFrame(frameType ControlFrameType) (controlFrame, error) { + ctor, ok := cframeCtor[frameType] + if !ok { + return nil, &Error{Err: InvalidControlFrame} + } + return ctor(), nil +} + +var cframeCtor = map[ControlFrameType]func() controlFrame{ + TypeSynStream: func() controlFrame { return new(SynStreamFrame) }, + TypeSynReply: func() controlFrame { return new(SynReplyFrame) }, + TypeRstStream: func() controlFrame { return new(RstStreamFrame) }, + TypeSettings: func() controlFrame { return new(SettingsFrame) }, + TypePing: func() controlFrame { return new(PingFrame) }, + TypeGoAway: func() controlFrame { return new(GoAwayFrame) }, + TypeHeaders: func() controlFrame { return new(HeadersFrame) }, + TypeWindowUpdate: func() controlFrame { return new(WindowUpdateFrame) }, +} + +func (f *Framer) uncorkHeaderDecompressor(payloadSize int64) error { + if f.headerDecompressor != nil { + f.headerReader.N = payloadSize + return nil + } + f.headerReader = io.LimitedReader{R: f.r, N: payloadSize} + decompressor, err := zlib.NewReaderDict(&f.headerReader, []byte(headerDictionary)) + if err != nil { + return err + } + f.headerDecompressor = decompressor + return nil +} + +// ReadFrame reads SPDY encoded data and returns a decompressed Frame. +func (f *Framer) ReadFrame() (Frame, error) { + var firstWord uint32 + if err := binary.Read(f.r, binary.BigEndian, &firstWord); err != nil { + return nil, err + } + if firstWord&0x80000000 != 0 { + frameType := ControlFrameType(firstWord & 0xffff) + version := uint16(firstWord >> 16 & 0x7fff) + return f.parseControlFrame(version, frameType) + } + return f.parseDataFrame(StreamId(firstWord & 0x7fffffff)) +} + +func (f *Framer) parseControlFrame(version uint16, frameType ControlFrameType) (Frame, error) { + var length uint32 + if err := binary.Read(f.r, binary.BigEndian, &length); err != nil { + return nil, err + } + flags := ControlFlags((length & 0xff000000) >> 24) + length &= 0xffffff + header := ControlFrameHeader{version, frameType, flags, length} + cframe, err := newControlFrame(frameType) + if err != nil { + return nil, err + } + if err = cframe.read(header, f); err != nil { + return nil, err + } + return cframe, nil +} + +func parseHeaderValueBlock(r io.Reader, streamId StreamId) (http.Header, error) { + var numHeaders uint32 + if err := binary.Read(r, binary.BigEndian, &numHeaders); err != nil { + return nil, err + } + var e error + h := make(http.Header, int(numHeaders)) + for i := 0; i < int(numHeaders); i++ { + var length uint32 + if err := binary.Read(r, binary.BigEndian, &length); err != nil { + return nil, err + } + nameBytes := make([]byte, length) + if _, err := io.ReadFull(r, nameBytes); err != nil { + return nil, err + } + name := string(nameBytes) + if name != strings.ToLower(name) { + e = &Error{UnlowercasedHeaderName, streamId} + name = strings.ToLower(name) + } + if h[name] != nil { + e = &Error{DuplicateHeaders, streamId} + } + if err := binary.Read(r, binary.BigEndian, &length); err != nil { + return nil, err + } + value := make([]byte, length) + if _, err := io.ReadFull(r, value); err != nil { + return nil, err + } + valueList := strings.Split(string(value), headerValueSeparator) + for _, v := range valueList { + h.Add(name, v) + } + } + if e != nil { + return h, e + } + return h, nil +} + +func (f *Framer) readSynStreamFrame(h ControlFrameHeader, frame *SynStreamFrame) error { + frame.CFHeader = h + var err error + if err = binary.Read(f.r, binary.BigEndian, &frame.StreamId); err != nil { + return err + } + if err = binary.Read(f.r, binary.BigEndian, &frame.AssociatedToStreamId); err != nil { + return err + } + if err = binary.Read(f.r, binary.BigEndian, &frame.Priority); err != nil { + return err + } + frame.Priority >>= 5 + if err = binary.Read(f.r, binary.BigEndian, &frame.Slot); err != nil { + return err + } + reader := f.r + if !f.headerCompressionDisabled { + err := f.uncorkHeaderDecompressor(int64(h.length - 10)) + if err != nil { + return err + } + reader = f.headerDecompressor + } + frame.Headers, err = parseHeaderValueBlock(reader, frame.StreamId) + if !f.headerCompressionDisabled && (err == io.EOF && f.headerReader.N == 0 || f.headerReader.N != 0) { + err = &Error{WrongCompressedPayloadSize, 0} + } + if err != nil { + return err + } + for h := range frame.Headers { + if invalidReqHeaders[h] { + return &Error{InvalidHeaderPresent, frame.StreamId} + } + } + if frame.StreamId == 0 { + return &Error{ZeroStreamId, 0} + } + return nil +} + +func (f *Framer) readSynReplyFrame(h ControlFrameHeader, frame *SynReplyFrame) error { + frame.CFHeader = h + var err error + if err = binary.Read(f.r, binary.BigEndian, &frame.StreamId); err != nil { + return err + } + reader := f.r + if !f.headerCompressionDisabled { + err := f.uncorkHeaderDecompressor(int64(h.length - 4)) + if err != nil { + return err + } + reader = f.headerDecompressor + } + frame.Headers, err = parseHeaderValueBlock(reader, frame.StreamId) + if !f.headerCompressionDisabled && (err == io.EOF && f.headerReader.N == 0 || f.headerReader.N != 0) { + err = &Error{WrongCompressedPayloadSize, 0} + } + if err != nil { + return err + } + for h := range frame.Headers { + if invalidRespHeaders[h] { + return &Error{InvalidHeaderPresent, frame.StreamId} + } + } + if frame.StreamId == 0 { + return &Error{ZeroStreamId, 0} + } + return nil +} + +func (f *Framer) readHeadersFrame(h ControlFrameHeader, frame *HeadersFrame) error { + frame.CFHeader = h + var err error + if err = binary.Read(f.r, binary.BigEndian, &frame.StreamId); err != nil { + return err + } + reader := f.r + if !f.headerCompressionDisabled { + err := f.uncorkHeaderDecompressor(int64(h.length - 4)) + if err != nil { + return err + } + reader = f.headerDecompressor + } + frame.Headers, err = parseHeaderValueBlock(reader, frame.StreamId) + if !f.headerCompressionDisabled && (err == io.EOF && f.headerReader.N == 0 || f.headerReader.N != 0) { + err = &Error{WrongCompressedPayloadSize, 0} + } + if err != nil { + return err + } + var invalidHeaders map[string]bool + if frame.StreamId%2 == 0 { + invalidHeaders = invalidReqHeaders + } else { + invalidHeaders = invalidRespHeaders + } + for h := range frame.Headers { + if invalidHeaders[h] { + return &Error{InvalidHeaderPresent, frame.StreamId} + } + } + if frame.StreamId == 0 { + return &Error{ZeroStreamId, 0} + } + return nil +} + +func (f *Framer) parseDataFrame(streamId StreamId) (*DataFrame, error) { + var length uint32 + if err := binary.Read(f.r, binary.BigEndian, &length); err != nil { + return nil, err + } + var frame DataFrame + frame.StreamId = streamId + frame.Flags = DataFlags(length >> 24) + length &= 0xffffff + frame.Data = make([]byte, length) + if _, err := io.ReadFull(f.r, frame.Data); err != nil { + return nil, err + } + if frame.StreamId == 0 { + return nil, &Error{ZeroStreamId, 0} + } + return &frame, nil +} diff --git a/vendor/github.com/moby/spdystream/spdy/types.go b/vendor/github.com/moby/spdystream/spdy/types.go new file mode 100644 index 0000000000..a254a43ab9 --- /dev/null +++ b/vendor/github.com/moby/spdystream/spdy/types.go @@ -0,0 +1,291 @@ +/* + Copyright 2014-2021 Docker Inc. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +// Copyright 2011 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package spdy implements the SPDY protocol (currently SPDY/3), described in +// http://www.chromium.org/spdy/spdy-protocol/spdy-protocol-draft3. +package spdy + +import ( + "bytes" + "compress/zlib" + "io" + "net/http" +) + +// Version is the protocol version number that this package implements. +const Version = 3 + +// ControlFrameType stores the type field in a control frame header. +type ControlFrameType uint16 + +const ( + TypeSynStream ControlFrameType = 0x0001 + TypeSynReply ControlFrameType = 0x0002 + TypeRstStream ControlFrameType = 0x0003 + TypeSettings ControlFrameType = 0x0004 + TypePing ControlFrameType = 0x0006 + TypeGoAway ControlFrameType = 0x0007 + TypeHeaders ControlFrameType = 0x0008 + TypeWindowUpdate ControlFrameType = 0x0009 +) + +// ControlFlags are the flags that can be set on a control frame. +type ControlFlags uint8 + +const ( + ControlFlagFin ControlFlags = 0x01 + ControlFlagUnidirectional ControlFlags = 0x02 + ControlFlagSettingsClearSettings ControlFlags = 0x01 +) + +// DataFlags are the flags that can be set on a data frame. +type DataFlags uint8 + +const ( + DataFlagFin DataFlags = 0x01 +) + +// MaxDataLength is the maximum number of bytes that can be stored in one frame. +const MaxDataLength = 1<<24 - 1 + +// headerValueSepator separates multiple header values. +const headerValueSeparator = "\x00" + +// Frame is a single SPDY frame in its unpacked in-memory representation. Use +// Framer to read and write it. +type Frame interface { + write(f *Framer) error +} + +// ControlFrameHeader contains all the fields in a control frame header, +// in its unpacked in-memory representation. +type ControlFrameHeader struct { + // Note, high bit is the "Control" bit. + version uint16 // spdy version number + frameType ControlFrameType + Flags ControlFlags + length uint32 // length of data field +} + +type controlFrame interface { + Frame + read(h ControlFrameHeader, f *Framer) error +} + +// StreamId represents a 31-bit value identifying the stream. +type StreamId uint32 + +// SynStreamFrame is the unpacked, in-memory representation of a SYN_STREAM +// frame. +type SynStreamFrame struct { + CFHeader ControlFrameHeader + StreamId StreamId + AssociatedToStreamId StreamId // stream id for a stream which this stream is associated to + Priority uint8 // priority of this frame (3-bit) + Slot uint8 // index in the server's credential vector of the client certificate + Headers http.Header +} + +// SynReplyFrame is the unpacked, in-memory representation of a SYN_REPLY frame. +type SynReplyFrame struct { + CFHeader ControlFrameHeader + StreamId StreamId + Headers http.Header +} + +// RstStreamStatus represents the status that led to a RST_STREAM. +type RstStreamStatus uint32 + +const ( + ProtocolError RstStreamStatus = iota + 1 + InvalidStream + RefusedStream + UnsupportedVersion + Cancel + InternalError + FlowControlError + StreamInUse + StreamAlreadyClosed + InvalidCredentials + FrameTooLarge +) + +// RstStreamFrame is the unpacked, in-memory representation of a RST_STREAM +// frame. +type RstStreamFrame struct { + CFHeader ControlFrameHeader + StreamId StreamId + Status RstStreamStatus +} + +// SettingsFlag represents a flag in a SETTINGS frame. +type SettingsFlag uint8 + +const ( + FlagSettingsPersistValue SettingsFlag = 0x1 + FlagSettingsPersisted SettingsFlag = 0x2 +) + +// SettingsFlag represents the id of an id/value pair in a SETTINGS frame. +type SettingsId uint32 + +const ( + SettingsUploadBandwidth SettingsId = iota + 1 + SettingsDownloadBandwidth + SettingsRoundTripTime + SettingsMaxConcurrentStreams + SettingsCurrentCwnd + SettingsDownloadRetransRate + SettingsInitialWindowSize + SettingsClientCretificateVectorSize +) + +// SettingsFlagIdValue is the unpacked, in-memory representation of the +// combined flag/id/value for a setting in a SETTINGS frame. +type SettingsFlagIdValue struct { + Flag SettingsFlag + Id SettingsId + Value uint32 +} + +// SettingsFrame is the unpacked, in-memory representation of a SPDY +// SETTINGS frame. +type SettingsFrame struct { + CFHeader ControlFrameHeader + FlagIdValues []SettingsFlagIdValue +} + +// PingFrame is the unpacked, in-memory representation of a PING frame. +type PingFrame struct { + CFHeader ControlFrameHeader + Id uint32 // unique id for this ping, from server is even, from client is odd. +} + +// GoAwayStatus represents the status in a GoAwayFrame. +type GoAwayStatus uint32 + +const ( + GoAwayOK GoAwayStatus = iota + GoAwayProtocolError + GoAwayInternalError +) + +// GoAwayFrame is the unpacked, in-memory representation of a GOAWAY frame. +type GoAwayFrame struct { + CFHeader ControlFrameHeader + LastGoodStreamId StreamId // last stream id which was accepted by sender + Status GoAwayStatus +} + +// HeadersFrame is the unpacked, in-memory representation of a HEADERS frame. +type HeadersFrame struct { + CFHeader ControlFrameHeader + StreamId StreamId + Headers http.Header +} + +// WindowUpdateFrame is the unpacked, in-memory representation of a +// WINDOW_UPDATE frame. +type WindowUpdateFrame struct { + CFHeader ControlFrameHeader + StreamId StreamId + DeltaWindowSize uint32 // additional number of bytes to existing window size +} + +// TODO: Implement credential frame and related methods. + +// DataFrame is the unpacked, in-memory representation of a DATA frame. +type DataFrame struct { + // Note, high bit is the "Control" bit. Should be 0 for data frames. + StreamId StreamId + Flags DataFlags + Data []byte // payload data of this frame +} + +// A SPDY specific error. +type ErrorCode string + +const ( + UnlowercasedHeaderName ErrorCode = "header was not lowercased" + DuplicateHeaders ErrorCode = "multiple headers with same name" + WrongCompressedPayloadSize ErrorCode = "compressed payload size was incorrect" + UnknownFrameType ErrorCode = "unknown frame type" + InvalidControlFrame ErrorCode = "invalid control frame" + InvalidDataFrame ErrorCode = "invalid data frame" + InvalidHeaderPresent ErrorCode = "frame contained invalid header" + ZeroStreamId ErrorCode = "stream id zero is disallowed" +) + +// Error contains both the type of error and additional values. StreamId is 0 +// if Error is not associated with a stream. +type Error struct { + Err ErrorCode + StreamId StreamId +} + +func (e *Error) Error() string { + return string(e.Err) +} + +var invalidReqHeaders = map[string]bool{ + "Connection": true, + "Host": true, + "Keep-Alive": true, + "Proxy-Connection": true, + "Transfer-Encoding": true, +} + +var invalidRespHeaders = map[string]bool{ + "Connection": true, + "Keep-Alive": true, + "Proxy-Connection": true, + "Transfer-Encoding": true, +} + +// Framer handles serializing/deserializing SPDY frames, including compressing/ +// decompressing payloads. +type Framer struct { + headerCompressionDisabled bool + w io.Writer + headerBuf *bytes.Buffer + headerCompressor *zlib.Writer + r io.Reader + headerReader io.LimitedReader + headerDecompressor io.ReadCloser +} + +// NewFramer allocates a new Framer for a given SPDY connection, represented by +// a io.Writer and io.Reader. Note that Framer will read and write individual fields +// from/to the Reader and Writer, so the caller should pass in an appropriately +// buffered implementation to optimize performance. +func NewFramer(w io.Writer, r io.Reader) (*Framer, error) { + compressBuf := new(bytes.Buffer) + compressor, err := zlib.NewWriterLevelDict(compressBuf, zlib.BestCompression, []byte(headerDictionary)) + if err != nil { + return nil, err + } + framer := &Framer{ + w: w, + headerBuf: compressBuf, + headerCompressor: compressor, + r: r, + } + return framer, nil +} diff --git a/vendor/github.com/moby/spdystream/spdy/write.go b/vendor/github.com/moby/spdystream/spdy/write.go new file mode 100644 index 0000000000..ab6d91f3b8 --- /dev/null +++ b/vendor/github.com/moby/spdystream/spdy/write.go @@ -0,0 +1,334 @@ +/* + Copyright 2014-2021 Docker Inc. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +// Copyright 2011 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package spdy + +import ( + "encoding/binary" + "io" + "net/http" + "strings" +) + +func (frame *SynStreamFrame) write(f *Framer) error { + return f.writeSynStreamFrame(frame) +} + +func (frame *SynReplyFrame) write(f *Framer) error { + return f.writeSynReplyFrame(frame) +} + +func (frame *RstStreamFrame) write(f *Framer) (err error) { + if frame.StreamId == 0 { + return &Error{ZeroStreamId, 0} + } + frame.CFHeader.version = Version + frame.CFHeader.frameType = TypeRstStream + frame.CFHeader.Flags = 0 + frame.CFHeader.length = 8 + + // Serialize frame to Writer. + if err = writeControlFrameHeader(f.w, frame.CFHeader); err != nil { + return + } + if err = binary.Write(f.w, binary.BigEndian, frame.StreamId); err != nil { + return + } + if frame.Status == 0 { + return &Error{InvalidControlFrame, frame.StreamId} + } + if err = binary.Write(f.w, binary.BigEndian, frame.Status); err != nil { + return + } + return +} + +func (frame *SettingsFrame) write(f *Framer) (err error) { + frame.CFHeader.version = Version + frame.CFHeader.frameType = TypeSettings + frame.CFHeader.length = uint32(len(frame.FlagIdValues)*8 + 4) + + // Serialize frame to Writer. + if err = writeControlFrameHeader(f.w, frame.CFHeader); err != nil { + return + } + if err = binary.Write(f.w, binary.BigEndian, uint32(len(frame.FlagIdValues))); err != nil { + return + } + for _, flagIdValue := range frame.FlagIdValues { + flagId := uint32(flagIdValue.Flag)<<24 | uint32(flagIdValue.Id) + if err = binary.Write(f.w, binary.BigEndian, flagId); err != nil { + return + } + if err = binary.Write(f.w, binary.BigEndian, flagIdValue.Value); err != nil { + return + } + } + return +} + +func (frame *PingFrame) write(f *Framer) (err error) { + if frame.Id == 0 { + return &Error{ZeroStreamId, 0} + } + frame.CFHeader.version = Version + frame.CFHeader.frameType = TypePing + frame.CFHeader.Flags = 0 + frame.CFHeader.length = 4 + + // Serialize frame to Writer. + if err = writeControlFrameHeader(f.w, frame.CFHeader); err != nil { + return + } + if err = binary.Write(f.w, binary.BigEndian, frame.Id); err != nil { + return + } + return +} + +func (frame *GoAwayFrame) write(f *Framer) (err error) { + frame.CFHeader.version = Version + frame.CFHeader.frameType = TypeGoAway + frame.CFHeader.Flags = 0 + frame.CFHeader.length = 8 + + // Serialize frame to Writer. + if err = writeControlFrameHeader(f.w, frame.CFHeader); err != nil { + return + } + if err = binary.Write(f.w, binary.BigEndian, frame.LastGoodStreamId); err != nil { + return + } + if err = binary.Write(f.w, binary.BigEndian, frame.Status); err != nil { + return + } + return nil +} + +func (frame *HeadersFrame) write(f *Framer) error { + return f.writeHeadersFrame(frame) +} + +func (frame *WindowUpdateFrame) write(f *Framer) (err error) { + frame.CFHeader.version = Version + frame.CFHeader.frameType = TypeWindowUpdate + frame.CFHeader.Flags = 0 + frame.CFHeader.length = 8 + + // Serialize frame to Writer. + if err = writeControlFrameHeader(f.w, frame.CFHeader); err != nil { + return + } + if err = binary.Write(f.w, binary.BigEndian, frame.StreamId); err != nil { + return + } + if err = binary.Write(f.w, binary.BigEndian, frame.DeltaWindowSize); err != nil { + return + } + return nil +} + +func (frame *DataFrame) write(f *Framer) error { + return f.writeDataFrame(frame) +} + +// WriteFrame writes a frame. +func (f *Framer) WriteFrame(frame Frame) error { + return frame.write(f) +} + +func writeControlFrameHeader(w io.Writer, h ControlFrameHeader) error { + if err := binary.Write(w, binary.BigEndian, 0x8000|h.version); err != nil { + return err + } + if err := binary.Write(w, binary.BigEndian, h.frameType); err != nil { + return err + } + flagsAndLength := uint32(h.Flags)<<24 | h.length + if err := binary.Write(w, binary.BigEndian, flagsAndLength); err != nil { + return err + } + return nil +} + +func writeHeaderValueBlock(w io.Writer, h http.Header) (n int, err error) { + n = 0 + if err = binary.Write(w, binary.BigEndian, uint32(len(h))); err != nil { + return + } + n += 2 + for name, values := range h { + if err = binary.Write(w, binary.BigEndian, uint32(len(name))); err != nil { + return + } + n += 2 + name = strings.ToLower(name) + if _, err = io.WriteString(w, name); err != nil { + return + } + n += len(name) + v := strings.Join(values, headerValueSeparator) + if err = binary.Write(w, binary.BigEndian, uint32(len(v))); err != nil { + return + } + n += 2 + if _, err = io.WriteString(w, v); err != nil { + return + } + n += len(v) + } + return +} + +func (f *Framer) writeSynStreamFrame(frame *SynStreamFrame) (err error) { + if frame.StreamId == 0 { + return &Error{ZeroStreamId, 0} + } + // Marshal the headers. + var writer io.Writer = f.headerBuf + if !f.headerCompressionDisabled { + writer = f.headerCompressor + } + if _, err = writeHeaderValueBlock(writer, frame.Headers); err != nil { + return + } + if !f.headerCompressionDisabled { + f.headerCompressor.Flush() + } + + // Set ControlFrameHeader. + frame.CFHeader.version = Version + frame.CFHeader.frameType = TypeSynStream + frame.CFHeader.length = uint32(len(f.headerBuf.Bytes()) + 10) + + // Serialize frame to Writer. + if err = writeControlFrameHeader(f.w, frame.CFHeader); err != nil { + return err + } + if err = binary.Write(f.w, binary.BigEndian, frame.StreamId); err != nil { + return err + } + if err = binary.Write(f.w, binary.BigEndian, frame.AssociatedToStreamId); err != nil { + return err + } + if err = binary.Write(f.w, binary.BigEndian, frame.Priority<<5); err != nil { + return err + } + if err = binary.Write(f.w, binary.BigEndian, frame.Slot); err != nil { + return err + } + if _, err = f.w.Write(f.headerBuf.Bytes()); err != nil { + return err + } + f.headerBuf.Reset() + return nil +} + +func (f *Framer) writeSynReplyFrame(frame *SynReplyFrame) (err error) { + if frame.StreamId == 0 { + return &Error{ZeroStreamId, 0} + } + // Marshal the headers. + var writer io.Writer = f.headerBuf + if !f.headerCompressionDisabled { + writer = f.headerCompressor + } + if _, err = writeHeaderValueBlock(writer, frame.Headers); err != nil { + return + } + if !f.headerCompressionDisabled { + f.headerCompressor.Flush() + } + + // Set ControlFrameHeader. + frame.CFHeader.version = Version + frame.CFHeader.frameType = TypeSynReply + frame.CFHeader.length = uint32(len(f.headerBuf.Bytes()) + 4) + + // Serialize frame to Writer. + if err = writeControlFrameHeader(f.w, frame.CFHeader); err != nil { + return + } + if err = binary.Write(f.w, binary.BigEndian, frame.StreamId); err != nil { + return + } + if _, err = f.w.Write(f.headerBuf.Bytes()); err != nil { + return + } + f.headerBuf.Reset() + return +} + +func (f *Framer) writeHeadersFrame(frame *HeadersFrame) (err error) { + if frame.StreamId == 0 { + return &Error{ZeroStreamId, 0} + } + // Marshal the headers. + var writer io.Writer = f.headerBuf + if !f.headerCompressionDisabled { + writer = f.headerCompressor + } + if _, err = writeHeaderValueBlock(writer, frame.Headers); err != nil { + return + } + if !f.headerCompressionDisabled { + f.headerCompressor.Flush() + } + + // Set ControlFrameHeader. + frame.CFHeader.version = Version + frame.CFHeader.frameType = TypeHeaders + frame.CFHeader.length = uint32(len(f.headerBuf.Bytes()) + 4) + + // Serialize frame to Writer. + if err = writeControlFrameHeader(f.w, frame.CFHeader); err != nil { + return + } + if err = binary.Write(f.w, binary.BigEndian, frame.StreamId); err != nil { + return + } + if _, err = f.w.Write(f.headerBuf.Bytes()); err != nil { + return + } + f.headerBuf.Reset() + return +} + +func (f *Framer) writeDataFrame(frame *DataFrame) (err error) { + if frame.StreamId == 0 { + return &Error{ZeroStreamId, 0} + } + if frame.StreamId&0x80000000 != 0 || len(frame.Data) > MaxDataLength { + return &Error{InvalidDataFrame, frame.StreamId} + } + + // Serialize frame to Writer. + if err = binary.Write(f.w, binary.BigEndian, frame.StreamId); err != nil { + return + } + flagsAndLength := uint32(frame.Flags)<<24 | uint32(len(frame.Data)) + if err = binary.Write(f.w, binary.BigEndian, flagsAndLength); err != nil { + return + } + if _, err = f.w.Write(frame.Data); err != nil { + return + } + return nil +} diff --git a/vendor/github.com/moby/spdystream/stream.go b/vendor/github.com/moby/spdystream/stream.go new file mode 100644 index 0000000000..404e3c02df --- /dev/null +++ b/vendor/github.com/moby/spdystream/stream.go @@ -0,0 +1,343 @@ +/* + Copyright 2014-2021 Docker Inc. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package spdystream + +import ( + "errors" + "fmt" + "io" + "net" + "net/http" + "sync" + "time" + + "github.com/moby/spdystream/spdy" +) + +var ( + ErrUnreadPartialData = errors.New("unread partial data") +) + +type Stream struct { + streamId spdy.StreamId + parent *Stream + conn *Connection + startChan chan error + + dataLock sync.RWMutex + dataChan chan []byte + unread []byte + + priority uint8 + headers http.Header + headerChan chan http.Header + finishLock sync.Mutex + finished bool + replyCond *sync.Cond + replied bool + closeLock sync.Mutex + closeChan chan bool +} + +// WriteData writes data to stream, sending a dataframe per call +func (s *Stream) WriteData(data []byte, fin bool) error { + s.waitWriteReply() + var flags spdy.DataFlags + + if fin { + flags = spdy.DataFlagFin + s.finishLock.Lock() + if s.finished { + s.finishLock.Unlock() + return ErrWriteClosedStream + } + s.finished = true + s.finishLock.Unlock() + } + + dataFrame := &spdy.DataFrame{ + StreamId: s.streamId, + Flags: flags, + Data: data, + } + + debugMessage("(%p) (%d) Writing data frame", s, s.streamId) + return s.conn.framer.WriteFrame(dataFrame) +} + +// Write writes bytes to a stream, calling write data for each call. +func (s *Stream) Write(data []byte) (n int, err error) { + err = s.WriteData(data, false) + if err == nil { + n = len(data) + } + return +} + +// Read reads bytes from a stream, a single read will never get more +// than what is sent on a single data frame, but a multiple calls to +// read may get data from the same data frame. +func (s *Stream) Read(p []byte) (n int, err error) { + if s.unread == nil { + select { + case <-s.closeChan: + return 0, io.EOF + case read, ok := <-s.dataChan: + if !ok { + return 0, io.EOF + } + s.unread = read + } + } + n = copy(p, s.unread) + if n < len(s.unread) { + s.unread = s.unread[n:] + } else { + s.unread = nil + } + return +} + +// ReadData reads an entire data frame and returns the byte array +// from the data frame. If there is unread data from the result +// of a Read call, this function will return an ErrUnreadPartialData. +func (s *Stream) ReadData() ([]byte, error) { + debugMessage("(%p) Reading data from %d", s, s.streamId) + if s.unread != nil { + return nil, ErrUnreadPartialData + } + select { + case <-s.closeChan: + return nil, io.EOF + case read, ok := <-s.dataChan: + if !ok { + return nil, io.EOF + } + return read, nil + } +} + +func (s *Stream) waitWriteReply() { + if s.replyCond != nil { + s.replyCond.L.Lock() + for !s.replied { + s.replyCond.Wait() + } + s.replyCond.L.Unlock() + } +} + +// Wait waits for the stream to receive a reply. +func (s *Stream) Wait() error { + return s.WaitTimeout(time.Duration(0)) +} + +// WaitTimeout waits for the stream to receive a reply or for timeout. +// When the timeout is reached, ErrTimeout will be returned. +func (s *Stream) WaitTimeout(timeout time.Duration) error { + var timeoutChan <-chan time.Time + if timeout > time.Duration(0) { + timeoutChan = time.After(timeout) + } + + select { + case err := <-s.startChan: + if err != nil { + return err + } + break + case <-timeoutChan: + return ErrTimeout + } + return nil +} + +// Close closes the stream by sending an empty data frame with the +// finish flag set, indicating this side is finished with the stream. +func (s *Stream) Close() error { + select { + case <-s.closeChan: + // Stream is now fully closed + s.conn.removeStream(s) + default: + break + } + return s.WriteData([]byte{}, true) +} + +// Reset sends a reset frame, putting the stream into the fully closed state. +func (s *Stream) Reset() error { + s.conn.removeStream(s) + return s.resetStream() +} + +func (s *Stream) resetStream() error { + // Always call closeRemoteChannels, even if s.finished is already true. + // This makes it so that stream.Close() followed by stream.Reset() allows + // stream.Read() to unblock. + s.closeRemoteChannels() + + s.finishLock.Lock() + if s.finished { + s.finishLock.Unlock() + return nil + } + s.finished = true + s.finishLock.Unlock() + + resetFrame := &spdy.RstStreamFrame{ + StreamId: s.streamId, + Status: spdy.Cancel, + } + return s.conn.framer.WriteFrame(resetFrame) +} + +// CreateSubStream creates a stream using the current as the parent +func (s *Stream) CreateSubStream(headers http.Header, fin bool) (*Stream, error) { + return s.conn.CreateStream(headers, s, fin) +} + +// SetPriority sets the stream priority, does not affect the +// remote priority of this stream after Open has been called. +// Valid values are 0 through 7, 0 being the highest priority +// and 7 the lowest. +func (s *Stream) SetPriority(priority uint8) { + s.priority = priority +} + +// SendHeader sends a header frame across the stream +func (s *Stream) SendHeader(headers http.Header, fin bool) error { + return s.conn.sendHeaders(headers, s, fin) +} + +// SendReply sends a reply on a stream, only valid to be called once +// when handling a new stream +func (s *Stream) SendReply(headers http.Header, fin bool) error { + if s.replyCond == nil { + return errors.New("cannot reply on initiated stream") + } + s.replyCond.L.Lock() + defer s.replyCond.L.Unlock() + if s.replied { + return nil + } + + err := s.conn.sendReply(headers, s, fin) + if err != nil { + return err + } + + s.replied = true + s.replyCond.Broadcast() + return nil +} + +// Refuse sends a reset frame with the status refuse, only +// valid to be called once when handling a new stream. This +// may be used to indicate that a stream is not allowed +// when http status codes are not being used. +func (s *Stream) Refuse() error { + if s.replied { + return nil + } + s.replied = true + return s.conn.sendReset(spdy.RefusedStream, s) +} + +// Cancel sends a reset frame with the status canceled. This +// can be used at any time by the creator of the Stream to +// indicate the stream is no longer needed. +func (s *Stream) Cancel() error { + return s.conn.sendReset(spdy.Cancel, s) +} + +// ReceiveHeader receives a header sent on the other side +// of the stream. This function will block until a header +// is received or stream is closed. +func (s *Stream) ReceiveHeader() (http.Header, error) { + select { + case <-s.closeChan: + break + case header, ok := <-s.headerChan: + if !ok { + return nil, fmt.Errorf("header chan closed") + } + return header, nil + } + return nil, fmt.Errorf("stream closed") +} + +// Parent returns the parent stream +func (s *Stream) Parent() *Stream { + return s.parent +} + +// Headers returns the headers used to create the stream +func (s *Stream) Headers() http.Header { + return s.headers +} + +// String returns the string version of stream using the +// streamId to uniquely identify the stream +func (s *Stream) String() string { + return fmt.Sprintf("stream:%d", s.streamId) +} + +// Identifier returns a 32 bit identifier for the stream +func (s *Stream) Identifier() uint32 { + return uint32(s.streamId) +} + +// IsFinished returns whether the stream has finished +// sending data +func (s *Stream) IsFinished() bool { + return s.finished +} + +// Implement net.Conn interface + +func (s *Stream) LocalAddr() net.Addr { + return s.conn.conn.LocalAddr() +} + +func (s *Stream) RemoteAddr() net.Addr { + return s.conn.conn.RemoteAddr() +} + +// TODO set per stream values instead of connection-wide + +func (s *Stream) SetDeadline(t time.Time) error { + return s.conn.conn.SetDeadline(t) +} + +func (s *Stream) SetReadDeadline(t time.Time) error { + return s.conn.conn.SetReadDeadline(t) +} + +func (s *Stream) SetWriteDeadline(t time.Time) error { + return s.conn.conn.SetWriteDeadline(t) +} + +func (s *Stream) closeRemoteChannels() { + s.closeLock.Lock() + defer s.closeLock.Unlock() + select { + case <-s.closeChan: + default: + close(s.closeChan) + } +} diff --git a/vendor/github.com/moby/spdystream/utils.go b/vendor/github.com/moby/spdystream/utils.go new file mode 100644 index 0000000000..e9f7fffd60 --- /dev/null +++ b/vendor/github.com/moby/spdystream/utils.go @@ -0,0 +1,32 @@ +/* + Copyright 2014-2021 Docker Inc. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package spdystream + +import ( + "log" + "os" +) + +var ( + DEBUG = os.Getenv("DEBUG") +) + +func debugMessage(fmt string, args ...interface{}) { + if DEBUG != "" { + log.Printf(fmt, args...) + } +} diff --git a/vendor/github.com/opencontainers/image-spec/specs-go/v1/annotations.go b/vendor/github.com/opencontainers/image-spec/specs-go/v1/annotations.go index 35d8108958..581cf7cdfa 100644 --- a/vendor/github.com/opencontainers/image-spec/specs-go/v1/annotations.go +++ b/vendor/github.com/opencontainers/image-spec/specs-go/v1/annotations.go @@ -53,4 +53,10 @@ const ( // AnnotationDescription is the annotation key for the human-readable description of the software packaged in the image. AnnotationDescription = "org.opencontainers.image.description" + + // AnnotationBaseImageDigest is the annotation key for the digest of the image's base image. + AnnotationBaseImageDigest = "org.opencontainers.image.base.digest" + + // AnnotationBaseImageName is the annotation key for the image reference of the image's base image. + AnnotationBaseImageName = "org.opencontainers.image.base.name" ) diff --git a/vendor/github.com/opencontainers/image-spec/specs-go/v1/config.go b/vendor/github.com/opencontainers/image-spec/specs-go/v1/config.go index fe799bd698..ffff4b6d18 100644 --- a/vendor/github.com/opencontainers/image-spec/specs-go/v1/config.go +++ b/vendor/github.com/opencontainers/image-spec/specs-go/v1/config.go @@ -89,9 +89,20 @@ type Image struct { // Architecture is the CPU architecture which the binaries in this image are built to run on. Architecture string `json:"architecture"` + // Variant is the variant of the specified CPU architecture which image binaries are intended to run on. + Variant string `json:"variant,omitempty"` + // OS is the name of the operating system which the image is built to run on. OS string `json:"os"` + // OSVersion is an optional field specifying the operating system + // version, for example on Windows `10.0.14393.1066`. + OSVersion string `json:"os.version,omitempty"` + + // OSFeatures is an optional field specifying an array of strings, + // each listing a required OS feature (for example on Windows `win32k`). + OSFeatures []string `json:"os.features,omitempty"` + // Config defines the execution parameters which should be used as a base when running a container using the image. Config ImageConfig `json:"config,omitempty"` diff --git a/vendor/github.com/opencontainers/runc/libcontainer/user/MAINTAINERS b/vendor/github.com/opencontainers/runc/libcontainer/user/MAINTAINERS deleted file mode 100644 index edbe200669..0000000000 --- a/vendor/github.com/opencontainers/runc/libcontainer/user/MAINTAINERS +++ /dev/null @@ -1,2 +0,0 @@ -Tianon Gravi (@tianon) -Aleksa Sarai (@cyphar) diff --git a/vendor/github.com/opencontainers/runc/libcontainer/user/lookup.go b/vendor/github.com/opencontainers/runc/libcontainer/user/lookup.go deleted file mode 100644 index 6fd8dd0d44..0000000000 --- a/vendor/github.com/opencontainers/runc/libcontainer/user/lookup.go +++ /dev/null @@ -1,41 +0,0 @@ -package user - -import ( - "errors" -) - -var ( - // The current operating system does not provide the required data for user lookups. - ErrUnsupported = errors.New("user lookup: operating system does not provide passwd-formatted data") - // No matching entries found in file. - ErrNoPasswdEntries = errors.New("no matching entries in passwd file") - ErrNoGroupEntries = errors.New("no matching entries in group file") -) - -// LookupUser looks up a user by their username in /etc/passwd. If the user -// cannot be found (or there is no /etc/passwd file on the filesystem), then -// LookupUser returns an error. -func LookupUser(username string) (User, error) { - return lookupUser(username) -} - -// LookupUid looks up a user by their user id in /etc/passwd. If the user cannot -// be found (or there is no /etc/passwd file on the filesystem), then LookupId -// returns an error. -func LookupUid(uid int) (User, error) { - return lookupUid(uid) -} - -// LookupGroup looks up a group by its name in /etc/group. If the group cannot -// be found (or there is no /etc/group file on the filesystem), then LookupGroup -// returns an error. -func LookupGroup(groupname string) (Group, error) { - return lookupGroup(groupname) -} - -// LookupGid looks up a group by its group id in /etc/group. If the group cannot -// be found (or there is no /etc/group file on the filesystem), then LookupGid -// returns an error. -func LookupGid(gid int) (Group, error) { - return lookupGid(gid) -} diff --git a/vendor/github.com/opencontainers/runc/libcontainer/user/lookup_unix.go b/vendor/github.com/opencontainers/runc/libcontainer/user/lookup_unix.go index 92b5ae8de0..967717a1b1 100644 --- a/vendor/github.com/opencontainers/runc/libcontainer/user/lookup_unix.go +++ b/vendor/github.com/opencontainers/runc/libcontainer/user/lookup_unix.go @@ -16,13 +16,19 @@ const ( unixGroupPath = "/etc/group" ) -func lookupUser(username string) (User, error) { +// LookupUser looks up a user by their username in /etc/passwd. If the user +// cannot be found (or there is no /etc/passwd file on the filesystem), then +// LookupUser returns an error. +func LookupUser(username string) (User, error) { return lookupUserFunc(func(u User) bool { return u.Name == username }) } -func lookupUid(uid int) (User, error) { +// LookupUid looks up a user by their user id in /etc/passwd. If the user cannot +// be found (or there is no /etc/passwd file on the filesystem), then LookupId +// returns an error. +func LookupUid(uid int) (User, error) { return lookupUserFunc(func(u User) bool { return u.Uid == uid }) @@ -51,13 +57,19 @@ func lookupUserFunc(filter func(u User) bool) (User, error) { return users[0], nil } -func lookupGroup(groupname string) (Group, error) { +// LookupGroup looks up a group by its name in /etc/group. If the group cannot +// be found (or there is no /etc/group file on the filesystem), then LookupGroup +// returns an error. +func LookupGroup(groupname string) (Group, error) { return lookupGroupFunc(func(g Group) bool { return g.Name == groupname }) } -func lookupGid(gid int) (Group, error) { +// LookupGid looks up a group by its group id in /etc/group. If the group cannot +// be found (or there is no /etc/group file on the filesystem), then LookupGid +// returns an error. +func LookupGid(gid int) (Group, error) { return lookupGroupFunc(func(g Group) bool { return g.Gid == gid }) diff --git a/vendor/github.com/opencontainers/runc/libcontainer/user/lookup_windows.go b/vendor/github.com/opencontainers/runc/libcontainer/user/lookup_windows.go deleted file mode 100644 index f19333e61e..0000000000 --- a/vendor/github.com/opencontainers/runc/libcontainer/user/lookup_windows.go +++ /dev/null @@ -1,40 +0,0 @@ -// +build windows - -package user - -import ( - "os/user" - "strconv" -) - -func lookupUser(username string) (User, error) { - u, err := user.Lookup(username) - if err != nil { - return User{}, err - } - return userFromOS(u) -} - -func lookupUid(uid int) (User, error) { - u, err := user.LookupId(strconv.Itoa(uid)) - if err != nil { - return User{}, err - } - return userFromOS(u) -} - -func lookupGroup(groupname string) (Group, error) { - g, err := user.LookupGroup(groupname) - if err != nil { - return Group{}, err - } - return groupFromOS(g) -} - -func lookupGid(gid int) (Group, error) { - g, err := user.LookupGroupId(strconv.Itoa(gid)) - if err != nil { - return Group{}, err - } - return groupFromOS(g) -} diff --git a/vendor/github.com/opencontainers/runc/libcontainer/user/user.go b/vendor/github.com/opencontainers/runc/libcontainer/user/user.go index a533bf5e66..cc7a106be5 100644 --- a/vendor/github.com/opencontainers/runc/libcontainer/user/user.go +++ b/vendor/github.com/opencontainers/runc/libcontainer/user/user.go @@ -2,21 +2,27 @@ package user import ( "bufio" + "bytes" + "errors" "fmt" "io" "os" - "os/user" "strconv" "strings" ) const ( - minId = 0 - maxId = 1<<31 - 1 //for 32-bit systems compatibility + minID = 0 + maxID = 1<<31 - 1 // for 32-bit systems compatibility ) var ( - ErrRange = fmt.Errorf("uids and gids must be in range %d-%d", minId, maxId) + // ErrNoPasswdEntries is returned if no matching entries were found in /etc/group. + ErrNoPasswdEntries = errors.New("no matching entries in passwd file") + // ErrNoGroupEntries is returned if no matching entries were found in /etc/passwd. + ErrNoGroupEntries = errors.New("no matching entries in group file") + // ErrRange is returned if a UID or GID is outside of the valid range. + ErrRange = fmt.Errorf("uids and gids must be in range %d-%d", minID, maxID) ) type User struct { @@ -29,28 +35,6 @@ type User struct { Shell string } -// userFromOS converts an os/user.(*User) to local User -// -// (This does not include Pass, Shell or Gecos) -func userFromOS(u *user.User) (User, error) { - newUser := User{ - Name: u.Username, - Home: u.HomeDir, - } - id, err := strconv.Atoi(u.Uid) - if err != nil { - return newUser, err - } - newUser.Uid = id - - id, err = strconv.Atoi(u.Gid) - if err != nil { - return newUser, err - } - newUser.Gid = id - return newUser, nil -} - type Group struct { Name string Pass string @@ -58,23 +42,6 @@ type Group struct { List []string } -// groupFromOS converts an os/user.(*Group) to local Group -// -// (This does not include Pass or List) -func groupFromOS(g *user.Group) (Group, error) { - newGroup := Group{ - Name: g.Name, - } - - id, err := strconv.Atoi(g.Gid) - if err != nil { - return newGroup, err - } - newGroup.Gid = id - - return newGroup, nil -} - // SubID represents an entry in /etc/sub{u,g}id type SubID struct { Name string @@ -89,11 +56,11 @@ type IDMap struct { Count int64 } -func parseLine(line string, v ...interface{}) { - parseParts(strings.Split(line, ":"), v...) +func parseLine(line []byte, v ...interface{}) { + parseParts(bytes.Split(line, []byte(":")), v...) } -func parseParts(parts []string, v ...interface{}) { +func parseParts(parts [][]byte, v ...interface{}) { if len(parts) == 0 { return } @@ -109,16 +76,16 @@ func parseParts(parts []string, v ...interface{}) { // This is legit. switch e := v[i].(type) { case *string: - *e = p + *e = string(p) case *int: // "numbers", with conversion errors ignored because of some misbehaving configuration files. - *e, _ = strconv.Atoi(p) + *e, _ = strconv.Atoi(string(p)) case *int64: - *e, _ = strconv.ParseInt(p, 10, 64) + *e, _ = strconv.ParseInt(string(p), 10, 64) case *[]string: // Comma-separated lists. - if p != "" { - *e = strings.Split(p, ",") + if len(p) != 0 { + *e = strings.Split(string(p), ",") } else { *e = []string{} } @@ -162,8 +129,8 @@ func ParsePasswdFilter(r io.Reader, filter func(User) bool) ([]User, error) { ) for s.Scan() { - line := strings.TrimSpace(s.Text()) - if line == "" { + line := bytes.TrimSpace(s.Bytes()) + if len(line) == 0 { continue } @@ -213,15 +180,53 @@ func ParseGroupFilter(r io.Reader, filter func(Group) bool) ([]Group, error) { if r == nil { return nil, fmt.Errorf("nil source for group-formatted data") } + rd := bufio.NewReader(r) + out := []Group{} - var ( - s = bufio.NewScanner(r) - out = []Group{} - ) + // Read the file line-by-line. + for { + var ( + isPrefix bool + wholeLine []byte + err error + ) - for s.Scan() { - text := s.Text() - if text == "" { + // Read the next line. We do so in chunks (as much as reader's + // buffer is able to keep), check if we read enough columns + // already on each step and store final result in wholeLine. + for { + var line []byte + line, isPrefix, err = rd.ReadLine() + + if err != nil { + // We should return no error if EOF is reached + // without a match. + if err == io.EOF { //nolint:errorlint // comparison with io.EOF is legit, https://github.com/polyfloyd/go-errorlint/pull/12 + err = nil + } + return out, err + } + + // Simple common case: line is short enough to fit in a + // single reader's buffer. + if !isPrefix && len(wholeLine) == 0 { + wholeLine = line + break + } + + wholeLine = append(wholeLine, line...) + + // Check if we read the whole line already. + if !isPrefix { + break + } + } + + // There's no spec for /etc/passwd or /etc/group, but we try to follow + // the same rules as the glibc parser, which allows comments and blank + // space at the beginning of a line. + wholeLine = bytes.TrimSpace(wholeLine) + if len(wholeLine) == 0 || wholeLine[0] == '#' { continue } @@ -231,17 +236,12 @@ func ParseGroupFilter(r io.Reader, filter func(Group) bool) ([]Group, error) { // root:x:0:root // adm:x:4:root,adm,daemon p := Group{} - parseLine(text, &p.Name, &p.Pass, &p.Gid, &p.List) + parseLine(wholeLine, &p.Name, &p.Pass, &p.Gid, &p.List) if filter == nil || filter(p) { out = append(out, p) } } - if err := s.Err(); err != nil { - return nil, err - } - - return out, nil } type ExecUser struct { @@ -312,7 +312,7 @@ func GetExecUser(userSpec string, defaults *ExecUser, passwd, group io.Reader) ( // Allow for userArg to have either "user" syntax, or optionally "user:group" syntax var userArg, groupArg string - parseLine(userSpec, &userArg, &groupArg) + parseLine([]byte(userSpec), &userArg, &groupArg) // Convert userArg and groupArg to be numeric, so we don't have to execute // Atoi *twice* for each iteration over lines. @@ -360,7 +360,7 @@ func GetExecUser(userSpec string, defaults *ExecUser, passwd, group io.Reader) ( user.Uid = uidArg // Must be inside valid uid range. - if user.Uid < minId || user.Uid > maxId { + if user.Uid < minID || user.Uid > maxID { return nil, ErrRange } @@ -409,7 +409,7 @@ func GetExecUser(userSpec string, defaults *ExecUser, passwd, group io.Reader) ( user.Gid = gidArg // Must be inside valid gid range. - if user.Gid < minId || user.Gid > maxId { + if user.Gid < minID || user.Gid > maxID { return nil, ErrRange } @@ -433,7 +433,7 @@ func GetExecUser(userSpec string, defaults *ExecUser, passwd, group io.Reader) ( // or the given group data is nil, the id will be returned as-is // provided it is in the legal range. func GetAdditionalGroups(additionalGroups []string, group io.Reader) ([]int, error) { - var groups = []Group{} + groups := []Group{} if group != nil { var err error groups, err = ParseGroupFilter(group, func(g Group) bool { @@ -471,7 +471,7 @@ func GetAdditionalGroups(additionalGroups []string, group io.Reader) ([]int, err return nil, fmt.Errorf("Unable to find group %s", ag) } // Ensure gid is inside gid range. - if gid < minId || gid > maxId { + if gid < minID || gid > maxID { return nil, ErrRange } gidMap[int(gid)] = struct{}{} @@ -530,8 +530,8 @@ func ParseSubIDFilter(r io.Reader, filter func(SubID) bool) ([]SubID, error) { ) for s.Scan() { - line := strings.TrimSpace(s.Text()) - if line == "" { + line := bytes.TrimSpace(s.Bytes()) + if len(line) == 0 { continue } @@ -583,14 +583,14 @@ func ParseIDMapFilter(r io.Reader, filter func(IDMap) bool) ([]IDMap, error) { ) for s.Scan() { - line := strings.TrimSpace(s.Text()) - if line == "" { + line := bytes.TrimSpace(s.Bytes()) + if len(line) == 0 { continue } // see: man 7 user_namespaces p := IDMap{} - parseParts(strings.Fields(line), &p.ID, &p.ParentID, &p.Count) + parseParts(bytes.Fields(line), &p.ID, &p.ParentID, &p.Count) if filter == nil || filter(p) { out = append(out, p) diff --git a/vendor/github.com/opencontainers/runc/libcontainer/user/user_fuzzer.go b/vendor/github.com/opencontainers/runc/libcontainer/user/user_fuzzer.go new file mode 100644 index 0000000000..8c9bb5df39 --- /dev/null +++ b/vendor/github.com/opencontainers/runc/libcontainer/user/user_fuzzer.go @@ -0,0 +1,42 @@ +// +build gofuzz + +package user + +import ( + "io" + "strings" +) + +func IsDivisbleBy(n int, divisibleby int) bool { + return (n % divisibleby) == 0 +} + +func FuzzUser(data []byte) int { + if len(data) == 0 { + return -1 + } + if !IsDivisbleBy(len(data), 5) { + return -1 + } + + var divided [][]byte + + chunkSize := len(data) / 5 + + for i := 0; i < len(data); i += chunkSize { + end := i + chunkSize + + divided = append(divided, data[i:end]) + } + + _, _ = ParsePasswdFilter(strings.NewReader(string(divided[0])), nil) + + var passwd, group io.Reader + + group = strings.NewReader(string(divided[1])) + _, _ = GetAdditionalGroups([]string{string(divided[2])}, group) + + passwd = strings.NewReader(string(divided[3])) + _, _ = GetExecUser(string(divided[4]), nil, passwd, group) + return 1 +} diff --git a/vendor/github.com/opencontainers/runtime-spec/specs-go/config.go b/vendor/github.com/opencontainers/runtime-spec/specs-go/config.go index 5fceeb6353..6a7a91e559 100644 --- a/vendor/github.com/opencontainers/runtime-spec/specs-go/config.go +++ b/vendor/github.com/opencontainers/runtime-spec/specs-go/config.go @@ -598,10 +598,13 @@ type VMImage struct { // LinuxSeccomp represents syscall restrictions type LinuxSeccomp struct { - DefaultAction LinuxSeccompAction `json:"defaultAction"` - Architectures []Arch `json:"architectures,omitempty"` - Flags []LinuxSeccompFlag `json:"flags,omitempty"` - Syscalls []LinuxSyscall `json:"syscalls,omitempty"` + DefaultAction LinuxSeccompAction `json:"defaultAction"` + DefaultErrnoRet *uint `json:"defaultErrnoRet,omitempty"` + Architectures []Arch `json:"architectures,omitempty"` + Flags []LinuxSeccompFlag `json:"flags,omitempty"` + ListenerPath string `json:"listenerPath,omitempty"` + ListenerMetadata string `json:"listenerMetadata,omitempty"` + Syscalls []LinuxSyscall `json:"syscalls,omitempty"` } // Arch used for additional architectures @@ -641,11 +644,13 @@ type LinuxSeccompAction string const ( ActKill LinuxSeccompAction = "SCMP_ACT_KILL" ActKillProcess LinuxSeccompAction = "SCMP_ACT_KILL_PROCESS" + ActKillThread LinuxSeccompAction = "SCMP_ACT_KILL_THREAD" ActTrap LinuxSeccompAction = "SCMP_ACT_TRAP" ActErrno LinuxSeccompAction = "SCMP_ACT_ERRNO" ActTrace LinuxSeccompAction = "SCMP_ACT_TRACE" ActAllow LinuxSeccompAction = "SCMP_ACT_ALLOW" ActLog LinuxSeccompAction = "SCMP_ACT_LOG" + ActNotify LinuxSeccompAction = "SCMP_ACT_NOTIFY" ) // LinuxSeccompOperator used to match syscall arguments in Seccomp diff --git a/vendor/github.com/opencontainers/runtime-spec/specs-go/state.go b/vendor/github.com/opencontainers/runtime-spec/specs-go/state.go index e2e64c6631..7c010d4fe7 100644 --- a/vendor/github.com/opencontainers/runtime-spec/specs-go/state.go +++ b/vendor/github.com/opencontainers/runtime-spec/specs-go/state.go @@ -5,17 +5,17 @@ type ContainerState string const ( // StateCreating indicates that the container is being created - StateCreating ContainerState = "creating" + StateCreating ContainerState = "creating" // StateCreated indicates that the runtime has finished the create operation - StateCreated ContainerState = "created" + StateCreated ContainerState = "created" // StateRunning indicates that the container process has executed the // user-specified program but has not exited - StateRunning ContainerState = "running" + StateRunning ContainerState = "running" // StateStopped indicates that the container process has exited - StateStopped ContainerState = "stopped" + StateStopped ContainerState = "stopped" ) // State holds information about the runtime state of the container. @@ -33,3 +33,24 @@ type State struct { // Annotations are key values associated with the container. Annotations map[string]string `json:"annotations,omitempty"` } + +const ( + // SeccompFdName is the name of the seccomp notify file descriptor. + SeccompFdName string = "seccompFd" +) + +// ContainerProcessState holds information about the state of a container process. +type ContainerProcessState struct { + // Version is the version of the specification that is supported. + Version string `json:"ociVersion"` + // Fds is a string array containing the names of the file descriptors passed. + // The index of the name in this array corresponds to index of the file + // descriptor in the `SCM_RIGHTS` array. + Fds []string `json:"fds"` + // Pid is the process ID as seen by the runtime. + Pid int `json:"pid"` + // Opaque metadata. + Metadata string `json:"metadata,omitempty"` + // State of the container. + State State `json:"state"` +} diff --git a/vendor/github.com/opencontainers/selinux/go-selinux/doc.go b/vendor/github.com/opencontainers/selinux/go-selinux/doc.go index 9c9cbd120a..0ac7d819e6 100644 --- a/vendor/github.com/opencontainers/selinux/go-selinux/doc.go +++ b/vendor/github.com/opencontainers/selinux/go-selinux/doc.go @@ -1,10 +1,6 @@ /* Package selinux provides a high-level interface for interacting with selinux. -This package uses a selinux build tag to enable the selinux functionality. This -allows non-linux and linux users who do not have selinux support to still use -tools that rely on this library. - Usage: import "github.com/opencontainers/selinux/go-selinux" diff --git a/vendor/github.com/opencontainers/selinux/go-selinux/label/label_linux.go b/vendor/github.com/opencontainers/selinux/go-selinux/label/label_linux.go index 4394555117..b3d142d8c5 100644 --- a/vendor/github.com/opencontainers/selinux/go-selinux/label/label_linux.go +++ b/vendor/github.com/opencontainers/selinux/go-selinux/label/label_linux.go @@ -25,6 +25,8 @@ var ErrIncompatibleLabel = errors.New("Bad SELinux option z and Z can not be use // the container. A list of options can be passed into this function to alter // the labels. The labels returned will include a random MCS String, that is // guaranteed to be unique. +// If the disabled flag is passed in, the process label will not be set, but the mount label will be set +// to the container_file label with the maximum category. This label is not usable by any confined label. func InitLabels(options []string) (plabel string, mlabel string, retErr error) { if !selinux.GetEnabled() { return "", "", nil @@ -47,7 +49,8 @@ func InitLabels(options []string) (plabel string, mlabel string, retErr error) { } for _, opt := range options { if opt == "disable" { - return "", mountLabel, nil + selinux.ReleaseLabel(mountLabel) + return "", selinux.PrivContainerMountLabel(), nil } if i := strings.Index(opt, ":"); i == -1 { return "", "", errors.Errorf("Bad label option %q, valid options 'disable' or \n'user, role, level, type, filetype' followed by ':' and a value", opt) diff --git a/vendor/github.com/opencontainers/selinux/go-selinux/selinux.go b/vendor/github.com/opencontainers/selinux/go-selinux/selinux.go index d9119908b7..b336ebad3a 100644 --- a/vendor/github.com/opencontainers/selinux/go-selinux/selinux.go +++ b/vendor/github.com/opencontainers/selinux/go-selinux/selinux.go @@ -11,9 +11,10 @@ const ( Permissive = 0 // Disabled constant to indicate SELinux is disabled Disabled = -1 - + // maxCategory is the maximum number of categories used within containers + maxCategory = 1024 // DefaultCategoryRange is the upper bound on the category range - DefaultCategoryRange = uint32(1024) + DefaultCategoryRange = uint32(maxCategory) ) var ( @@ -276,3 +277,8 @@ func DisableSecOpt() []string { func GetDefaultContextWithLevel(user, level, scon string) (string, error) { return getDefaultContextWithLevel(user, level, scon) } + +// PrivContainerMountLabel returns mount label for privileged containers +func PrivContainerMountLabel() string { + return privContainerMountLabel +} diff --git a/vendor/github.com/opencontainers/selinux/go-selinux/selinux_linux.go b/vendor/github.com/opencontainers/selinux/go-selinux/selinux_linux.go index 5bfcc04902..a91a116f84 100644 --- a/vendor/github.com/opencontainers/selinux/go-selinux/selinux_linux.go +++ b/vendor/github.com/opencontainers/selinux/go-selinux/selinux_linux.go @@ -16,9 +16,9 @@ import ( "strings" "sync" + "github.com/bits-and-blooms/bitset" "github.com/opencontainers/selinux/pkg/pwalk" "github.com/pkg/errors" - "github.com/willf/bitset" "golang.org/x/sys/unix" ) @@ -892,13 +892,13 @@ func openContextFile() (*os.File, error) { return os.Open(lxcPath) } -var labels = loadLabels() +var labels, privContainerMountLabel = loadLabels() -func loadLabels() map[string]string { +func loadLabels() (map[string]string, string) { labels := make(map[string]string) in, err := openContextFile() if err != nil { - return labels + return labels, "" } defer in.Close() @@ -920,7 +920,10 @@ func loadLabels() map[string]string { } } - return labels + con, _ := NewContext(labels["file"]) + con["level"] = fmt.Sprintf("s0:c%d,c%d", maxCategory-2, maxCategory-1) + reserveLabel(con.get()) + return labels, con.get() } // kvmContainerLabels returns the default processLabel and mountLabel to be used diff --git a/vendor/github.com/opencontainers/selinux/go-selinux/selinux_stub.go b/vendor/github.com/opencontainers/selinux/go-selinux/selinux_stub.go index 70b7b7c851..b7218a0b6a 100644 --- a/vendor/github.com/opencontainers/selinux/go-selinux/selinux_stub.go +++ b/vendor/github.com/opencontainers/selinux/go-selinux/selinux_stub.go @@ -2,6 +2,8 @@ package selinux +const privContainerMountLabel = "" + func setDisabled() { } diff --git a/vendor/github.com/spf13/cast/.travis.yml b/vendor/github.com/spf13/cast/.travis.yml deleted file mode 100644 index 833a48799e..0000000000 --- a/vendor/github.com/spf13/cast/.travis.yml +++ /dev/null @@ -1,16 +0,0 @@ -language: go -env: - - GO111MODULE=on -sudo: required -go: - - "1.11.x" - - "1.12.x" - - tip -os: - - linux -matrix: - allow_failures: - - go: tip - fast_finish: true -script: - - make check diff --git a/vendor/github.com/spf13/cast/README.md b/vendor/github.com/spf13/cast/README.md index e6939397dd..120a573426 100644 --- a/vendor/github.com/spf13/cast/README.md +++ b/vendor/github.com/spf13/cast/README.md @@ -1,7 +1,7 @@ cast ==== [![GoDoc](https://godoc.org/github.com/spf13/cast?status.svg)](https://godoc.org/github.com/spf13/cast) -[![Build Status](https://api.travis-ci.org/spf13/cast.svg?branch=master)](https://travis-ci.org/spf13/cast) +[![Build Status](https://github.com/spf13/cast/actions/workflows/go.yml/badge.svg)](https://github.com/spf13/cast/actions/workflows/go.yml) [![Go Report Card](https://goreportcard.com/badge/github.com/spf13/cast)](https://goreportcard.com/report/github.com/spf13/cast) Easy and safe casting from one type to another in Go diff --git a/vendor/github.com/spf13/cast/cast.go b/vendor/github.com/spf13/cast/cast.go index 9fba638d46..0cfe9418de 100644 --- a/vendor/github.com/spf13/cast/cast.go +++ b/vendor/github.com/spf13/cast/cast.go @@ -20,6 +20,11 @@ func ToTime(i interface{}) time.Time { return v } +func ToTimeInDefaultLocation(i interface{}, location *time.Location) time.Time { + v, _ := ToTimeInDefaultLocationE(i, location) + return v +} + // ToDuration casts an interface to a time.Duration type. func ToDuration(i interface{}) time.Duration { v, _ := ToDurationE(i) diff --git a/vendor/github.com/spf13/cast/caste.go b/vendor/github.com/spf13/cast/caste.go index 70c7291bed..c04af6a974 100644 --- a/vendor/github.com/spf13/cast/caste.go +++ b/vendor/github.com/spf13/cast/caste.go @@ -20,13 +20,20 @@ var errNegativeNotAllowed = errors.New("unable to cast negative value") // ToTimeE casts an interface to a time.Time type. func ToTimeE(i interface{}) (tim time.Time, err error) { + return ToTimeInDefaultLocationE(i, time.UTC) +} + +// ToTimeInDefaultLocationE casts an empty interface to time.Time, +// interpreting inputs without a timezone to be in the given location, +// or the local timezone if nil. +func ToTimeInDefaultLocationE(i interface{}, location *time.Location) (tim time.Time, err error) { i = indirect(i) switch v := i.(type) { case time.Time: return v, nil case string: - return StringToDate(v) + return StringToDateInDefaultLocation(v, location) case int: return time.Unix(int64(v), 0), nil case int64: @@ -1129,8 +1136,43 @@ func ToStringSliceE(i interface{}) ([]string, error) { return a, nil case []string: return v, nil + case []int8: + for _, u := range v { + a = append(a, ToString(u)) + } + return a, nil + case []int: + for _, u := range v { + a = append(a, ToString(u)) + } + return a, nil + case []int32: + for _, u := range v { + a = append(a, ToString(u)) + } + return a, nil + case []int64: + for _, u := range v { + a = append(a, ToString(u)) + } + return a, nil + case []float32: + for _, u := range v { + a = append(a, ToString(u)) + } + return a, nil + case []float64: + for _, u := range v { + a = append(a, ToString(u)) + } + return a, nil case string: return strings.Fields(v), nil + case []error: + for _, err := range i.([]error) { + a = append(a, err.Error()) + } + return a, nil case interface{}: str, err := ToStringE(v) if err != nil { @@ -1204,37 +1246,83 @@ func ToDurationSliceE(i interface{}) ([]time.Duration, error) { // predefined list of formats. If no suitable format is found, an error is // returned. func StringToDate(s string) (time.Time, error) { - return parseDateWith(s, []string{ - time.RFC3339, - "2006-01-02T15:04:05", // iso8601 without timezone - time.RFC1123Z, - time.RFC1123, - time.RFC822Z, - time.RFC822, - time.RFC850, - time.ANSIC, - time.UnixDate, - time.RubyDate, - "2006-01-02 15:04:05.999999999 -0700 MST", // Time.String() - "2006-01-02", - "02 Jan 2006", - "2006-01-02T15:04:05-0700", // RFC3339 without timezone hh:mm colon - "2006-01-02 15:04:05 -07:00", - "2006-01-02 15:04:05 -0700", - "2006-01-02 15:04:05Z07:00", // RFC3339 without T - "2006-01-02 15:04:05Z0700", // RFC3339 without T or timezone hh:mm colon - "2006-01-02 15:04:05", - time.Kitchen, - time.Stamp, - time.StampMilli, - time.StampMicro, - time.StampNano, - }) + return parseDateWith(s, time.UTC, timeFormats) +} + +// StringToDateInDefaultLocation casts an empty interface to a time.Time, +// interpreting inputs without a timezone to be in the given location, +// or the local timezone if nil. +func StringToDateInDefaultLocation(s string, location *time.Location) (time.Time, error) { + return parseDateWith(s, location, timeFormats) } -func parseDateWith(s string, dates []string) (d time.Time, e error) { - for _, dateType := range dates { - if d, e = time.Parse(dateType, s); e == nil { +type timeFormatType int + +const ( + timeFormatNoTimezone timeFormatType = iota + timeFormatNamedTimezone + timeFormatNumericTimezone + timeFormatNumericAndNamedTimezone + timeFormatTimeOnly +) + +type timeFormat struct { + format string + typ timeFormatType +} + +func (f timeFormat) hasTimezone() bool { + // We don't include the formats with only named timezones, see + // https://github.com/golang/go/issues/19694#issuecomment-289103522 + return f.typ >= timeFormatNumericTimezone && f.typ <= timeFormatNumericAndNamedTimezone +} + +var ( + timeFormats = []timeFormat{ + timeFormat{time.RFC3339, timeFormatNumericTimezone}, + timeFormat{"2006-01-02T15:04:05", timeFormatNoTimezone}, // iso8601 without timezone + timeFormat{time.RFC1123Z, timeFormatNumericTimezone}, + timeFormat{time.RFC1123, timeFormatNamedTimezone}, + timeFormat{time.RFC822Z, timeFormatNumericTimezone}, + timeFormat{time.RFC822, timeFormatNamedTimezone}, + timeFormat{time.RFC850, timeFormatNamedTimezone}, + timeFormat{"2006-01-02 15:04:05.999999999 -0700 MST", timeFormatNumericAndNamedTimezone}, // Time.String() + timeFormat{"2006-01-02T15:04:05-0700", timeFormatNumericTimezone}, // RFC3339 without timezone hh:mm colon + timeFormat{"2006-01-02 15:04:05Z0700", timeFormatNumericTimezone}, // RFC3339 without T or timezone hh:mm colon + timeFormat{"2006-01-02 15:04:05", timeFormatNoTimezone}, + timeFormat{time.ANSIC, timeFormatNoTimezone}, + timeFormat{time.UnixDate, timeFormatNamedTimezone}, + timeFormat{time.RubyDate, timeFormatNumericTimezone}, + timeFormat{"2006-01-02 15:04:05Z07:00", timeFormatNumericTimezone}, + timeFormat{"2006-01-02", timeFormatNoTimezone}, + timeFormat{"02 Jan 2006", timeFormatNoTimezone}, + timeFormat{"2006-01-02 15:04:05 -07:00", timeFormatNumericTimezone}, + timeFormat{"2006-01-02 15:04:05 -0700", timeFormatNumericTimezone}, + timeFormat{time.Kitchen, timeFormatTimeOnly}, + timeFormat{time.Stamp, timeFormatTimeOnly}, + timeFormat{time.StampMilli, timeFormatTimeOnly}, + timeFormat{time.StampMicro, timeFormatTimeOnly}, + timeFormat{time.StampNano, timeFormatTimeOnly}, + } +) + +func parseDateWith(s string, location *time.Location, formats []timeFormat) (d time.Time, e error) { + + for _, format := range formats { + if d, e = time.Parse(format.format, s); e == nil { + + // Some time formats have a zone name, but no offset, so it gets + // put in that zone name (not the default one passed in to us), but + // without that zone's offset. So set the location manually. + if format.typ <= timeFormatNamedTimezone { + if location == nil { + location = time.Local + } + year, month, day := d.Date() + hour, min, sec := d.Clock() + d = time.Date(year, month, day, hour, min, sec, d.Nanosecond(), location) + } + return } } diff --git a/vendor/github.com/spf13/cast/timeformattype_string.go b/vendor/github.com/spf13/cast/timeformattype_string.go new file mode 100644 index 0000000000..1524fc82ce --- /dev/null +++ b/vendor/github.com/spf13/cast/timeformattype_string.go @@ -0,0 +1,27 @@ +// Code generated by "stringer -type timeFormatType"; DO NOT EDIT. + +package cast + +import "strconv" + +func _() { + // An "invalid array index" compiler error signifies that the constant values have changed. + // Re-run the stringer command to generate them again. + var x [1]struct{} + _ = x[timeFormatNoTimezone-0] + _ = x[timeFormatNamedTimezone-1] + _ = x[timeFormatNumericTimezone-2] + _ = x[timeFormatNumericAndNamedTimezone-3] + _ = x[timeFormatTimeOnly-4] +} + +const _timeFormatType_name = "timeFormatNoTimezonetimeFormatNamedTimezonetimeFormatNumericTimezonetimeFormatNumericAndNamedTimezonetimeFormatTimeOnly" + +var _timeFormatType_index = [...]uint8{0, 20, 43, 68, 101, 119} + +func (i timeFormatType) String() string { + if i < 0 || i >= timeFormatType(len(_timeFormatType_index)-1) { + return "timeFormatType(" + strconv.FormatInt(int64(i), 10) + ")" + } + return _timeFormatType_name[_timeFormatType_index[i]:_timeFormatType_index[i+1]] +} diff --git a/vendor/github.com/spf13/viper/README.md b/vendor/github.com/spf13/viper/README.md index f409b15192..9712e70514 100644 --- a/vendor/github.com/spf13/viper/README.md +++ b/vendor/github.com/spf13/viper/README.md @@ -127,11 +127,11 @@ You can handle the specific case where no config file is found like this: ```go if err := viper.ReadInConfig(); err != nil { - if _, ok := err.(viper.ConfigFileNotFoundError); ok { - // Config file not found; ignore error if desired - } else { - // Config file was found but another error was produced - } + if _, ok := err.(viper.ConfigFileNotFoundError); ok { + // Config file not found; ignore error if desired + } else { + // Config file was found but another error was produced + } } // Config file found and successfully parsed @@ -175,10 +175,10 @@ Optionally you can provide a function for Viper to run each time a change occurs **Make sure you add all of the configPaths prior to calling `WatchConfig()`** ```go -viper.WatchConfig() viper.OnConfigChange(func(e fsnotify.Event) { fmt.Println("Config file changed:", e.Name) }) +viper.WatchConfig() ``` ### Reading Config from io.Reader @@ -354,7 +354,7 @@ func main() { i := viper.GetInt("flagname") // retrieve value from viper - ... + // ... } ``` @@ -503,18 +503,18 @@ runtime_viper.Unmarshal(&runtime_conf) // open a goroutine to watch remote changes forever go func(){ for { - time.Sleep(time.Second * 5) // delay after each request - - // currently, only tested with etcd support - err := runtime_viper.WatchRemoteConfig() - if err != nil { - log.Errorf("unable to read remote config: %v", err) - continue - } - - // unmarshal new config into our runtime config struct. you can also use channel - // to implement a signal to notify the system of the changes - runtime_viper.Unmarshal(&runtime_conf) + time.Sleep(time.Second * 5) // delay after each request + + // currently, only tested with etcd support + err := runtime_viper.WatchRemoteConfig() + if err != nil { + log.Errorf("unable to read remote config: %v", err) + continue + } + + // unmarshal new config into our runtime config struct. you can also use channel + // to implement a signal to notify the system of the changes + runtime_viper.Unmarshal(&runtime_conf) } }() ``` @@ -546,7 +546,7 @@ Example: ```go viper.GetString("logfile") // case-insensitive Setting & Getting if viper.GetBool("verbose") { - fmt.Println("verbose enabled") + fmt.Println("verbose enabled") } ``` ### Accessing nested keys @@ -669,7 +669,7 @@ So instead of doing that let's pass a Viper instance to the constructor that rep ```go cache1Config := viper.Sub("cache.cache1") if cache1Config == nil { // Sub returns nil if the key cannot be found - panic("cache configuration not found") + panic("cache configuration not found") } cache1 := NewCache(cache1Config) @@ -681,10 +681,10 @@ Internally, the `NewCache` function can address `max-items` and `item-size` keys ```go func NewCache(v *Viper) *Cache { - return &Cache{ - MaxItems: v.GetInt("max-items"), - ItemSize: v.GetInt("item-size"), - } + return &Cache{ + MaxItems: v.GetInt("max-items"), + ItemSize: v.GetInt("item-size"), + } } ``` @@ -726,18 +726,18 @@ you have to change the delimiter: v := viper.NewWithOptions(viper.KeyDelimiter("::")) v.SetDefault("chart::values", map[string]interface{}{ - "ingress": map[string]interface{}{ - "annotations": map[string]interface{}{ - "traefik.frontend.rule.type": "PathPrefix", - "traefik.ingress.kubernetes.io/ssl-redirect": "true", - }, - }, + "ingress": map[string]interface{}{ + "annotations": map[string]interface{}{ + "traefik.frontend.rule.type": "PathPrefix", + "traefik.ingress.kubernetes.io/ssl-redirect": "true", + }, + }, }) type config struct { Chart struct{ - Values map[string]interface{} - } + Values map[string]interface{} + } } var C config @@ -778,6 +778,15 @@ if err != nil { Viper uses [github.com/mitchellh/mapstructure](https://github.com/mitchellh/mapstructure) under the hood for unmarshaling values which uses `mapstructure` tags by default. +### Decoding custom formats + +A frequently requested feature for Viper is adding more value formats and decoders. +For example, parsing character (dot, comma, semicolon, etc) separated strings into slices. + +This is already available in Viper using mapstructure decode hooks. + +Read more about the details in [this blog post](https://sagikazarmark.hu/blog/decoding-custom-formats-with-viper/). + ### Marshalling to string You may need to marshal all the settings held in viper into a string rather than write them to a file. @@ -785,17 +794,17 @@ You can use your favorite format's marshaller with the config returned by `AllSe ```go import ( - yaml "gopkg.in/yaml.v2" - // ... + yaml "gopkg.in/yaml.v2" + // ... ) func yamlStringSettings() string { - c := viper.AllSettings() - bs, err := yaml.Marshal(c) - if err != nil { - log.Fatalf("unable to marshal config to YAML: %v", err) - } - return string(bs) + c := viper.AllSettings() + bs, err := yaml.Marshal(c) + if err != nil { + log.Fatalf("unable to marshal config to YAML: %v", err) + } + return string(bs) } ``` diff --git a/vendor/github.com/spf13/viper/go.mod b/vendor/github.com/spf13/viper/go.mod index 145e0a100f..fcc1a5d923 100644 --- a/vendor/github.com/spf13/viper/go.mod +++ b/vendor/github.com/spf13/viper/go.mod @@ -3,19 +3,18 @@ module github.com/spf13/viper go 1.12 require ( - github.com/bketelsen/crypt v0.0.4 - github.com/fsnotify/fsnotify v1.4.9 + github.com/fsnotify/fsnotify v1.5.1 github.com/hashicorp/hcl v1.0.0 github.com/magiconair/properties v1.8.5 - github.com/mitchellh/mapstructure v1.4.1 - github.com/pelletier/go-toml v1.9.3 - github.com/smartystreets/goconvey v1.6.4 // indirect + github.com/mitchellh/mapstructure v1.4.2 + github.com/pelletier/go-toml v1.9.4 + github.com/sagikazarmark/crypt v0.1.0 github.com/spf13/afero v1.6.0 - github.com/spf13/cast v1.3.1 + github.com/spf13/cast v1.4.1 github.com/spf13/jwalterweatherman v1.1.0 github.com/spf13/pflag v1.0.5 github.com/stretchr/testify v1.7.0 github.com/subosito/gotenv v1.2.0 - gopkg.in/ini.v1 v1.62.0 + gopkg.in/ini.v1 v1.63.2 gopkg.in/yaml.v2 v2.4.0 ) diff --git a/vendor/github.com/spf13/viper/go.sum b/vendor/github.com/spf13/viper/go.sum index 27730e2aa8..3e0a13ea16 100644 --- a/vendor/github.com/spf13/viper/go.sum +++ b/vendor/github.com/spf13/viper/go.sum @@ -17,8 +17,13 @@ cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKP cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk= cloud.google.com/go v0.78.0/go.mod h1:QjdrLG0uq+YwhjoVOLsS1t7TW8fs36kLs4XO5R5ECHg= cloud.google.com/go v0.79.0/go.mod h1:3bzgcEeQlzbuEAYu4mrWhKqWjmpprinYgKJLgKHnbb8= -cloud.google.com/go v0.81.0 h1:at8Tk2zUz63cLPR0JPWm5vp77pEZmzxEQBEfRKn1VV8= cloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0= +cloud.google.com/go v0.83.0/go.mod h1:Z7MJUsANfY0pYPdw0lbnivPx4/vhy/e2FEkSkF7vAVY= +cloud.google.com/go v0.84.0/go.mod h1:RazrYuxIK6Kb7YrzzhPoLmCVzl7Sup4NrbKPg8KHSUM= +cloud.google.com/go v0.87.0/go.mod h1:TpDYlFy7vuLzZMMZ+B6iRiELaY7z/gJPaqbMx6mlWcY= +cloud.google.com/go v0.90.0/go.mod h1:kRX0mNRHe0e2rC6oNakvwQqzyDmg57xJ+SZU1eT2aDQ= +cloud.google.com/go v0.93.3 h1:wPBktZFzYBcCZVARvwVKqH1uEj+aLXofJEtrb4oOsio= +cloud.google.com/go v0.93.3/go.mod h1:8utlLll2EF5XMAV15woO4lSbWQlk8rer9aLOfLh7+YI= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= @@ -27,8 +32,8 @@ cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4g cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= -cloud.google.com/go/firestore v1.1.0 h1:9x7Bx0A9R5/M9jibeJeZWqjeVEIxYW9fZYqB9a70/bY= -cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk= +cloud.google.com/go/firestore v1.6.0 h1:dMIWvm+3O0E3DM7kcZPH0FBQ94Xg/OMkdTNDaY9itbI= +cloud.google.com/go/firestore v1.6.0/go.mod h1:afJwI0vaXwAG54kI7A//lP/lSPDkQORQuMkv56TxEPU= cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= @@ -41,15 +46,16 @@ cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9 dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= +github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da h1:8GUt8eRujhVEGZFFEjBj46YV4rDjvGrNxb0KMWYkL2I= 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-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= -github.com/bketelsen/crypt v0.0.4 h1:w/jqZtC9YD4DS/Vp9GhWfWcCpuAL58oTnLoI8vE9YHU= -github.com/bketelsen/crypt v0.0.4/go.mod h1:aI6NrJ0pMGgvZKL1iVgXLnfIFJtfV+bKCoqOes/6LfM= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= @@ -57,6 +63,7 @@ github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDk github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/coreos/go-semver v0.3.0 h1:wkHLiw0WNATZnSG7epLsujiMCgPAc9xhjJ4tgnAxmfM= github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= @@ -69,10 +76,13 @@ github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1m github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= -github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= -github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= +github.com/fatih/color v1.9.0 h1:8xPHl4/q1VyqGIPif1F+1V3Y3lSmrq01EabUW3CoW5s= +github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= +github.com/fsnotify/fsnotify v1.5.1 h1:mZcQUHVQUQWoPXXtuf9yuEXKudkV2sx1E06UadKWpgI= +github.com/fsnotify/fsnotify v1.5.1/go.mod h1:T3375wBYaZdLLcVNkcVbzGHY7f1l/uK5T5Ai1i3InKU= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= @@ -92,6 +102,7 @@ github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8= +github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= @@ -110,6 +121,7 @@ github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaS github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM= github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0 h1:0udJVsspx3VBr5FwtLhQQtuAsVc79tTq0ocGIPAU6qo= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= @@ -123,12 +135,14 @@ github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ= +github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= +github.com/google/martian/v3 v3.2.1/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= @@ -140,82 +154,91 @@ github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLe github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= -github.com/googleapis/gax-go/v2 v2.0.5 h1:sjZBwGj9Jlw33ImPtvFviGYvseOtDM7hkSKB7+Tv3SM= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= -github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8= -github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= +github.com/googleapis/gax-go/v2 v2.1.0 h1:6DWmvNpomjL1+3liNSZbVns3zsYzzCjm6pRBO1tLeso= +github.com/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pfu6SK+H1/DsU0= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= -github.com/hashicorp/consul/api v1.1.0 h1:BNQPM9ytxj6jbjjdRPioQ94T6YXriSopn0i8COv6SRA= -github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= -github.com/hashicorp/consul/sdk v0.1.1 h1:LnuDWGNsoajlhGyHJvuWW6FVqRl8JOTPqS6CPTsYjhY= -github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= +github.com/hashicorp/consul/api v1.10.1 h1:MwZJp86nlnL+6+W1Zly4JUuVn9YHhMggBirMpHGD7kw= +github.com/hashicorp/consul/api v1.10.1/go.mod h1:XjsvQN+RJGWI2TWy1/kqaE16HrR2J/FWgkYjdZQsX9M= +github.com/hashicorp/consul/sdk v0.8.0 h1:OJtKBtEjboEZvG6AOUdh4Z1Zbyu0WcxQ0qatRrZHTVU= +github.com/hashicorp/consul/sdk v0.8.0/go.mod h1:GBvyrGALthsZObzUGsfgHZQDXjg4lOjagTIwIR1vPms= github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/go-cleanhttp v0.5.1 h1:dH3aiDG9Jvb5r5+bYHsikaOUIpcM0xvgMXVoDkXMzJM= github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= +github.com/hashicorp/go-hclog v0.12.0 h1:d4QkX8FRTYaKaCZBoXYY8zJX2BXjWxurN/GA2tkrmZM= +github.com/hashicorp/go-hclog v0.12.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= github.com/hashicorp/go-immutable-radix v1.0.0 h1:AKDB1HM5PWEA7i4nhcpwOrO2byshxBjXVn/J/3+z5/0= github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= github.com/hashicorp/go-msgpack v0.5.3 h1:zKjpN5BK/P5lMYrLmBHdBULWbJ0XpYR+7NGzqkZzoD4= github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= -github.com/hashicorp/go-multierror v1.0.0 h1:iVjPR7a6H0tWELX5NxNe7bYopibicUzc7uPribsnS6o= github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= -github.com/hashicorp/go-rootcerts v1.0.0 h1:Rqb66Oo1X/eSV1x66xbDccZjhJigjg0+e82kpwzSwCI= -github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= +github.com/hashicorp/go-multierror v1.1.0 h1:B9UzwGQJehnUY1yNrnwREHc3fGbC2xefo8g4TbElacI= +github.com/hashicorp/go-multierror v1.1.0/go.mod h1:spPvp8C1qA32ftKqdAHm4hHTbPw+vmowP0z+KUhOZdA= +github.com/hashicorp/go-rootcerts v1.0.2 h1:jzhAVGtqPKbwpyCPELlgNWhE1znq+qwJtW5Oi2viEzc= +github.com/hashicorp/go-rootcerts v1.0.2/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8= github.com/hashicorp/go-sockaddr v1.0.0 h1:GeH6tui99pF4NJgfnhp+L6+FfobzVW3Ah46sLo0ICXs= github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-uuid v1.0.1 h1:fv1ep09latC32wFoVwnqcnKJGnMSdBanPczbHAYm1BE= github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= -github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= -github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= -github.com/hashicorp/memberlist v0.1.3 h1:EmmoJme1matNzb+hMpDuR/0sbJSUisxyqBGG676r31M= -github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= -github.com/hashicorp/serf v0.8.2 h1:YZ7UKsJv+hKjqGVUUbtE3HNj79Eln2oQ75tniF6iPt0= -github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= +github.com/hashicorp/mdns v1.0.1/go.mod h1:4gW7WsVCke5TE7EPeYliwHlRUyBtfCwuFwuMg2DmyNY= +github.com/hashicorp/memberlist v0.2.2 h1:5+RffWKwqJ71YPu9mWsF7ZOscZmwfasdA8kbdC7AO2g= +github.com/hashicorp/memberlist v0.2.2/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOnAH9VT3Sh9MUE= +github.com/hashicorp/serf v0.9.5 h1:EBWvyu9tcRszt3Bxp3KNssBMP1KuHWyO51lz9+786iM= +github.com/hashicorp/serf v0.9.5/go.mod h1:UWDWwZeL5cuWDJdl0C6wrvrUwEqtQ4ZKBKKENpqIUyk= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/json-iterator/go v1.1.11 h1:uVUAXhF2To8cbw/3xN3pxj6kk7TYKs98NIrTqPlMWAQ= github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= -github.com/jstemmer/go-junit-report v0.9.1 h1:6QPYqodiu3GuPL+7mfx+NwDdp2eTkp9IfEUpgAwUN0o= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= -github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= -github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= -github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.2.0 h1:s5hAObm+yFO5uHYt5dYjxi2rXrsnmRpJx4OYvIWUaQs= +github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/magiconair/properties v1.8.5 h1:b6kJs+EmPFMYGkow9GiUyCyOvIwYetYJ3fSaWak/Gls= github.com/magiconair/properties v1.8.5/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= +github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= +github.com/mattn/go-colorable v0.1.6 h1:6Su7aK7lXmJ/U79bYtBjLNaha4Fs1Rg9plHpcH+vvnE= +github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= -github.com/miekg/dns v1.0.14 h1:9jZdLNd/P4+SfEJ0TNyxYpsK8N4GtfylBLqtbYN1sbA= +github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84= +github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE= +github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY= +github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= -github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= -github.com/mitchellh/go-homedir v1.0.0 h1:vKb8ShqSby24Yrqr/yDYkuFz8d0WUjys40rvnGC8aR0= -github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/miekg/dns v1.1.26 h1:gPxPSwALAeHJSjarOs00QjVdV9QoBvc1D2ujQUr5BzU= +github.com/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso= +github.com/mitchellh/cli v1.1.0/go.mod h1:xcISNoH86gajksDmfB23e/pu+B+GeFRMYmoHXxx3xhI= +github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= +github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-testing-interface v1.0.0 h1:fzU/JVNcaqHQEcVFAKeR41fkiLdIPrefOvVG1VZ96U0= github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= -github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= -github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= -github.com/mitchellh/mapstructure v1.4.1 h1:CpVNEelQCZBooIPDn+AR3NpivK/TIKU8bDxdASFVQag= -github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mitchellh/mapstructure v1.4.2 h1:6h7AQ0yhTcIsmFmnAwQls75jp2Gzs4iB8W7pjMO+rqo= +github.com/mitchellh/mapstructure v1.4.2/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= @@ -223,32 +246,33 @@ github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9 github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c h1:Lgl0gzECD8GnQ5QCWA8o6BtfL6mDH5rQgM4/fX3avOs= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= -github.com/pelletier/go-toml v1.9.3 h1:zeC5b1GviRUyKYd6OJPvBU/mcVDVoL1OhT17FCt5dSQ= -github.com/pelletier/go-toml v1.9.3/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= +github.com/pelletier/go-toml v1.9.4 h1:tjENF6MfZAg8e4ZmZTeWaWiT2vXtsoO6+iuOjFhECwM= +github.com/pelletier/go-toml v1.9.4/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= +github.com/posener/complete v1.2.3/go.mod h1:WZIdtGGp+qx0sLrYKtIRAruyNpv6hFCicSgv7Sy7s/s= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= +github.com/sagikazarmark/crypt v0.1.0 h1:AyO7PGna28P9TMH93Bsxd7m9QC4xE6zyGQTXCo7ZrA8= +github.com/sagikazarmark/crypt v0.1.0/go.mod h1:B/mN0msZuINBtQ1zZLEQcegFJJf9vnYIR88KRMEuODE= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 h1:nn5Wsu0esKSJiIVhscUtVbo7ada43DJhG55ua/hjS5I= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= -github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM= -github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= -github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s= -github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= +github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/afero v1.6.0 h1:xoax2sJ2DT8S8xA2paPFjDCScCNeWsg75VG0DLRreiY= github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I= -github.com/spf13/cast v1.3.1 h1:nFm6S0SMdyzrzcmThSipiEubIDy8WEXKNZ0UOgiRpng= -github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= +github.com/spf13/cast v1.4.1 h1:s0hze+J0196ZfEMTs80N7UlFt0BDuQ7Q+JDnHiMWKdA= +github.com/spf13/cast v1.4.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk= github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/stretchr/objx v0.1.0 h1:4G4v2dO3VZwixGIRoQ5Lfboy6nUhCyYzaqnIAPPhYs4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= @@ -278,6 +302,7 @@ go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= go.opencensus.io v0.23.0 h1:gqCw0LfLxScz8irSi8exQc7fyQ0fKQU/qnC/X8+V/1M= go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= +go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo= @@ -286,9 +311,11 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20210817164053-32db794688a5 h1:HWj/xjIHfjYU5nVXpTM0s39J9CbLn7Cc5a7IC5rwsMQ= +golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -312,7 +339,6 @@ golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRu golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 h1:VLliZ0d+/avPrXXH+OakdXhpJuEoBZuwh1m2j7U6Iug= golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= @@ -324,12 +350,10 @@ golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.4.2 h1:Gz96sIWK3OalVv/I/qNygP42zyoKp3xptRVCWRFEBvo= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= @@ -340,6 +364,7 @@ golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -361,8 +386,9 @@ golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= -golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4 h1:4nGaVu0QrbjT/AK2PRLuQfQuh6DJve+pELhqTdAj3x0= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= +golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420 h1:a8jGStKg0XqKDlKqjLrXn0ioF5MH36pT7Z0BRTqLhbk= +golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -374,8 +400,11 @@ golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210402161424-2e8d93401602 h1:0Ja1LBD+yisY6RWM/BH7TJVXWsSjs2VwBSmvSX4HdBc= -golang.org/x/oauth2 v0.0.0-20210402161424-2e8d93401602/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210628180205-a41e5a781914/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210805134026-6f1e6394065a/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f h1:Qmd2pbz05z7z6lm0DrgQVVPuBm92jqujBKMHMOlOQEw= +golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -392,6 +421,7 @@ golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -399,12 +429,17 @@ golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -428,8 +463,16 @@ golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210510120138-977fb7262007 h1:gG67DSER+11cZvqIMb8S8bt0vZtiN6xWYARwirrOSfE= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210603125802-9665404d3644/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf h1:2ucpDCmfkl8Bd/FsLtiD653Wf96cW37s+iGx93zsu4k= +golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -437,8 +480,9 @@ golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3 golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.5 h1:i6eZZ+zk0SOf0xgBpEpPD18qWcJda6q1sxt3S0kzyUQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -448,7 +492,6 @@ golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3 golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= @@ -456,9 +499,9 @@ golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgw golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20190907020128-2ca718005c18/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= @@ -492,8 +535,11 @@ golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= -golang.org/x/tools v0.1.2 h1:kRBLX7v7Af8W7Gdbbc908OJcdgtK8bOz9Uaj8/F1ACA= +golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -520,8 +566,13 @@ google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34q google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU= google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94= -google.golang.org/api v0.44.0 h1:URs6qR1lAxDsqWITsQXI4ZkGiYJ5dHtRNiCpfs2OeKA= -google.golang.org/api v0.44.0/go.mod h1:EBOGZqzyhtvMDoxwS97ctnh0zUmYY6CxqXsc1AvkYD8= +google.golang.org/api v0.47.0/go.mod h1:Wbvgpq1HddcWVtzsVLyfLp8lDg6AA241LmgIL59tHXo= +google.golang.org/api v0.48.0/go.mod h1:71Pr1vy+TAZRPkPs/xlCf5SsU8WjuAWv1Pfjbtukyy4= +google.golang.org/api v0.50.0/go.mod h1:4bNT5pAuq5ji4SRZm+5QIkjny9JAyVD/3gaSihNefaw= +google.golang.org/api v0.51.0/go.mod h1:t4HdrdoNgyN5cbEfm7Lum0lcLDLiise1F8qDKX00sOU= +google.golang.org/api v0.54.0/go.mod h1:7C4bFFOvVDGXjfDTAsgGwDgAxRDeQ4X8NvUedIt6z3k= +google.golang.org/api v0.56.0 h1:08F9XVYTLOGeSQb3xI9C0gXMuQanhdGed0cWFhDozbI= +google.golang.org/api v0.56.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= @@ -570,8 +621,19 @@ google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6D google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= -google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c h1:wtujag7C+4D6KMoulW9YauvK2lgdvCMS260jsqqBXr0= +google.golang.org/genproto v0.0.0-20210513213006-bf773b8c8384/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= +google.golang.org/genproto v0.0.0-20210604141403-392c879c8b08/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= +google.golang.org/genproto v0.0.0-20210608205507-b6d2f5bf0d7d/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= +google.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84/go.mod h1:SzzZ/N+nwJDaO1kznhnlzqS8ocJICar6hYhVyhi++24= +google.golang.org/genproto v0.0.0-20210713002101-d411969a0d9a/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k= +google.golang.org/genproto v0.0.0-20210716133855-ce7ef5c701ea/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k= +google.golang.org/genproto v0.0.0-20210728212813-7823e685a01f/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= +google.golang.org/genproto v0.0.0-20210805201207-89edb61ffb67/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= +google.golang.org/genproto v0.0.0-20210813162853-db860fec028c/go.mod h1:cFeNkxwySK631ADgubI+/XFU/xp8FD5KIVV4rj8UC5w= +google.golang.org/genproto v0.0.0-20210821163610-241b8fcbd6c8/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210828152312-66f60bf46e71 h1:z+ErRPu0+KS02Td3fOAgdX+lnPDh/VyaABEJPD4JRQs= +google.golang.org/genproto v0.0.0-20210828152312-66f60bf46e71/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= @@ -591,8 +653,14 @@ google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA5 google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= -google.golang.org/grpc v1.38.0 h1:/9BgsAsa5nWe26HqOlvlgJnqBuktYOLCgjCPqsa56W0= +google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +google.golang.org/grpc v1.37.1/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +google.golang.org/grpc v1.39.0/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= +google.golang.org/grpc v1.39.1/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= +google.golang.org/grpc v1.40.0 h1:AGJ0Ih4mHjSeibYkFGh1dD9KJ/eOtZ93I6hoHhukQ5Q= +google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= +google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -604,14 +672,16 @@ google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpAD google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= -google.golang.org/protobuf v1.26.0 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.27.1 h1:SnqbnDw1V7RiZcXPx5MEeqPv2s79L9i7BJUlG/+RurQ= +google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= -gopkg.in/ini.v1 v1.62.0 h1:duBzk771uxoUuOlyRLkHsygud9+5lrlGjdFBb4mSKDU= -gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/ini.v1 v1.63.2 h1:tGK/CyBg7SMzb60vP1M03vNZ3VDu3wGQJwn7Sxi9r3c= +gopkg.in/ini.v1 v1.63.2/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/vendor/github.com/spf13/viper/internal/encoding/decoder.go b/vendor/github.com/spf13/viper/internal/encoding/decoder.go new file mode 100644 index 0000000000..08b1bb66b5 --- /dev/null +++ b/vendor/github.com/spf13/viper/internal/encoding/decoder.go @@ -0,0 +1,61 @@ +package encoding + +import ( + "sync" +) + +// Decoder decodes the contents of b into a v representation. +// It's primarily used for decoding contents of a file into a map[string]interface{}. +type Decoder interface { + Decode(b []byte, v interface{}) error +} + +const ( + // ErrDecoderNotFound is returned when there is no decoder registered for a format. + ErrDecoderNotFound = encodingError("decoder not found for this format") + + // ErrDecoderFormatAlreadyRegistered is returned when an decoder is already registered for a format. + ErrDecoderFormatAlreadyRegistered = encodingError("decoder already registered for this format") +) + +// DecoderRegistry can choose an appropriate Decoder based on the provided format. +type DecoderRegistry struct { + decoders map[string]Decoder + + mu sync.RWMutex +} + +// NewDecoderRegistry returns a new, initialized DecoderRegistry. +func NewDecoderRegistry() *DecoderRegistry { + return &DecoderRegistry{ + decoders: make(map[string]Decoder), + } +} + +// RegisterDecoder registers a Decoder for a format. +// Registering a Decoder for an already existing format is not supported. +func (e *DecoderRegistry) RegisterDecoder(format string, enc Decoder) error { + e.mu.Lock() + defer e.mu.Unlock() + + if _, ok := e.decoders[format]; ok { + return ErrDecoderFormatAlreadyRegistered + } + + e.decoders[format] = enc + + return nil +} + +// Decode calls the underlying Decoder based on the format. +func (e *DecoderRegistry) Decode(format string, b []byte, v interface{}) error { + e.mu.RLock() + decoder, ok := e.decoders[format] + e.mu.RUnlock() + + if !ok { + return ErrDecoderNotFound + } + + return decoder.Decode(b, v) +} diff --git a/vendor/github.com/spf13/viper/internal/encoding/encoder.go b/vendor/github.com/spf13/viper/internal/encoding/encoder.go new file mode 100644 index 0000000000..82c7996cbb --- /dev/null +++ b/vendor/github.com/spf13/viper/internal/encoding/encoder.go @@ -0,0 +1,60 @@ +package encoding + +import ( + "sync" +) + +// Encoder encodes the contents of v into a byte representation. +// It's primarily used for encoding a map[string]interface{} into a file format. +type Encoder interface { + Encode(v interface{}) ([]byte, error) +} + +const ( + // ErrEncoderNotFound is returned when there is no encoder registered for a format. + ErrEncoderNotFound = encodingError("encoder not found for this format") + + // ErrEncoderFormatAlreadyRegistered is returned when an encoder is already registered for a format. + ErrEncoderFormatAlreadyRegistered = encodingError("encoder already registered for this format") +) + +// EncoderRegistry can choose an appropriate Encoder based on the provided format. +type EncoderRegistry struct { + encoders map[string]Encoder + + mu sync.RWMutex +} + +// NewEncoderRegistry returns a new, initialized EncoderRegistry. +func NewEncoderRegistry() *EncoderRegistry { + return &EncoderRegistry{ + encoders: make(map[string]Encoder), + } +} + +// RegisterEncoder registers an Encoder for a format. +// Registering a Encoder for an already existing format is not supported. +func (e *EncoderRegistry) RegisterEncoder(format string, enc Encoder) error { + e.mu.Lock() + defer e.mu.Unlock() + + if _, ok := e.encoders[format]; ok { + return ErrEncoderFormatAlreadyRegistered + } + + e.encoders[format] = enc + + return nil +} + +func (e *EncoderRegistry) Encode(format string, v interface{}) ([]byte, error) { + e.mu.RLock() + encoder, ok := e.encoders[format] + e.mu.RUnlock() + + if !ok { + return nil, ErrEncoderNotFound + } + + return encoder.Encode(v) +} diff --git a/vendor/github.com/spf13/viper/internal/encoding/error.go b/vendor/github.com/spf13/viper/internal/encoding/error.go new file mode 100644 index 0000000000..e4cde02d7b --- /dev/null +++ b/vendor/github.com/spf13/viper/internal/encoding/error.go @@ -0,0 +1,7 @@ +package encoding + +type encodingError string + +func (e encodingError) Error() string { + return string(e) +} diff --git a/vendor/github.com/spf13/viper/internal/encoding/hcl/codec.go b/vendor/github.com/spf13/viper/internal/encoding/hcl/codec.go new file mode 100644 index 0000000000..f3e4ab1228 --- /dev/null +++ b/vendor/github.com/spf13/viper/internal/encoding/hcl/codec.go @@ -0,0 +1,40 @@ +package hcl + +import ( + "bytes" + "encoding/json" + + "github.com/hashicorp/hcl" + "github.com/hashicorp/hcl/hcl/printer" +) + +// Codec implements the encoding.Encoder and encoding.Decoder interfaces for HCL encoding. +// TODO: add printer config to the codec? +type Codec struct{} + +func (Codec) Encode(v interface{}) ([]byte, error) { + b, err := json.Marshal(v) + if err != nil { + return nil, err + } + + // TODO: use printer.Format? Is the trailing newline an issue? + + ast, err := hcl.Parse(string(b)) + if err != nil { + return nil, err + } + + var buf bytes.Buffer + + err = printer.Fprint(&buf, ast.Node) + if err != nil { + return nil, err + } + + return buf.Bytes(), nil +} + +func (Codec) Decode(b []byte, v interface{}) error { + return hcl.Unmarshal(b, v) +} diff --git a/vendor/github.com/spf13/viper/internal/encoding/json/codec.go b/vendor/github.com/spf13/viper/internal/encoding/json/codec.go new file mode 100644 index 0000000000..dff9ec9824 --- /dev/null +++ b/vendor/github.com/spf13/viper/internal/encoding/json/codec.go @@ -0,0 +1,17 @@ +package json + +import ( + "encoding/json" +) + +// Codec implements the encoding.Encoder and encoding.Decoder interfaces for JSON encoding. +type Codec struct{} + +func (Codec) Encode(v interface{}) ([]byte, error) { + // TODO: expose prefix and indent in the Codec as setting? + return json.MarshalIndent(v, "", " ") +} + +func (Codec) Decode(b []byte, v interface{}) error { + return json.Unmarshal(b, v) +} diff --git a/vendor/github.com/spf13/viper/internal/encoding/toml/codec.go b/vendor/github.com/spf13/viper/internal/encoding/toml/codec.go new file mode 100644 index 0000000000..c043802b91 --- /dev/null +++ b/vendor/github.com/spf13/viper/internal/encoding/toml/codec.go @@ -0,0 +1,45 @@ +package toml + +import ( + "github.com/pelletier/go-toml" +) + +// Codec implements the encoding.Encoder and encoding.Decoder interfaces for TOML encoding. +type Codec struct{} + +func (Codec) Encode(v interface{}) ([]byte, error) { + if m, ok := v.(map[string]interface{}); ok { + t, err := toml.TreeFromMap(m) + if err != nil { + return nil, err + } + + s, err := t.ToTomlString() + if err != nil { + return nil, err + } + + return []byte(s), nil + } + + return toml.Marshal(v) +} + +func (Codec) Decode(b []byte, v interface{}) error { + tree, err := toml.LoadBytes(b) + if err != nil { + return err + } + + if m, ok := v.(*map[string]interface{}); ok { + vmap := *m + tmap := tree.ToMap() + for k, v := range tmap { + vmap[k] = v + } + + return nil + } + + return tree.Unmarshal(v) +} diff --git a/vendor/github.com/spf13/viper/internal/encoding/yaml/codec.go b/vendor/github.com/spf13/viper/internal/encoding/yaml/codec.go new file mode 100644 index 0000000000..f94b269966 --- /dev/null +++ b/vendor/github.com/spf13/viper/internal/encoding/yaml/codec.go @@ -0,0 +1,14 @@ +package yaml + +import "gopkg.in/yaml.v2" + +// Codec implements the encoding.Encoder and encoding.Decoder interfaces for YAML encoding. +type Codec struct{} + +func (Codec) Encode(v interface{}) ([]byte, error) { + return yaml.Marshal(v) +} + +func (Codec) Decode(b []byte, v interface{}) error { + return yaml.Unmarshal(b, v) +} diff --git a/vendor/github.com/spf13/viper/util.go b/vendor/github.com/spf13/viper/util.go index cee6b24296..09d051a221 100644 --- a/vendor/github.com/spf13/viper/util.go +++ b/vendor/github.com/spf13/viper/util.go @@ -95,19 +95,7 @@ func absPathify(inPath string) string { inPath = userHomeDir() + inPath[5:] } - if strings.HasPrefix(inPath, "$") { - end := strings.Index(inPath, string(os.PathSeparator)) - - var value, suffix string - if end == -1 { - value = os.Getenv(inPath[1:]) - } else { - value = os.Getenv(inPath[1:end]) - suffix = inPath[end:] - } - - inPath = value + suffix - } + inPath = os.ExpandEnv(inPath) if filepath.IsAbs(inPath) { return filepath.Clean(inPath) diff --git a/vendor/github.com/spf13/viper/viper.go b/vendor/github.com/spf13/viper/viper.go index e8c04627bb..9e2e3537f6 100644 --- a/vendor/github.com/spf13/viper/viper.go +++ b/vendor/github.com/spf13/viper/viper.go @@ -22,7 +22,6 @@ package viper import ( "bytes" "encoding/csv" - "encoding/json" "errors" "fmt" "io" @@ -36,18 +35,20 @@ import ( "time" "github.com/fsnotify/fsnotify" - "github.com/hashicorp/hcl" - "github.com/hashicorp/hcl/hcl/printer" "github.com/magiconair/properties" "github.com/mitchellh/mapstructure" - "github.com/pelletier/go-toml" "github.com/spf13/afero" "github.com/spf13/cast" jww "github.com/spf13/jwalterweatherman" "github.com/spf13/pflag" "github.com/subosito/gotenv" "gopkg.in/ini.v1" - "gopkg.in/yaml.v2" + + "github.com/spf13/viper/internal/encoding" + "github.com/spf13/viper/internal/encoding/hcl" + "github.com/spf13/viper/internal/encoding/json" + "github.com/spf13/viper/internal/encoding/toml" + "github.com/spf13/viper/internal/encoding/yaml" ) // ConfigMarshalError happens when failing to marshal the configuration. @@ -67,8 +68,47 @@ type RemoteResponse struct { Error error } +var ( + encoderRegistry = encoding.NewEncoderRegistry() + decoderRegistry = encoding.NewDecoderRegistry() +) + func init() { v = New() + + { + codec := yaml.Codec{} + + encoderRegistry.RegisterEncoder("yaml", codec) + decoderRegistry.RegisterDecoder("yaml", codec) + + encoderRegistry.RegisterEncoder("yml", codec) + decoderRegistry.RegisterDecoder("yml", codec) + } + + { + codec := json.Codec{} + + encoderRegistry.RegisterEncoder("json", codec) + decoderRegistry.RegisterDecoder("json", codec) + } + + { + codec := toml.Codec{} + + encoderRegistry.RegisterEncoder("toml", codec) + decoderRegistry.RegisterDecoder("toml", codec) + } + + { + codec := hcl.Codec{} + + encoderRegistry.RegisterEncoder("hcl", codec) + decoderRegistry.RegisterDecoder("hcl", codec) + + encoderRegistry.RegisterEncoder("tfvars", codec) + decoderRegistry.RegisterDecoder("tfvars", codec) + } } type remoteConfigFactory interface { @@ -292,7 +332,7 @@ func NewWithOptions(opts ...Option) *Viper { // can use it in their testing as well. func Reset() { v = New() - SupportedExts = []string{"json", "toml", "yaml", "yml", "properties", "props", "prop", "hcl", "dotenv", "env", "ini"} + SupportedExts = []string{"json", "toml", "yaml", "yml", "properties", "props", "prop", "hcl", "tfvars", "dotenv", "env", "ini"} SupportedRemoteProviders = []string{"etcd", "consul", "firestore"} } @@ -331,7 +371,7 @@ type RemoteProvider interface { } // SupportedExts are universally supported extensions. -var SupportedExts = []string{"json", "toml", "yaml", "yml", "properties", "props", "prop", "hcl", "dotenv", "env", "ini"} +var SupportedExts = []string{"json", "toml", "yaml", "yml", "properties", "props", "prop", "hcl", "tfvars", "dotenv", "env", "ini"} // SupportedRemoteProviders are universally supported remote providers. var SupportedRemoteProviders = []string{"etcd", "consul", "firestore"} @@ -1367,11 +1407,13 @@ func (v *Viper) realKey(key string) string { func InConfig(key string) bool { return v.InConfig(key) } func (v *Viper) InConfig(key string) bool { + lcaseKey := strings.ToLower(key) + // if the requested key is an alias, then return the proper key - key = v.realKey(key) + lcaseKey = v.realKey(lcaseKey) + path := strings.Split(lcaseKey, v.keyDelim) - _, exists := v.config[key] - return exists + return v.searchIndexableWithPathPrefixes(v.config, path) != nil } // SetDefault sets the default value for this key. @@ -1542,7 +1584,7 @@ func (v *Viper) writeConfig(filename string, force bool) error { var configType string ext := filepath.Ext(filename) - if ext != "" { + if ext != "" && ext != filepath.Base(filename) { configType = ext[1:] } else { configType = v.configType @@ -1584,35 +1626,12 @@ func (v *Viper) unmarshalReader(in io.Reader, c map[string]interface{}) error { buf := new(bytes.Buffer) buf.ReadFrom(in) - switch strings.ToLower(v.getConfigType()) { - case "yaml", "yml": - if err := yaml.Unmarshal(buf.Bytes(), &c); err != nil { - return ConfigParseError{err} - } - - case "json": - if err := json.Unmarshal(buf.Bytes(), &c); err != nil { - return ConfigParseError{err} - } - - case "hcl": - obj, err := hcl.Parse(buf.String()) - if err != nil { - return ConfigParseError{err} - } - if err = hcl.DecodeObject(&c, obj); err != nil { - return ConfigParseError{err} - } - - case "toml": - tree, err := toml.LoadReader(buf) + switch format := strings.ToLower(v.getConfigType()); format { + case "yaml", "yml", "json", "toml", "hcl", "tfvars": + err := decoderRegistry.Decode(format, buf.Bytes(), &c) if err != nil { return ConfigParseError{err} } - tmap := tree.ToMap() - for k, v := range tmap { - c[k] = v - } case "dotenv", "env": env, err := gotenv.StrictParse(buf) @@ -1665,26 +1684,13 @@ func (v *Viper) unmarshalReader(in io.Reader, c map[string]interface{}) error { func (v *Viper) marshalWriter(f afero.File, configType string) error { c := v.AllSettings() switch configType { - case "json": - b, err := json.MarshalIndent(c, "", " ") - if err != nil { - return ConfigMarshalError{err} - } - _, err = f.WriteString(string(b)) + case "yaml", "yml", "json", "toml", "hcl", "tfvars": + b, err := encoderRegistry.Encode(configType, c) if err != nil { return ConfigMarshalError{err} } - case "hcl": - b, err := json.Marshal(c) - if err != nil { - return ConfigMarshalError{err} - } - ast, err := hcl.Parse(string(b)) - if err != nil { - return ConfigMarshalError{err} - } - err = printer.Fprint(f, ast.Node) + _, err = f.WriteString(string(b)) if err != nil { return ConfigMarshalError{err} } @@ -1717,25 +1723,6 @@ func (v *Viper) marshalWriter(f afero.File, configType string) error { return ConfigMarshalError{err} } - case "toml": - t, err := toml.TreeFromMap(c) - if err != nil { - return ConfigMarshalError{err} - } - s := t.String() - if _, err := f.WriteString(s); err != nil { - return ConfigMarshalError{err} - } - - case "yaml", "yml": - b, err := yaml.Marshal(c) - if err != nil { - return ConfigMarshalError{err} - } - if _, err = f.WriteString(string(b)); err != nil { - return ConfigMarshalError{err} - } - case "ini": keys := v.AllKeys() cfg := ini.Empty() diff --git a/vendor/github.com/thediveo/enumflag/LICENSE b/vendor/github.com/thediveo/enumflag/LICENSE new file mode 100644 index 0000000000..d9a10c0d8e --- /dev/null +++ b/vendor/github.com/thediveo/enumflag/LICENSE @@ -0,0 +1,176 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS diff --git a/vendor/github.com/thediveo/enumflag/README.md b/vendor/github.com/thediveo/enumflag/README.md new file mode 100644 index 0000000000..cf9e833bee --- /dev/null +++ b/vendor/github.com/thediveo/enumflag/README.md @@ -0,0 +1,166 @@ +# CLI Enumeration Flags + +[![GoDoc](https://godoc.org/github.com/thediveo/enumflag?status.svg)](http://godoc.org/github.com/thediveo/enumflag) +[![GitHub](https://img.shields.io/github/license/thediveo/enumflag)](https://img.shields.io/github/license/thediveo/enumflag) +![build and test](https://github.com/thediveo/enumflag/workflows/build%20and%20test/badge.svg?branch=master) +[![Go Report Card](https://goreportcard.com/badge/github.com/thediveo/enumflag)](https://goreportcard.com/report/github.com/thediveo/enumflag) +![Coverage](https://img.shields.io/badge/coverage-135.72%25-darkcyan) + +`enumflag` is a Golang package which supplements the Golang CLI flag packages +[spf13/cobra](https://github.com/spf13/cobra) and +[spf13/pflag](https://github.com/spf13/pflag) with enumeration flags, including +support for enumeration slices. + +For instance, users can specify enum flags as `--mode=foo` or `--mode=bar`, +where `foo` and `bar` are valid enumeration values. Other values which are not +part of the set of allowed enumeration values cannot be set and raise CLI flag +errors. In case of an enumeration _slice_ flag users can specify multiple +enumeration values either with a single flag `--mode=foo,bar` or multiple flag +calls, such as `--mode=foo --mode=bar`. + +Application programmers then simply deal with enumeration values in form of +uints (or ints), liberated from parsing strings and validating enumeration +flags. + +## Alternatives + +In case you are just interested in string-based one-of-a-set flags, then the +following packages offer you a minimalist approach: + +- [hashicorp/packer/helper/enumflag](https://godoc.org/github.com/hashicorp/packer/helper/enumflag) + really is a reduced-to-the-max version without any whistles and bells. + +- [creachadair/goflags/enumflag](https://godoc.org/github.com/creachadair/goflags/enumflag) + has a similar, but slightly more elaborate API with additional "indices" for + enumeration values. + +But if you instead want to handle one-of-a-set flags as properly typed +enumerations instead of strings, or if you need (multiple-of-a-set) slice +support, then please read on. + +## How To Use: Properly Typed Enum Flag + +Without further ado, here's how to define and use enum flags in your own +applications... + +```go +import ( + "fmt" + + "github.com/spf13/cobra" + "github.com/thediveo/enumflag" +) + +// ① Define your new enum flag type. It can be derived from enumflag.Flag, but +// it doesn't need to be as long as it is compatible with enumflag.Flag, so +// either an int or uint. +type FooMode enumflag.Flag + +// ② Define the enumeration values for FooMode. +const ( + Foo FooMode = iota + Bar +) + +// ③ Map enumeration values to their textual representations (value +// identifiers). +var FooModeIds = map[FooMode][]string{ + Foo: {"foo"}, + Bar: {"bar"}, +} + +// ④ Now use the FooMode enum flag. +var foomode FooMode + +func main() { + rootCmd := &cobra.Command{ + Run: func(cmd *cobra.Command, _ []string) { + fmt.Printf("mode is: %d=%q\n", + foomode, + cmd.PersistentFlags().Lookup("mode").Value.String()) + }, + } + // ⑤ Define the CLI flag parameters for your wrapped enum flag. + rootCmd.PersistentFlags().VarP( + enumflag.New(&foomode, "mode", FooModeIds, enumflag.EnumCaseInsensitive), + "mode", "m", + "foos the output; can be 'foo' or 'bar'") + + rootCmd.SetArgs([]string{"--mode", "bAr"}) + _ = rootCmd.Execute() +} +``` + +The boilerplate pattern is always the same: + +1. Define your own new enumeration type, such as `type FooMode enumflag.Flag`. +2. Define the constants in your enumeration. +3. Define the mapping of the constants onto enum values (textual + representations). +4. Somewhere, declare a flag variable of your enum flag type. +5. Wire up your flag variable to its flag long and short names, et cetera. + +## How To Use: Slice of Enums + +For a slice of enumerations, simply declare your variable to be a slice of your +enumeration type and then use `enumflag.NewSlice(...)` instead of +`enumflag.New(...)`. + +```go +import ( + "fmt" + + "github.com/spf13/cobra" + "github.com/thediveo/enumflag" +) + +// ① Define your new enum flag type. It can be derived from enumflag.Flag, but +// it doesn't need to be as long as it is compatible with enumflag.Flag, so +// either an int or uint. +type MooMode enumflag.Flag + +// ② Define the enumeration values for FooMode. +const ( + Moo MooMode = (iota + 1) * 111 + Møø + Mimimi +) + +// ③ Map enumeration values to their textual representations (value +// identifiers). +var MooModeIds = map[MooMode][]string{ + Moo: {"moo"}, + Møø: {"møø"}, + Mimimi: {"mimimi"}, +} + +// User-defined enum flag types should be derived from "enumflag.Flag"; however +// this is not strictly necessary as long as they can be converted into the +// "enumflag.Flag" type. Actually, "enumflag.Flag" is just a fancy name for an +// "uint". In order to use such user-defined enum flags as flag slices, simply +// wrap them using enumflag.NewSlice. +func Example_slice() { + // ④ Define your enum slice flag value. + var moomode []MooMode + rootCmd := &cobra.Command{ + Run: func(cmd *cobra.Command, _ []string) { + fmt.Printf("mode is: %d=%q\n", + moomode, + cmd.PersistentFlags().Lookup("mode").Value.String()) + }, + } + // ⑤ Define the CLI flag parameters for your wrapped enumm slice flag. + rootCmd.PersistentFlags().VarP( + enumflag.NewSlice(&moomode, "mode", MooModeIds, enumflag.EnumCaseInsensitive), + "mode", "m", + "can be any combination of 'moo', 'møø', 'mimimi'") + + rootCmd.SetArgs([]string{"--mode", "Moo,møø"}) + _ = rootCmd.Execute() +} +``` + +## Copyright and License + +`lxkns` is Copyright 2020 Harald Albrecht, and licensed under the Apache +License, Version 2.0. diff --git a/vendor/github.com/thediveo/enumflag/doc.go b/vendor/github.com/thediveo/enumflag/doc.go new file mode 100644 index 0000000000..37405e7935 --- /dev/null +++ b/vendor/github.com/thediveo/enumflag/doc.go @@ -0,0 +1,16 @@ +/* + +Package enumflag supplements the Golang CLI flag handling packages spf13/cobra +and spf13/pflag with enumeration flags. + +For instance, users can specify enum flags as "--mode=foo" or "--mode=bar", +where "foo" and "bar" are valid enumeration values. Other values which are not +part of the set of allowed enumeration values cannot be set and raise CLI flag +errors. + +Application programmers then simply deal with enumeration values in form of +uints (or ints), liberated from parsing strings and validating enumeration +flags. + +*/ +package enumflag diff --git a/vendor/github.com/thediveo/enumflag/enumflag.code-workspace b/vendor/github.com/thediveo/enumflag/enumflag.code-workspace new file mode 100644 index 0000000000..362d7c25bb --- /dev/null +++ b/vendor/github.com/thediveo/enumflag/enumflag.code-workspace @@ -0,0 +1,7 @@ +{ + "folders": [ + { + "path": "." + } + ] +} \ No newline at end of file diff --git a/vendor/github.com/thediveo/enumflag/enumflag.go b/vendor/github.com/thediveo/enumflag/enumflag.go new file mode 100644 index 0000000000..df84581e2f --- /dev/null +++ b/vendor/github.com/thediveo/enumflag/enumflag.go @@ -0,0 +1,196 @@ +// Copyright 2020 Harald Albrecht. +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may not +// use this file except in compliance with the License. You may obtain a copy +// of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +// License for the specific language governing permissions and limitations +// under the License. + +package enumflag + +import ( + "fmt" + "reflect" + "sort" + "strings" +) + +// Flag represents a CLI (enumeration) flag which can take on only a single +// enumeration value out of a fixed set of enumeration values. Applications +// using the enumflag package might want to derive their enumeration flags from +// Flag, such as "type MyFoo enumflag.Flag", but they don't need to. The only +// requirement for user-defined enumeration flags is that they must be +// compatible with the Flag type. +type Flag uint + +// EnumCaseSensitivity specifies whether the textual representations of enum +// values are considered to be case sensitive, or not. +type EnumCaseSensitivity bool + +// Controls whether the textual representations for enum values are case +// sensitive, or not. +const ( + EnumCaseInsensitive EnumCaseSensitivity = false + EnumCaseSensitive EnumCaseSensitivity = true +) + +// EnumValue wraps a user-defined enum type value and implements the pflag.Value +// interface, so the user's enum type value can directly be used with the fine +// pflag drop-in package for Golang CLI flags. +type EnumValue struct { + value interface{} // enum value of a user-defined enum type. + enumtype string // name of the user-defined enum type. + names enumValueNames // enum value names. + sensitivity EnumCaseSensitivity // case sensitive or insensitive? + flagtype reflect.Type // cached enum reflection type. +} + +// New wraps a given enum variable so that it can be used as a flag Value with +// pflag.Var and pflag.VarP. The specified flag must be a pointer to a +// user-defined enum value, as otherwise the flag value cannot be managed +// (changed) later on, when a CLI user tries to set it via its corresponding CLI +// flag. +func New(flag interface{}, typename string, mapping interface{}, sensitivity EnumCaseSensitivity) *EnumValue { + // Ensure that the specified enumeration variable is of a compatible type + // and that it actually is a pointer to the enum value. + flagtype := reflect.TypeOf(flag) + if flagtype.Kind() != reflect.Ptr { + panic(fmt.Sprintf( + "New requires flag to be a pointer to an enum value in order to manage it")) + } + return newEnumValue(flag, typename, mapping, sensitivity) +} + +// newEnumValue returns a correctly set up new EnumValue. It expects the flag +// var to be either a pointer or a pointer to the slice, and the caller to have +// checked this before calling. +func newEnumValue(flag interface{}, typename string, mapping interface{}, sensitivity EnumCaseSensitivity) *EnumValue { + flagtype := reflect.TypeOf(flag).Elem() + if flagtype.Kind() == reflect.Slice { + flagtype = flagtype.Elem() + } + flagtypename := flagtype.Name() + if !flagtype.ConvertibleTo(uintType) { + panic(fmt.Sprintf("incompatible enum value type %s", flagtypename)) + } + // Next, ensure that the enumeration values (in form of textual + // representations) actually are stored in a map. + mappingrval := reflect.ValueOf(mapping) + if mappingrval.Kind() != reflect.Map || !mappingrval.Type().Key().ConvertibleTo(uintType) { + panic(fmt.Sprintf("incompatible enum values map type %s", + mappingrval.Type().Name())) + } + // Oh, the magic of Golang reflexions makes us put on our beer googles, erm, + // goggles: we now convert the specified enum values into our "canonical" + // mapping. While we can (mostly) keep the map values (which are string + // slices), we have to convert the map keys into our canonical EnumFlag key + // type (=enum values type). + enummap := enumValueNames{} + for _, key := range mappingrval.MapKeys() { + names := mappingrval.MapIndex(key).Interface().([]string) + if sensitivity == EnumCaseInsensitive { + names = append(names[:0:0], names...) // https://github.com/golang/go/wiki/SliceTricks + for idx, name := range names { + names[idx] = strings.ToLower(name) + } + } + enummap[key.Convert(enumFlagType).Interface().(Flag)] = names + } + // Finally return the Value-compatible wrapper, which now has the necessary + // information about the mapping and case sensitivity, as well as the other + // things. + return &EnumValue{ + value: flag, + enumtype: typename, + names: enummap, + sensitivity: sensitivity, + flagtype: flagtype, + } +} + +// Get returns the managed enum value as a convenience. +func (e *EnumValue) Get() interface{} { + return e.value +} + +// Set sets the enum flag to the specified enum value. If the specified value +// isn't a valid enum value, then the enum flag will be unchanged and an error +// returned instead. +func (e *EnumValue) Set(val string) error { + enumcode, err := e.code(val) + if err == nil { + // When creating our enum flag wrapper we made sure it has a value + // reference, so we don't need to double-check here again, but now access it + // always indirectly. + reflect.ValueOf(e.value).Elem().Set( + reflect.ValueOf(enumcode).Convert(e.flagtype)) + } + return err +} + +// code parses the textual representation of an enumeration value, returning the +// corresponding enumeration value, or an error. +func (e *EnumValue) code(val string) (Flag, error) { + if e.sensitivity == EnumCaseInsensitive { + val = strings.ToLower(val) + } + // Try to find a matching enum value textual representation, and then take + // its enumation value ("code"). + for enumval, ids := range e.names { + for _, id := range ids { + if val == id { + return enumval, nil + } + } + } + // Oh no! An invalid textual enum value was specified, so let's generate + // some useful error explaining which textual representations are valid. + // We're ordering values by their canonical names in order to achieve a + // stable error message. + allids := []string{} + for _, ids := range e.names { + s := []string{} + for _, id := range ids { + s = append(s, "'"+id+"'") + } + allids = append(allids, strings.Join(s, "/")) + } + sort.Strings(allids) + return 0, fmt.Errorf("must be %s", strings.Join(allids, ", ")) +} + +// String returns the textual representation of an enumeration (flag) value. In +// case multiple textual representations (=identifiers) exist for the same +// enumeration value, then only the first textual representation is returned, +// which is considered to be the canonical one. +func (e *EnumValue) String() string { + flagval := reflect.ValueOf(e.value).Elem() + if ids, ok := e.names[flagval.Convert(enumFlagType).Interface().(Flag)]; ok { + if len(ids) > 0 { + return ids[0] + } + } + return "" +} + +// Type returns the name of the flag value type. The type name is used in error +// message. +func (e *EnumValue) Type() string { + return e.enumtype +} + +// enumValueNames maps enumeration values to their corresponding textual +// representations. This mapping is a one-to-many mapping in that the same +// enumeration value may have more than only one associated textual +// representation. +type enumValueNames map[Flag][]string + +// Reflection types used in this package. +var enumFlagType = reflect.TypeOf(Flag(0)) +var uintType = reflect.TypeOf(uint(0)) diff --git a/vendor/github.com/thediveo/enumflag/enumslice.go b/vendor/github.com/thediveo/enumflag/enumslice.go new file mode 100644 index 0000000000..d08b49015f --- /dev/null +++ b/vendor/github.com/thediveo/enumflag/enumslice.go @@ -0,0 +1,94 @@ +package enumflag + +import ( + "fmt" + "reflect" + "strings" +) + +// EnumSliceValue wraps a slice of enum values for a user-defined enum type. +type EnumSliceValue struct { + *EnumValue + merge bool // replace complete slice or merge values? +} + +// NewSlice warps a given enum slice variable so that it can ve used as a flag +// Value with pflag.Var and pflag.VarP. It takes the same parameters as New, +// with the exception of expecting a slice instead of a single enum var. +func NewSlice(flag interface{}, typename string, mapping interface{}, sensitivity EnumCaseSensitivity) *EnumSliceValue { + flagtype := reflect.TypeOf(flag) + if flagtype.Kind() != reflect.Ptr || flagtype.Elem().Kind() != reflect.Slice { + panic(fmt.Sprintf( + "NewSlice requires flag to be a pointer to an enum value slice in order to manage it")) + } + return &EnumSliceValue{ + EnumValue: newEnumValue(flag, typename, mapping, sensitivity), + } +} + +// Set either sets or merges the enum slice flag: the first call will set the +// flag value to the specified set of enum values. Later calls then merge enum +// values instead of replacing the current set. This mimics the behavior of +// pflag's slice flags. +func (e *EnumSliceValue) Set(val string) error { + // First parse and convert the textual enum values into their + // program-internal codes. + vals := strings.Split(val, ",") + enums := make([]Flag, len(vals)) + for idx, enumval := range vals { + enumcode, err := e.code(enumval) + if err != nil { + return err + } + enums[idx] = enumcode + } + enumslice := reflect.ValueOf(e.value).Elem() + if !e.merge { + // Replace any existing default enum value set. For this, we need to + // convert the parsed enum codes into the format used by the + // user-defined enum slice. + size := len(enums) + v := reflect.MakeSlice(reflect.TypeOf(e.value).Elem(), size, size) + for idx, enumcode := range enums { + v.Index(idx).Set(reflect.ValueOf(enumcode).Convert(e.flagtype)) + } + enumslice.Set(v) + e.merge = true // ...and next time: merge. + } else { + // Merge in the existing enum values. + next: + for _, enumcode := range enums { + // Is this enum value (code) already part of the slice? Then skip + // it, otherwise append it. + size := enumslice.Len() + for idx := 0; idx < size; idx++ { + if enumslice.Index(idx).Convert(enumFlagType).Interface().(Flag) == enumcode { + continue next + } + } + enumslice.Set(reflect.Append( + enumslice, + reflect.ValueOf(enumcode).Convert(e.flagtype))) + } + } + return nil +} + +// String returns the textual representation of an enumeration (flag) slice, +// which can contain multiple enumeration values from the same enumeration +// simultaneously. In case multiple textual representations (=identifiers) exist +// for the same enumeration value, then only the first textual representation is +// returned, which is considered to be the canonical one. +func (e *EnumSliceValue) String() string { + flagvals := reflect.ValueOf(e.value).Elem() + idsl := []string{} + size := flagvals.Len() + for idx := 0; idx < size; idx++ { + if ids, ok := e.names[flagvals.Index(idx).Convert(enumFlagType).Interface().(Flag)]; ok { + if len(ids) > 0 { + idsl = append(idsl, ids[0]) + } + } + } + return "[" + strings.Join(idsl, ",") + "]" +} diff --git a/vendor/github.com/thediveo/enumflag/go.mod b/vendor/github.com/thediveo/enumflag/go.mod new file mode 100644 index 0000000000..7a5dc4eb7e --- /dev/null +++ b/vendor/github.com/thediveo/enumflag/go.mod @@ -0,0 +1,9 @@ +module github.com/thediveo/enumflag + +go 1.13 + +require ( + github.com/onsi/ginkgo v1.12.0 + github.com/onsi/gomega v1.9.0 + github.com/spf13/cobra v0.0.7 +) diff --git a/vendor/github.com/thediveo/enumflag/go.sum b/vendor/github.com/thediveo/enumflag/go.sum new file mode 100644 index 0000000000..1646949c1f --- /dev/null +++ b/vendor/github.com/thediveo/enumflag/go.sum @@ -0,0 +1,148 @@ +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= +github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= +github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= +github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= +github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= +github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= +github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= +github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= +github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= +github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= +github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= +github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= +github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= +github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= +github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= +github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= +github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= +github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= +github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= +github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= +github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.12.0 h1:Iw5WCbBcaAAd0fpRb1c9r5YCylv4XDoCSigm1zLevwU= +github.com/onsi/ginkgo v1.12.0/go.mod h1:oUhWkIvk5aDxtKvDDuw8gItl8pKl42LzjC9KZE0HfGg= +github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= +github.com/onsi/gomega v1.9.0 h1:R1uwffexN6Pr340GtYRIdZmAiN4J+iw6WG4wog1DUXg= +github.com/onsi/gomega v1.9.0/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoTdcA= +github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= +github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= +github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= +github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= +github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= +github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= +github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= +github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= +github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= +github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= +github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= +github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= +github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= +github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= +github.com/spf13/cobra v0.0.7 h1:FfTH+vuMXOas8jmfb5/M7dzEYx7LpcLb7a0LPe34uOU= +github.com/spf13/cobra v0.0.7/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE= +github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= +github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg= +github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE= +github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= +github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= +github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= +github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= +go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= +go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= +go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= +go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= +golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190522155817-f3200d17e092 h1:4QSRKanuywn15aTZvI/mIDEgPQpswuFndXpOj3rKEco= +golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e h1:N7DeIrjYszNmSW409R3frPPwglRwMkXSBzwVbkOjLLA= +golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7 h1:9zdDQZ7Thm29KFXgAX/+yaf3eVbP7djjWp/dXAppNCc= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= +gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I= +gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/vendor/github.com/vbatts/tar-split/LICENSE b/vendor/github.com/vbatts/tar-split/LICENSE new file mode 100644 index 0000000000..ca03685b15 --- /dev/null +++ b/vendor/github.com/vbatts/tar-split/LICENSE @@ -0,0 +1,28 @@ +Copyright (c) 2015 Vincent Batts, Raleigh, NC, USA + +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this +list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its contributors +may be used to endorse or promote products derived from this software without +specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/github.com/vbatts/tar-split/archive/tar/common.go b/vendor/github.com/vbatts/tar-split/archive/tar/common.go new file mode 100644 index 0000000000..dee9e47e4a --- /dev/null +++ b/vendor/github.com/vbatts/tar-split/archive/tar/common.go @@ -0,0 +1,723 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package tar implements access to tar archives. +// +// Tape archives (tar) are a file format for storing a sequence of files that +// can be read and written in a streaming manner. +// This package aims to cover most variations of the format, +// including those produced by GNU and BSD tar tools. +package tar + +import ( + "errors" + "fmt" + "math" + "os" + "path" + "reflect" + "strconv" + "strings" + "time" +) + +// BUG: Use of the Uid and Gid fields in Header could overflow on 32-bit +// architectures. If a large value is encountered when decoding, the result +// stored in Header will be the truncated version. + +var ( + ErrHeader = errors.New("archive/tar: invalid tar header") + ErrWriteTooLong = errors.New("archive/tar: write too long") + ErrFieldTooLong = errors.New("archive/tar: header field too long") + ErrWriteAfterClose = errors.New("archive/tar: write after close") + errMissData = errors.New("archive/tar: sparse file references non-existent data") + errUnrefData = errors.New("archive/tar: sparse file contains unreferenced data") + errWriteHole = errors.New("archive/tar: write non-NUL byte in sparse hole") +) + +type headerError []string + +func (he headerError) Error() string { + const prefix = "archive/tar: cannot encode header" + var ss []string + for _, s := range he { + if s != "" { + ss = append(ss, s) + } + } + if len(ss) == 0 { + return prefix + } + return fmt.Sprintf("%s: %v", prefix, strings.Join(ss, "; and ")) +} + +// Type flags for Header.Typeflag. +const ( + // Type '0' indicates a regular file. + TypeReg = '0' + TypeRegA = '\x00' // Deprecated: Use TypeReg instead. + + // Type '1' to '6' are header-only flags and may not have a data body. + TypeLink = '1' // Hard link + TypeSymlink = '2' // Symbolic link + TypeChar = '3' // Character device node + TypeBlock = '4' // Block device node + TypeDir = '5' // Directory + TypeFifo = '6' // FIFO node + + // Type '7' is reserved. + TypeCont = '7' + + // Type 'x' is used by the PAX format to store key-value records that + // are only relevant to the next file. + // This package transparently handles these types. + TypeXHeader = 'x' + + // Type 'g' is used by the PAX format to store key-value records that + // are relevant to all subsequent files. + // This package only supports parsing and composing such headers, + // but does not currently support persisting the global state across files. + TypeXGlobalHeader = 'g' + + // Type 'S' indicates a sparse file in the GNU format. + TypeGNUSparse = 'S' + + // Types 'L' and 'K' are used by the GNU format for a meta file + // used to store the path or link name for the next file. + // This package transparently handles these types. + TypeGNULongName = 'L' + TypeGNULongLink = 'K' +) + +// Keywords for PAX extended header records. +const ( + paxNone = "" // Indicates that no PAX key is suitable + paxPath = "path" + paxLinkpath = "linkpath" + paxSize = "size" + paxUid = "uid" + paxGid = "gid" + paxUname = "uname" + paxGname = "gname" + paxMtime = "mtime" + paxAtime = "atime" + paxCtime = "ctime" // Removed from later revision of PAX spec, but was valid + paxCharset = "charset" // Currently unused + paxComment = "comment" // Currently unused + + paxSchilyXattr = "SCHILY.xattr." + + // Keywords for GNU sparse files in a PAX extended header. + paxGNUSparse = "GNU.sparse." + paxGNUSparseNumBlocks = "GNU.sparse.numblocks" + paxGNUSparseOffset = "GNU.sparse.offset" + paxGNUSparseNumBytes = "GNU.sparse.numbytes" + paxGNUSparseMap = "GNU.sparse.map" + paxGNUSparseName = "GNU.sparse.name" + paxGNUSparseMajor = "GNU.sparse.major" + paxGNUSparseMinor = "GNU.sparse.minor" + paxGNUSparseSize = "GNU.sparse.size" + paxGNUSparseRealSize = "GNU.sparse.realsize" +) + +// basicKeys is a set of the PAX keys for which we have built-in support. +// This does not contain "charset" or "comment", which are both PAX-specific, +// so adding them as first-class features of Header is unlikely. +// Users can use the PAXRecords field to set it themselves. +var basicKeys = map[string]bool{ + paxPath: true, paxLinkpath: true, paxSize: true, paxUid: true, paxGid: true, + paxUname: true, paxGname: true, paxMtime: true, paxAtime: true, paxCtime: true, +} + +// A Header represents a single header in a tar archive. +// Some fields may not be populated. +// +// For forward compatibility, users that retrieve a Header from Reader.Next, +// mutate it in some ways, and then pass it back to Writer.WriteHeader +// should do so by creating a new Header and copying the fields +// that they are interested in preserving. +type Header struct { + // Typeflag is the type of header entry. + // The zero value is automatically promoted to either TypeReg or TypeDir + // depending on the presence of a trailing slash in Name. + Typeflag byte + + Name string // Name of file entry + Linkname string // Target name of link (valid for TypeLink or TypeSymlink) + + Size int64 // Logical file size in bytes + Mode int64 // Permission and mode bits + Uid int // User ID of owner + Gid int // Group ID of owner + Uname string // User name of owner + Gname string // Group name of owner + + // If the Format is unspecified, then Writer.WriteHeader rounds ModTime + // to the nearest second and ignores the AccessTime and ChangeTime fields. + // + // To use AccessTime or ChangeTime, specify the Format as PAX or GNU. + // To use sub-second resolution, specify the Format as PAX. + ModTime time.Time // Modification time + AccessTime time.Time // Access time (requires either PAX or GNU support) + ChangeTime time.Time // Change time (requires either PAX or GNU support) + + Devmajor int64 // Major device number (valid for TypeChar or TypeBlock) + Devminor int64 // Minor device number (valid for TypeChar or TypeBlock) + + // Xattrs stores extended attributes as PAX records under the + // "SCHILY.xattr." namespace. + // + // The following are semantically equivalent: + // h.Xattrs[key] = value + // h.PAXRecords["SCHILY.xattr."+key] = value + // + // When Writer.WriteHeader is called, the contents of Xattrs will take + // precedence over those in PAXRecords. + // + // Deprecated: Use PAXRecords instead. + Xattrs map[string]string + + // PAXRecords is a map of PAX extended header records. + // + // User-defined records should have keys of the following form: + // VENDOR.keyword + // Where VENDOR is some namespace in all uppercase, and keyword may + // not contain the '=' character (e.g., "GOLANG.pkg.version"). + // The key and value should be non-empty UTF-8 strings. + // + // When Writer.WriteHeader is called, PAX records derived from the + // other fields in Header take precedence over PAXRecords. + PAXRecords map[string]string + + // Format specifies the format of the tar header. + // + // This is set by Reader.Next as a best-effort guess at the format. + // Since the Reader liberally reads some non-compliant files, + // it is possible for this to be FormatUnknown. + // + // If the format is unspecified when Writer.WriteHeader is called, + // then it uses the first format (in the order of USTAR, PAX, GNU) + // capable of encoding this Header (see Format). + Format Format +} + +// sparseEntry represents a Length-sized fragment at Offset in the file. +type sparseEntry struct{ Offset, Length int64 } + +func (s sparseEntry) endOffset() int64 { return s.Offset + s.Length } + +// A sparse file can be represented as either a sparseDatas or a sparseHoles. +// As long as the total size is known, they are equivalent and one can be +// converted to the other form and back. The various tar formats with sparse +// file support represent sparse files in the sparseDatas form. That is, they +// specify the fragments in the file that has data, and treat everything else as +// having zero bytes. As such, the encoding and decoding logic in this package +// deals with sparseDatas. +// +// However, the external API uses sparseHoles instead of sparseDatas because the +// zero value of sparseHoles logically represents a normal file (i.e., there are +// no holes in it). On the other hand, the zero value of sparseDatas implies +// that the file has no data in it, which is rather odd. +// +// As an example, if the underlying raw file contains the 10-byte data: +// var compactFile = "abcdefgh" +// +// And the sparse map has the following entries: +// var spd sparseDatas = []sparseEntry{ +// {Offset: 2, Length: 5}, // Data fragment for 2..6 +// {Offset: 18, Length: 3}, // Data fragment for 18..20 +// } +// var sph sparseHoles = []sparseEntry{ +// {Offset: 0, Length: 2}, // Hole fragment for 0..1 +// {Offset: 7, Length: 11}, // Hole fragment for 7..17 +// {Offset: 21, Length: 4}, // Hole fragment for 21..24 +// } +// +// Then the content of the resulting sparse file with a Header.Size of 25 is: +// var sparseFile = "\x00"*2 + "abcde" + "\x00"*11 + "fgh" + "\x00"*4 +type ( + sparseDatas []sparseEntry + sparseHoles []sparseEntry +) + +// validateSparseEntries reports whether sp is a valid sparse map. +// It does not matter whether sp represents data fragments or hole fragments. +func validateSparseEntries(sp []sparseEntry, size int64) bool { + // Validate all sparse entries. These are the same checks as performed by + // the BSD tar utility. + if size < 0 { + return false + } + var pre sparseEntry + for _, cur := range sp { + switch { + case cur.Offset < 0 || cur.Length < 0: + return false // Negative values are never okay + case cur.Offset > math.MaxInt64-cur.Length: + return false // Integer overflow with large length + case cur.endOffset() > size: + return false // Region extends beyond the actual size + case pre.endOffset() > cur.Offset: + return false // Regions cannot overlap and must be in order + } + pre = cur + } + return true +} + +// alignSparseEntries mutates src and returns dst where each fragment's +// starting offset is aligned up to the nearest block edge, and each +// ending offset is aligned down to the nearest block edge. +// +// Even though the Go tar Reader and the BSD tar utility can handle entries +// with arbitrary offsets and lengths, the GNU tar utility can only handle +// offsets and lengths that are multiples of blockSize. +func alignSparseEntries(src []sparseEntry, size int64) []sparseEntry { + dst := src[:0] + for _, s := range src { + pos, end := s.Offset, s.endOffset() + pos += blockPadding(+pos) // Round-up to nearest blockSize + if end != size { + end -= blockPadding(-end) // Round-down to nearest blockSize + } + if pos < end { + dst = append(dst, sparseEntry{Offset: pos, Length: end - pos}) + } + } + return dst +} + +// invertSparseEntries converts a sparse map from one form to the other. +// If the input is sparseHoles, then it will output sparseDatas and vice-versa. +// The input must have been already validated. +// +// This function mutates src and returns a normalized map where: +// * adjacent fragments are coalesced together +// * only the last fragment may be empty +// * the endOffset of the last fragment is the total size +func invertSparseEntries(src []sparseEntry, size int64) []sparseEntry { + dst := src[:0] + var pre sparseEntry + for _, cur := range src { + if cur.Length == 0 { + continue // Skip empty fragments + } + pre.Length = cur.Offset - pre.Offset + if pre.Length > 0 { + dst = append(dst, pre) // Only add non-empty fragments + } + pre.Offset = cur.endOffset() + } + pre.Length = size - pre.Offset // Possibly the only empty fragment + return append(dst, pre) +} + +// fileState tracks the number of logical (includes sparse holes) and physical +// (actual in tar archive) bytes remaining for the current file. +// +// Invariant: LogicalRemaining >= PhysicalRemaining +type fileState interface { + LogicalRemaining() int64 + PhysicalRemaining() int64 +} + +// allowedFormats determines which formats can be used. +// The value returned is the logical OR of multiple possible formats. +// If the value is FormatUnknown, then the input Header cannot be encoded +// and an error is returned explaining why. +// +// As a by-product of checking the fields, this function returns paxHdrs, which +// contain all fields that could not be directly encoded. +// A value receiver ensures that this method does not mutate the source Header. +func (h Header) allowedFormats() (format Format, paxHdrs map[string]string, err error) { + format = FormatUSTAR | FormatPAX | FormatGNU + paxHdrs = make(map[string]string) + + var whyNoUSTAR, whyNoPAX, whyNoGNU string + var preferPAX bool // Prefer PAX over USTAR + verifyString := func(s string, size int, name, paxKey string) { + // NUL-terminator is optional for path and linkpath. + // Technically, it is required for uname and gname, + // but neither GNU nor BSD tar checks for it. + tooLong := len(s) > size + allowLongGNU := paxKey == paxPath || paxKey == paxLinkpath + if hasNUL(s) || (tooLong && !allowLongGNU) { + whyNoGNU = fmt.Sprintf("GNU cannot encode %s=%q", name, s) + format.mustNotBe(FormatGNU) + } + if !isASCII(s) || tooLong { + canSplitUSTAR := paxKey == paxPath + if _, _, ok := splitUSTARPath(s); !canSplitUSTAR || !ok { + whyNoUSTAR = fmt.Sprintf("USTAR cannot encode %s=%q", name, s) + format.mustNotBe(FormatUSTAR) + } + if paxKey == paxNone { + whyNoPAX = fmt.Sprintf("PAX cannot encode %s=%q", name, s) + format.mustNotBe(FormatPAX) + } else { + paxHdrs[paxKey] = s + } + } + if v, ok := h.PAXRecords[paxKey]; ok && v == s { + paxHdrs[paxKey] = v + } + } + verifyNumeric := func(n int64, size int, name, paxKey string) { + if !fitsInBase256(size, n) { + whyNoGNU = fmt.Sprintf("GNU cannot encode %s=%d", name, n) + format.mustNotBe(FormatGNU) + } + if !fitsInOctal(size, n) { + whyNoUSTAR = fmt.Sprintf("USTAR cannot encode %s=%d", name, n) + format.mustNotBe(FormatUSTAR) + if paxKey == paxNone { + whyNoPAX = fmt.Sprintf("PAX cannot encode %s=%d", name, n) + format.mustNotBe(FormatPAX) + } else { + paxHdrs[paxKey] = strconv.FormatInt(n, 10) + } + } + if v, ok := h.PAXRecords[paxKey]; ok && v == strconv.FormatInt(n, 10) { + paxHdrs[paxKey] = v + } + } + verifyTime := func(ts time.Time, size int, name, paxKey string) { + if ts.IsZero() { + return // Always okay + } + if !fitsInBase256(size, ts.Unix()) { + whyNoGNU = fmt.Sprintf("GNU cannot encode %s=%v", name, ts) + format.mustNotBe(FormatGNU) + } + isMtime := paxKey == paxMtime + fitsOctal := fitsInOctal(size, ts.Unix()) + if (isMtime && !fitsOctal) || !isMtime { + whyNoUSTAR = fmt.Sprintf("USTAR cannot encode %s=%v", name, ts) + format.mustNotBe(FormatUSTAR) + } + needsNano := ts.Nanosecond() != 0 + if !isMtime || !fitsOctal || needsNano { + preferPAX = true // USTAR may truncate sub-second measurements + if paxKey == paxNone { + whyNoPAX = fmt.Sprintf("PAX cannot encode %s=%v", name, ts) + format.mustNotBe(FormatPAX) + } else { + paxHdrs[paxKey] = formatPAXTime(ts) + } + } + if v, ok := h.PAXRecords[paxKey]; ok && v == formatPAXTime(ts) { + paxHdrs[paxKey] = v + } + } + + // Check basic fields. + var blk block + v7 := blk.V7() + ustar := blk.USTAR() + gnu := blk.GNU() + verifyString(h.Name, len(v7.Name()), "Name", paxPath) + verifyString(h.Linkname, len(v7.LinkName()), "Linkname", paxLinkpath) + verifyString(h.Uname, len(ustar.UserName()), "Uname", paxUname) + verifyString(h.Gname, len(ustar.GroupName()), "Gname", paxGname) + verifyNumeric(h.Mode, len(v7.Mode()), "Mode", paxNone) + verifyNumeric(int64(h.Uid), len(v7.UID()), "Uid", paxUid) + verifyNumeric(int64(h.Gid), len(v7.GID()), "Gid", paxGid) + verifyNumeric(h.Size, len(v7.Size()), "Size", paxSize) + verifyNumeric(h.Devmajor, len(ustar.DevMajor()), "Devmajor", paxNone) + verifyNumeric(h.Devminor, len(ustar.DevMinor()), "Devminor", paxNone) + verifyTime(h.ModTime, len(v7.ModTime()), "ModTime", paxMtime) + verifyTime(h.AccessTime, len(gnu.AccessTime()), "AccessTime", paxAtime) + verifyTime(h.ChangeTime, len(gnu.ChangeTime()), "ChangeTime", paxCtime) + + // Check for header-only types. + var whyOnlyPAX, whyOnlyGNU string + switch h.Typeflag { + case TypeReg, TypeChar, TypeBlock, TypeFifo, TypeGNUSparse: + // Exclude TypeLink and TypeSymlink, since they may reference directories. + if strings.HasSuffix(h.Name, "/") { + return FormatUnknown, nil, headerError{"filename may not have trailing slash"} + } + case TypeXHeader, TypeGNULongName, TypeGNULongLink: + return FormatUnknown, nil, headerError{"cannot manually encode TypeXHeader, TypeGNULongName, or TypeGNULongLink headers"} + case TypeXGlobalHeader: + h2 := Header{Name: h.Name, Typeflag: h.Typeflag, Xattrs: h.Xattrs, PAXRecords: h.PAXRecords, Format: h.Format} + if !reflect.DeepEqual(h, h2) { + return FormatUnknown, nil, headerError{"only PAXRecords should be set for TypeXGlobalHeader"} + } + whyOnlyPAX = "only PAX supports TypeXGlobalHeader" + format.mayOnlyBe(FormatPAX) + } + if !isHeaderOnlyType(h.Typeflag) && h.Size < 0 { + return FormatUnknown, nil, headerError{"negative size on header-only type"} + } + + // Check PAX records. + if len(h.Xattrs) > 0 { + for k, v := range h.Xattrs { + paxHdrs[paxSchilyXattr+k] = v + } + whyOnlyPAX = "only PAX supports Xattrs" + format.mayOnlyBe(FormatPAX) + } + if len(h.PAXRecords) > 0 { + for k, v := range h.PAXRecords { + switch _, exists := paxHdrs[k]; { + case exists: + continue // Do not overwrite existing records + case h.Typeflag == TypeXGlobalHeader: + paxHdrs[k] = v // Copy all records + case !basicKeys[k] && !strings.HasPrefix(k, paxGNUSparse): + paxHdrs[k] = v // Ignore local records that may conflict + } + } + whyOnlyPAX = "only PAX supports PAXRecords" + format.mayOnlyBe(FormatPAX) + } + for k, v := range paxHdrs { + if !validPAXRecord(k, v) { + return FormatUnknown, nil, headerError{fmt.Sprintf("invalid PAX record: %q", k+" = "+v)} + } + } + + // TODO(dsnet): Re-enable this when adding sparse support. + // See https://golang.org/issue/22735 + /* + // Check sparse files. + if len(h.SparseHoles) > 0 || h.Typeflag == TypeGNUSparse { + if isHeaderOnlyType(h.Typeflag) { + return FormatUnknown, nil, headerError{"header-only type cannot be sparse"} + } + if !validateSparseEntries(h.SparseHoles, h.Size) { + return FormatUnknown, nil, headerError{"invalid sparse holes"} + } + if h.Typeflag == TypeGNUSparse { + whyOnlyGNU = "only GNU supports TypeGNUSparse" + format.mayOnlyBe(FormatGNU) + } else { + whyNoGNU = "GNU supports sparse files only with TypeGNUSparse" + format.mustNotBe(FormatGNU) + } + whyNoUSTAR = "USTAR does not support sparse files" + format.mustNotBe(FormatUSTAR) + } + */ + + // Check desired format. + if wantFormat := h.Format; wantFormat != FormatUnknown { + if wantFormat.has(FormatPAX) && !preferPAX { + wantFormat.mayBe(FormatUSTAR) // PAX implies USTAR allowed too + } + format.mayOnlyBe(wantFormat) // Set union of formats allowed and format wanted + } + if format == FormatUnknown { + switch h.Format { + case FormatUSTAR: + err = headerError{"Format specifies USTAR", whyNoUSTAR, whyOnlyPAX, whyOnlyGNU} + case FormatPAX: + err = headerError{"Format specifies PAX", whyNoPAX, whyOnlyGNU} + case FormatGNU: + err = headerError{"Format specifies GNU", whyNoGNU, whyOnlyPAX} + default: + err = headerError{whyNoUSTAR, whyNoPAX, whyNoGNU, whyOnlyPAX, whyOnlyGNU} + } + } + return format, paxHdrs, err +} + +// FileInfo returns an os.FileInfo for the Header. +func (h *Header) FileInfo() os.FileInfo { + return headerFileInfo{h} +} + +// headerFileInfo implements os.FileInfo. +type headerFileInfo struct { + h *Header +} + +func (fi headerFileInfo) Size() int64 { return fi.h.Size } +func (fi headerFileInfo) IsDir() bool { return fi.Mode().IsDir() } +func (fi headerFileInfo) ModTime() time.Time { return fi.h.ModTime } +func (fi headerFileInfo) Sys() interface{} { return fi.h } + +// Name returns the base name of the file. +func (fi headerFileInfo) Name() string { + if fi.IsDir() { + return path.Base(path.Clean(fi.h.Name)) + } + return path.Base(fi.h.Name) +} + +// Mode returns the permission and mode bits for the headerFileInfo. +func (fi headerFileInfo) Mode() (mode os.FileMode) { + // Set file permission bits. + mode = os.FileMode(fi.h.Mode).Perm() + + // Set setuid, setgid and sticky bits. + if fi.h.Mode&c_ISUID != 0 { + mode |= os.ModeSetuid + } + if fi.h.Mode&c_ISGID != 0 { + mode |= os.ModeSetgid + } + if fi.h.Mode&c_ISVTX != 0 { + mode |= os.ModeSticky + } + + // Set file mode bits; clear perm, setuid, setgid, and sticky bits. + switch m := os.FileMode(fi.h.Mode) &^ 07777; m { + case c_ISDIR: + mode |= os.ModeDir + case c_ISFIFO: + mode |= os.ModeNamedPipe + case c_ISLNK: + mode |= os.ModeSymlink + case c_ISBLK: + mode |= os.ModeDevice + case c_ISCHR: + mode |= os.ModeDevice + mode |= os.ModeCharDevice + case c_ISSOCK: + mode |= os.ModeSocket + } + + switch fi.h.Typeflag { + case TypeSymlink: + mode |= os.ModeSymlink + case TypeChar: + mode |= os.ModeDevice + mode |= os.ModeCharDevice + case TypeBlock: + mode |= os.ModeDevice + case TypeDir: + mode |= os.ModeDir + case TypeFifo: + mode |= os.ModeNamedPipe + } + + return mode +} + +// sysStat, if non-nil, populates h from system-dependent fields of fi. +var sysStat func(fi os.FileInfo, h *Header) error + +const ( + // Mode constants from the USTAR spec: + // See http://pubs.opengroup.org/onlinepubs/9699919799/utilities/pax.html#tag_20_92_13_06 + c_ISUID = 04000 // Set uid + c_ISGID = 02000 // Set gid + c_ISVTX = 01000 // Save text (sticky bit) + + // Common Unix mode constants; these are not defined in any common tar standard. + // Header.FileInfo understands these, but FileInfoHeader will never produce these. + c_ISDIR = 040000 // Directory + c_ISFIFO = 010000 // FIFO + c_ISREG = 0100000 // Regular file + c_ISLNK = 0120000 // Symbolic link + c_ISBLK = 060000 // Block special file + c_ISCHR = 020000 // Character special file + c_ISSOCK = 0140000 // Socket +) + +// FileInfoHeader creates a partially-populated Header from fi. +// If fi describes a symlink, FileInfoHeader records link as the link target. +// If fi describes a directory, a slash is appended to the name. +// +// Since os.FileInfo's Name method only returns the base name of +// the file it describes, it may be necessary to modify Header.Name +// to provide the full path name of the file. +func FileInfoHeader(fi os.FileInfo, link string) (*Header, error) { + if fi == nil { + return nil, errors.New("archive/tar: FileInfo is nil") + } + fm := fi.Mode() + h := &Header{ + Name: fi.Name(), + ModTime: fi.ModTime(), + Mode: int64(fm.Perm()), // or'd with c_IS* constants later + } + switch { + case fm.IsRegular(): + h.Typeflag = TypeReg + h.Size = fi.Size() + case fi.IsDir(): + h.Typeflag = TypeDir + h.Name += "/" + case fm&os.ModeSymlink != 0: + h.Typeflag = TypeSymlink + h.Linkname = link + case fm&os.ModeDevice != 0: + if fm&os.ModeCharDevice != 0 { + h.Typeflag = TypeChar + } else { + h.Typeflag = TypeBlock + } + case fm&os.ModeNamedPipe != 0: + h.Typeflag = TypeFifo + case fm&os.ModeSocket != 0: + return nil, fmt.Errorf("archive/tar: sockets not supported") + default: + return nil, fmt.Errorf("archive/tar: unknown file mode %v", fm) + } + if fm&os.ModeSetuid != 0 { + h.Mode |= c_ISUID + } + if fm&os.ModeSetgid != 0 { + h.Mode |= c_ISGID + } + if fm&os.ModeSticky != 0 { + h.Mode |= c_ISVTX + } + // If possible, populate additional fields from OS-specific + // FileInfo fields. + if sys, ok := fi.Sys().(*Header); ok { + // This FileInfo came from a Header (not the OS). Use the + // original Header to populate all remaining fields. + h.Uid = sys.Uid + h.Gid = sys.Gid + h.Uname = sys.Uname + h.Gname = sys.Gname + h.AccessTime = sys.AccessTime + h.ChangeTime = sys.ChangeTime + if sys.Xattrs != nil { + h.Xattrs = make(map[string]string) + for k, v := range sys.Xattrs { + h.Xattrs[k] = v + } + } + if sys.Typeflag == TypeLink { + // hard link + h.Typeflag = TypeLink + h.Size = 0 + h.Linkname = sys.Linkname + } + if sys.PAXRecords != nil { + h.PAXRecords = make(map[string]string) + for k, v := range sys.PAXRecords { + h.PAXRecords[k] = v + } + } + } + if sysStat != nil { + return h, sysStat(fi, h) + } + return h, nil +} + +// isHeaderOnlyType checks if the given type flag is of the type that has no +// data section even if a size is specified. +func isHeaderOnlyType(flag byte) bool { + switch flag { + case TypeLink, TypeSymlink, TypeChar, TypeBlock, TypeDir, TypeFifo: + return true + default: + return false + } +} + +func min(a, b int64) int64 { + if a < b { + return a + } + return b +} diff --git a/vendor/github.com/vbatts/tar-split/archive/tar/format.go b/vendor/github.com/vbatts/tar-split/archive/tar/format.go new file mode 100644 index 0000000000..1f89d0c59a --- /dev/null +++ b/vendor/github.com/vbatts/tar-split/archive/tar/format.go @@ -0,0 +1,303 @@ +// Copyright 2016 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package tar + +import "strings" + +// Format represents the tar archive format. +// +// The original tar format was introduced in Unix V7. +// Since then, there have been multiple competing formats attempting to +// standardize or extend the V7 format to overcome its limitations. +// The most common formats are the USTAR, PAX, and GNU formats, +// each with their own advantages and limitations. +// +// The following table captures the capabilities of each format: +// +// | USTAR | PAX | GNU +// ------------------+--------+-----------+---------- +// Name | 256B | unlimited | unlimited +// Linkname | 100B | unlimited | unlimited +// Size | uint33 | unlimited | uint89 +// Mode | uint21 | uint21 | uint57 +// Uid/Gid | uint21 | unlimited | uint57 +// Uname/Gname | 32B | unlimited | 32B +// ModTime | uint33 | unlimited | int89 +// AccessTime | n/a | unlimited | int89 +// ChangeTime | n/a | unlimited | int89 +// Devmajor/Devminor | uint21 | uint21 | uint57 +// ------------------+--------+-----------+---------- +// string encoding | ASCII | UTF-8 | binary +// sub-second times | no | yes | no +// sparse files | no | yes | yes +// +// The table's upper portion shows the Header fields, where each format reports +// the maximum number of bytes allowed for each string field and +// the integer type used to store each numeric field +// (where timestamps are stored as the number of seconds since the Unix epoch). +// +// The table's lower portion shows specialized features of each format, +// such as supported string encodings, support for sub-second timestamps, +// or support for sparse files. +// +// The Writer currently provides no support for sparse files. +type Format int + +// Constants to identify various tar formats. +const ( + // Deliberately hide the meaning of constants from public API. + _ Format = (1 << iota) / 4 // Sequence of 0, 0, 1, 2, 4, 8, etc... + + // FormatUnknown indicates that the format is unknown. + FormatUnknown + + // The format of the original Unix V7 tar tool prior to standardization. + formatV7 + + // FormatUSTAR represents the USTAR header format defined in POSIX.1-1988. + // + // While this format is compatible with most tar readers, + // the format has several limitations making it unsuitable for some usages. + // Most notably, it cannot support sparse files, files larger than 8GiB, + // filenames larger than 256 characters, and non-ASCII filenames. + // + // Reference: + // http://pubs.opengroup.org/onlinepubs/9699919799/utilities/pax.html#tag_20_92_13_06 + FormatUSTAR + + // FormatPAX represents the PAX header format defined in POSIX.1-2001. + // + // PAX extends USTAR by writing a special file with Typeflag TypeXHeader + // preceding the original header. This file contains a set of key-value + // records, which are used to overcome USTAR's shortcomings, in addition to + // providing the ability to have sub-second resolution for timestamps. + // + // Some newer formats add their own extensions to PAX by defining their + // own keys and assigning certain semantic meaning to the associated values. + // For example, sparse file support in PAX is implemented using keys + // defined by the GNU manual (e.g., "GNU.sparse.map"). + // + // Reference: + // http://pubs.opengroup.org/onlinepubs/009695399/utilities/pax.html + FormatPAX + + // FormatGNU represents the GNU header format. + // + // The GNU header format is older than the USTAR and PAX standards and + // is not compatible with them. The GNU format supports + // arbitrary file sizes, filenames of arbitrary encoding and length, + // sparse files, and other features. + // + // It is recommended that PAX be chosen over GNU unless the target + // application can only parse GNU formatted archives. + // + // Reference: + // https://www.gnu.org/software/tar/manual/html_node/Standard.html + FormatGNU + + // Schily's tar format, which is incompatible with USTAR. + // This does not cover STAR extensions to the PAX format; these fall under + // the PAX format. + formatSTAR + + formatMax +) + +func (f Format) has(f2 Format) bool { return f&f2 != 0 } +func (f *Format) mayBe(f2 Format) { *f |= f2 } +func (f *Format) mayOnlyBe(f2 Format) { *f &= f2 } +func (f *Format) mustNotBe(f2 Format) { *f &^= f2 } + +var formatNames = map[Format]string{ + formatV7: "V7", FormatUSTAR: "USTAR", FormatPAX: "PAX", FormatGNU: "GNU", formatSTAR: "STAR", +} + +func (f Format) String() string { + var ss []string + for f2 := Format(1); f2 < formatMax; f2 <<= 1 { + if f.has(f2) { + ss = append(ss, formatNames[f2]) + } + } + switch len(ss) { + case 0: + return "" + case 1: + return ss[0] + default: + return "(" + strings.Join(ss, " | ") + ")" + } +} + +// Magics used to identify various formats. +const ( + magicGNU, versionGNU = "ustar ", " \x00" + magicUSTAR, versionUSTAR = "ustar\x00", "00" + trailerSTAR = "tar\x00" +) + +// Size constants from various tar specifications. +const ( + blockSize = 512 // Size of each block in a tar stream + nameSize = 100 // Max length of the name field in USTAR format + prefixSize = 155 // Max length of the prefix field in USTAR format +) + +// blockPadding computes the number of bytes needed to pad offset up to the +// nearest block edge where 0 <= n < blockSize. +func blockPadding(offset int64) (n int64) { + return -offset & (blockSize - 1) +} + +var zeroBlock block + +type block [blockSize]byte + +// Convert block to any number of formats. +func (b *block) V7() *headerV7 { return (*headerV7)(b) } +func (b *block) GNU() *headerGNU { return (*headerGNU)(b) } +func (b *block) STAR() *headerSTAR { return (*headerSTAR)(b) } +func (b *block) USTAR() *headerUSTAR { return (*headerUSTAR)(b) } +func (b *block) Sparse() sparseArray { return (sparseArray)(b[:]) } + +// GetFormat checks that the block is a valid tar header based on the checksum. +// It then attempts to guess the specific format based on magic values. +// If the checksum fails, then FormatUnknown is returned. +func (b *block) GetFormat() Format { + // Verify checksum. + var p parser + value := p.parseOctal(b.V7().Chksum()) + chksum1, chksum2 := b.ComputeChecksum() + if p.err != nil || (value != chksum1 && value != chksum2) { + return FormatUnknown + } + + // Guess the magic values. + magic := string(b.USTAR().Magic()) + version := string(b.USTAR().Version()) + trailer := string(b.STAR().Trailer()) + switch { + case magic == magicUSTAR && trailer == trailerSTAR: + return formatSTAR + case magic == magicUSTAR: + return FormatUSTAR | FormatPAX + case magic == magicGNU && version == versionGNU: + return FormatGNU + default: + return formatV7 + } +} + +// SetFormat writes the magic values necessary for specified format +// and then updates the checksum accordingly. +func (b *block) SetFormat(format Format) { + // Set the magic values. + switch { + case format.has(formatV7): + // Do nothing. + case format.has(FormatGNU): + copy(b.GNU().Magic(), magicGNU) + copy(b.GNU().Version(), versionGNU) + case format.has(formatSTAR): + copy(b.STAR().Magic(), magicUSTAR) + copy(b.STAR().Version(), versionUSTAR) + copy(b.STAR().Trailer(), trailerSTAR) + case format.has(FormatUSTAR | FormatPAX): + copy(b.USTAR().Magic(), magicUSTAR) + copy(b.USTAR().Version(), versionUSTAR) + default: + panic("invalid format") + } + + // Update checksum. + // This field is special in that it is terminated by a NULL then space. + var f formatter + field := b.V7().Chksum() + chksum, _ := b.ComputeChecksum() // Possible values are 256..128776 + f.formatOctal(field[:7], chksum) // Never fails since 128776 < 262143 + field[7] = ' ' +} + +// ComputeChecksum computes the checksum for the header block. +// POSIX specifies a sum of the unsigned byte values, but the Sun tar used +// signed byte values. +// We compute and return both. +func (b *block) ComputeChecksum() (unsigned, signed int64) { + for i, c := range b { + if 148 <= i && i < 156 { + c = ' ' // Treat the checksum field itself as all spaces. + } + unsigned += int64(c) + signed += int64(int8(c)) + } + return unsigned, signed +} + +// Reset clears the block with all zeros. +func (b *block) Reset() { + *b = block{} +} + +type headerV7 [blockSize]byte + +func (h *headerV7) Name() []byte { return h[000:][:100] } +func (h *headerV7) Mode() []byte { return h[100:][:8] } +func (h *headerV7) UID() []byte { return h[108:][:8] } +func (h *headerV7) GID() []byte { return h[116:][:8] } +func (h *headerV7) Size() []byte { return h[124:][:12] } +func (h *headerV7) ModTime() []byte { return h[136:][:12] } +func (h *headerV7) Chksum() []byte { return h[148:][:8] } +func (h *headerV7) TypeFlag() []byte { return h[156:][:1] } +func (h *headerV7) LinkName() []byte { return h[157:][:100] } + +type headerGNU [blockSize]byte + +func (h *headerGNU) V7() *headerV7 { return (*headerV7)(h) } +func (h *headerGNU) Magic() []byte { return h[257:][:6] } +func (h *headerGNU) Version() []byte { return h[263:][:2] } +func (h *headerGNU) UserName() []byte { return h[265:][:32] } +func (h *headerGNU) GroupName() []byte { return h[297:][:32] } +func (h *headerGNU) DevMajor() []byte { return h[329:][:8] } +func (h *headerGNU) DevMinor() []byte { return h[337:][:8] } +func (h *headerGNU) AccessTime() []byte { return h[345:][:12] } +func (h *headerGNU) ChangeTime() []byte { return h[357:][:12] } +func (h *headerGNU) Sparse() sparseArray { return (sparseArray)(h[386:][:24*4+1]) } +func (h *headerGNU) RealSize() []byte { return h[483:][:12] } + +type headerSTAR [blockSize]byte + +func (h *headerSTAR) V7() *headerV7 { return (*headerV7)(h) } +func (h *headerSTAR) Magic() []byte { return h[257:][:6] } +func (h *headerSTAR) Version() []byte { return h[263:][:2] } +func (h *headerSTAR) UserName() []byte { return h[265:][:32] } +func (h *headerSTAR) GroupName() []byte { return h[297:][:32] } +func (h *headerSTAR) DevMajor() []byte { return h[329:][:8] } +func (h *headerSTAR) DevMinor() []byte { return h[337:][:8] } +func (h *headerSTAR) Prefix() []byte { return h[345:][:131] } +func (h *headerSTAR) AccessTime() []byte { return h[476:][:12] } +func (h *headerSTAR) ChangeTime() []byte { return h[488:][:12] } +func (h *headerSTAR) Trailer() []byte { return h[508:][:4] } + +type headerUSTAR [blockSize]byte + +func (h *headerUSTAR) V7() *headerV7 { return (*headerV7)(h) } +func (h *headerUSTAR) Magic() []byte { return h[257:][:6] } +func (h *headerUSTAR) Version() []byte { return h[263:][:2] } +func (h *headerUSTAR) UserName() []byte { return h[265:][:32] } +func (h *headerUSTAR) GroupName() []byte { return h[297:][:32] } +func (h *headerUSTAR) DevMajor() []byte { return h[329:][:8] } +func (h *headerUSTAR) DevMinor() []byte { return h[337:][:8] } +func (h *headerUSTAR) Prefix() []byte { return h[345:][:155] } + +type sparseArray []byte + +func (s sparseArray) Entry(i int) sparseElem { return (sparseElem)(s[i*24:]) } +func (s sparseArray) IsExtended() []byte { return s[24*s.MaxEntries():][:1] } +func (s sparseArray) MaxEntries() int { return len(s) / 24 } + +type sparseElem []byte + +func (s sparseElem) Offset() []byte { return s[00:][:12] } +func (s sparseElem) Length() []byte { return s[12:][:12] } diff --git a/vendor/github.com/vbatts/tar-split/archive/tar/reader.go b/vendor/github.com/vbatts/tar-split/archive/tar/reader.go new file mode 100644 index 0000000000..ea64a38207 --- /dev/null +++ b/vendor/github.com/vbatts/tar-split/archive/tar/reader.go @@ -0,0 +1,923 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package tar + +import ( + "bytes" + "io" + "io/ioutil" + "strconv" + "strings" + "time" +) + +// Reader provides sequential access to the contents of a tar archive. +// Reader.Next advances to the next file in the archive (including the first), +// and then Reader can be treated as an io.Reader to access the file's data. +type Reader struct { + r io.Reader + pad int64 // Amount of padding (ignored) after current file entry + curr fileReader // Reader for current file entry + blk block // Buffer to use as temporary local storage + + // err is a persistent error. + // It is only the responsibility of every exported method of Reader to + // ensure that this error is sticky. + err error + + RawAccounting bool // Whether to enable the access needed to reassemble the tar from raw bytes. Some performance/memory hit for this. + rawBytes *bytes.Buffer // last raw bits +} + +type fileReader interface { + io.Reader + fileState + + WriteTo(io.Writer) (int64, error) +} + +// RawBytes accesses the raw bytes of the archive, apart from the file payload itself. +// This includes the header and padding. +// +// This call resets the current rawbytes buffer +// +// Only when RawAccounting is enabled, otherwise this returns nil +func (tr *Reader) RawBytes() []byte { + if !tr.RawAccounting { + return nil + } + if tr.rawBytes == nil { + tr.rawBytes = bytes.NewBuffer(nil) + } + defer tr.rawBytes.Reset() // if we've read them, then flush them. + + return tr.rawBytes.Bytes() + +} + +// NewReader creates a new Reader reading from r. +func NewReader(r io.Reader) *Reader { + return &Reader{r: r, curr: ®FileReader{r, 0}} +} + +// Next advances to the next entry in the tar archive. +// The Header.Size determines how many bytes can be read for the next file. +// Any remaining data in the current file is automatically discarded. +// +// io.EOF is returned at the end of the input. +func (tr *Reader) Next() (*Header, error) { + if tr.err != nil { + return nil, tr.err + } + hdr, err := tr.next() + tr.err = err + return hdr, err +} + +func (tr *Reader) next() (*Header, error) { + var paxHdrs map[string]string + var gnuLongName, gnuLongLink string + + if tr.RawAccounting { + if tr.rawBytes == nil { + tr.rawBytes = bytes.NewBuffer(nil) + } else { + tr.rawBytes.Reset() + } + } + + // Externally, Next iterates through the tar archive as if it is a series of + // files. Internally, the tar format often uses fake "files" to add meta + // data that describes the next file. These meta data "files" should not + // normally be visible to the outside. As such, this loop iterates through + // one or more "header files" until it finds a "normal file". + format := FormatUSTAR | FormatPAX | FormatGNU + for { + // Discard the remainder of the file and any padding. + if err := discard(tr, tr.curr.PhysicalRemaining()); err != nil { + return nil, err + } + n, err := tryReadFull(tr.r, tr.blk[:tr.pad]) + if err != nil { + return nil, err + } + if tr.RawAccounting { + tr.rawBytes.Write(tr.blk[:n]) + } + tr.pad = 0 + + hdr, rawHdr, err := tr.readHeader() + if err != nil { + return nil, err + } + if err := tr.handleRegularFile(hdr); err != nil { + return nil, err + } + format.mayOnlyBe(hdr.Format) + + // Check for PAX/GNU special headers and files. + switch hdr.Typeflag { + case TypeXHeader, TypeXGlobalHeader: + format.mayOnlyBe(FormatPAX) + paxHdrs, err = parsePAX(tr) + if err != nil { + return nil, err + } + if hdr.Typeflag == TypeXGlobalHeader { + mergePAX(hdr, paxHdrs) + return &Header{ + Name: hdr.Name, + Typeflag: hdr.Typeflag, + Xattrs: hdr.Xattrs, + PAXRecords: hdr.PAXRecords, + Format: format, + }, nil + } + continue // This is a meta header affecting the next header + case TypeGNULongName, TypeGNULongLink: + format.mayOnlyBe(FormatGNU) + realname, err := ioutil.ReadAll(tr) + if err != nil { + return nil, err + } + + if tr.RawAccounting { + tr.rawBytes.Write(realname) + } + + var p parser + switch hdr.Typeflag { + case TypeGNULongName: + gnuLongName = p.parseString(realname) + case TypeGNULongLink: + gnuLongLink = p.parseString(realname) + } + continue // This is a meta header affecting the next header + default: + // The old GNU sparse format is handled here since it is technically + // just a regular file with additional attributes. + + if err := mergePAX(hdr, paxHdrs); err != nil { + return nil, err + } + if gnuLongName != "" { + hdr.Name = gnuLongName + } + if gnuLongLink != "" { + hdr.Linkname = gnuLongLink + } + if hdr.Typeflag == TypeRegA { + if strings.HasSuffix(hdr.Name, "/") { + hdr.Typeflag = TypeDir // Legacy archives use trailing slash for directories + } else { + hdr.Typeflag = TypeReg + } + } + + // The extended headers may have updated the size. + // Thus, setup the regFileReader again after merging PAX headers. + if err := tr.handleRegularFile(hdr); err != nil { + return nil, err + } + + // Sparse formats rely on being able to read from the logical data + // section; there must be a preceding call to handleRegularFile. + if err := tr.handleSparseFile(hdr, rawHdr); err != nil { + return nil, err + } + + // Set the final guess at the format. + if format.has(FormatUSTAR) && format.has(FormatPAX) { + format.mayOnlyBe(FormatUSTAR) + } + hdr.Format = format + return hdr, nil // This is a file, so stop + } + } +} + +// handleRegularFile sets up the current file reader and padding such that it +// can only read the following logical data section. It will properly handle +// special headers that contain no data section. +func (tr *Reader) handleRegularFile(hdr *Header) error { + nb := hdr.Size + if isHeaderOnlyType(hdr.Typeflag) { + nb = 0 + } + if nb < 0 { + return ErrHeader + } + + tr.pad = blockPadding(nb) + tr.curr = ®FileReader{r: tr.r, nb: nb} + return nil +} + +// handleSparseFile checks if the current file is a sparse format of any type +// and sets the curr reader appropriately. +func (tr *Reader) handleSparseFile(hdr *Header, rawHdr *block) error { + var spd sparseDatas + var err error + if hdr.Typeflag == TypeGNUSparse { + spd, err = tr.readOldGNUSparseMap(hdr, rawHdr) + } else { + spd, err = tr.readGNUSparsePAXHeaders(hdr) + } + + // If sp is non-nil, then this is a sparse file. + // Note that it is possible for len(sp) == 0. + if err == nil && spd != nil { + if isHeaderOnlyType(hdr.Typeflag) || !validateSparseEntries(spd, hdr.Size) { + return ErrHeader + } + sph := invertSparseEntries(spd, hdr.Size) + tr.curr = &sparseFileReader{tr.curr, sph, 0} + } + return err +} + +// readGNUSparsePAXHeaders checks the PAX headers for GNU sparse headers. +// If they are found, then this function reads the sparse map and returns it. +// This assumes that 0.0 headers have already been converted to 0.1 headers +// by the PAX header parsing logic. +func (tr *Reader) readGNUSparsePAXHeaders(hdr *Header) (sparseDatas, error) { + // Identify the version of GNU headers. + var is1x0 bool + major, minor := hdr.PAXRecords[paxGNUSparseMajor], hdr.PAXRecords[paxGNUSparseMinor] + switch { + case major == "0" && (minor == "0" || minor == "1"): + is1x0 = false + case major == "1" && minor == "0": + is1x0 = true + case major != "" || minor != "": + return nil, nil // Unknown GNU sparse PAX version + case hdr.PAXRecords[paxGNUSparseMap] != "": + is1x0 = false // 0.0 and 0.1 did not have explicit version records, so guess + default: + return nil, nil // Not a PAX format GNU sparse file. + } + hdr.Format.mayOnlyBe(FormatPAX) + + // Update hdr from GNU sparse PAX headers. + if name := hdr.PAXRecords[paxGNUSparseName]; name != "" { + hdr.Name = name + } + size := hdr.PAXRecords[paxGNUSparseSize] + if size == "" { + size = hdr.PAXRecords[paxGNUSparseRealSize] + } + if size != "" { + n, err := strconv.ParseInt(size, 10, 64) + if err != nil { + return nil, ErrHeader + } + hdr.Size = n + } + + // Read the sparse map according to the appropriate format. + if is1x0 { + return readGNUSparseMap1x0(tr.curr) + } + return readGNUSparseMap0x1(hdr.PAXRecords) +} + +// mergePAX merges paxHdrs into hdr for all relevant fields of Header. +func mergePAX(hdr *Header, paxHdrs map[string]string) (err error) { + for k, v := range paxHdrs { + if v == "" { + continue // Keep the original USTAR value + } + var id64 int64 + switch k { + case paxPath: + hdr.Name = v + case paxLinkpath: + hdr.Linkname = v + case paxUname: + hdr.Uname = v + case paxGname: + hdr.Gname = v + case paxUid: + id64, err = strconv.ParseInt(v, 10, 64) + hdr.Uid = int(id64) // Integer overflow possible + case paxGid: + id64, err = strconv.ParseInt(v, 10, 64) + hdr.Gid = int(id64) // Integer overflow possible + case paxAtime: + hdr.AccessTime, err = parsePAXTime(v) + case paxMtime: + hdr.ModTime, err = parsePAXTime(v) + case paxCtime: + hdr.ChangeTime, err = parsePAXTime(v) + case paxSize: + hdr.Size, err = strconv.ParseInt(v, 10, 64) + default: + if strings.HasPrefix(k, paxSchilyXattr) { + if hdr.Xattrs == nil { + hdr.Xattrs = make(map[string]string) + } + hdr.Xattrs[k[len(paxSchilyXattr):]] = v + } + } + if err != nil { + return ErrHeader + } + } + hdr.PAXRecords = paxHdrs + return nil +} + +// parsePAX parses PAX headers. +// If an extended header (type 'x') is invalid, ErrHeader is returned +func parsePAX(r io.Reader) (map[string]string, error) { + buf, err := ioutil.ReadAll(r) + if err != nil { + return nil, err + } + // leaving this function for io.Reader makes it more testable + if tr, ok := r.(*Reader); ok && tr.RawAccounting { + if _, err = tr.rawBytes.Write(buf); err != nil { + return nil, err + } + } + sbuf := string(buf) + + // For GNU PAX sparse format 0.0 support. + // This function transforms the sparse format 0.0 headers into format 0.1 + // headers since 0.0 headers were not PAX compliant. + var sparseMap []string + + paxHdrs := make(map[string]string) + for len(sbuf) > 0 { + key, value, residual, err := parsePAXRecord(sbuf) + if err != nil { + return nil, ErrHeader + } + sbuf = residual + + switch key { + case paxGNUSparseOffset, paxGNUSparseNumBytes: + // Validate sparse header order and value. + if (len(sparseMap)%2 == 0 && key != paxGNUSparseOffset) || + (len(sparseMap)%2 == 1 && key != paxGNUSparseNumBytes) || + strings.Contains(value, ",") { + return nil, ErrHeader + } + sparseMap = append(sparseMap, value) + default: + paxHdrs[key] = value + } + } + if len(sparseMap) > 0 { + paxHdrs[paxGNUSparseMap] = strings.Join(sparseMap, ",") + } + return paxHdrs, nil +} + +// readHeader reads the next block header and assumes that the underlying reader +// is already aligned to a block boundary. It returns the raw block of the +// header in case further processing is required. +// +// The err will be set to io.EOF only when one of the following occurs: +// * Exactly 0 bytes are read and EOF is hit. +// * Exactly 1 block of zeros is read and EOF is hit. +// * At least 2 blocks of zeros are read. +func (tr *Reader) readHeader() (*Header, *block, error) { + // Two blocks of zero bytes marks the end of the archive. + n, err := io.ReadFull(tr.r, tr.blk[:]) + if tr.RawAccounting && (err == nil || err == io.EOF) { + tr.rawBytes.Write(tr.blk[:n]) + } + if err != nil { + return nil, nil, err // EOF is okay here; exactly 0 bytes read + } + + if bytes.Equal(tr.blk[:], zeroBlock[:]) { + n, err = io.ReadFull(tr.r, tr.blk[:]) + if tr.RawAccounting && (err == nil || err == io.EOF) { + tr.rawBytes.Write(tr.blk[:n]) + } + if err != nil { + return nil, nil, err // EOF is okay here; exactly 1 block of zeros read + } + if bytes.Equal(tr.blk[:], zeroBlock[:]) { + return nil, nil, io.EOF // normal EOF; exactly 2 block of zeros read + } + return nil, nil, ErrHeader // Zero block and then non-zero block + } + + // Verify the header matches a known format. + format := tr.blk.GetFormat() + if format == FormatUnknown { + return nil, nil, ErrHeader + } + + var p parser + hdr := new(Header) + + // Unpack the V7 header. + v7 := tr.blk.V7() + hdr.Typeflag = v7.TypeFlag()[0] + hdr.Name = p.parseString(v7.Name()) + hdr.Linkname = p.parseString(v7.LinkName()) + hdr.Size = p.parseNumeric(v7.Size()) + hdr.Mode = p.parseNumeric(v7.Mode()) + hdr.Uid = int(p.parseNumeric(v7.UID())) + hdr.Gid = int(p.parseNumeric(v7.GID())) + hdr.ModTime = time.Unix(p.parseNumeric(v7.ModTime()), 0) + + // Unpack format specific fields. + if format > formatV7 { + ustar := tr.blk.USTAR() + hdr.Uname = p.parseString(ustar.UserName()) + hdr.Gname = p.parseString(ustar.GroupName()) + hdr.Devmajor = p.parseNumeric(ustar.DevMajor()) + hdr.Devminor = p.parseNumeric(ustar.DevMinor()) + + var prefix string + switch { + case format.has(FormatUSTAR | FormatPAX): + hdr.Format = format + ustar := tr.blk.USTAR() + prefix = p.parseString(ustar.Prefix()) + + // For Format detection, check if block is properly formatted since + // the parser is more liberal than what USTAR actually permits. + notASCII := func(r rune) bool { return r >= 0x80 } + if bytes.IndexFunc(tr.blk[:], notASCII) >= 0 { + hdr.Format = FormatUnknown // Non-ASCII characters in block. + } + nul := func(b []byte) bool { return int(b[len(b)-1]) == 0 } + if !(nul(v7.Size()) && nul(v7.Mode()) && nul(v7.UID()) && nul(v7.GID()) && + nul(v7.ModTime()) && nul(ustar.DevMajor()) && nul(ustar.DevMinor())) { + hdr.Format = FormatUnknown // Numeric fields must end in NUL + } + case format.has(formatSTAR): + star := tr.blk.STAR() + prefix = p.parseString(star.Prefix()) + hdr.AccessTime = time.Unix(p.parseNumeric(star.AccessTime()), 0) + hdr.ChangeTime = time.Unix(p.parseNumeric(star.ChangeTime()), 0) + case format.has(FormatGNU): + hdr.Format = format + var p2 parser + gnu := tr.blk.GNU() + if b := gnu.AccessTime(); b[0] != 0 { + hdr.AccessTime = time.Unix(p2.parseNumeric(b), 0) + } + if b := gnu.ChangeTime(); b[0] != 0 { + hdr.ChangeTime = time.Unix(p2.parseNumeric(b), 0) + } + + // Prior to Go1.8, the Writer had a bug where it would output + // an invalid tar file in certain rare situations because the logic + // incorrectly believed that the old GNU format had a prefix field. + // This is wrong and leads to an output file that mangles the + // atime and ctime fields, which are often left unused. + // + // In order to continue reading tar files created by former, buggy + // versions of Go, we skeptically parse the atime and ctime fields. + // If we are unable to parse them and the prefix field looks like + // an ASCII string, then we fallback on the pre-Go1.8 behavior + // of treating these fields as the USTAR prefix field. + // + // Note that this will not use the fallback logic for all possible + // files generated by a pre-Go1.8 toolchain. If the generated file + // happened to have a prefix field that parses as valid + // atime and ctime fields (e.g., when they are valid octal strings), + // then it is impossible to distinguish between an valid GNU file + // and an invalid pre-Go1.8 file. + // + // See https://golang.org/issues/12594 + // See https://golang.org/issues/21005 + if p2.err != nil { + hdr.AccessTime, hdr.ChangeTime = time.Time{}, time.Time{} + ustar := tr.blk.USTAR() + if s := p.parseString(ustar.Prefix()); isASCII(s) { + prefix = s + } + hdr.Format = FormatUnknown // Buggy file is not GNU + } + } + if len(prefix) > 0 { + hdr.Name = prefix + "/" + hdr.Name + } + } + return hdr, &tr.blk, p.err +} + +// readOldGNUSparseMap reads the sparse map from the old GNU sparse format. +// The sparse map is stored in the tar header if it's small enough. +// If it's larger than four entries, then one or more extension headers are used +// to store the rest of the sparse map. +// +// The Header.Size does not reflect the size of any extended headers used. +// Thus, this function will read from the raw io.Reader to fetch extra headers. +// This method mutates blk in the process. +func (tr *Reader) readOldGNUSparseMap(hdr *Header, blk *block) (sparseDatas, error) { + // Make sure that the input format is GNU. + // Unfortunately, the STAR format also has a sparse header format that uses + // the same type flag but has a completely different layout. + if blk.GetFormat() != FormatGNU { + return nil, ErrHeader + } + hdr.Format.mayOnlyBe(FormatGNU) + + var p parser + hdr.Size = p.parseNumeric(blk.GNU().RealSize()) + if p.err != nil { + return nil, p.err + } + s := blk.GNU().Sparse() + spd := make(sparseDatas, 0, s.MaxEntries()) + for { + for i := 0; i < s.MaxEntries(); i++ { + // This termination condition is identical to GNU and BSD tar. + if s.Entry(i).Offset()[0] == 0x00 { + break // Don't return, need to process extended headers (even if empty) + } + offset := p.parseNumeric(s.Entry(i).Offset()) + length := p.parseNumeric(s.Entry(i).Length()) + if p.err != nil { + return nil, p.err + } + spd = append(spd, sparseEntry{Offset: offset, Length: length}) + } + + if s.IsExtended()[0] > 0 { + // There are more entries. Read an extension header and parse its entries. + if _, err := mustReadFull(tr.r, blk[:]); err != nil { + return nil, err + } + if tr.RawAccounting { + tr.rawBytes.Write(blk[:]) + } + s = blk.Sparse() + continue + } + return spd, nil // Done + } +} + +// readGNUSparseMap1x0 reads the sparse map as stored in GNU's PAX sparse format +// version 1.0. The format of the sparse map consists of a series of +// newline-terminated numeric fields. The first field is the number of entries +// and is always present. Following this are the entries, consisting of two +// fields (offset, length). This function must stop reading at the end +// boundary of the block containing the last newline. +// +// Note that the GNU manual says that numeric values should be encoded in octal +// format. However, the GNU tar utility itself outputs these values in decimal. +// As such, this library treats values as being encoded in decimal. +func readGNUSparseMap1x0(r io.Reader) (sparseDatas, error) { + var ( + cntNewline int64 + buf bytes.Buffer + blk block + ) + + // feedTokens copies data in blocks from r into buf until there are + // at least cnt newlines in buf. It will not read more blocks than needed. + feedTokens := func(n int64) error { + for cntNewline < n { + if _, err := mustReadFull(r, blk[:]); err != nil { + return err + } + buf.Write(blk[:]) + for _, c := range blk { + if c == '\n' { + cntNewline++ + } + } + } + return nil + } + + // nextToken gets the next token delimited by a newline. This assumes that + // at least one newline exists in the buffer. + nextToken := func() string { + cntNewline-- + tok, _ := buf.ReadString('\n') + return strings.TrimRight(tok, "\n") + } + + // Parse for the number of entries. + // Use integer overflow resistant math to check this. + if err := feedTokens(1); err != nil { + return nil, err + } + numEntries, err := strconv.ParseInt(nextToken(), 10, 0) // Intentionally parse as native int + if err != nil || numEntries < 0 || int(2*numEntries) < int(numEntries) { + return nil, ErrHeader + } + + // Parse for all member entries. + // numEntries is trusted after this since a potential attacker must have + // committed resources proportional to what this library used. + if err := feedTokens(2 * numEntries); err != nil { + return nil, err + } + spd := make(sparseDatas, 0, numEntries) + for i := int64(0); i < numEntries; i++ { + offset, err1 := strconv.ParseInt(nextToken(), 10, 64) + length, err2 := strconv.ParseInt(nextToken(), 10, 64) + if err1 != nil || err2 != nil { + return nil, ErrHeader + } + spd = append(spd, sparseEntry{Offset: offset, Length: length}) + } + return spd, nil +} + +// readGNUSparseMap0x1 reads the sparse map as stored in GNU's PAX sparse format +// version 0.1. The sparse map is stored in the PAX headers. +func readGNUSparseMap0x1(paxHdrs map[string]string) (sparseDatas, error) { + // Get number of entries. + // Use integer overflow resistant math to check this. + numEntriesStr := paxHdrs[paxGNUSparseNumBlocks] + numEntries, err := strconv.ParseInt(numEntriesStr, 10, 0) // Intentionally parse as native int + if err != nil || numEntries < 0 || int(2*numEntries) < int(numEntries) { + return nil, ErrHeader + } + + // There should be two numbers in sparseMap for each entry. + sparseMap := strings.Split(paxHdrs[paxGNUSparseMap], ",") + if len(sparseMap) == 1 && sparseMap[0] == "" { + sparseMap = sparseMap[:0] + } + if int64(len(sparseMap)) != 2*numEntries { + return nil, ErrHeader + } + + // Loop through the entries in the sparse map. + // numEntries is trusted now. + spd := make(sparseDatas, 0, numEntries) + for len(sparseMap) >= 2 { + offset, err1 := strconv.ParseInt(sparseMap[0], 10, 64) + length, err2 := strconv.ParseInt(sparseMap[1], 10, 64) + if err1 != nil || err2 != nil { + return nil, ErrHeader + } + spd = append(spd, sparseEntry{Offset: offset, Length: length}) + sparseMap = sparseMap[2:] + } + return spd, nil +} + +// Read reads from the current file in the tar archive. +// It returns (0, io.EOF) when it reaches the end of that file, +// until Next is called to advance to the next file. +// +// If the current file is sparse, then the regions marked as a hole +// are read back as NUL-bytes. +// +// Calling Read on special types like TypeLink, TypeSymlink, TypeChar, +// TypeBlock, TypeDir, and TypeFifo returns (0, io.EOF) regardless of what +// the Header.Size claims. +func (tr *Reader) Read(b []byte) (int, error) { + if tr.err != nil { + return 0, tr.err + } + n, err := tr.curr.Read(b) + if err != nil && err != io.EOF { + tr.err = err + } + return n, err +} + +// writeTo writes the content of the current file to w. +// The bytes written matches the number of remaining bytes in the current file. +// +// If the current file is sparse and w is an io.WriteSeeker, +// then writeTo uses Seek to skip past holes defined in Header.SparseHoles, +// assuming that skipped regions are filled with NULs. +// This always writes the last byte to ensure w is the right size. +// +// TODO(dsnet): Re-export this when adding sparse file support. +// See https://golang.org/issue/22735 +func (tr *Reader) writeTo(w io.Writer) (int64, error) { + if tr.err != nil { + return 0, tr.err + } + n, err := tr.curr.WriteTo(w) + if err != nil { + tr.err = err + } + return n, err +} + +// regFileReader is a fileReader for reading data from a regular file entry. +type regFileReader struct { + r io.Reader // Underlying Reader + nb int64 // Number of remaining bytes to read +} + +func (fr *regFileReader) Read(b []byte) (n int, err error) { + if int64(len(b)) > fr.nb { + b = b[:fr.nb] + } + if len(b) > 0 { + n, err = fr.r.Read(b) + fr.nb -= int64(n) + } + switch { + case err == io.EOF && fr.nb > 0: + return n, io.ErrUnexpectedEOF + case err == nil && fr.nb == 0: + return n, io.EOF + default: + return n, err + } +} + +func (fr *regFileReader) WriteTo(w io.Writer) (int64, error) { + return io.Copy(w, struct{ io.Reader }{fr}) +} + +func (fr regFileReader) LogicalRemaining() int64 { + return fr.nb +} + +func (fr regFileReader) PhysicalRemaining() int64 { + return fr.nb +} + +// sparseFileReader is a fileReader for reading data from a sparse file entry. +type sparseFileReader struct { + fr fileReader // Underlying fileReader + sp sparseHoles // Normalized list of sparse holes + pos int64 // Current position in sparse file +} + +func (sr *sparseFileReader) Read(b []byte) (n int, err error) { + finished := int64(len(b)) >= sr.LogicalRemaining() + if finished { + b = b[:sr.LogicalRemaining()] + } + + b0 := b + endPos := sr.pos + int64(len(b)) + for endPos > sr.pos && err == nil { + var nf int // Bytes read in fragment + holeStart, holeEnd := sr.sp[0].Offset, sr.sp[0].endOffset() + if sr.pos < holeStart { // In a data fragment + bf := b[:min(int64(len(b)), holeStart-sr.pos)] + nf, err = tryReadFull(sr.fr, bf) + } else { // In a hole fragment + bf := b[:min(int64(len(b)), holeEnd-sr.pos)] + nf, err = tryReadFull(zeroReader{}, bf) + } + b = b[nf:] + sr.pos += int64(nf) + if sr.pos >= holeEnd && len(sr.sp) > 1 { + sr.sp = sr.sp[1:] // Ensure last fragment always remains + } + } + + n = len(b0) - len(b) + switch { + case err == io.EOF: + return n, errMissData // Less data in dense file than sparse file + case err != nil: + return n, err + case sr.LogicalRemaining() == 0 && sr.PhysicalRemaining() > 0: + return n, errUnrefData // More data in dense file than sparse file + case finished: + return n, io.EOF + default: + return n, nil + } +} + +func (sr *sparseFileReader) WriteTo(w io.Writer) (n int64, err error) { + ws, ok := w.(io.WriteSeeker) + if ok { + if _, err := ws.Seek(0, io.SeekCurrent); err != nil { + ok = false // Not all io.Seeker can really seek + } + } + if !ok { + return io.Copy(w, struct{ io.Reader }{sr}) + } + + var writeLastByte bool + pos0 := sr.pos + for sr.LogicalRemaining() > 0 && !writeLastByte && err == nil { + var nf int64 // Size of fragment + holeStart, holeEnd := sr.sp[0].Offset, sr.sp[0].endOffset() + if sr.pos < holeStart { // In a data fragment + nf = holeStart - sr.pos + nf, err = io.CopyN(ws, sr.fr, nf) + } else { // In a hole fragment + nf = holeEnd - sr.pos + if sr.PhysicalRemaining() == 0 { + writeLastByte = true + nf-- + } + _, err = ws.Seek(nf, io.SeekCurrent) + } + sr.pos += nf + if sr.pos >= holeEnd && len(sr.sp) > 1 { + sr.sp = sr.sp[1:] // Ensure last fragment always remains + } + } + + // If the last fragment is a hole, then seek to 1-byte before EOF, and + // write a single byte to ensure the file is the right size. + if writeLastByte && err == nil { + _, err = ws.Write([]byte{0}) + sr.pos++ + } + + n = sr.pos - pos0 + switch { + case err == io.EOF: + return n, errMissData // Less data in dense file than sparse file + case err != nil: + return n, err + case sr.LogicalRemaining() == 0 && sr.PhysicalRemaining() > 0: + return n, errUnrefData // More data in dense file than sparse file + default: + return n, nil + } +} + +func (sr sparseFileReader) LogicalRemaining() int64 { + return sr.sp[len(sr.sp)-1].endOffset() - sr.pos +} +func (sr sparseFileReader) PhysicalRemaining() int64 { + return sr.fr.PhysicalRemaining() +} + +type zeroReader struct{} + +func (zeroReader) Read(b []byte) (int, error) { + for i := range b { + b[i] = 0 + } + return len(b), nil +} + +// mustReadFull is like io.ReadFull except it returns +// io.ErrUnexpectedEOF when io.EOF is hit before len(b) bytes are read. +func mustReadFull(r io.Reader, b []byte) (int, error) { + n, err := tryReadFull(r, b) + if err == io.EOF { + err = io.ErrUnexpectedEOF + } + return n, err +} + +// tryReadFull is like io.ReadFull except it returns +// io.EOF when it is hit before len(b) bytes are read. +func tryReadFull(r io.Reader, b []byte) (n int, err error) { + for len(b) > n && err == nil { + var nn int + nn, err = r.Read(b[n:]) + n += nn + } + if len(b) == n && err == io.EOF { + err = nil + } + return n, err +} + +// discard skips n bytes in r, reporting an error if unable to do so. +func discard(tr *Reader, n int64) error { + var seekSkipped, copySkipped int64 + var err error + r := tr.r + if tr.RawAccounting { + + copySkipped, err = io.CopyN(tr.rawBytes, tr.r, n) + goto out + } + + // If possible, Seek to the last byte before the end of the data section. + // Do this because Seek is often lazy about reporting errors; this will mask + // the fact that the stream may be truncated. We can rely on the + // io.CopyN done shortly afterwards to trigger any IO errors. + if sr, ok := r.(io.Seeker); ok && n > 1 { + // Not all io.Seeker can actually Seek. For example, os.Stdin implements + // io.Seeker, but calling Seek always returns an error and performs + // no action. Thus, we try an innocent seek to the current position + // to see if Seek is really supported. + pos1, err := sr.Seek(0, io.SeekCurrent) + if pos1 >= 0 && err == nil { + // Seek seems supported, so perform the real Seek. + pos2, err := sr.Seek(n-1, io.SeekCurrent) + if pos2 < 0 || err != nil { + return err + } + seekSkipped = pos2 - pos1 + } + } + + copySkipped, err = io.CopyN(ioutil.Discard, r, n-seekSkipped) +out: + if err == io.EOF && seekSkipped+copySkipped < n { + err = io.ErrUnexpectedEOF + } + return err +} diff --git a/vendor/github.com/vbatts/tar-split/archive/tar/stat_actime1.go b/vendor/github.com/vbatts/tar-split/archive/tar/stat_actime1.go new file mode 100644 index 0000000000..cf9cc79c59 --- /dev/null +++ b/vendor/github.com/vbatts/tar-split/archive/tar/stat_actime1.go @@ -0,0 +1,20 @@ +// Copyright 2012 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build linux dragonfly openbsd solaris + +package tar + +import ( + "syscall" + "time" +) + +func statAtime(st *syscall.Stat_t) time.Time { + return time.Unix(st.Atim.Unix()) +} + +func statCtime(st *syscall.Stat_t) time.Time { + return time.Unix(st.Ctim.Unix()) +} diff --git a/vendor/github.com/vbatts/tar-split/archive/tar/stat_actime2.go b/vendor/github.com/vbatts/tar-split/archive/tar/stat_actime2.go new file mode 100644 index 0000000000..6f17dbe307 --- /dev/null +++ b/vendor/github.com/vbatts/tar-split/archive/tar/stat_actime2.go @@ -0,0 +1,20 @@ +// Copyright 2012 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build darwin freebsd netbsd + +package tar + +import ( + "syscall" + "time" +) + +func statAtime(st *syscall.Stat_t) time.Time { + return time.Unix(st.Atimespec.Unix()) +} + +func statCtime(st *syscall.Stat_t) time.Time { + return time.Unix(st.Ctimespec.Unix()) +} diff --git a/vendor/github.com/vbatts/tar-split/archive/tar/stat_unix.go b/vendor/github.com/vbatts/tar-split/archive/tar/stat_unix.go new file mode 100644 index 0000000000..868105f338 --- /dev/null +++ b/vendor/github.com/vbatts/tar-split/archive/tar/stat_unix.go @@ -0,0 +1,96 @@ +// Copyright 2012 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build linux darwin dragonfly freebsd openbsd netbsd solaris + +package tar + +import ( + "os" + "os/user" + "runtime" + "strconv" + "sync" + "syscall" +) + +func init() { + sysStat = statUnix +} + +// userMap and groupMap caches UID and GID lookups for performance reasons. +// The downside is that renaming uname or gname by the OS never takes effect. +var userMap, groupMap sync.Map // map[int]string + +func statUnix(fi os.FileInfo, h *Header) error { + sys, ok := fi.Sys().(*syscall.Stat_t) + if !ok { + return nil + } + h.Uid = int(sys.Uid) + h.Gid = int(sys.Gid) + + // Best effort at populating Uname and Gname. + // The os/user functions may fail for any number of reasons + // (not implemented on that platform, cgo not enabled, etc). + if u, ok := userMap.Load(h.Uid); ok { + h.Uname = u.(string) + } else if u, err := user.LookupId(strconv.Itoa(h.Uid)); err == nil { + h.Uname = u.Username + userMap.Store(h.Uid, h.Uname) + } + if g, ok := groupMap.Load(h.Gid); ok { + h.Gname = g.(string) + } else if g, err := user.LookupGroupId(strconv.Itoa(h.Gid)); err == nil { + h.Gname = g.Name + groupMap.Store(h.Gid, h.Gname) + } + + h.AccessTime = statAtime(sys) + h.ChangeTime = statCtime(sys) + + // Best effort at populating Devmajor and Devminor. + if h.Typeflag == TypeChar || h.Typeflag == TypeBlock { + dev := uint64(sys.Rdev) // May be int32 or uint32 + switch runtime.GOOS { + case "linux": + // Copied from golang.org/x/sys/unix/dev_linux.go. + major := uint32((dev & 0x00000000000fff00) >> 8) + major |= uint32((dev & 0xfffff00000000000) >> 32) + minor := uint32((dev & 0x00000000000000ff) >> 0) + minor |= uint32((dev & 0x00000ffffff00000) >> 12) + h.Devmajor, h.Devminor = int64(major), int64(minor) + case "darwin": + // Copied from golang.org/x/sys/unix/dev_darwin.go. + major := uint32((dev >> 24) & 0xff) + minor := uint32(dev & 0xffffff) + h.Devmajor, h.Devminor = int64(major), int64(minor) + case "dragonfly": + // Copied from golang.org/x/sys/unix/dev_dragonfly.go. + major := uint32((dev >> 8) & 0xff) + minor := uint32(dev & 0xffff00ff) + h.Devmajor, h.Devminor = int64(major), int64(minor) + case "freebsd": + // Copied from golang.org/x/sys/unix/dev_freebsd.go. + major := uint32((dev >> 8) & 0xff) + minor := uint32(dev & 0xffff00ff) + h.Devmajor, h.Devminor = int64(major), int64(minor) + case "netbsd": + // Copied from golang.org/x/sys/unix/dev_netbsd.go. + major := uint32((dev & 0x000fff00) >> 8) + minor := uint32((dev & 0x000000ff) >> 0) + minor |= uint32((dev & 0xfff00000) >> 12) + h.Devmajor, h.Devminor = int64(major), int64(minor) + case "openbsd": + // Copied from golang.org/x/sys/unix/dev_openbsd.go. + major := uint32((dev & 0x0000ff00) >> 8) + minor := uint32((dev & 0x000000ff) >> 0) + minor |= uint32((dev & 0xffff0000) >> 8) + h.Devmajor, h.Devminor = int64(major), int64(minor) + default: + // TODO: Implement solaris (see https://golang.org/issue/8106) + } + } + return nil +} diff --git a/vendor/github.com/vbatts/tar-split/archive/tar/strconv.go b/vendor/github.com/vbatts/tar-split/archive/tar/strconv.go new file mode 100644 index 0000000000..d144485a49 --- /dev/null +++ b/vendor/github.com/vbatts/tar-split/archive/tar/strconv.go @@ -0,0 +1,326 @@ +// Copyright 2016 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package tar + +import ( + "bytes" + "fmt" + "strconv" + "strings" + "time" +) + +// hasNUL reports whether the NUL character exists within s. +func hasNUL(s string) bool { + return strings.IndexByte(s, 0) >= 0 +} + +// isASCII reports whether the input is an ASCII C-style string. +func isASCII(s string) bool { + for _, c := range s { + if c >= 0x80 || c == 0x00 { + return false + } + } + return true +} + +// toASCII converts the input to an ASCII C-style string. +// This a best effort conversion, so invalid characters are dropped. +func toASCII(s string) string { + if isASCII(s) { + return s + } + b := make([]byte, 0, len(s)) + for _, c := range s { + if c < 0x80 && c != 0x00 { + b = append(b, byte(c)) + } + } + return string(b) +} + +type parser struct { + err error // Last error seen +} + +type formatter struct { + err error // Last error seen +} + +// parseString parses bytes as a NUL-terminated C-style string. +// If a NUL byte is not found then the whole slice is returned as a string. +func (*parser) parseString(b []byte) string { + if i := bytes.IndexByte(b, 0); i >= 0 { + return string(b[:i]) + } + return string(b) +} + +// formatString copies s into b, NUL-terminating if possible. +func (f *formatter) formatString(b []byte, s string) { + if len(s) > len(b) { + f.err = ErrFieldTooLong + } + copy(b, s) + if len(s) < len(b) { + b[len(s)] = 0 + } + + // Some buggy readers treat regular files with a trailing slash + // in the V7 path field as a directory even though the full path + // recorded elsewhere (e.g., via PAX record) contains no trailing slash. + if len(s) > len(b) && b[len(b)-1] == '/' { + n := len(strings.TrimRight(s[:len(b)], "/")) + b[n] = 0 // Replace trailing slash with NUL terminator + } +} + +// fitsInBase256 reports whether x can be encoded into n bytes using base-256 +// encoding. Unlike octal encoding, base-256 encoding does not require that the +// string ends with a NUL character. Thus, all n bytes are available for output. +// +// If operating in binary mode, this assumes strict GNU binary mode; which means +// that the first byte can only be either 0x80 or 0xff. Thus, the first byte is +// equivalent to the sign bit in two's complement form. +func fitsInBase256(n int, x int64) bool { + binBits := uint(n-1) * 8 + return n >= 9 || (x >= -1< 0 && b[0]&0x80 != 0 { + // Handling negative numbers relies on the following identity: + // -a-1 == ^a + // + // If the number is negative, we use an inversion mask to invert the + // data bytes and treat the value as an unsigned number. + var inv byte // 0x00 if positive or zero, 0xff if negative + if b[0]&0x40 != 0 { + inv = 0xff + } + + var x uint64 + for i, c := range b { + c ^= inv // Inverts c only if inv is 0xff, otherwise does nothing + if i == 0 { + c &= 0x7f // Ignore signal bit in first byte + } + if (x >> 56) > 0 { + p.err = ErrHeader // Integer overflow + return 0 + } + x = x<<8 | uint64(c) + } + if (x >> 63) > 0 { + p.err = ErrHeader // Integer overflow + return 0 + } + if inv == 0xff { + return ^int64(x) + } + return int64(x) + } + + // Normal case is base-8 (octal) format. + return p.parseOctal(b) +} + +// formatNumeric encodes x into b using base-8 (octal) encoding if possible. +// Otherwise it will attempt to use base-256 (binary) encoding. +func (f *formatter) formatNumeric(b []byte, x int64) { + if fitsInOctal(len(b), x) { + f.formatOctal(b, x) + return + } + + if fitsInBase256(len(b), x) { + for i := len(b) - 1; i >= 0; i-- { + b[i] = byte(x) + x >>= 8 + } + b[0] |= 0x80 // Highest bit indicates binary format + return + } + + f.formatOctal(b, 0) // Last resort, just write zero + f.err = ErrFieldTooLong +} + +func (p *parser) parseOctal(b []byte) int64 { + // Because unused fields are filled with NULs, we need + // to skip leading NULs. Fields may also be padded with + // spaces or NULs. + // So we remove leading and trailing NULs and spaces to + // be sure. + b = bytes.Trim(b, " \x00") + + if len(b) == 0 { + return 0 + } + x, perr := strconv.ParseUint(p.parseString(b), 8, 64) + if perr != nil { + p.err = ErrHeader + } + return int64(x) +} + +func (f *formatter) formatOctal(b []byte, x int64) { + if !fitsInOctal(len(b), x) { + x = 0 // Last resort, just write zero + f.err = ErrFieldTooLong + } + + s := strconv.FormatInt(x, 8) + // Add leading zeros, but leave room for a NUL. + if n := len(b) - len(s) - 1; n > 0 { + s = strings.Repeat("0", n) + s + } + f.formatString(b, s) +} + +// fitsInOctal reports whether the integer x fits in a field n-bytes long +// using octal encoding with the appropriate NUL terminator. +func fitsInOctal(n int, x int64) bool { + octBits := uint(n-1) * 3 + return x >= 0 && (n >= 22 || x < 1<= 0 { + ss, sn = s[:pos], s[pos+1:] + } + + // Parse the seconds. + secs, err := strconv.ParseInt(ss, 10, 64) + if err != nil { + return time.Time{}, ErrHeader + } + if len(sn) == 0 { + return time.Unix(secs, 0), nil // No sub-second values + } + + // Parse the nanoseconds. + if strings.Trim(sn, "0123456789") != "" { + return time.Time{}, ErrHeader + } + if len(sn) < maxNanoSecondDigits { + sn += strings.Repeat("0", maxNanoSecondDigits-len(sn)) // Right pad + } else { + sn = sn[:maxNanoSecondDigits] // Right truncate + } + nsecs, _ := strconv.ParseInt(sn, 10, 64) // Must succeed + if len(ss) > 0 && ss[0] == '-' { + return time.Unix(secs, -1*nsecs), nil // Negative correction + } + return time.Unix(secs, nsecs), nil +} + +// formatPAXTime converts ts into a time of the form %d.%d as described in the +// PAX specification. This function is capable of negative timestamps. +func formatPAXTime(ts time.Time) (s string) { + secs, nsecs := ts.Unix(), ts.Nanosecond() + if nsecs == 0 { + return strconv.FormatInt(secs, 10) + } + + // If seconds is negative, then perform correction. + sign := "" + if secs < 0 { + sign = "-" // Remember sign + secs = -(secs + 1) // Add a second to secs + nsecs = -(nsecs - 1E9) // Take that second away from nsecs + } + return strings.TrimRight(fmt.Sprintf("%s%d.%09d", sign, secs, nsecs), "0") +} + +// parsePAXRecord parses the input PAX record string into a key-value pair. +// If parsing is successful, it will slice off the currently read record and +// return the remainder as r. +func parsePAXRecord(s string) (k, v, r string, err error) { + // The size field ends at the first space. + sp := strings.IndexByte(s, ' ') + if sp == -1 { + return "", "", s, ErrHeader + } + + // Parse the first token as a decimal integer. + n, perr := strconv.ParseInt(s[:sp], 10, 0) // Intentionally parse as native int + if perr != nil || n < 5 || int64(len(s)) < n { + return "", "", s, ErrHeader + } + + // Extract everything between the space and the final newline. + rec, nl, rem := s[sp+1:n-1], s[n-1:n], s[n:] + if nl != "\n" { + return "", "", s, ErrHeader + } + + // The first equals separates the key from the value. + eq := strings.IndexByte(rec, '=') + if eq == -1 { + return "", "", s, ErrHeader + } + k, v = rec[:eq], rec[eq+1:] + + if !validPAXRecord(k, v) { + return "", "", s, ErrHeader + } + return k, v, rem, nil +} + +// formatPAXRecord formats a single PAX record, prefixing it with the +// appropriate length. +func formatPAXRecord(k, v string) (string, error) { + if !validPAXRecord(k, v) { + return "", ErrHeader + } + + const padding = 3 // Extra padding for ' ', '=', and '\n' + size := len(k) + len(v) + padding + size += len(strconv.Itoa(size)) + record := strconv.Itoa(size) + " " + k + "=" + v + "\n" + + // Final adjustment if adding size field increased the record size. + if len(record) != size { + size = len(record) + record = strconv.Itoa(size) + " " + k + "=" + v + "\n" + } + return record, nil +} + +// validPAXRecord reports whether the key-value pair is valid where each +// record is formatted as: +// "%d %s=%s\n" % (size, key, value) +// +// Keys and values should be UTF-8, but the number of bad writers out there +// forces us to be a more liberal. +// Thus, we only reject all keys with NUL, and only reject NULs in values +// for the PAX version of the USTAR string fields. +// The key must not contain an '=' character. +func validPAXRecord(k, v string) bool { + if k == "" || strings.IndexByte(k, '=') >= 0 { + return false + } + switch k { + case paxPath, paxLinkpath, paxUname, paxGname: + return !hasNUL(v) + default: + return !hasNUL(k) + } +} diff --git a/vendor/github.com/vbatts/tar-split/archive/tar/writer.go b/vendor/github.com/vbatts/tar-split/archive/tar/writer.go new file mode 100644 index 0000000000..e80498d03e --- /dev/null +++ b/vendor/github.com/vbatts/tar-split/archive/tar/writer.go @@ -0,0 +1,653 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package tar + +import ( + "fmt" + "io" + "path" + "sort" + "strings" + "time" +) + +// Writer provides sequential writing of a tar archive. +// Write.WriteHeader begins a new file with the provided Header, +// and then Writer can be treated as an io.Writer to supply that file's data. +type Writer struct { + w io.Writer + pad int64 // Amount of padding to write after current file entry + curr fileWriter // Writer for current file entry + hdr Header // Shallow copy of Header that is safe for mutations + blk block // Buffer to use as temporary local storage + + // err is a persistent error. + // It is only the responsibility of every exported method of Writer to + // ensure that this error is sticky. + err error +} + +// NewWriter creates a new Writer writing to w. +func NewWriter(w io.Writer) *Writer { + return &Writer{w: w, curr: ®FileWriter{w, 0}} +} + +type fileWriter interface { + io.Writer + fileState + + ReadFrom(io.Reader) (int64, error) +} + +// Flush finishes writing the current file's block padding. +// The current file must be fully written before Flush can be called. +// +// This is unnecessary as the next call to WriteHeader or Close +// will implicitly flush out the file's padding. +func (tw *Writer) Flush() error { + if tw.err != nil { + return tw.err + } + if nb := tw.curr.LogicalRemaining(); nb > 0 { + return fmt.Errorf("archive/tar: missed writing %d bytes", nb) + } + if _, tw.err = tw.w.Write(zeroBlock[:tw.pad]); tw.err != nil { + return tw.err + } + tw.pad = 0 + return nil +} + +// WriteHeader writes hdr and prepares to accept the file's contents. +// The Header.Size determines how many bytes can be written for the next file. +// If the current file is not fully written, then this returns an error. +// This implicitly flushes any padding necessary before writing the header. +func (tw *Writer) WriteHeader(hdr *Header) error { + if err := tw.Flush(); err != nil { + return err + } + tw.hdr = *hdr // Shallow copy of Header + + // Avoid usage of the legacy TypeRegA flag, and automatically promote + // it to use TypeReg or TypeDir. + if tw.hdr.Typeflag == TypeRegA { + if strings.HasSuffix(tw.hdr.Name, "/") { + tw.hdr.Typeflag = TypeDir + } else { + tw.hdr.Typeflag = TypeReg + } + } + + // Round ModTime and ignore AccessTime and ChangeTime unless + // the format is explicitly chosen. + // This ensures nominal usage of WriteHeader (without specifying the format) + // does not always result in the PAX format being chosen, which + // causes a 1KiB increase to every header. + if tw.hdr.Format == FormatUnknown { + tw.hdr.ModTime = tw.hdr.ModTime.Round(time.Second) + tw.hdr.AccessTime = time.Time{} + tw.hdr.ChangeTime = time.Time{} + } + + allowedFormats, paxHdrs, err := tw.hdr.allowedFormats() + switch { + case allowedFormats.has(FormatUSTAR): + tw.err = tw.writeUSTARHeader(&tw.hdr) + return tw.err + case allowedFormats.has(FormatPAX): + tw.err = tw.writePAXHeader(&tw.hdr, paxHdrs) + return tw.err + case allowedFormats.has(FormatGNU): + tw.err = tw.writeGNUHeader(&tw.hdr) + return tw.err + default: + return err // Non-fatal error + } +} + +func (tw *Writer) writeUSTARHeader(hdr *Header) error { + // Check if we can use USTAR prefix/suffix splitting. + var namePrefix string + if prefix, suffix, ok := splitUSTARPath(hdr.Name); ok { + namePrefix, hdr.Name = prefix, suffix + } + + // Pack the main header. + var f formatter + blk := tw.templateV7Plus(hdr, f.formatString, f.formatOctal) + f.formatString(blk.USTAR().Prefix(), namePrefix) + blk.SetFormat(FormatUSTAR) + if f.err != nil { + return f.err // Should never happen since header is validated + } + return tw.writeRawHeader(blk, hdr.Size, hdr.Typeflag) +} + +func (tw *Writer) writePAXHeader(hdr *Header, paxHdrs map[string]string) error { + realName, realSize := hdr.Name, hdr.Size + + // TODO(dsnet): Re-enable this when adding sparse support. + // See https://golang.org/issue/22735 + /* + // Handle sparse files. + var spd sparseDatas + var spb []byte + if len(hdr.SparseHoles) > 0 { + sph := append([]sparseEntry{}, hdr.SparseHoles...) // Copy sparse map + sph = alignSparseEntries(sph, hdr.Size) + spd = invertSparseEntries(sph, hdr.Size) + + // Format the sparse map. + hdr.Size = 0 // Replace with encoded size + spb = append(strconv.AppendInt(spb, int64(len(spd)), 10), '\n') + for _, s := range spd { + hdr.Size += s.Length + spb = append(strconv.AppendInt(spb, s.Offset, 10), '\n') + spb = append(strconv.AppendInt(spb, s.Length, 10), '\n') + } + pad := blockPadding(int64(len(spb))) + spb = append(spb, zeroBlock[:pad]...) + hdr.Size += int64(len(spb)) // Accounts for encoded sparse map + + // Add and modify appropriate PAX records. + dir, file := path.Split(realName) + hdr.Name = path.Join(dir, "GNUSparseFile.0", file) + paxHdrs[paxGNUSparseMajor] = "1" + paxHdrs[paxGNUSparseMinor] = "0" + paxHdrs[paxGNUSparseName] = realName + paxHdrs[paxGNUSparseRealSize] = strconv.FormatInt(realSize, 10) + paxHdrs[paxSize] = strconv.FormatInt(hdr.Size, 10) + delete(paxHdrs, paxPath) // Recorded by paxGNUSparseName + } + */ + _ = realSize + + // Write PAX records to the output. + isGlobal := hdr.Typeflag == TypeXGlobalHeader + if len(paxHdrs) > 0 || isGlobal { + // Sort keys for deterministic ordering. + var keys []string + for k := range paxHdrs { + keys = append(keys, k) + } + sort.Strings(keys) + + // Write each record to a buffer. + var buf strings.Builder + for _, k := range keys { + rec, err := formatPAXRecord(k, paxHdrs[k]) + if err != nil { + return err + } + buf.WriteString(rec) + } + + // Write the extended header file. + var name string + var flag byte + if isGlobal { + name = realName + if name == "" { + name = "GlobalHead.0.0" + } + flag = TypeXGlobalHeader + } else { + dir, file := path.Split(realName) + name = path.Join(dir, "PaxHeaders.0", file) + flag = TypeXHeader + } + data := buf.String() + if err := tw.writeRawFile(name, data, flag, FormatPAX); err != nil || isGlobal { + return err // Global headers return here + } + } + + // Pack the main header. + var f formatter // Ignore errors since they are expected + fmtStr := func(b []byte, s string) { f.formatString(b, toASCII(s)) } + blk := tw.templateV7Plus(hdr, fmtStr, f.formatOctal) + blk.SetFormat(FormatPAX) + if err := tw.writeRawHeader(blk, hdr.Size, hdr.Typeflag); err != nil { + return err + } + + // TODO(dsnet): Re-enable this when adding sparse support. + // See https://golang.org/issue/22735 + /* + // Write the sparse map and setup the sparse writer if necessary. + if len(spd) > 0 { + // Use tw.curr since the sparse map is accounted for in hdr.Size. + if _, err := tw.curr.Write(spb); err != nil { + return err + } + tw.curr = &sparseFileWriter{tw.curr, spd, 0} + } + */ + return nil +} + +func (tw *Writer) writeGNUHeader(hdr *Header) error { + // Use long-link files if Name or Linkname exceeds the field size. + const longName = "././@LongLink" + if len(hdr.Name) > nameSize { + data := hdr.Name + "\x00" + if err := tw.writeRawFile(longName, data, TypeGNULongName, FormatGNU); err != nil { + return err + } + } + if len(hdr.Linkname) > nameSize { + data := hdr.Linkname + "\x00" + if err := tw.writeRawFile(longName, data, TypeGNULongLink, FormatGNU); err != nil { + return err + } + } + + // Pack the main header. + var f formatter // Ignore errors since they are expected + var spd sparseDatas + var spb []byte + blk := tw.templateV7Plus(hdr, f.formatString, f.formatNumeric) + if !hdr.AccessTime.IsZero() { + f.formatNumeric(blk.GNU().AccessTime(), hdr.AccessTime.Unix()) + } + if !hdr.ChangeTime.IsZero() { + f.formatNumeric(blk.GNU().ChangeTime(), hdr.ChangeTime.Unix()) + } + // TODO(dsnet): Re-enable this when adding sparse support. + // See https://golang.org/issue/22735 + /* + if hdr.Typeflag == TypeGNUSparse { + sph := append([]sparseEntry{}, hdr.SparseHoles...) // Copy sparse map + sph = alignSparseEntries(sph, hdr.Size) + spd = invertSparseEntries(sph, hdr.Size) + + // Format the sparse map. + formatSPD := func(sp sparseDatas, sa sparseArray) sparseDatas { + for i := 0; len(sp) > 0 && i < sa.MaxEntries(); i++ { + f.formatNumeric(sa.Entry(i).Offset(), sp[0].Offset) + f.formatNumeric(sa.Entry(i).Length(), sp[0].Length) + sp = sp[1:] + } + if len(sp) > 0 { + sa.IsExtended()[0] = 1 + } + return sp + } + sp2 := formatSPD(spd, blk.GNU().Sparse()) + for len(sp2) > 0 { + var spHdr block + sp2 = formatSPD(sp2, spHdr.Sparse()) + spb = append(spb, spHdr[:]...) + } + + // Update size fields in the header block. + realSize := hdr.Size + hdr.Size = 0 // Encoded size; does not account for encoded sparse map + for _, s := range spd { + hdr.Size += s.Length + } + copy(blk.V7().Size(), zeroBlock[:]) // Reset field + f.formatNumeric(blk.V7().Size(), hdr.Size) + f.formatNumeric(blk.GNU().RealSize(), realSize) + } + */ + blk.SetFormat(FormatGNU) + if err := tw.writeRawHeader(blk, hdr.Size, hdr.Typeflag); err != nil { + return err + } + + // Write the extended sparse map and setup the sparse writer if necessary. + if len(spd) > 0 { + // Use tw.w since the sparse map is not accounted for in hdr.Size. + if _, err := tw.w.Write(spb); err != nil { + return err + } + tw.curr = &sparseFileWriter{tw.curr, spd, 0} + } + return nil +} + +type ( + stringFormatter func([]byte, string) + numberFormatter func([]byte, int64) +) + +// templateV7Plus fills out the V7 fields of a block using values from hdr. +// It also fills out fields (uname, gname, devmajor, devminor) that are +// shared in the USTAR, PAX, and GNU formats using the provided formatters. +// +// The block returned is only valid until the next call to +// templateV7Plus or writeRawFile. +func (tw *Writer) templateV7Plus(hdr *Header, fmtStr stringFormatter, fmtNum numberFormatter) *block { + tw.blk.Reset() + + modTime := hdr.ModTime + if modTime.IsZero() { + modTime = time.Unix(0, 0) + } + + v7 := tw.blk.V7() + v7.TypeFlag()[0] = hdr.Typeflag + fmtStr(v7.Name(), hdr.Name) + fmtStr(v7.LinkName(), hdr.Linkname) + fmtNum(v7.Mode(), hdr.Mode) + fmtNum(v7.UID(), int64(hdr.Uid)) + fmtNum(v7.GID(), int64(hdr.Gid)) + fmtNum(v7.Size(), hdr.Size) + fmtNum(v7.ModTime(), modTime.Unix()) + + ustar := tw.blk.USTAR() + fmtStr(ustar.UserName(), hdr.Uname) + fmtStr(ustar.GroupName(), hdr.Gname) + fmtNum(ustar.DevMajor(), hdr.Devmajor) + fmtNum(ustar.DevMinor(), hdr.Devminor) + + return &tw.blk +} + +// writeRawFile writes a minimal file with the given name and flag type. +// It uses format to encode the header format and will write data as the body. +// It uses default values for all of the other fields (as BSD and GNU tar does). +func (tw *Writer) writeRawFile(name, data string, flag byte, format Format) error { + tw.blk.Reset() + + // Best effort for the filename. + name = toASCII(name) + if len(name) > nameSize { + name = name[:nameSize] + } + name = strings.TrimRight(name, "/") + + var f formatter + v7 := tw.blk.V7() + v7.TypeFlag()[0] = flag + f.formatString(v7.Name(), name) + f.formatOctal(v7.Mode(), 0) + f.formatOctal(v7.UID(), 0) + f.formatOctal(v7.GID(), 0) + f.formatOctal(v7.Size(), int64(len(data))) // Must be < 8GiB + f.formatOctal(v7.ModTime(), 0) + tw.blk.SetFormat(format) + if f.err != nil { + return f.err // Only occurs if size condition is violated + } + + // Write the header and data. + if err := tw.writeRawHeader(&tw.blk, int64(len(data)), flag); err != nil { + return err + } + _, err := io.WriteString(tw, data) + return err +} + +// writeRawHeader writes the value of blk, regardless of its value. +// It sets up the Writer such that it can accept a file of the given size. +// If the flag is a special header-only flag, then the size is treated as zero. +func (tw *Writer) writeRawHeader(blk *block, size int64, flag byte) error { + if err := tw.Flush(); err != nil { + return err + } + if _, err := tw.w.Write(blk[:]); err != nil { + return err + } + if isHeaderOnlyType(flag) { + size = 0 + } + tw.curr = ®FileWriter{tw.w, size} + tw.pad = blockPadding(size) + return nil +} + +// splitUSTARPath splits a path according to USTAR prefix and suffix rules. +// If the path is not splittable, then it will return ("", "", false). +func splitUSTARPath(name string) (prefix, suffix string, ok bool) { + length := len(name) + if length <= nameSize || !isASCII(name) { + return "", "", false + } else if length > prefixSize+1 { + length = prefixSize + 1 + } else if name[length-1] == '/' { + length-- + } + + i := strings.LastIndex(name[:length], "/") + nlen := len(name) - i - 1 // nlen is length of suffix + plen := i // plen is length of prefix + if i <= 0 || nlen > nameSize || nlen == 0 || plen > prefixSize { + return "", "", false + } + return name[:i], name[i+1:], true +} + +// Write writes to the current file in the tar archive. +// Write returns the error ErrWriteTooLong if more than +// Header.Size bytes are written after WriteHeader. +// +// Calling Write on special types like TypeLink, TypeSymlink, TypeChar, +// TypeBlock, TypeDir, and TypeFifo returns (0, ErrWriteTooLong) regardless +// of what the Header.Size claims. +func (tw *Writer) Write(b []byte) (int, error) { + if tw.err != nil { + return 0, tw.err + } + n, err := tw.curr.Write(b) + if err != nil && err != ErrWriteTooLong { + tw.err = err + } + return n, err +} + +// readFrom populates the content of the current file by reading from r. +// The bytes read must match the number of remaining bytes in the current file. +// +// If the current file is sparse and r is an io.ReadSeeker, +// then readFrom uses Seek to skip past holes defined in Header.SparseHoles, +// assuming that skipped regions are all NULs. +// This always reads the last byte to ensure r is the right size. +// +// TODO(dsnet): Re-export this when adding sparse file support. +// See https://golang.org/issue/22735 +func (tw *Writer) readFrom(r io.Reader) (int64, error) { + if tw.err != nil { + return 0, tw.err + } + n, err := tw.curr.ReadFrom(r) + if err != nil && err != ErrWriteTooLong { + tw.err = err + } + return n, err +} + +// Close closes the tar archive by flushing the padding, and writing the footer. +// If the current file (from a prior call to WriteHeader) is not fully written, +// then this returns an error. +func (tw *Writer) Close() error { + if tw.err == ErrWriteAfterClose { + return nil + } + if tw.err != nil { + return tw.err + } + + // Trailer: two zero blocks. + err := tw.Flush() + for i := 0; i < 2 && err == nil; i++ { + _, err = tw.w.Write(zeroBlock[:]) + } + + // Ensure all future actions are invalid. + tw.err = ErrWriteAfterClose + return err // Report IO errors +} + +// regFileWriter is a fileWriter for writing data to a regular file entry. +type regFileWriter struct { + w io.Writer // Underlying Writer + nb int64 // Number of remaining bytes to write +} + +func (fw *regFileWriter) Write(b []byte) (n int, err error) { + overwrite := int64(len(b)) > fw.nb + if overwrite { + b = b[:fw.nb] + } + if len(b) > 0 { + n, err = fw.w.Write(b) + fw.nb -= int64(n) + } + switch { + case err != nil: + return n, err + case overwrite: + return n, ErrWriteTooLong + default: + return n, nil + } +} + +func (fw *regFileWriter) ReadFrom(r io.Reader) (int64, error) { + return io.Copy(struct{ io.Writer }{fw}, r) +} + +func (fw regFileWriter) LogicalRemaining() int64 { + return fw.nb +} +func (fw regFileWriter) PhysicalRemaining() int64 { + return fw.nb +} + +// sparseFileWriter is a fileWriter for writing data to a sparse file entry. +type sparseFileWriter struct { + fw fileWriter // Underlying fileWriter + sp sparseDatas // Normalized list of data fragments + pos int64 // Current position in sparse file +} + +func (sw *sparseFileWriter) Write(b []byte) (n int, err error) { + overwrite := int64(len(b)) > sw.LogicalRemaining() + if overwrite { + b = b[:sw.LogicalRemaining()] + } + + b0 := b + endPos := sw.pos + int64(len(b)) + for endPos > sw.pos && err == nil { + var nf int // Bytes written in fragment + dataStart, dataEnd := sw.sp[0].Offset, sw.sp[0].endOffset() + if sw.pos < dataStart { // In a hole fragment + bf := b[:min(int64(len(b)), dataStart-sw.pos)] + nf, err = zeroWriter{}.Write(bf) + } else { // In a data fragment + bf := b[:min(int64(len(b)), dataEnd-sw.pos)] + nf, err = sw.fw.Write(bf) + } + b = b[nf:] + sw.pos += int64(nf) + if sw.pos >= dataEnd && len(sw.sp) > 1 { + sw.sp = sw.sp[1:] // Ensure last fragment always remains + } + } + + n = len(b0) - len(b) + switch { + case err == ErrWriteTooLong: + return n, errMissData // Not possible; implies bug in validation logic + case err != nil: + return n, err + case sw.LogicalRemaining() == 0 && sw.PhysicalRemaining() > 0: + return n, errUnrefData // Not possible; implies bug in validation logic + case overwrite: + return n, ErrWriteTooLong + default: + return n, nil + } +} + +func (sw *sparseFileWriter) ReadFrom(r io.Reader) (n int64, err error) { + rs, ok := r.(io.ReadSeeker) + if ok { + if _, err := rs.Seek(0, io.SeekCurrent); err != nil { + ok = false // Not all io.Seeker can really seek + } + } + if !ok { + return io.Copy(struct{ io.Writer }{sw}, r) + } + + var readLastByte bool + pos0 := sw.pos + for sw.LogicalRemaining() > 0 && !readLastByte && err == nil { + var nf int64 // Size of fragment + dataStart, dataEnd := sw.sp[0].Offset, sw.sp[0].endOffset() + if sw.pos < dataStart { // In a hole fragment + nf = dataStart - sw.pos + if sw.PhysicalRemaining() == 0 { + readLastByte = true + nf-- + } + _, err = rs.Seek(nf, io.SeekCurrent) + } else { // In a data fragment + nf = dataEnd - sw.pos + nf, err = io.CopyN(sw.fw, rs, nf) + } + sw.pos += nf + if sw.pos >= dataEnd && len(sw.sp) > 1 { + sw.sp = sw.sp[1:] // Ensure last fragment always remains + } + } + + // If the last fragment is a hole, then seek to 1-byte before EOF, and + // read a single byte to ensure the file is the right size. + if readLastByte && err == nil { + _, err = mustReadFull(rs, []byte{0}) + sw.pos++ + } + + n = sw.pos - pos0 + switch { + case err == io.EOF: + return n, io.ErrUnexpectedEOF + case err == ErrWriteTooLong: + return n, errMissData // Not possible; implies bug in validation logic + case err != nil: + return n, err + case sw.LogicalRemaining() == 0 && sw.PhysicalRemaining() > 0: + return n, errUnrefData // Not possible; implies bug in validation logic + default: + return n, ensureEOF(rs) + } +} + +func (sw sparseFileWriter) LogicalRemaining() int64 { + return sw.sp[len(sw.sp)-1].endOffset() - sw.pos +} +func (sw sparseFileWriter) PhysicalRemaining() int64 { + return sw.fw.PhysicalRemaining() +} + +// zeroWriter may only be written with NULs, otherwise it returns errWriteHole. +type zeroWriter struct{} + +func (zeroWriter) Write(b []byte) (int, error) { + for i, c := range b { + if c != 0 { + return i, errWriteHole + } + } + return len(b), nil +} + +// ensureEOF checks whether r is at EOF, reporting ErrWriteTooLong if not so. +func ensureEOF(r io.Reader) error { + n, err := tryReadFull(r, []byte{0}) + switch { + case n > 0: + return ErrWriteTooLong + case err == io.EOF: + return nil + default: + return err + } +} diff --git a/vendor/github.com/wavesoftware/go-ensure/.editorconfig b/vendor/github.com/wavesoftware/go-ensure/.editorconfig new file mode 100644 index 0000000000..25d2a11a99 --- /dev/null +++ b/vendor/github.com/wavesoftware/go-ensure/.editorconfig @@ -0,0 +1,15 @@ +# EditorConfig is awesome: https://EditorConfig.org + +# top-most EditorConfig file +root = true + +# Unix-style newlines with a newline ending every file +[*] +end_of_line = lf +insert_final_newline = true +charset = utf-8 +indent_style = space +indent_size = 2 + +[*.go] +indent_style = tab diff --git a/vendor/github.com/wavesoftware/go-ensure/.gitignore b/vendor/github.com/wavesoftware/go-ensure/.gitignore new file mode 100644 index 0000000000..e67b8a3c6f --- /dev/null +++ b/vendor/github.com/wavesoftware/go-ensure/.gitignore @@ -0,0 +1,17 @@ +# Binaries for programs and plugins +*.exe +*.exe~ +*.dll +*.so +*.dylib + +# Test binary, built with `go test -c` +*.test + +# Output of the go coverage tool, specifically when used with LiteIDE +*.out + +# Dependency directories (remove the comment below to include it) +vendor/ + +build/ diff --git a/vendor/github.com/wavesoftware/go-ensure/.travis.yml b/vendor/github.com/wavesoftware/go-ensure/.travis.yml new file mode 100644 index 0000000000..2f4b5c2f14 --- /dev/null +++ b/vendor/github.com/wavesoftware/go-ensure/.travis.yml @@ -0,0 +1,15 @@ +--- +language: go +sudo: false +dist: bionic +go: + - 1.13.x +script: + - make clean test +branches: + only: + - master + - develop + - "/^v\\d/" +notifications: + email: onchange diff --git a/vendor/github.com/wavesoftware/go-ensure/LICENSE b/vendor/github.com/wavesoftware/go-ensure/LICENSE new file mode 100644 index 0000000000..6c180a6f23 --- /dev/null +++ b/vendor/github.com/wavesoftware/go-ensure/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2020 Wave Software + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/vendor/github.com/wavesoftware/go-ensure/Makefile b/vendor/github.com/wavesoftware/go-ensure/Makefile new file mode 100644 index 0000000000..afa4896e3a --- /dev/null +++ b/vendor/github.com/wavesoftware/go-ensure/Makefile @@ -0,0 +1,32 @@ +PROJECT_DIR = $(shell readlink -f .) +BUILD_DIR = "$(PROJECT_DIR)/build" + +GO ?= go +RICHGO ?= rich$(GO) + +.PHONY: default +default: binaries + +.PHONY: builddeps +builddeps: + @GO111MODULE=off $(GO) get github.com/kyoh86/richgo + @GO111MODULE=off $(GO) get github.com/mgechev/revive + +.PHONY: builddir +builddir: + @mkdir -p build + +.PHONY: clean +clean: builddeps + @echo "🛁 Cleaning" + @rm -frv $(BUILD_DIR) + +.PHONY: check +check: builddeps + @echo "🛂 Checking" + revive -config revive.toml -formatter stylish ./... + +.PHONY: test +test: builddir check + @echo "✔️ Testing" + $(RICHGO) test -v -covermode=count -coverprofile=build/coverage.out ./... diff --git a/vendor/github.com/wavesoftware/go-ensure/README.md b/vendor/github.com/wavesoftware/go-ensure/README.md new file mode 100644 index 0000000000..82e73e4525 --- /dev/null +++ b/vendor/github.com/wavesoftware/go-ensure/README.md @@ -0,0 +1,55 @@ +# Ensure for Go + +A simple ensure package for Golang + +## Use case + +Writing a Go code makes a lot of repetition, regarding error checking. That's +especially true for end user code like e2e tests when we expect that something +will work. In other cases that's a bug and should code should panic then. + +## Usage + +Instead of writing: + +```go +func DeployAllComponents() error { + alpha, err := deployAlpha() + if err != nil { + return errors.WithMessage(err, "unexpected error") + } + beta, err := deployBeta(alpha) + if err != nil { + return errors.WithMessage(err, "unexpected error") + } + _, err := deployGamma(beta) + if err != nil { + return errors.WithMessage(err, "unexpected error") + } + return nil +} + +// execution isn't simple +err = DeployAllComponents() +if err != nil { + panic(err) +} +``` + +with this PR I can write it like: + +```go +func DeployAllComponents() { + alpha, err := deployAlpha() + ensure.NoError(err) + beta, err := deployBeta(alpha) + ensure.NoError(err) + _, err := deployGamma(beta) + ensure.NoError(err) +} + +// execution is simple +DeployAllComponents() +``` + +Above is much more readable and pleasant to see. diff --git a/vendor/github.com/wavesoftware/go-ensure/errors.go b/vendor/github.com/wavesoftware/go-ensure/errors.go new file mode 100644 index 0000000000..9da1e2e860 --- /dev/null +++ b/vendor/github.com/wavesoftware/go-ensure/errors.go @@ -0,0 +1,33 @@ +package ensure + +import ( + "fmt" + "github.com/pkg/errors" + "regexp" +) + +// NoError will panic if given an error, as it was unexpected +func NoError(err error) { + if err != nil { + panic(errors.WithMessage(err, "unexpected error")) + } +} + +// Error will panic if given no error, as it expected one +func Error(err error) { + if err == nil { + panic(errors.New("expecting error, but none given")) + } +} + +// ErrorWithMessage will panic if given no error, or error message don't match provided regexp +func ErrorWithMessage(err error, messageRegexp string) { + Error(err) + validErrorMessage := regexp.MustCompile(messageRegexp) + if !validErrorMessage.MatchString(err.Error()) { + panic(errors.WithMessage( + err, + fmt.Sprintf("given error doesn't match given regexp (%s)", messageRegexp), + )) + } +} diff --git a/vendor/github.com/wavesoftware/go-ensure/go.mod b/vendor/github.com/wavesoftware/go-ensure/go.mod new file mode 100644 index 0000000000..06dbff1184 --- /dev/null +++ b/vendor/github.com/wavesoftware/go-ensure/go.mod @@ -0,0 +1,5 @@ +module github.com/wavesoftware/go-ensure + +go 1.13 + +require github.com/pkg/errors v0.9.1 diff --git a/vendor/github.com/wavesoftware/go-ensure/go.sum b/vendor/github.com/wavesoftware/go-ensure/go.sum new file mode 100644 index 0000000000..7c401c3f58 --- /dev/null +++ b/vendor/github.com/wavesoftware/go-ensure/go.sum @@ -0,0 +1,2 @@ +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= diff --git a/vendor/github.com/wavesoftware/go-ensure/revive.toml b/vendor/github.com/wavesoftware/go-ensure/revive.toml new file mode 100644 index 0000000000..a4cb9ecd72 --- /dev/null +++ b/vendor/github.com/wavesoftware/go-ensure/revive.toml @@ -0,0 +1,35 @@ +# When set to false, ignores files with "GENERATED" header, similar to golint +ignoreGeneratedHeader = true + +# Sets the default severity to "warning" +severity = "warning" + +# Sets the default failure confidence. This means that linting errors +# with less than 0.8 confidence will be ignored. +confidence = 0.8 + +# Sets the error code for failures with severity "error" +errorCode = 102 + +# Sets the error code for failures with severity "warning" +warningCode = 102 + +[rule.blank-imports] +[rule.context-as-argument] +[rule.context-keys-type] +[rule.dot-imports] +[rule.error-return] +[rule.error-strings] +[rule.error-naming] +[rule.exported] +[rule.if-return] +[rule.increment-decrement] +[rule.var-naming] +[rule.var-declaration] +[rule.package-comments] +[rule.range] +[rule.receiver-naming] +[rule.time-naming] +[rule.unexported-return] +[rule.indent-error-flow] +[rule.errorf] diff --git a/vendor/github.com/willf/bitset/go.mod b/vendor/github.com/willf/bitset/go.mod deleted file mode 100644 index 583ecab78f..0000000000 --- a/vendor/github.com/willf/bitset/go.mod +++ /dev/null @@ -1,3 +0,0 @@ -module github.com/willf/bitset - -go 1.14 diff --git a/vendor/go.uber.org/zap/CHANGELOG.md b/vendor/go.uber.org/zap/CHANGELOG.md index fdfef8808a..794ee303e1 100644 --- a/vendor/go.uber.org/zap/CHANGELOG.md +++ b/vendor/go.uber.org/zap/CHANGELOG.md @@ -1,4 +1,16 @@ # Changelog +All notable changes to this project will be documented in this file. + +This project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). + +## 1.19.1 (8 Sep 2021) + +### Fixed +* [#1001][]: JSON: Fix complex number encoding with negative imaginary part. Thanks to @hemantjadon. +* [#1003][]: JSON: Fix inaccurate precision when encoding float32. + +[#1001]: https://github.com/uber-go/zap/pull/1001 +[#1003]: https://github.com/uber-go/zap/pull/1003 ## 1.19.0 (9 Aug 2021) diff --git a/vendor/go.uber.org/zap/go.mod b/vendor/go.uber.org/zap/go.mod index 9455c99cc9..3480ab4e14 100644 --- a/vendor/go.uber.org/zap/go.mod +++ b/vendor/go.uber.org/zap/go.mod @@ -7,7 +7,7 @@ require ( github.com/pkg/errors v0.8.1 github.com/stretchr/testify v1.7.0 go.uber.org/atomic v1.7.0 - go.uber.org/goleak v1.1.10 + go.uber.org/goleak v1.1.11-0.20210813005559-691160354723 go.uber.org/multierr v1.6.0 gopkg.in/yaml.v2 v2.2.8 gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect diff --git a/vendor/go.uber.org/zap/go.sum b/vendor/go.uber.org/zap/go.sum index 9031a6131a..1658da4354 100644 --- a/vendor/go.uber.org/zap/go.sum +++ b/vendor/go.uber.org/zap/go.sum @@ -14,31 +14,48 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= 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 h1:z+mqJhf6ss6BSfSM671tgKyZBFPTTJM+HLxnhPC3wu0= -go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= +go.uber.org/goleak v1.1.11-0.20210813005559-691160354723 h1:sHOAIxRGBp443oHZIPB+HsUGaksVCXVQENPxwTfQdH4= +go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= go.uber.org/multierr v1.6.0 h1:y6IPFStTAIT5Ytl7/XYmHvzXQ7S3g/IeZW9hyZ5thw4= go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/lint v0.0.0-20190930215403-16217165b5de h1:5hukYrvBGR8/eNkX5mdUezrA6JiaEZDtJb9Ei+1LlBs= golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/mod v0.4.2 h1:Gz96sIWK3OalVv/I/qNygP42zyoKp3xptRVCWRFEBvo= +golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210510120138-977fb7262007 h1:gG67DSER+11cZvqIMb8S8bt0vZtiN6xWYARwirrOSfE= +golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20191108193012-7d206e10da11 h1:Yq9t9jnGoR+dBuitxdo9l6Q7xh/zOyNnYUtDKaQ3x0E= -golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.1.5 h1:ouewzE6p+/VEB31YYnTbEJdi8pFqKp4P4n85vwo3DHA= +golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/vendor/go.uber.org/zap/zapcore/json_encoder.go b/vendor/go.uber.org/zap/zapcore/json_encoder.go index 5cf7d917e9..af220d9b4d 100644 --- a/vendor/go.uber.org/zap/zapcore/json_encoder.go +++ b/vendor/go.uber.org/zap/zapcore/json_encoder.go @@ -128,6 +128,11 @@ func (enc *jsonEncoder) AddFloat64(key string, val float64) { enc.AppendFloat64(val) } +func (enc *jsonEncoder) AddFloat32(key string, val float32) { + enc.addKey(key) + enc.AppendFloat32(val) +} + func (enc *jsonEncoder) AddInt64(key string, val int64) { enc.addKey(key) enc.AppendInt64(val) @@ -228,7 +233,11 @@ func (enc *jsonEncoder) AppendComplex128(val complex128) { // Because we're always in a quoted string, we can use strconv without // special-casing NaN and +/-Inf. enc.buf.AppendFloat(r, 64) - enc.buf.AppendByte('+') + // If imaginary part is less than 0, minus (-) sign is added by default + // by AppendFloat. + if i >= 0 { + enc.buf.AppendByte('+') + } enc.buf.AppendFloat(i, 64) enc.buf.AppendByte('i') enc.buf.AppendByte('"') @@ -293,7 +302,6 @@ func (enc *jsonEncoder) AppendUint64(val uint64) { } func (enc *jsonEncoder) AddComplex64(k string, v complex64) { enc.AddComplex128(k, complex128(v)) } -func (enc *jsonEncoder) AddFloat32(k string, v float32) { enc.AddFloat64(k, float64(v)) } func (enc *jsonEncoder) AddInt(k string, v int) { enc.AddInt64(k, int64(v)) } func (enc *jsonEncoder) AddInt32(k string, v int32) { enc.AddInt64(k, int64(v)) } func (enc *jsonEncoder) AddInt16(k string, v int16) { enc.AddInt64(k, int64(v)) } diff --git a/vendor/golang.org/x/net/http2/client_conn_pool.go b/vendor/golang.org/x/net/http2/client_conn_pool.go index 8fd95bbf1c..c936843eaf 100644 --- a/vendor/golang.org/x/net/http2/client_conn_pool.go +++ b/vendor/golang.org/x/net/http2/client_conn_pool.go @@ -48,7 +48,7 @@ type clientConnPool struct { conns map[string][]*ClientConn // key is host:port dialing map[string]*dialCall // currently in-flight dials keys map[*ClientConn][]string - addConnCalls map[string]*addConnCall // in-flight addConnIfNeede calls + addConnCalls map[string]*addConnCall // in-flight addConnIfNeeded calls } func (p *clientConnPool) GetClientConn(req *http.Request, addr string) (*ClientConn, error) { @@ -60,30 +60,8 @@ const ( noDialOnMiss = false ) -// shouldTraceGetConn reports whether getClientConn should call any -// ClientTrace.GetConn hook associated with the http.Request. -// -// This complexity is needed to avoid double calls of the GetConn hook -// during the back-and-forth between net/http and x/net/http2 (when the -// net/http.Transport is upgraded to also speak http2), as well as support -// the case where x/net/http2 is being used directly. -func (p *clientConnPool) shouldTraceGetConn(cc *ClientConn) bool { - // If our Transport wasn't made via ConfigureTransport, always - // trace the GetConn hook if provided, because that means the - // http2 package is being used directly and it's the one - // dialing, as opposed to net/http. - if _, ok := p.t.ConnPool.(noDialClientConnPool); !ok { - return true - } - // Otherwise, only use the GetConn hook if this connection has - // been used previously for other requests. For fresh - // connections, the net/http package does the dialing. - cc.mu.Lock() - defer cc.mu.Unlock() - return cc.nextStreamID == 1 -} - func (p *clientConnPool) getClientConn(req *http.Request, addr string, dialOnMiss bool) (*ClientConn, error) { + // TODO(dneil): Dial a new connection when t.DisableKeepAlives is set? if isConnectionCloseRequest(req) && dialOnMiss { // It gets its own connection. traceGetConn(req, addr) @@ -98,9 +76,13 @@ func (p *clientConnPool) getClientConn(req *http.Request, addr string, dialOnMis p.mu.Lock() for _, cc := range p.conns[addr] { if cc.ReserveNewRequest() { - if p.shouldTraceGetConn(cc) { + // When a connection is presented to us by the net/http package, + // the GetConn hook has already been called. + // Don't call it a second time here. + if !cc.getConnCalled { traceGetConn(req, addr) } + cc.getConnCalled = false p.mu.Unlock() return cc, nil } @@ -219,6 +201,7 @@ func (c *addConnCall) run(t *Transport, key string, tc *tls.Conn) { if err != nil { c.err = err } else { + cc.getConnCalled = true // already called by the net/http package p.addConnLocked(key, cc) } delete(p.addConnCalls, key) diff --git a/vendor/golang.org/x/net/http2/hpack/huffman.go b/vendor/golang.org/x/net/http2/hpack/huffman.go index a1ab2f0567..fe0b84ccd4 100644 --- a/vendor/golang.org/x/net/http2/hpack/huffman.go +++ b/vendor/golang.org/x/net/http2/hpack/huffman.go @@ -140,25 +140,29 @@ func buildRootHuffmanNode() { panic("unexpected size") } lazyRootHuffmanNode = newInternalNode() - for i, code := range huffmanCodes { - addDecoderNode(byte(i), code, huffmanCodeLen[i]) - } -} + // allocate a leaf node for each of the 256 symbols + leaves := new([256]node) + + for sym, code := range huffmanCodes { + codeLen := huffmanCodeLen[sym] + + cur := lazyRootHuffmanNode + for codeLen > 8 { + codeLen -= 8 + i := uint8(code >> codeLen) + if cur.children[i] == nil { + cur.children[i] = newInternalNode() + } + cur = cur.children[i] + } + shift := 8 - codeLen + start, end := int(uint8(code< 8 { - codeLen -= 8 - i := uint8(code >> codeLen) - if cur.children[i] == nil { - cur.children[i] = newInternalNode() + leaves[sym].sym = byte(sym) + leaves[sym].codeLen = codeLen + for i := start; i < start+end; i++ { + cur.children[i] = &leaves[sym] } - cur = cur.children[i] - } - shift := 8 - codeLen - start, end := int(uint8(code< last { - select { - case cs.resc <- resAndError{err: errClientConnGotGoAway}: - default: - } + cs.abortStreamLocked(errClientConnGotGoAway) } } } @@ -810,11 +769,65 @@ func (cc *ClientConn) ReserveNewRequest() bool { return true } +// ClientConnState describes the state of a ClientConn. +type ClientConnState struct { + // Closed is whether the connection is closed. + Closed bool + + // Closing is whether the connection is in the process of + // closing. It may be closing due to shutdown, being a + // single-use connection, being marked as DoNotReuse, or + // having received a GOAWAY frame. + Closing bool + + // StreamsActive is how many streams are active. + StreamsActive int + + // StreamsReserved is how many streams have been reserved via + // ClientConn.ReserveNewRequest. + StreamsReserved int + + // StreamsPending is how many requests have been sent in excess + // of the peer's advertised MaxConcurrentStreams setting and + // are waiting for other streams to complete. + StreamsPending int + + // MaxConcurrentStreams is how many concurrent streams the + // peer advertised as acceptable. Zero means no SETTINGS + // frame has been received yet. + MaxConcurrentStreams uint32 + + // LastIdle, if non-zero, is when the connection last + // transitioned to idle state. + LastIdle time.Time +} + +// State returns a snapshot of cc's state. +func (cc *ClientConn) State() ClientConnState { + cc.wmu.Lock() + maxConcurrent := cc.maxConcurrentStreams + if !cc.seenSettings { + maxConcurrent = 0 + } + cc.wmu.Unlock() + + cc.mu.Lock() + defer cc.mu.Unlock() + return ClientConnState{ + Closed: cc.closed, + Closing: cc.closing || cc.singleUse || cc.doNotReuse || cc.goAway != nil, + StreamsActive: len(cc.streams), + StreamsReserved: cc.streamsReserved, + StreamsPending: cc.pendingRequests, + LastIdle: cc.lastIdle, + MaxConcurrentStreams: maxConcurrent, + } +} + // clientConnIdleState describes the suitability of a client // connection to initiate a new RoundTrip request. type clientConnIdleState struct { canTakeNewRequest bool - freshConn bool // whether it's unused by any previous request } func (cc *ClientConn) idleState() clientConnIdleState { @@ -842,7 +855,6 @@ func (cc *ClientConn) idleStateLocked() (st clientConnIdleState) { !cc.doNotReuse && int64(cc.nextStreamID)+2*int64(cc.pendingRequests) < math.MaxInt32 && !cc.tooIdleLocked() - st.freshConn = cc.nextStreamID == 1 && st.canTakeNewRequest return } @@ -873,7 +885,7 @@ func (cc *ClientConn) onIdleTimeout() { func (cc *ClientConn) closeIfIdle() { cc.mu.Lock() - if len(cc.streams) > 0 { + if len(cc.streams) > 0 || cc.streamsReserved > 0 { cc.mu.Unlock() return } @@ -896,7 +908,7 @@ func (cc *ClientConn) isDoNotReuseAndIdle() bool { var shutdownEnterWaitStateHook = func() {} -// Shutdown gracefully close the client connection, waiting for running streams to complete. +// Shutdown gracefully closes the client connection, waiting for running streams to complete. func (cc *ClientConn) Shutdown(ctx context.Context) error { if err := cc.sendGoAway(); err != nil { return err @@ -961,20 +973,10 @@ func (cc *ClientConn) sendGoAway() error { // err is sent to streams. func (cc *ClientConn) closeForError(err error) error { cc.mu.Lock() - streams := cc.streams - cc.streams = nil cc.closed = true - cc.mu.Unlock() - - for _, cs := range streams { - select { - case cs.resc <- resAndError{err: err}: - default: - } - cs.bufPipe.CloseWithError(err) + for _, cs := range cc.streams { + cs.abortStreamLocked(err) } - - cc.mu.Lock() defer cc.cond.Broadcast() defer cc.mu.Unlock() return cc.tconn.Close() @@ -1071,70 +1073,129 @@ func (cc *ClientConn) decrStreamReservationsLocked() { } func (cc *ClientConn) RoundTrip(req *http.Request) (*http.Response, error) { - resp, _, err := cc.roundTrip(req) - return resp, err -} - -func (cc *ClientConn) roundTrip(req *http.Request) (res *http.Response, gotErrAfterReqBodyWrite bool, err error) { ctx := req.Context() - if err := checkConnHeaders(req); err != nil { - cc.decrStreamReservations() - return nil, false, err + cs := &clientStream{ + cc: cc, + ctx: ctx, + reqCancel: req.Cancel, + isHead: req.Method == "HEAD", + reqBody: req.Body, + reqBodyContentLength: actualContentLength(req), + trace: httptrace.ContextClientTrace(ctx), + peerClosed: make(chan struct{}), + abort: make(chan struct{}), + respHeaderRecv: make(chan struct{}), + donec: make(chan struct{}), + } + go cs.doRequest(req) + + waitDone := func() error { + select { + case <-cs.donec: + return nil + case <-ctx.Done(): + return ctx.Err() + case <-cs.reqCancel: + return errRequestCanceled + } } - if cc.idleTimer != nil { - cc.idleTimer.Stop() + + for { + select { + case <-cs.respHeaderRecv: + res := cs.res + if res.StatusCode > 299 { + // On error or status code 3xx, 4xx, 5xx, etc abort any + // ongoing write, assuming that the server doesn't care + // about our request body. If the server replied with 1xx or + // 2xx, however, then assume the server DOES potentially + // want our body (e.g. full-duplex streaming: + // golang.org/issue/13444). If it turns out the server + // doesn't, they'll RST_STREAM us soon enough. This is a + // heuristic to avoid adding knobs to Transport. Hopefully + // we can keep it. + cs.abortRequestBodyWrite() + } + res.Request = req + res.TLS = cc.tlsState + if res.Body == noBody && actualContentLength(req) == 0 { + // If there isn't a request or response body still being + // written, then wait for the stream to be closed before + // RoundTrip returns. + if err := waitDone(); err != nil { + return nil, err + } + } + return res, nil + case <-cs.abort: + waitDone() + return nil, cs.abortErr + case <-ctx.Done(): + err := ctx.Err() + cs.abortStream(err) + return nil, err + case <-cs.reqCancel: + cs.abortStream(errRequestCanceled) + return nil, errRequestCanceled + } } +} - trailers, err := commaSeparatedTrailers(req) - if err != nil { - cc.decrStreamReservations() - return nil, false, err +// doRequest runs for the duration of the request lifetime. +// +// It sends the request and performs post-request cleanup (closing Request.Body, etc.). +func (cs *clientStream) doRequest(req *http.Request) { + err := cs.writeRequest(req) + cs.cleanupWriteRequest(err) +} + +// writeRequest sends a request. +// +// It returns nil after the request is written, the response read, +// and the request stream is half-closed by the peer. +// +// It returns non-nil if the request ends otherwise. +// If the returned error is StreamError, the error Code may be used in resetting the stream. +func (cs *clientStream) writeRequest(req *http.Request) (err error) { + cc := cs.cc + ctx := cs.ctx + + if err := checkConnHeaders(req); err != nil { + return err } - hasTrailers := trailers != "" // Acquire the new-request lock by writing to reqHeaderMu. // This lock guards the critical section covering allocating a new stream ID // (requires mu) and creating the stream (requires wmu). if cc.reqHeaderMu == nil { - panic("RoundTrip on initialized ClientConn") // for tests + panic("RoundTrip on uninitialized ClientConn") // for tests } select { case cc.reqHeaderMu <- struct{}{}: - case <-req.Cancel: - cc.decrStreamReservations() - return nil, false, errRequestCanceled + case <-cs.reqCancel: + return errRequestCanceled case <-ctx.Done(): - cc.decrStreamReservations() - return nil, false, ctx.Err() + return ctx.Err() } - reqHeaderMuNeedsUnlock := true - defer func() { - if reqHeaderMuNeedsUnlock { - <-cc.reqHeaderMu - } - }() cc.mu.Lock() - cc.decrStreamReservationsLocked() - if req.URL == nil { - cc.mu.Unlock() - return nil, false, errNilRequestURL + if cc.idleTimer != nil { + cc.idleTimer.Stop() } - if err := cc.awaitOpenSlotForRequest(req); err != nil { + cc.decrStreamReservationsLocked() + if err := cc.awaitOpenSlotForStreamLocked(cs); err != nil { cc.mu.Unlock() - return nil, false, err + <-cc.reqHeaderMu + return err } - - body := req.Body - contentLen := actualContentLength(req) - hasBody := contentLen != 0 + cc.addStreamLocked(cs) // assigns stream ID + cc.mu.Unlock() // TODO(bradfitz): this is a copy of the logic in net/http. Unify somewhere? - var requestedGzip bool if !cc.t.disableCompression() && req.Header.Get("Accept-Encoding") == "" && req.Header.Get("Range") == "" && - req.Method != "HEAD" { + !cs.isHead { // Request gzip only, not deflate. Deflate is ambiguous and // not as universally supported anyway. // See: https://zlib.net/zlib_faq.html#faq39 @@ -1147,185 +1208,223 @@ func (cc *ClientConn) roundTrip(req *http.Request) (res *http.Response, gotErrAf // We don't request gzip if the request is for a range, since // auto-decoding a portion of a gzipped document will just fail // anyway. See https://golang.org/issue/8923 - requestedGzip = true + cs.requestedGzip = true } - cs := cc.newStream() - cs.req = req - cs.trace = httptrace.ContextClientTrace(req.Context()) - cs.requestedGzip = requestedGzip - bodyWriter := cc.t.getBodyWriterState(cs, body) - cs.on100 = bodyWriter.on100 - cc.mu.Unlock() + continueTimeout := cc.t.expectContinueTimeout() + if continueTimeout != 0 && + !httpguts.HeaderValuesContainsToken( + req.Header["Expect"], + "100-continue") { + continueTimeout = 0 + cs.on100 = make(chan struct{}, 1) + } + + // Past this point (where we send request headers), it is possible for + // RoundTrip to return successfully. Since the RoundTrip contract permits + // the caller to "mutate or reuse" the Request after closing the Response's Body, + // we must take care when referencing the Request from here on. + err = cs.encodeAndWriteHeaders(req) + <-cc.reqHeaderMu + if err != nil { + return err + } + + hasBody := cs.reqBodyContentLength != 0 + if !hasBody { + cs.sentEndStream = true + } else { + if continueTimeout != 0 { + traceWait100Continue(cs.trace) + timer := time.NewTimer(continueTimeout) + select { + case <-timer.C: + err = nil + case <-cs.on100: + err = nil + case <-cs.abort: + err = cs.abortErr + case <-ctx.Done(): + err = ctx.Err() + case <-cs.reqCancel: + err = errRequestCanceled + } + timer.Stop() + if err != nil { + traceWroteRequest(cs.trace, err) + return err + } + } + + if err = cs.writeRequestBody(req); err != nil { + if err != errStopReqBodyWrite { + traceWroteRequest(cs.trace, err) + return err + } + } else { + cs.sentEndStream = true + } + } + + traceWroteRequest(cs.trace, err) + + var respHeaderTimer <-chan time.Time + var respHeaderRecv chan struct{} + if d := cc.responseHeaderTimeout(); d != 0 { + timer := time.NewTimer(d) + defer timer.Stop() + respHeaderTimer = timer.C + respHeaderRecv = cs.respHeaderRecv + } + // Wait until the peer half-closes its end of the stream, + // or until the request is aborted (via context, error, or otherwise), + // whichever comes first. + for { + select { + case <-cs.peerClosed: + return nil + case <-respHeaderTimer: + return errTimeout + case <-respHeaderRecv: + respHeaderTimer = nil // keep waiting for END_STREAM + case <-cs.abort: + return cs.abortErr + case <-ctx.Done(): + return ctx.Err() + case <-cs.reqCancel: + return errRequestCanceled + } + } +} + +func (cs *clientStream) encodeAndWriteHeaders(req *http.Request) error { + cc := cs.cc + ctx := cs.ctx + + cc.wmu.Lock() + defer cc.wmu.Unlock() + // If the request was canceled while waiting for cc.mu, just quit. + select { + case <-cs.abort: + return cs.abortErr + case <-ctx.Done(): + return ctx.Err() + case <-cs.reqCancel: + return errRequestCanceled + default: + } + + // Encode headers. + // // we send: HEADERS{1}, CONTINUATION{0,} + DATA{0,} (DATA is // sent by writeRequestBody below, along with any Trailers, // again in form HEADERS{1}, CONTINUATION{0,}) - cc.wmu.Lock() - hdrs, err := cc.encodeHeaders(req, requestedGzip, trailers, contentLen) + trailers, err := commaSeparatedTrailers(req) if err != nil { - cc.wmu.Unlock() - return nil, false, err + return err + } + hasTrailers := trailers != "" + contentLen := actualContentLength(req) + hasBody := contentLen != 0 + hdrs, err := cc.encodeHeaders(req, cs.requestedGzip, trailers, contentLen) + if err != nil { + return err } - defer func() { - cc.wmu.Lock() - werr := cc.werr - cc.wmu.Unlock() - if werr != nil { - cc.Close() - } - }() - + // Write the request. endStream := !hasBody && !hasTrailers + cs.sentHeaders = true err = cc.writeHeaders(cs.ID, endStream, int(cc.maxFrameSize), hdrs) - cc.wmu.Unlock() - <-cc.reqHeaderMu // release the new-request lock - reqHeaderMuNeedsUnlock = false traceWroteHeaders(cs.trace) + return err +} - if err != nil { - if hasBody { - bodyWriter.cancel() - } - cc.forgetStreamID(cs.ID) - // Don't bother sending a RST_STREAM (our write already failed; - // no need to keep writing) - traceWroteRequest(cs.trace, err) - // TODO(dneil): An error occurred while writing the headers. - // Should we return an error indicating that this request can be retried? - return nil, false, err +// cleanupWriteRequest performs post-request tasks. +// +// If err (the result of writeRequest) is non-nil and the stream is not closed, +// cleanupWriteRequest will send a reset to the peer. +func (cs *clientStream) cleanupWriteRequest(err error) { + cc := cs.cc + + if cs.ID == 0 { + // We were canceled before creating the stream, so return our reservation. + cc.decrStreamReservations() } - var respHeaderTimer <-chan time.Time - if hasBody { - bodyWriter.scheduleBodyWrite() - } else { - traceWroteRequest(cs.trace, nil) - if d := cc.responseHeaderTimeout(); d != 0 { - timer := time.NewTimer(d) - defer timer.Stop() - respHeaderTimer = timer.C - } - } - - readLoopResCh := cs.resc - bodyWritten := false - - handleReadLoopResponse := func(re resAndError) (*http.Response, bool, error) { - res := re.res - if re.err != nil || res.StatusCode > 299 { - // On error or status code 3xx, 4xx, 5xx, etc abort any - // ongoing write, assuming that the server doesn't care - // about our request body. If the server replied with 1xx or - // 2xx, however, then assume the server DOES potentially - // want our body (e.g. full-duplex streaming: - // golang.org/issue/13444). If it turns out the server - // doesn't, they'll RST_STREAM us soon enough. This is a - // heuristic to avoid adding knobs to Transport. Hopefully - // we can keep it. - bodyWriter.cancel() - cs.abortRequestBodyWrite(errStopReqBodyWrite) - if hasBody && !bodyWritten { - <-bodyWriter.resc + // TODO: write h12Compare test showing whether + // Request.Body is closed by the Transport, + // and in multiple cases: server replies <=299 and >299 + // while still writing request body + cc.mu.Lock() + bodyClosed := cs.reqBodyClosed + cs.reqBodyClosed = true + cc.mu.Unlock() + if !bodyClosed && cs.reqBody != nil { + cs.reqBody.Close() + } + + if err != nil && cs.sentEndStream { + // If the connection is closed immediately after the response is read, + // we may be aborted before finishing up here. If the stream was closed + // cleanly on both sides, there is no error. + select { + case <-cs.peerClosed: + err = nil + default: + } + } + if err != nil { + cs.abortStream(err) // possibly redundant, but harmless + if cs.sentHeaders { + if se, ok := err.(StreamError); ok { + if se.Cause != errFromPeer { + cc.writeStreamReset(cs.ID, se.Code, err) + } + } else { + cc.writeStreamReset(cs.ID, ErrCodeCancel, err) } } - if re.err != nil { - cc.forgetStreamID(cs.ID) - return nil, cs.getStartedWrite(), re.err + cs.bufPipe.CloseWithError(err) // no-op if already closed + } else { + if cs.sentHeaders && !cs.sentEndStream { + cc.writeStreamReset(cs.ID, ErrCodeNo, nil) } - res.Request = req - res.TLS = cc.tlsState - return res, false, nil + cs.bufPipe.CloseWithError(errRequestCanceled) } - - handleError := func(err error) (*http.Response, bool, error) { - if !hasBody || bodyWritten { - cc.writeStreamReset(cs.ID, ErrCodeCancel, nil) - } else { - bodyWriter.cancel() - cs.abortRequestBodyWrite(errStopReqBodyWriteAndCancel) - <-bodyWriter.resc - } + if cs.ID != 0 { cc.forgetStreamID(cs.ID) - return nil, cs.getStartedWrite(), err } - for { - select { - case re := <-readLoopResCh: - return handleReadLoopResponse(re) - case <-respHeaderTimer: - return handleError(errTimeout) - case <-ctx.Done(): - return handleError(ctx.Err()) - case <-req.Cancel: - return handleError(errRequestCanceled) - case <-cs.peerReset: - // processResetStream already removed the - // stream from the streams map; no need for - // forgetStreamID. - return nil, cs.getStartedWrite(), cs.resetErr - case err := <-bodyWriter.resc: - bodyWritten = true - // Prefer the read loop's response, if available. Issue 16102. - select { - case re := <-readLoopResCh: - return handleReadLoopResponse(re) - default: - } - if err != nil { - cc.forgetStreamID(cs.ID) - return nil, cs.getStartedWrite(), err - } - if d := cc.responseHeaderTimeout(); d != 0 { - timer := time.NewTimer(d) - defer timer.Stop() - respHeaderTimer = timer.C - } - } + cc.wmu.Lock() + werr := cc.werr + cc.wmu.Unlock() + if werr != nil { + cc.Close() } + + close(cs.donec) } -// awaitOpenSlotForRequest waits until len(streams) < maxConcurrentStreams. +// awaitOpenSlotForStream waits until len(streams) < maxConcurrentStreams. // Must hold cc.mu. -func (cc *ClientConn) awaitOpenSlotForRequest(req *http.Request) error { - var waitingForConn chan struct{} - var waitingForConnErr error // guarded by cc.mu +func (cc *ClientConn) awaitOpenSlotForStreamLocked(cs *clientStream) error { for { cc.lastActive = time.Now() if cc.closed || !cc.canTakeNewRequestLocked() { - if waitingForConn != nil { - close(waitingForConn) - } return errClientConnUnusable } cc.lastIdle = time.Time{} if int64(len(cc.streams)) < int64(cc.maxConcurrentStreams) { - if waitingForConn != nil { - close(waitingForConn) - } return nil } - // Unfortunately, we cannot wait on a condition variable and channel at - // the same time, so instead, we spin up a goroutine to check if the - // request is canceled while we wait for a slot to open in the connection. - if waitingForConn == nil { - waitingForConn = make(chan struct{}) - go func() { - if err := awaitRequestCancel(req, waitingForConn); err != nil { - cc.mu.Lock() - waitingForConnErr = err - cc.cond.Broadcast() - cc.mu.Unlock() - } - }() - } cc.pendingRequests++ cc.cond.Wait() cc.pendingRequests-- - if waitingForConnErr != nil { - return waitingForConnErr + select { + case <-cs.abort: + return cs.abortErr + default: } } } @@ -1352,10 +1451,6 @@ func (cc *ClientConn) writeHeaders(streamID uint32, endStream bool, maxFrameSize cc.fr.WriteContinuation(streamID, endHeaders, chunk) } } - // TODO(bradfitz): this Flush could potentially block (as - // could the WriteHeaders call(s) above), which means they - // wouldn't respond to Request.Cancel being readable. That's - // rare, but this should probably be in a goroutine. cc.bw.Flush() return cc.werr } @@ -1382,7 +1477,7 @@ func (cs *clientStream) frameScratchBufferLen(maxFrameSize int) int { if n > max { n = max } - if cl := actualContentLength(cs.req); cl != -1 && cl+1 < n { + if cl := cs.reqBodyContentLength; cl != -1 && cl+1 < n { // Add an extra byte past the declared content-length to // give the caller's Request.Body io.Reader a chance to // give us more bytes than they declared, so we can catch it @@ -1397,31 +1492,13 @@ func (cs *clientStream) frameScratchBufferLen(maxFrameSize int) int { var bufPool sync.Pool // of *[]byte -func (cs *clientStream) writeRequestBody(body io.Reader, bodyCloser io.Closer) (err error) { +func (cs *clientStream) writeRequestBody(req *http.Request) (err error) { cc := cs.cc + body := cs.reqBody sentEnd := false // whether we sent the final DATA frame w/ END_STREAM - defer func() { - traceWroteRequest(cs.trace, err) - // TODO: write h12Compare test showing whether - // Request.Body is closed by the Transport, - // and in multiple cases: server replies <=299 and >299 - // while still writing request body - var cerr error - cc.mu.Lock() - if cs.stopReqBody == nil { - cs.stopReqBody = errStopReqBodyWrite - cerr = bodyCloser.Close() - } - cc.mu.Unlock() - if err == nil { - err = cerr - } - }() - - req := cs.req hasTrailers := req.Trailer != nil - remainLen := actualContentLength(req) + remainLen := cs.reqBodyContentLength hasContentLen := remainLen != -1 cc.mu.Lock() @@ -1459,29 +1536,29 @@ func (cs *clientStream) writeRequestBody(body io.Reader, bodyCloser io.Closer) ( } if remainLen < 0 { err = errReqBodyTooLong - cc.writeStreamReset(cs.ID, ErrCodeCancel, err) return err } } - if err == io.EOF { - sawEOF = true - err = nil - } else if err != nil { - cc.writeStreamReset(cs.ID, ErrCodeCancel, err) - return err + if err != nil { + cc.mu.Lock() + bodyClosed := cs.reqBodyClosed + cc.mu.Unlock() + switch { + case bodyClosed: + return errStopReqBodyWrite + case err == io.EOF: + sawEOF = true + err = nil + default: + return err + } } remain := buf[:n] for len(remain) > 0 && err == nil { var allowed int32 allowed, err = cs.awaitFlowControl(len(remain)) - switch { - case err == errStopReqBodyWrite: - return err - case err == errStopReqBodyWriteAndCancel: - cc.writeStreamReset(cs.ID, ErrCodeCancel, nil) - return err - case err != nil: + if err != nil { return err } cc.wmu.Lock() @@ -1512,18 +1589,26 @@ func (cs *clientStream) writeRequestBody(body io.Reader, bodyCloser io.Closer) ( return nil } + // Since the RoundTrip contract permits the caller to "mutate or reuse" + // a request after the Response's Body is closed, verify that this hasn't + // happened before accessing the trailers. + cc.mu.Lock() + trailer := req.Trailer + err = cs.abortErr + cc.mu.Unlock() + if err != nil { + return err + } + cc.wmu.Lock() + defer cc.wmu.Unlock() var trls []byte - if hasTrailers { - trls, err = cc.encodeTrailers(req) + if len(trailer) > 0 { + trls, err = cc.encodeTrailers(trailer) if err != nil { - cc.wmu.Unlock() - cc.writeStreamReset(cs.ID, ErrCodeInternal, err) - cc.forgetStreamID(cs.ID) return err } } - defer cc.wmu.Unlock() // Two ways to send END_STREAM: either with trailers, or // with an empty DATA frame. @@ -1544,17 +1629,24 @@ func (cs *clientStream) writeRequestBody(body io.Reader, bodyCloser io.Closer) ( // if the stream is dead. func (cs *clientStream) awaitFlowControl(maxBytes int) (taken int32, err error) { cc := cs.cc + ctx := cs.ctx cc.mu.Lock() defer cc.mu.Unlock() for { if cc.closed { return 0, errClientConnClosed } - if cs.stopReqBody != nil { - return 0, cs.stopReqBody + if cs.reqBodyClosed { + return 0, errStopReqBodyWrite } - if err := cs.checkResetOrDone(); err != nil { - return 0, err + select { + case <-cs.abort: + return 0, cs.abortErr + case <-ctx.Done(): + return 0, ctx.Err() + case <-cs.reqCancel: + return 0, errRequestCanceled + default: } if a := cs.flow.available(); a > 0 { take := a @@ -1766,11 +1858,11 @@ func shouldSendReqContentLength(method string, contentLength int64) bool { } // requires cc.wmu be held. -func (cc *ClientConn) encodeTrailers(req *http.Request) ([]byte, error) { +func (cc *ClientConn) encodeTrailers(trailer http.Header) ([]byte, error) { cc.hbuf.Reset() hlSize := uint64(0) - for k, vv := range req.Trailer { + for k, vv := range trailer { for _, v := range vv { hf := hpack.HeaderField{Name: k, Value: v} hlSize += uint64(hf.Size()) @@ -1780,7 +1872,7 @@ func (cc *ClientConn) encodeTrailers(req *http.Request) ([]byte, error) { return nil, errRequestHeaderListSize } - for k, vv := range req.Trailer { + for k, vv := range trailer { lowKey, ascii := asciiToLower(k) if !ascii { // Skip writing invalid headers. Per RFC 7540, Section 8.1.2, header @@ -1810,51 +1902,51 @@ type resAndError struct { } // requires cc.mu be held. -func (cc *ClientConn) newStream() *clientStream { - cs := &clientStream{ - cc: cc, - ID: cc.nextStreamID, - resc: make(chan resAndError, 1), - peerReset: make(chan struct{}), - done: make(chan struct{}), - } +func (cc *ClientConn) addStreamLocked(cs *clientStream) { cs.flow.add(int32(cc.initialWindowSize)) cs.flow.setConnFlow(&cc.flow) cs.inflow.add(transportDefaultStreamFlow) cs.inflow.setConnFlow(&cc.inflow) + cs.ID = cc.nextStreamID cc.nextStreamID += 2 cc.streams[cs.ID] = cs - return cs + if cs.ID == 0 { + panic("assigned stream ID 0") + } } func (cc *ClientConn) forgetStreamID(id uint32) { - cc.streamByID(id, true) -} - -func (cc *ClientConn) streamByID(id uint32, andRemove bool) *clientStream { cc.mu.Lock() - defer cc.mu.Unlock() - cs := cc.streams[id] - if andRemove && cs != nil && !cc.closed { - cc.lastActive = time.Now() - delete(cc.streams, id) - if len(cc.streams) == 0 && cc.idleTimer != nil { - cc.idleTimer.Reset(cc.idleTimeout) - cc.lastIdle = time.Now() - } - close(cs.done) - // Wake up checkResetOrDone via clientStream.awaitFlowControl and - // wake up RoundTrip if there is a pending request. - cc.cond.Broadcast() + slen := len(cc.streams) + delete(cc.streams, id) + if len(cc.streams) != slen-1 { + panic("forgetting unknown stream id") + } + cc.lastActive = time.Now() + if len(cc.streams) == 0 && cc.idleTimer != nil { + cc.idleTimer.Reset(cc.idleTimeout) + cc.lastIdle = time.Now() + } + // Wake up writeRequestBody via clientStream.awaitFlowControl and + // wake up RoundTrip if there is a pending request. + cc.cond.Broadcast() + + closeOnIdle := cc.singleUse || cc.doNotReuse || cc.t.disableKeepAlives() + if closeOnIdle && cc.streamsReserved == 0 && len(cc.streams) == 0 { + if VerboseLogs { + cc.vlogf("http2: Transport closing idle conn %p (forSingleUse=%v, maxStream=%v)", cc, cc.singleUse, cc.nextStreamID-2) + } + cc.closed = true + defer cc.tconn.Close() } - return cs + + cc.mu.Unlock() } // clientConnReadLoop is the state owned by the clientConn's frame-reading readLoop. type clientConnReadLoop struct { - _ incomparable - cc *ClientConn - closeWhenIdle bool + _ incomparable + cc *ClientConn } // readLoop runs in its own goroutine and reads and dispatches frames. @@ -1915,18 +2007,15 @@ func (rl *clientConnReadLoop) cleanup() { err = io.ErrUnexpectedEOF } cc.closed = true - streams := cc.streams - cc.streams = nil - cc.mu.Unlock() - for _, cs := range streams { - cs.bufPipe.CloseWithError(err) // no-op if already closed + for _, cs := range cc.streams { select { - case cs.resc <- resAndError{err: err}: + case <-cs.peerClosed: + // The server closed the stream before closing the conn, + // so no need to interrupt it. default: + cs.abortStreamLocked(err) } - close(cs.done) } - cc.mu.Lock() cc.cond.Broadcast() cc.mu.Unlock() } @@ -1960,8 +2049,6 @@ func (cc *ClientConn) countReadFrameError(err error) { func (rl *clientConnReadLoop) run() error { cc := rl.cc - rl.closeWhenIdle = cc.t.disableKeepAlives() || cc.singleUse - gotReply := false // ever saw a HEADERS reply gotSettings := false readIdleTimeout := cc.t.ReadIdleTimeout var t *time.Timer @@ -1978,9 +2065,7 @@ func (rl *clientConnReadLoop) run() error { cc.vlogf("http2: Transport readFrame error on conn %p: (%T) %v", cc, err, err) } if se, ok := err.(StreamError); ok { - if cs := cc.streamByID(se.StreamID, false); cs != nil { - cs.cc.writeStreamReset(cs.ID, se.Code, err) - cs.cc.forgetStreamID(cs.ID) + if cs := rl.streamByID(se.StreamID); cs != nil { if se.Cause == nil { se.Cause = cc.fr.errDetail } @@ -2001,22 +2086,16 @@ func (rl *clientConnReadLoop) run() error { } gotSettings = true } - maybeIdle := false // whether frame might transition us to idle switch f := f.(type) { case *MetaHeadersFrame: err = rl.processHeaders(f) - maybeIdle = true - gotReply = true case *DataFrame: err = rl.processData(f) - maybeIdle = true case *GoAwayFrame: err = rl.processGoAway(f) - maybeIdle = true case *RSTStreamFrame: err = rl.processResetStream(f) - maybeIdle = true case *SettingsFrame: err = rl.processSettings(f) case *PushPromiseFrame: @@ -2034,38 +2113,24 @@ func (rl *clientConnReadLoop) run() error { } return err } - if rl.closeWhenIdle && gotReply && maybeIdle { - cc.closeIfIdle() - } } } func (rl *clientConnReadLoop) processHeaders(f *MetaHeadersFrame) error { - cc := rl.cc - cs := cc.streamByID(f.StreamID, false) + cs := rl.streamByID(f.StreamID) if cs == nil { // We'd get here if we canceled a request while the // server had its response still in flight. So if this // was just something we canceled, ignore it. return nil } - if f.StreamEnded() { - // Issue 20521: If the stream has ended, streamByID() causes - // clientStream.done to be closed, which causes the request's bodyWriter - // to be closed with an errStreamClosed, which may be received by - // clientConn.RoundTrip before the result of processing these headers. - // Deferring stream closure allows the header processing to occur first. - // clientConn.RoundTrip may still receive the bodyWriter error first, but - // the fix for issue 16102 prioritises any response. - // - // Issue 22413: If there is no request body, we should close the - // stream before writing to cs.resc so that the stream is closed - // immediately once RoundTrip returns. - if cs.req.Body != nil { - defer cc.forgetStreamID(f.StreamID) - } else { - cc.forgetStreamID(f.StreamID) - } + if cs.readClosed { + rl.endStreamError(cs, StreamError{ + StreamID: f.StreamID, + Code: ErrCodeProtocol, + Cause: errors.New("protocol error: headers after END_STREAM"), + }) + return nil } if !cs.firstByte { if cs.trace != nil { @@ -2089,9 +2154,11 @@ func (rl *clientConnReadLoop) processHeaders(f *MetaHeadersFrame) error { return err } // Any other error type is a stream error. - cs.cc.writeStreamReset(f.StreamID, ErrCodeProtocol, err) - cc.forgetStreamID(cs.ID) - cs.resc <- resAndError{err: err} + rl.endStreamError(cs, StreamError{ + StreamID: f.StreamID, + Code: ErrCodeProtocol, + Cause: err, + }) return nil // return nil from process* funcs to keep conn alive } if res == nil { @@ -2099,7 +2166,11 @@ func (rl *clientConnReadLoop) processHeaders(f *MetaHeadersFrame) error { return nil } cs.resTrailer = &res.Trailer - cs.resc <- resAndError{res: res} + cs.res = res + close(cs.respHeaderRecv) + if f.StreamEnded() { + rl.endStream(cs) + } return nil } @@ -2161,6 +2232,9 @@ func (rl *clientConnReadLoop) handleResponse(cs *clientStream, f *MetaHeadersFra } if statusCode >= 100 && statusCode <= 199 { + if f.StreamEnded() { + return nil, errors.New("1xx informational response with END_STREAM flag") + } cs.num1xx++ const max1xxResponses = 5 // arbitrary bound on number of informational responses, same as net/http if cs.num1xx > max1xxResponses { @@ -2173,40 +2247,45 @@ func (rl *clientConnReadLoop) handleResponse(cs *clientStream, f *MetaHeadersFra } if statusCode == 100 { traceGot100Continue(cs.trace) - if cs.on100 != nil { - cs.on100() // forces any write delay timer to fire + select { + case cs.on100 <- struct{}{}: + default: } } cs.pastHeaders = false // do it all again return nil, nil } - streamEnded := f.StreamEnded() - isHead := cs.req.Method == "HEAD" - if !streamEnded || isHead { - res.ContentLength = -1 - if clens := res.Header["Content-Length"]; len(clens) == 1 { - if cl, err := strconv.ParseUint(clens[0], 10, 63); err == nil { - res.ContentLength = int64(cl) - } else { - // TODO: care? unlike http/1, it won't mess up our framing, so it's - // more safe smuggling-wise to ignore. - } - } else if len(clens) > 1 { + res.ContentLength = -1 + if clens := res.Header["Content-Length"]; len(clens) == 1 { + if cl, err := strconv.ParseUint(clens[0], 10, 63); err == nil { + res.ContentLength = int64(cl) + } else { // TODO: care? unlike http/1, it won't mess up our framing, so it's // more safe smuggling-wise to ignore. } + } else if len(clens) > 1 { + // TODO: care? unlike http/1, it won't mess up our framing, so it's + // more safe smuggling-wise to ignore. } - if streamEnded || isHead { + if cs.isHead { res.Body = noBody return res, nil } - cs.bufPipe = pipe{b: &dataBuffer{expected: res.ContentLength}} + if f.StreamEnded() { + if res.ContentLength > 0 { + res.Body = missingBody{} + } else { + res.Body = noBody + } + return res, nil + } + + cs.bufPipe.setBuffer(&dataBuffer{expected: res.ContentLength}) cs.bytesRemain = res.ContentLength res.Body = transportResponseBody{cs} - go cs.awaitRequestCancel(cs.req) if cs.requestedGzip && res.Header.Get("Content-Encoding") == "gzip" { res.Header.Del("Content-Encoding") @@ -2247,8 +2326,7 @@ func (rl *clientConnReadLoop) processTrailers(cs *clientStream, f *MetaHeadersFr } // transportResponseBody is the concrete type of Transport.RoundTrip's -// Response.Body. It is an io.ReadCloser. On Read, it reads from cs.body. -// On Close it sends RST_STREAM if EOF wasn't already seen. +// Response.Body. It is an io.ReadCloser. type transportResponseBody struct { cs *clientStream } @@ -2266,7 +2344,7 @@ func (b transportResponseBody) Read(p []byte) (n int, err error) { n = int(cs.bytesRemain) if err == nil { err = errors.New("net/http: server replied with more than declared Content-Length; truncated") - cc.writeStreamReset(cs.ID, ErrCodeProtocol, err) + cs.abortStream(err) } cs.readErr = err return int(cs.bytesRemain), err @@ -2322,24 +2400,18 @@ func (b transportResponseBody) Close() error { cs := b.cs cc := cs.cc - serverSentStreamEnd := cs.bufPipe.Err() == io.EOF unread := cs.bufPipe.Len() - - if unread > 0 || !serverSentStreamEnd { + if unread > 0 { cc.mu.Lock() - if !serverSentStreamEnd { - cs.didReset = true - } // Return connection-level flow control. if unread > 0 { cc.inflow.add(int32(unread)) } cc.mu.Unlock() + // TODO(dneil): Acquiring this mutex can block indefinitely. + // Move flow control return to a goroutine? cc.wmu.Lock() - if !serverSentStreamEnd { - cc.fr.WriteRSTStream(cs.ID, ErrCodeCancel) - } // Return connection-level flow control. if unread > 0 { cc.fr.WriteWindowUpdate(0, uint32(unread)) @@ -2349,16 +2421,21 @@ func (b transportResponseBody) Close() error { } cs.bufPipe.BreakWithError(errClosedResponseBody) - cc.forgetStreamID(cs.ID) + cs.abortStream(errClosedResponseBody) + + select { + case <-cs.donec: + case <-cs.ctx.Done(): + return cs.ctx.Err() + case <-cs.reqCancel: + return errRequestCanceled + } return nil } func (rl *clientConnReadLoop) processData(f *DataFrame) error { cc := rl.cc - cs := cc.streamByID(f.StreamID, f.StreamEnded()) - if f.StreamEnded() && cc.isDoNotReuseAndIdle() { - rl.closeWhenIdle = true - } + cs := rl.streamByID(f.StreamID) data := f.Data() if cs == nil { cc.mu.Lock() @@ -2387,6 +2464,14 @@ func (rl *clientConnReadLoop) processData(f *DataFrame) error { } return nil } + if cs.readClosed { + cc.logf("protocol error: received DATA after END_STREAM") + rl.endStreamError(cs, StreamError{ + StreamID: f.StreamID, + Code: ErrCodeProtocol, + }) + return nil + } if !cs.firstByte { cc.logf("protocol error: received DATA before a HEADERS frame") rl.endStreamError(cs, StreamError{ @@ -2396,7 +2481,7 @@ func (rl *clientConnReadLoop) processData(f *DataFrame) error { return nil } if f.Length > 0 { - if cs.req.Method == "HEAD" && len(data) > 0 { + if cs.isHead && len(data) > 0 { cc.logf("protocol error: received DATA on a HEAD request") rl.endStreamError(cs, StreamError{ StreamID: f.StreamID, @@ -2418,12 +2503,18 @@ func (rl *clientConnReadLoop) processData(f *DataFrame) error { if pad := int(f.Length) - len(data); pad > 0 { refund += pad } - // Return len(data) now if the stream is already closed, - // since data will never be read. - didReset := cs.didReset - if didReset { - refund += len(data) + + didReset := false + var err error + if len(data) > 0 { + if _, err = cs.bufPipe.Write(data); err != nil { + // Return len(data) now if the stream is already closed, + // since data will never be read. + didReset = true + refund += len(data) + } } + if refund > 0 { cc.inflow.add(int32(refund)) if !didReset { @@ -2442,11 +2533,9 @@ func (rl *clientConnReadLoop) processData(f *DataFrame) error { cc.wmu.Unlock() } - if len(data) > 0 && !didReset { - if _, err := cs.bufPipe.Write(data); err != nil { - rl.endStreamError(cs, err) - return err - } + if err != nil { + rl.endStreamError(cs, err) + return nil } } @@ -2459,24 +2548,26 @@ func (rl *clientConnReadLoop) processData(f *DataFrame) error { func (rl *clientConnReadLoop) endStream(cs *clientStream) { // TODO: check that any declared content-length matches, like // server.go's (*stream).endStream method. - rl.endStreamError(cs, nil) + if !cs.readClosed { + cs.readClosed = true + cs.bufPipe.closeWithErrorAndCode(io.EOF, cs.copyTrailers) + close(cs.peerClosed) + } } func (rl *clientConnReadLoop) endStreamError(cs *clientStream, err error) { - var code func() - if err == nil { - err = io.EOF - code = cs.copyTrailers - } - if isConnectionCloseRequest(cs.req) { - rl.closeWhenIdle = true - } - cs.bufPipe.closeWithErrorAndCode(err, code) + cs.readAborted = true + cs.abortStream(err) +} - select { - case cs.resc <- resAndError{err: err}: - default: +func (rl *clientConnReadLoop) streamByID(id uint32) *clientStream { + rl.cc.mu.Lock() + defer rl.cc.mu.Unlock() + cs := rl.cc.streams[id] + if cs != nil && !cs.readAborted { + return cs } + return nil } func (cs *clientStream) copyTrailers() { @@ -2589,7 +2680,7 @@ func (rl *clientConnReadLoop) processSettingsNoWrite(f *SettingsFrame) error { func (rl *clientConnReadLoop) processWindowUpdate(f *WindowUpdateFrame) error { cc := rl.cc - cs := cc.streamByID(f.StreamID, false) + cs := rl.streamByID(f.StreamID) if f.StreamID != 0 && cs == nil { return nil } @@ -2609,36 +2700,22 @@ func (rl *clientConnReadLoop) processWindowUpdate(f *WindowUpdateFrame) error { } func (rl *clientConnReadLoop) processResetStream(f *RSTStreamFrame) error { - cc := rl.cc - cs := cc.streamByID(f.StreamID, true) + cs := rl.streamByID(f.StreamID) if cs == nil { // TODO: return error if server tries to RST_STREAM an idle stream return nil } - if cc.isDoNotReuseAndIdle() { - rl.closeWhenIdle = true + serr := streamError(cs.ID, f.ErrCode) + serr.Cause = errFromPeer + if f.ErrCode == ErrCodeProtocol { + rl.cc.SetDoNotReuse() } - select { - case <-cs.peerReset: - // Already reset. - // This is the only goroutine - // which closes this, so there - // isn't a race. - default: - serr := streamError(cs.ID, f.ErrCode) - if f.ErrCode == ErrCodeProtocol { - rl.cc.SetDoNotReuse() - serr.Cause = errFromPeer - rl.closeWhenIdle = true - } - if fn := cs.cc.t.CountError; fn != nil { - fn("recv_rststream_" + f.ErrCode.stringToken()) - } - cs.resetErr = serr - close(cs.peerReset) - cs.bufPipe.CloseWithError(serr) - cs.cc.cond.Broadcast() // wake up checkResetOrDone via clientStream.awaitFlowControl + if fn := cs.cc.t.CountError; fn != nil { + fn("recv_rststream_" + f.ErrCode.stringToken()) } + cs.abortStream(serr) + + cs.bufPipe.CloseWithError(serr) return nil } @@ -2660,19 +2737,24 @@ func (cc *ClientConn) Ping(ctx context.Context) error { } cc.mu.Unlock() } - cc.wmu.Lock() - if err := cc.fr.WritePing(false, p); err != nil { - cc.wmu.Unlock() - return err - } - if err := cc.bw.Flush(); err != nil { - cc.wmu.Unlock() - return err - } - cc.wmu.Unlock() + errc := make(chan error, 1) + go func() { + cc.wmu.Lock() + defer cc.wmu.Unlock() + if err := cc.fr.WritePing(false, p); err != nil { + errc <- err + return + } + if err := cc.bw.Flush(); err != nil { + errc <- err + return + } + }() select { case <-c: return nil + case err := <-errc: + return err case <-ctx.Done(): return ctx.Err() case <-cc.readerDone: @@ -2749,6 +2831,11 @@ func (t *Transport) logf(format string, args ...interface{}) { var noBody io.ReadCloser = ioutil.NopCloser(bytes.NewReader(nil)) +type missingBody struct{} + +func (missingBody) Close() error { return nil } +func (missingBody) Read([]byte) (int, error) { return 0, io.ErrUnexpectedEOF } + func strSliceContains(ss []string, s string) bool { for _, v := range ss { if v == s { @@ -2794,87 +2881,6 @@ type errorReader struct{ err error } func (r errorReader) Read(p []byte) (int, error) { return 0, r.err } -// bodyWriterState encapsulates various state around the Transport's writing -// of the request body, particularly regarding doing delayed writes of the body -// when the request contains "Expect: 100-continue". -type bodyWriterState struct { - cs *clientStream - timer *time.Timer // if non-nil, we're doing a delayed write - fnonce *sync.Once // to call fn with - fn func() // the code to run in the goroutine, writing the body - resc chan error // result of fn's execution - delay time.Duration // how long we should delay a delayed write for -} - -func (t *Transport) getBodyWriterState(cs *clientStream, body io.Reader) (s bodyWriterState) { - s.cs = cs - if body == nil { - return - } - resc := make(chan error, 1) - s.resc = resc - s.fn = func() { - cs.cc.mu.Lock() - cs.startedWrite = true - cs.cc.mu.Unlock() - resc <- cs.writeRequestBody(body, cs.req.Body) - } - s.delay = t.expectContinueTimeout() - if s.delay == 0 || - !httpguts.HeaderValuesContainsToken( - cs.req.Header["Expect"], - "100-continue") { - return - } - s.fnonce = new(sync.Once) - - // Arm the timer with a very large duration, which we'll - // intentionally lower later. It has to be large now because - // we need a handle to it before writing the headers, but the - // s.delay value is defined to not start until after the - // request headers were written. - const hugeDuration = 365 * 24 * time.Hour - s.timer = time.AfterFunc(hugeDuration, func() { - s.fnonce.Do(s.fn) - }) - return -} - -func (s bodyWriterState) cancel() { - if s.timer != nil { - if s.timer.Stop() { - s.resc <- nil - } - } -} - -func (s bodyWriterState) on100() { - if s.timer == nil { - // If we didn't do a delayed write, ignore the server's - // bogus 100 continue response. - return - } - s.timer.Stop() - go func() { s.fnonce.Do(s.fn) }() -} - -// scheduleBodyWrite starts writing the body, either immediately (in -// the common case) or after the delay timeout. It should not be -// called until after the headers have been written. -func (s bodyWriterState) scheduleBodyWrite() { - if s.timer == nil { - // We're not doing a delayed write (see - // getBodyWriterState), so just start the writing - // goroutine immediately. - go s.fn() - return - } - traceWait100Continue(s.cs.trace) - if s.timer.Stop() { - s.timer.Reset(s.delay) - } -} - // isConnectionCloseRequest reports whether req should use its own // connection for a single request and then close the connection. func isConnectionCloseRequest(req *http.Request) bool { diff --git a/vendor/golang.org/x/oauth2/google/google.go b/vendor/golang.org/x/oauth2/google/google.go index 422ff1fe34..41ced10acd 100644 --- a/vendor/golang.org/x/oauth2/google/google.go +++ b/vendor/golang.org/x/oauth2/google/google.go @@ -123,6 +123,7 @@ type credentialsFile struct { ServiceAccountImpersonationURL string `json:"service_account_impersonation_url"` CredentialSource externalaccount.CredentialSource `json:"credential_source"` QuotaProjectID string `json:"quota_project_id"` + WorkforcePoolUserProject string `json:"workforce_pool_user_project"` } func (f *credentialsFile) jwtConfig(scopes []string, subject string) *jwt.Config { @@ -176,6 +177,7 @@ func (f *credentialsFile) tokenSource(ctx context.Context, params CredentialsPar CredentialSource: f.CredentialSource, QuotaProjectID: f.QuotaProjectID, Scopes: params.Scopes, + WorkforcePoolUserProject: f.WorkforcePoolUserProject, } return cfg.TokenSource(ctx) case "": diff --git a/vendor/golang.org/x/oauth2/google/internal/externalaccount/basecredentials.go b/vendor/golang.org/x/oauth2/google/internal/externalaccount/basecredentials.go index dab917f39e..a1e36c0c70 100644 --- a/vendor/golang.org/x/oauth2/google/internal/externalaccount/basecredentials.go +++ b/vendor/golang.org/x/oauth2/google/internal/externalaccount/basecredentials.go @@ -53,6 +53,11 @@ type Config struct { QuotaProjectID string // Scopes contains the desired scopes for the returned access token. Scopes []string + // The optional workforce pool user project number when the credential + // corresponds to a workforce pool and not a workload identity pool. + // The underlying principal must still have serviceusage.services.use IAM + // permission to use the project for billing/quota. + WorkforcePoolUserProject string } // Each element consists of a list of patterns. validateURLs checks for matches @@ -73,6 +78,7 @@ var ( regexp.MustCompile(`^iamcredentials\.[^\.\s\/\\]+\.googleapis\.com$`), regexp.MustCompile(`^[^\.\s\/\\]+-iamcredentials\.googleapis\.com$`), } + validWorkforceAudiencePattern *regexp.Regexp = regexp.MustCompile(`//iam\.googleapis\.com/locations/[^/]+/workforcePools/`) ) func validateURL(input string, patterns []*regexp.Regexp, scheme string) bool { @@ -86,14 +92,17 @@ func validateURL(input string, patterns []*regexp.Regexp, scheme string) bool { toTest := parsed.Host for _, pattern := range patterns { - - if valid := pattern.MatchString(toTest); valid { + if pattern.MatchString(toTest) { return true } } return false } +func validateWorkforceAudience(input string) bool { + return validWorkforceAudiencePattern.MatchString(input) +} + // TokenSource Returns an external account TokenSource struct. This is to be called by package google to construct a google.Credentials. func (c *Config) TokenSource(ctx context.Context) (oauth2.TokenSource, error) { return c.tokenSource(ctx, validTokenURLPatterns, validImpersonateURLPatterns, "https") @@ -115,6 +124,13 @@ func (c *Config) tokenSource(ctx context.Context, tokenURLValidPats []*regexp.Re } } + if c.WorkforcePoolUserProject != "" { + valid := validateWorkforceAudience(c.Audience) + if !valid { + return nil, fmt.Errorf("oauth2/google: workforce_pool_user_project should not be set for non-workforce pool credentials") + } + } + ts := tokenSource{ ctx: ctx, conf: c, @@ -224,7 +240,15 @@ func (ts tokenSource) Token() (*oauth2.Token, error) { ClientID: conf.ClientID, ClientSecret: conf.ClientSecret, } - stsResp, err := exchangeToken(ts.ctx, conf.TokenURL, &stsRequest, clientAuth, header, nil) + var options map[string]interface{} + // Do not pass workforce_pool_user_project when client authentication is used. + // The client ID is sufficient for determining the user project. + if conf.WorkforcePoolUserProject != "" && conf.ClientID == "" { + options = map[string]interface{}{ + "userProject": conf.WorkforcePoolUserProject, + } + } + stsResp, err := exchangeToken(ts.ctx, conf.TokenURL, &stsRequest, clientAuth, header, options) if err != nil { return nil, err } diff --git a/vendor/golang.org/x/sys/unix/mkerrors.sh b/vendor/golang.org/x/sys/unix/mkerrors.sh index 850aafec1e..a74ef58f8c 100644 --- a/vendor/golang.org/x/sys/unix/mkerrors.sh +++ b/vendor/golang.org/x/sys/unix/mkerrors.sh @@ -54,7 +54,7 @@ includes_AIX=' includes_Darwin=' #define _DARWIN_C_SOURCE -#define KERNEL +#define KERNEL 1 #define _DARWIN_USE_64_BIT_INODE #define __APPLE_USE_RFC_3542 #include @@ -75,6 +75,7 @@ includes_Darwin=' #include #include #include +#include #include #include #include @@ -82,6 +83,9 @@ includes_Darwin=' #include #include #include + +// for backwards compatibility because moved TIOCREMOTE to Kernel.framework after MacOSX12.0.sdk. +#define TIOCREMOTE 0x80047469 ' includes_DragonFly=' @@ -466,7 +470,6 @@ ccflags="$@" $2 !~ /^EQUIV_/ && $2 !~ /^EXPR_/ && $2 !~ /^EVIOC/ && - $2 !~ /^EV_/ && $2 ~ /^E[A-Z0-9_]+$/ || $2 ~ /^B[0-9_]+$/ || $2 ~ /^(OLD|NEW)DEV$/ || diff --git a/vendor/golang.org/x/sys/unix/sockcmsg_linux.go b/vendor/golang.org/x/sys/unix/sockcmsg_linux.go index 8bf4570594..326fb04a52 100644 --- a/vendor/golang.org/x/sys/unix/sockcmsg_linux.go +++ b/vendor/golang.org/x/sys/unix/sockcmsg_linux.go @@ -34,3 +34,56 @@ func ParseUnixCredentials(m *SocketControlMessage) (*Ucred, error) { ucred := *(*Ucred)(unsafe.Pointer(&m.Data[0])) return &ucred, nil } + +// PktInfo4 encodes Inet4Pktinfo into a socket control message of type IP_PKTINFO. +func PktInfo4(info *Inet4Pktinfo) []byte { + b := make([]byte, CmsgSpace(SizeofInet4Pktinfo)) + h := (*Cmsghdr)(unsafe.Pointer(&b[0])) + h.Level = SOL_IP + h.Type = IP_PKTINFO + h.SetLen(CmsgLen(SizeofInet4Pktinfo)) + *(*Inet4Pktinfo)(h.data(0)) = *info + return b +} + +// PktInfo6 encodes Inet6Pktinfo into a socket control message of type IPV6_PKTINFO. +func PktInfo6(info *Inet6Pktinfo) []byte { + b := make([]byte, CmsgSpace(SizeofInet6Pktinfo)) + h := (*Cmsghdr)(unsafe.Pointer(&b[0])) + h.Level = SOL_IPV6 + h.Type = IPV6_PKTINFO + h.SetLen(CmsgLen(SizeofInet6Pktinfo)) + *(*Inet6Pktinfo)(h.data(0)) = *info + return b +} + +// ParseOrigDstAddr decodes a socket control message containing the original +// destination address. To receive such a message the IP_RECVORIGDSTADDR or +// IPV6_RECVORIGDSTADDR option must be enabled on the socket. +func ParseOrigDstAddr(m *SocketControlMessage) (Sockaddr, error) { + switch { + case m.Header.Level == SOL_IP && m.Header.Type == IP_ORIGDSTADDR: + pp := (*RawSockaddrInet4)(unsafe.Pointer(&m.Data[0])) + sa := new(SockaddrInet4) + p := (*[2]byte)(unsafe.Pointer(&pp.Port)) + sa.Port = int(p[0])<<8 + int(p[1]) + for i := 0; i < len(sa.Addr); i++ { + sa.Addr[i] = pp.Addr[i] + } + return sa, nil + + case m.Header.Level == SOL_IPV6 && m.Header.Type == IPV6_ORIGDSTADDR: + pp := (*RawSockaddrInet6)(unsafe.Pointer(&m.Data[0])) + sa := new(SockaddrInet6) + p := (*[2]byte)(unsafe.Pointer(&pp.Port)) + sa.Port = int(p[0])<<8 + int(p[1]) + sa.ZoneId = pp.Scope_id + for i := 0; i < len(sa.Addr); i++ { + sa.Addr[i] = pp.Addr[i] + } + return sa, nil + + default: + return nil, EINVAL + } +} diff --git a/vendor/golang.org/x/sys/unix/syscall_darwin.go b/vendor/golang.org/x/sys/unix/syscall_darwin.go index d59fb95c82..a8c13317d7 100644 --- a/vendor/golang.org/x/sys/unix/syscall_darwin.go +++ b/vendor/golang.org/x/sys/unix/syscall_darwin.go @@ -48,6 +48,30 @@ func (sa *SockaddrCtl) sockaddr() (unsafe.Pointer, _Socklen, error) { return unsafe.Pointer(&sa.raw), SizeofSockaddrCtl, nil } +// SockaddrVM implements the Sockaddr interface for AF_VSOCK type sockets. +// SockaddrVM provides access to Darwin VM sockets: a mechanism that enables +// bidirectional communication between a hypervisor and its guest virtual +// machines. +type SockaddrVM struct { + // CID and Port specify a context ID and port address for a VM socket. + // Guests have a unique CID, and hosts may have a well-known CID of: + // - VMADDR_CID_HYPERVISOR: refers to the hypervisor process. + // - VMADDR_CID_LOCAL: refers to local communication (loopback). + // - VMADDR_CID_HOST: refers to other processes on the host. + CID uint32 + Port uint32 + raw RawSockaddrVM +} + +func (sa *SockaddrVM) sockaddr() (unsafe.Pointer, _Socklen, error) { + sa.raw.Len = SizeofSockaddrVM + sa.raw.Family = AF_VSOCK + sa.raw.Port = sa.Port + sa.raw.Cid = sa.CID + + return unsafe.Pointer(&sa.raw), SizeofSockaddrVM, nil +} + func anyToSockaddrGOOS(fd int, rsa *RawSockaddrAny) (Sockaddr, error) { switch rsa.Addr.Family { case AF_SYSTEM: @@ -58,6 +82,13 @@ func anyToSockaddrGOOS(fd int, rsa *RawSockaddrAny) (Sockaddr, error) { sa.Unit = pp.Sc_unit return sa, nil } + case AF_VSOCK: + pp := (*RawSockaddrVM)(unsafe.Pointer(rsa)) + sa := &SockaddrVM{ + CID: pp.Cid, + Port: pp.Port, + } + return sa, nil } return nil, EAFNOSUPPORT } diff --git a/vendor/golang.org/x/sys/unix/sysvshm_unix.go b/vendor/golang.org/x/sys/unix/sysvshm_unix.go index 7d6ba360c6..0bb4c8de55 100644 --- a/vendor/golang.org/x/sys/unix/sysvshm_unix.go +++ b/vendor/golang.org/x/sys/unix/sysvshm_unix.go @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -//go:build (darwin && amd64) || linux -// +build darwin,amd64 linux +//go:build (darwin && !ios) || linux +// +build darwin,!ios linux package unix diff --git a/vendor/golang.org/x/sys/unix/sysvshm_unix_other.go b/vendor/golang.org/x/sys/unix/sysvshm_unix_other.go index 579b53bfc9..71bddefdb8 100644 --- a/vendor/golang.org/x/sys/unix/sysvshm_unix_other.go +++ b/vendor/golang.org/x/sys/unix/sysvshm_unix_other.go @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -//go:build (darwin && amd64) -// +build darwin,amd64 +//go:build darwin && !ios +// +build darwin,!ios package unix diff --git a/vendor/golang.org/x/sys/unix/zerrors_darwin_amd64.go b/vendor/golang.org/x/sys/unix/zerrors_darwin_amd64.go index a3a45fec59..476a1c7e77 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_darwin_amd64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_darwin_amd64.go @@ -12,1556 +12,1582 @@ package unix import "syscall" const ( - AF_APPLETALK = 0x10 - AF_CCITT = 0xa - AF_CHAOS = 0x5 - AF_CNT = 0x15 - AF_COIP = 0x14 - AF_DATAKIT = 0x9 - AF_DECnet = 0xc - AF_DLI = 0xd - AF_E164 = 0x1c - AF_ECMA = 0x8 - AF_HYLINK = 0xf - AF_IEEE80211 = 0x25 - AF_IMPLINK = 0x3 - AF_INET = 0x2 - AF_INET6 = 0x1e - AF_IPX = 0x17 - AF_ISDN = 0x1c - AF_ISO = 0x7 - AF_LAT = 0xe - AF_LINK = 0x12 - AF_LOCAL = 0x1 - AF_MAX = 0x29 - AF_NATM = 0x1f - AF_NDRV = 0x1b - AF_NETBIOS = 0x21 - AF_NS = 0x6 - AF_OSI = 0x7 - AF_PPP = 0x22 - AF_PUP = 0x4 - AF_RESERVED_36 = 0x24 - AF_ROUTE = 0x11 - AF_SIP = 0x18 - AF_SNA = 0xb - AF_SYSTEM = 0x20 - AF_SYS_CONTROL = 0x2 - AF_UNIX = 0x1 - AF_UNSPEC = 0x0 - AF_UTUN = 0x26 - AF_VSOCK = 0x28 - ALTWERASE = 0x200 - ATTR_BIT_MAP_COUNT = 0x5 - ATTR_CMN_ACCESSMASK = 0x20000 - ATTR_CMN_ACCTIME = 0x1000 - ATTR_CMN_ADDEDTIME = 0x10000000 - ATTR_CMN_BKUPTIME = 0x2000 - ATTR_CMN_CHGTIME = 0x800 - ATTR_CMN_CRTIME = 0x200 - ATTR_CMN_DATA_PROTECT_FLAGS = 0x40000000 - ATTR_CMN_DEVID = 0x2 - ATTR_CMN_DOCUMENT_ID = 0x100000 - ATTR_CMN_ERROR = 0x20000000 - ATTR_CMN_EXTENDED_SECURITY = 0x400000 - ATTR_CMN_FILEID = 0x2000000 - ATTR_CMN_FLAGS = 0x40000 - ATTR_CMN_FNDRINFO = 0x4000 - ATTR_CMN_FSID = 0x4 - ATTR_CMN_FULLPATH = 0x8000000 - ATTR_CMN_GEN_COUNT = 0x80000 - ATTR_CMN_GRPID = 0x10000 - ATTR_CMN_GRPUUID = 0x1000000 - ATTR_CMN_MODTIME = 0x400 - ATTR_CMN_NAME = 0x1 - ATTR_CMN_NAMEDATTRCOUNT = 0x80000 - ATTR_CMN_NAMEDATTRLIST = 0x100000 - ATTR_CMN_OBJID = 0x20 - ATTR_CMN_OBJPERMANENTID = 0x40 - ATTR_CMN_OBJTAG = 0x10 - ATTR_CMN_OBJTYPE = 0x8 - ATTR_CMN_OWNERID = 0x8000 - ATTR_CMN_PARENTID = 0x4000000 - ATTR_CMN_PAROBJID = 0x80 - ATTR_CMN_RETURNED_ATTRS = 0x80000000 - ATTR_CMN_SCRIPT = 0x100 - ATTR_CMN_SETMASK = 0x51c7ff00 - ATTR_CMN_USERACCESS = 0x200000 - ATTR_CMN_UUID = 0x800000 - ATTR_CMN_VALIDMASK = 0xffffffff - ATTR_CMN_VOLSETMASK = 0x6700 - ATTR_FILE_ALLOCSIZE = 0x4 - ATTR_FILE_CLUMPSIZE = 0x10 - ATTR_FILE_DATAALLOCSIZE = 0x400 - ATTR_FILE_DATAEXTENTS = 0x800 - ATTR_FILE_DATALENGTH = 0x200 - ATTR_FILE_DEVTYPE = 0x20 - ATTR_FILE_FILETYPE = 0x40 - ATTR_FILE_FORKCOUNT = 0x80 - ATTR_FILE_FORKLIST = 0x100 - ATTR_FILE_IOBLOCKSIZE = 0x8 - ATTR_FILE_LINKCOUNT = 0x1 - ATTR_FILE_RSRCALLOCSIZE = 0x2000 - ATTR_FILE_RSRCEXTENTS = 0x4000 - ATTR_FILE_RSRCLENGTH = 0x1000 - ATTR_FILE_SETMASK = 0x20 - ATTR_FILE_TOTALSIZE = 0x2 - ATTR_FILE_VALIDMASK = 0x37ff - ATTR_VOL_ALLOCATIONCLUMP = 0x40 - ATTR_VOL_ATTRIBUTES = 0x40000000 - ATTR_VOL_CAPABILITIES = 0x20000 - ATTR_VOL_DIRCOUNT = 0x400 - ATTR_VOL_ENCODINGSUSED = 0x10000 - ATTR_VOL_FILECOUNT = 0x200 - ATTR_VOL_FSTYPE = 0x1 - ATTR_VOL_INFO = 0x80000000 - ATTR_VOL_IOBLOCKSIZE = 0x80 - ATTR_VOL_MAXOBJCOUNT = 0x800 - ATTR_VOL_MINALLOCATION = 0x20 - ATTR_VOL_MOUNTEDDEVICE = 0x8000 - ATTR_VOL_MOUNTFLAGS = 0x4000 - ATTR_VOL_MOUNTPOINT = 0x1000 - ATTR_VOL_NAME = 0x2000 - ATTR_VOL_OBJCOUNT = 0x100 - ATTR_VOL_QUOTA_SIZE = 0x10000000 - ATTR_VOL_RESERVED_SIZE = 0x20000000 - ATTR_VOL_SETMASK = 0x80002000 - ATTR_VOL_SIGNATURE = 0x2 - ATTR_VOL_SIZE = 0x4 - ATTR_VOL_SPACEAVAIL = 0x10 - ATTR_VOL_SPACEFREE = 0x8 - ATTR_VOL_UUID = 0x40000 - ATTR_VOL_VALIDMASK = 0xf007ffff - B0 = 0x0 - B110 = 0x6e - B115200 = 0x1c200 - B1200 = 0x4b0 - B134 = 0x86 - B14400 = 0x3840 - B150 = 0x96 - B1800 = 0x708 - B19200 = 0x4b00 - B200 = 0xc8 - B230400 = 0x38400 - B2400 = 0x960 - B28800 = 0x7080 - B300 = 0x12c - B38400 = 0x9600 - B4800 = 0x12c0 - B50 = 0x32 - B57600 = 0xe100 - B600 = 0x258 - B7200 = 0x1c20 - B75 = 0x4b - B76800 = 0x12c00 - B9600 = 0x2580 - BIOCFLUSH = 0x20004268 - BIOCGBLEN = 0x40044266 - BIOCGDLT = 0x4004426a - BIOCGDLTLIST = 0xc00c4279 - BIOCGETIF = 0x4020426b - BIOCGHDRCMPLT = 0x40044274 - BIOCGRSIG = 0x40044272 - BIOCGRTIMEOUT = 0x4010426e - BIOCGSEESENT = 0x40044276 - BIOCGSTATS = 0x4008426f - BIOCIMMEDIATE = 0x80044270 - BIOCPROMISC = 0x20004269 - BIOCSBLEN = 0xc0044266 - BIOCSDLT = 0x80044278 - BIOCSETF = 0x80104267 - BIOCSETFNR = 0x8010427e - BIOCSETIF = 0x8020426c - BIOCSHDRCMPLT = 0x80044275 - BIOCSRSIG = 0x80044273 - BIOCSRTIMEOUT = 0x8010426d - BIOCSSEESENT = 0x80044277 - BIOCVERSION = 0x40044271 - BPF_A = 0x10 - BPF_ABS = 0x20 - BPF_ADD = 0x0 - BPF_ALIGNMENT = 0x4 - BPF_ALU = 0x4 - BPF_AND = 0x50 - BPF_B = 0x10 - BPF_DIV = 0x30 - BPF_H = 0x8 - BPF_IMM = 0x0 - BPF_IND = 0x40 - BPF_JA = 0x0 - BPF_JEQ = 0x10 - BPF_JGE = 0x30 - BPF_JGT = 0x20 - BPF_JMP = 0x5 - BPF_JSET = 0x40 - BPF_K = 0x0 - BPF_LD = 0x0 - BPF_LDX = 0x1 - BPF_LEN = 0x80 - BPF_LSH = 0x60 - BPF_MAJOR_VERSION = 0x1 - BPF_MAXBUFSIZE = 0x80000 - BPF_MAXINSNS = 0x200 - BPF_MEM = 0x60 - BPF_MEMWORDS = 0x10 - BPF_MINBUFSIZE = 0x20 - BPF_MINOR_VERSION = 0x1 - BPF_MISC = 0x7 - BPF_MSH = 0xa0 - BPF_MUL = 0x20 - BPF_NEG = 0x80 - BPF_OR = 0x40 - BPF_RELEASE = 0x30bb6 - BPF_RET = 0x6 - BPF_RSH = 0x70 - BPF_ST = 0x2 - BPF_STX = 0x3 - BPF_SUB = 0x10 - BPF_TAX = 0x0 - BPF_TXA = 0x80 - BPF_W = 0x0 - BPF_X = 0x8 - BRKINT = 0x2 - BS0 = 0x0 - BS1 = 0x8000 - BSDLY = 0x8000 - CFLUSH = 0xf - CLOCAL = 0x8000 - CLOCK_MONOTONIC = 0x6 - CLOCK_MONOTONIC_RAW = 0x4 - CLOCK_MONOTONIC_RAW_APPROX = 0x5 - CLOCK_PROCESS_CPUTIME_ID = 0xc - CLOCK_REALTIME = 0x0 - CLOCK_THREAD_CPUTIME_ID = 0x10 - CLOCK_UPTIME_RAW = 0x8 - CLOCK_UPTIME_RAW_APPROX = 0x9 - CLONE_NOFOLLOW = 0x1 - CLONE_NOOWNERCOPY = 0x2 - CR0 = 0x0 - CR1 = 0x1000 - CR2 = 0x2000 - CR3 = 0x3000 - CRDLY = 0x3000 - CREAD = 0x800 - CRTSCTS = 0x30000 - CS5 = 0x0 - CS6 = 0x100 - CS7 = 0x200 - CS8 = 0x300 - CSIZE = 0x300 - CSTART = 0x11 - CSTATUS = 0x14 - CSTOP = 0x13 - CSTOPB = 0x400 - CSUSP = 0x1a - CTLIOCGINFO = 0xc0644e03 - CTL_HW = 0x6 - CTL_KERN = 0x1 - CTL_MAXNAME = 0xc - CTL_NET = 0x4 - DLT_A429 = 0xb8 - DLT_A653_ICM = 0xb9 - DLT_AIRONET_HEADER = 0x78 - DLT_AOS = 0xde - DLT_APPLE_IP_OVER_IEEE1394 = 0x8a - DLT_ARCNET = 0x7 - DLT_ARCNET_LINUX = 0x81 - DLT_ATM_CLIP = 0x13 - DLT_ATM_RFC1483 = 0xb - DLT_AURORA = 0x7e - DLT_AX25 = 0x3 - DLT_AX25_KISS = 0xca - DLT_BACNET_MS_TP = 0xa5 - DLT_BLUETOOTH_HCI_H4 = 0xbb - DLT_BLUETOOTH_HCI_H4_WITH_PHDR = 0xc9 - DLT_CAN20B = 0xbe - DLT_CAN_SOCKETCAN = 0xe3 - DLT_CHAOS = 0x5 - DLT_CHDLC = 0x68 - DLT_CISCO_IOS = 0x76 - DLT_C_HDLC = 0x68 - DLT_C_HDLC_WITH_DIR = 0xcd - DLT_DBUS = 0xe7 - DLT_DECT = 0xdd - DLT_DOCSIS = 0x8f - DLT_DVB_CI = 0xeb - DLT_ECONET = 0x73 - DLT_EN10MB = 0x1 - DLT_EN3MB = 0x2 - DLT_ENC = 0x6d - DLT_ERF = 0xc5 - DLT_ERF_ETH = 0xaf - DLT_ERF_POS = 0xb0 - DLT_FC_2 = 0xe0 - DLT_FC_2_WITH_FRAME_DELIMS = 0xe1 - DLT_FDDI = 0xa - DLT_FLEXRAY = 0xd2 - DLT_FRELAY = 0x6b - DLT_FRELAY_WITH_DIR = 0xce - DLT_GCOM_SERIAL = 0xad - DLT_GCOM_T1E1 = 0xac - DLT_GPF_F = 0xab - DLT_GPF_T = 0xaa - DLT_GPRS_LLC = 0xa9 - DLT_GSMTAP_ABIS = 0xda - DLT_GSMTAP_UM = 0xd9 - DLT_HHDLC = 0x79 - DLT_IBM_SN = 0x92 - DLT_IBM_SP = 0x91 - DLT_IEEE802 = 0x6 - DLT_IEEE802_11 = 0x69 - DLT_IEEE802_11_RADIO = 0x7f - DLT_IEEE802_11_RADIO_AVS = 0xa3 - DLT_IEEE802_15_4 = 0xc3 - DLT_IEEE802_15_4_LINUX = 0xbf - DLT_IEEE802_15_4_NOFCS = 0xe6 - DLT_IEEE802_15_4_NONASK_PHY = 0xd7 - DLT_IEEE802_16_MAC_CPS = 0xbc - DLT_IEEE802_16_MAC_CPS_RADIO = 0xc1 - DLT_IPFILTER = 0x74 - DLT_IPMB = 0xc7 - DLT_IPMB_LINUX = 0xd1 - DLT_IPNET = 0xe2 - DLT_IPOIB = 0xf2 - DLT_IPV4 = 0xe4 - DLT_IPV6 = 0xe5 - DLT_IP_OVER_FC = 0x7a - DLT_JUNIPER_ATM1 = 0x89 - DLT_JUNIPER_ATM2 = 0x87 - DLT_JUNIPER_ATM_CEMIC = 0xee - DLT_JUNIPER_CHDLC = 0xb5 - DLT_JUNIPER_ES = 0x84 - DLT_JUNIPER_ETHER = 0xb2 - DLT_JUNIPER_FIBRECHANNEL = 0xea - DLT_JUNIPER_FRELAY = 0xb4 - DLT_JUNIPER_GGSN = 0x85 - DLT_JUNIPER_ISM = 0xc2 - DLT_JUNIPER_MFR = 0x86 - DLT_JUNIPER_MLFR = 0x83 - DLT_JUNIPER_MLPPP = 0x82 - DLT_JUNIPER_MONITOR = 0xa4 - DLT_JUNIPER_PIC_PEER = 0xae - DLT_JUNIPER_PPP = 0xb3 - DLT_JUNIPER_PPPOE = 0xa7 - DLT_JUNIPER_PPPOE_ATM = 0xa8 - DLT_JUNIPER_SERVICES = 0x88 - DLT_JUNIPER_SRX_E2E = 0xe9 - DLT_JUNIPER_ST = 0xc8 - DLT_JUNIPER_VP = 0xb7 - DLT_JUNIPER_VS = 0xe8 - DLT_LAPB_WITH_DIR = 0xcf - DLT_LAPD = 0xcb - DLT_LIN = 0xd4 - DLT_LINUX_EVDEV = 0xd8 - DLT_LINUX_IRDA = 0x90 - DLT_LINUX_LAPD = 0xb1 - DLT_LINUX_PPP_WITHDIRECTION = 0xa6 - DLT_LINUX_SLL = 0x71 - DLT_LOOP = 0x6c - DLT_LTALK = 0x72 - DLT_MATCHING_MAX = 0x10a - DLT_MATCHING_MIN = 0x68 - DLT_MFR = 0xb6 - DLT_MOST = 0xd3 - DLT_MPEG_2_TS = 0xf3 - DLT_MPLS = 0xdb - DLT_MTP2 = 0x8c - DLT_MTP2_WITH_PHDR = 0x8b - DLT_MTP3 = 0x8d - DLT_MUX27010 = 0xec - DLT_NETANALYZER = 0xf0 - DLT_NETANALYZER_TRANSPARENT = 0xf1 - DLT_NFC_LLCP = 0xf5 - DLT_NFLOG = 0xef - DLT_NG40 = 0xf4 - DLT_NULL = 0x0 - DLT_PCI_EXP = 0x7d - DLT_PFLOG = 0x75 - DLT_PFSYNC = 0x12 - DLT_PPI = 0xc0 - DLT_PPP = 0x9 - DLT_PPP_BSDOS = 0x10 - DLT_PPP_ETHER = 0x33 - DLT_PPP_PPPD = 0xa6 - DLT_PPP_SERIAL = 0x32 - DLT_PPP_WITH_DIR = 0xcc - DLT_PPP_WITH_DIRECTION = 0xa6 - DLT_PRISM_HEADER = 0x77 - DLT_PRONET = 0x4 - DLT_RAIF1 = 0xc6 - DLT_RAW = 0xc - DLT_RIO = 0x7c - DLT_SCCP = 0x8e - DLT_SITA = 0xc4 - DLT_SLIP = 0x8 - DLT_SLIP_BSDOS = 0xf - DLT_STANAG_5066_D_PDU = 0xed - DLT_SUNATM = 0x7b - DLT_SYMANTEC_FIREWALL = 0x63 - DLT_TZSP = 0x80 - DLT_USB = 0xba - DLT_USB_DARWIN = 0x10a - DLT_USB_LINUX = 0xbd - DLT_USB_LINUX_MMAPPED = 0xdc - DLT_USER0 = 0x93 - DLT_USER1 = 0x94 - DLT_USER10 = 0x9d - DLT_USER11 = 0x9e - DLT_USER12 = 0x9f - DLT_USER13 = 0xa0 - DLT_USER14 = 0xa1 - DLT_USER15 = 0xa2 - DLT_USER2 = 0x95 - DLT_USER3 = 0x96 - DLT_USER4 = 0x97 - DLT_USER5 = 0x98 - DLT_USER6 = 0x99 - DLT_USER7 = 0x9a - DLT_USER8 = 0x9b - DLT_USER9 = 0x9c - DLT_WIHART = 0xdf - DLT_X2E_SERIAL = 0xd5 - DLT_X2E_XORAYA = 0xd6 - DT_BLK = 0x6 - DT_CHR = 0x2 - DT_DIR = 0x4 - DT_FIFO = 0x1 - DT_LNK = 0xa - DT_REG = 0x8 - DT_SOCK = 0xc - DT_UNKNOWN = 0x0 - DT_WHT = 0xe - ECHO = 0x8 - ECHOCTL = 0x40 - ECHOE = 0x2 - ECHOK = 0x4 - ECHOKE = 0x1 - ECHONL = 0x10 - ECHOPRT = 0x20 - EVFILT_AIO = -0x3 - EVFILT_EXCEPT = -0xf - EVFILT_FS = -0x9 - EVFILT_MACHPORT = -0x8 - EVFILT_PROC = -0x5 - EVFILT_READ = -0x1 - EVFILT_SIGNAL = -0x6 - EVFILT_SYSCOUNT = 0x11 - EVFILT_THREADMARKER = 0x11 - EVFILT_TIMER = -0x7 - EVFILT_USER = -0xa - EVFILT_VM = -0xc - EVFILT_VNODE = -0x4 - EVFILT_WRITE = -0x2 - EV_ADD = 0x1 - EV_CLEAR = 0x20 - EV_DELETE = 0x2 - EV_DISABLE = 0x8 - EV_DISPATCH = 0x80 - EV_DISPATCH2 = 0x180 - EV_ENABLE = 0x4 - EV_EOF = 0x8000 - EV_ERROR = 0x4000 - EV_FLAG0 = 0x1000 - EV_FLAG1 = 0x2000 - EV_ONESHOT = 0x10 - EV_OOBAND = 0x2000 - EV_POLL = 0x1000 - EV_RECEIPT = 0x40 - EV_SYSFLAGS = 0xf000 - EV_UDATA_SPECIFIC = 0x100 - EV_VANISHED = 0x200 - EXTA = 0x4b00 - EXTB = 0x9600 - EXTPROC = 0x800 - FD_CLOEXEC = 0x1 - FD_SETSIZE = 0x400 - FF0 = 0x0 - FF1 = 0x4000 - FFDLY = 0x4000 - FLUSHO = 0x800000 - FSOPT_ATTR_CMN_EXTENDED = 0x20 - FSOPT_NOFOLLOW = 0x1 - FSOPT_NOINMEMUPDATE = 0x2 - FSOPT_PACK_INVAL_ATTRS = 0x8 - FSOPT_REPORT_FULLSIZE = 0x4 - FSOPT_RETURN_REALDEV = 0x200 - F_ADDFILESIGS = 0x3d - F_ADDFILESIGS_FOR_DYLD_SIM = 0x53 - F_ADDFILESIGS_INFO = 0x67 - F_ADDFILESIGS_RETURN = 0x61 - F_ADDFILESUPPL = 0x68 - F_ADDSIGS = 0x3b - F_ALLOCATEALL = 0x4 - F_ALLOCATECONTIG = 0x2 - F_BARRIERFSYNC = 0x55 - F_CHECK_LV = 0x62 - F_CHKCLEAN = 0x29 - F_DUPFD = 0x0 - F_DUPFD_CLOEXEC = 0x43 - F_FINDSIGS = 0x4e - F_FLUSH_DATA = 0x28 - F_FREEZE_FS = 0x35 - F_FULLFSYNC = 0x33 - F_GETCODEDIR = 0x48 - F_GETFD = 0x1 - F_GETFL = 0x3 - F_GETLK = 0x7 - F_GETLKPID = 0x42 - F_GETNOSIGPIPE = 0x4a - F_GETOWN = 0x5 - F_GETPATH = 0x32 - F_GETPATH_MTMINFO = 0x47 - F_GETPATH_NOFIRMLINK = 0x66 - F_GETPROTECTIONCLASS = 0x3f - F_GETPROTECTIONLEVEL = 0x4d - F_GETSIGSINFO = 0x69 - F_GLOBAL_NOCACHE = 0x37 - F_LOG2PHYS = 0x31 - F_LOG2PHYS_EXT = 0x41 - F_NOCACHE = 0x30 - F_NODIRECT = 0x3e - F_OK = 0x0 - F_PATHPKG_CHECK = 0x34 - F_PEOFPOSMODE = 0x3 - F_PREALLOCATE = 0x2a - F_PUNCHHOLE = 0x63 - F_RDADVISE = 0x2c - F_RDAHEAD = 0x2d - F_RDLCK = 0x1 - F_SETBACKINGSTORE = 0x46 - F_SETFD = 0x2 - F_SETFL = 0x4 - F_SETLK = 0x8 - F_SETLKW = 0x9 - F_SETLKWTIMEOUT = 0xa - F_SETNOSIGPIPE = 0x49 - F_SETOWN = 0x6 - F_SETPROTECTIONCLASS = 0x40 - F_SETSIZE = 0x2b - F_SINGLE_WRITER = 0x4c - F_SPECULATIVE_READ = 0x65 - F_THAW_FS = 0x36 - F_TRANSCODEKEY = 0x4b - F_TRIM_ACTIVE_FILE = 0x64 - F_UNLCK = 0x2 - F_VOLPOSMODE = 0x4 - F_WRLCK = 0x3 - HUPCL = 0x4000 - HW_MACHINE = 0x1 - ICANON = 0x100 - ICMP6_FILTER = 0x12 - ICRNL = 0x100 - IEXTEN = 0x400 - IFF_ALLMULTI = 0x200 - IFF_ALTPHYS = 0x4000 - IFF_BROADCAST = 0x2 - IFF_DEBUG = 0x4 - IFF_LINK0 = 0x1000 - IFF_LINK1 = 0x2000 - IFF_LINK2 = 0x4000 - IFF_LOOPBACK = 0x8 - IFF_MULTICAST = 0x8000 - IFF_NOARP = 0x80 - IFF_NOTRAILERS = 0x20 - IFF_OACTIVE = 0x400 - IFF_POINTOPOINT = 0x10 - IFF_PROMISC = 0x100 - IFF_RUNNING = 0x40 - IFF_SIMPLEX = 0x800 - IFF_UP = 0x1 - IFNAMSIZ = 0x10 - IFT_1822 = 0x2 - IFT_6LOWPAN = 0x40 - IFT_AAL5 = 0x31 - IFT_ARCNET = 0x23 - IFT_ARCNETPLUS = 0x24 - IFT_ATM = 0x25 - IFT_BRIDGE = 0xd1 - IFT_CARP = 0xf8 - IFT_CELLULAR = 0xff - IFT_CEPT = 0x13 - IFT_DS3 = 0x1e - IFT_ENC = 0xf4 - IFT_EON = 0x19 - IFT_ETHER = 0x6 - IFT_FAITH = 0x38 - IFT_FDDI = 0xf - IFT_FRELAY = 0x20 - IFT_FRELAYDCE = 0x2c - IFT_GIF = 0x37 - IFT_HDH1822 = 0x3 - IFT_HIPPI = 0x2f - IFT_HSSI = 0x2e - IFT_HY = 0xe - IFT_IEEE1394 = 0x90 - IFT_IEEE8023ADLAG = 0x88 - IFT_ISDNBASIC = 0x14 - IFT_ISDNPRIMARY = 0x15 - IFT_ISO88022LLC = 0x29 - IFT_ISO88023 = 0x7 - IFT_ISO88024 = 0x8 - IFT_ISO88025 = 0x9 - IFT_ISO88026 = 0xa - IFT_L2VLAN = 0x87 - IFT_LAPB = 0x10 - IFT_LOCALTALK = 0x2a - IFT_LOOP = 0x18 - IFT_MIOX25 = 0x26 - IFT_MODEM = 0x30 - IFT_NSIP = 0x1b - IFT_OTHER = 0x1 - IFT_P10 = 0xc - IFT_P80 = 0xd - IFT_PARA = 0x22 - IFT_PDP = 0xff - IFT_PFLOG = 0xf5 - IFT_PFSYNC = 0xf6 - IFT_PKTAP = 0xfe - IFT_PPP = 0x17 - IFT_PROPMUX = 0x36 - IFT_PROPVIRTUAL = 0x35 - IFT_PTPSERIAL = 0x16 - IFT_RS232 = 0x21 - IFT_SDLC = 0x11 - IFT_SIP = 0x1f - IFT_SLIP = 0x1c - IFT_SMDSDXI = 0x2b - IFT_SMDSICIP = 0x34 - IFT_SONET = 0x27 - IFT_SONETPATH = 0x32 - IFT_SONETVT = 0x33 - IFT_STARLAN = 0xb - IFT_STF = 0x39 - IFT_T1 = 0x12 - IFT_ULTRA = 0x1d - IFT_V35 = 0x2d - IFT_X25 = 0x5 - IFT_X25DDN = 0x4 - IFT_X25PLE = 0x28 - IFT_XETHER = 0x1a - IGNBRK = 0x1 - IGNCR = 0x80 - IGNPAR = 0x4 - IMAXBEL = 0x2000 - INLCR = 0x40 - INPCK = 0x10 - IN_CLASSA_HOST = 0xffffff - IN_CLASSA_MAX = 0x80 - IN_CLASSA_NET = 0xff000000 - IN_CLASSA_NSHIFT = 0x18 - IN_CLASSB_HOST = 0xffff - IN_CLASSB_MAX = 0x10000 - IN_CLASSB_NET = 0xffff0000 - IN_CLASSB_NSHIFT = 0x10 - IN_CLASSC_HOST = 0xff - IN_CLASSC_NET = 0xffffff00 - IN_CLASSC_NSHIFT = 0x8 - IN_CLASSD_HOST = 0xfffffff - IN_CLASSD_NET = 0xf0000000 - IN_CLASSD_NSHIFT = 0x1c - IN_LINKLOCALNETNUM = 0xa9fe0000 - IN_LOOPBACKNET = 0x7f - IPPROTO_3PC = 0x22 - IPPROTO_ADFS = 0x44 - IPPROTO_AH = 0x33 - IPPROTO_AHIP = 0x3d - IPPROTO_APES = 0x63 - IPPROTO_ARGUS = 0xd - IPPROTO_AX25 = 0x5d - IPPROTO_BHA = 0x31 - IPPROTO_BLT = 0x1e - IPPROTO_BRSATMON = 0x4c - IPPROTO_CFTP = 0x3e - IPPROTO_CHAOS = 0x10 - IPPROTO_CMTP = 0x26 - IPPROTO_CPHB = 0x49 - IPPROTO_CPNX = 0x48 - IPPROTO_DDP = 0x25 - IPPROTO_DGP = 0x56 - IPPROTO_DIVERT = 0xfe - IPPROTO_DONE = 0x101 - IPPROTO_DSTOPTS = 0x3c - IPPROTO_EGP = 0x8 - IPPROTO_EMCON = 0xe - IPPROTO_ENCAP = 0x62 - IPPROTO_EON = 0x50 - IPPROTO_ESP = 0x32 - IPPROTO_ETHERIP = 0x61 - IPPROTO_FRAGMENT = 0x2c - IPPROTO_GGP = 0x3 - IPPROTO_GMTP = 0x64 - IPPROTO_GRE = 0x2f - IPPROTO_HELLO = 0x3f - IPPROTO_HMP = 0x14 - IPPROTO_HOPOPTS = 0x0 - IPPROTO_ICMP = 0x1 - IPPROTO_ICMPV6 = 0x3a - IPPROTO_IDP = 0x16 - IPPROTO_IDPR = 0x23 - IPPROTO_IDRP = 0x2d - IPPROTO_IGMP = 0x2 - IPPROTO_IGP = 0x55 - IPPROTO_IGRP = 0x58 - IPPROTO_IL = 0x28 - IPPROTO_INLSP = 0x34 - IPPROTO_INP = 0x20 - IPPROTO_IP = 0x0 - IPPROTO_IPCOMP = 0x6c - IPPROTO_IPCV = 0x47 - IPPROTO_IPEIP = 0x5e - IPPROTO_IPIP = 0x4 - IPPROTO_IPPC = 0x43 - IPPROTO_IPV4 = 0x4 - IPPROTO_IPV6 = 0x29 - IPPROTO_IRTP = 0x1c - IPPROTO_KRYPTOLAN = 0x41 - IPPROTO_LARP = 0x5b - IPPROTO_LEAF1 = 0x19 - IPPROTO_LEAF2 = 0x1a - IPPROTO_MAX = 0x100 - IPPROTO_MAXID = 0x34 - IPPROTO_MEAS = 0x13 - IPPROTO_MHRP = 0x30 - IPPROTO_MICP = 0x5f - IPPROTO_MTP = 0x5c - IPPROTO_MUX = 0x12 - IPPROTO_ND = 0x4d - IPPROTO_NHRP = 0x36 - IPPROTO_NONE = 0x3b - IPPROTO_NSP = 0x1f - IPPROTO_NVPII = 0xb - IPPROTO_OSPFIGP = 0x59 - IPPROTO_PGM = 0x71 - IPPROTO_PIGP = 0x9 - IPPROTO_PIM = 0x67 - IPPROTO_PRM = 0x15 - IPPROTO_PUP = 0xc - IPPROTO_PVP = 0x4b - IPPROTO_RAW = 0xff - IPPROTO_RCCMON = 0xa - IPPROTO_RDP = 0x1b - IPPROTO_ROUTING = 0x2b - IPPROTO_RSVP = 0x2e - IPPROTO_RVD = 0x42 - IPPROTO_SATEXPAK = 0x40 - IPPROTO_SATMON = 0x45 - IPPROTO_SCCSP = 0x60 - IPPROTO_SCTP = 0x84 - IPPROTO_SDRP = 0x2a - IPPROTO_SEP = 0x21 - IPPROTO_SRPC = 0x5a - IPPROTO_ST = 0x7 - IPPROTO_SVMTP = 0x52 - IPPROTO_SWIPE = 0x35 - IPPROTO_TCF = 0x57 - IPPROTO_TCP = 0x6 - IPPROTO_TP = 0x1d - IPPROTO_TPXX = 0x27 - IPPROTO_TRUNK1 = 0x17 - IPPROTO_TRUNK2 = 0x18 - IPPROTO_TTP = 0x54 - IPPROTO_UDP = 0x11 - IPPROTO_VINES = 0x53 - IPPROTO_VISA = 0x46 - IPPROTO_VMTP = 0x51 - IPPROTO_WBEXPAK = 0x4f - IPPROTO_WBMON = 0x4e - IPPROTO_WSN = 0x4a - IPPROTO_XNET = 0xf - IPPROTO_XTP = 0x24 - IPV6_2292DSTOPTS = 0x17 - IPV6_2292HOPLIMIT = 0x14 - IPV6_2292HOPOPTS = 0x16 - IPV6_2292NEXTHOP = 0x15 - IPV6_2292PKTINFO = 0x13 - IPV6_2292PKTOPTIONS = 0x19 - IPV6_2292RTHDR = 0x18 - IPV6_3542DSTOPTS = 0x32 - IPV6_3542HOPLIMIT = 0x2f - IPV6_3542HOPOPTS = 0x31 - IPV6_3542NEXTHOP = 0x30 - IPV6_3542PKTINFO = 0x2e - IPV6_3542RTHDR = 0x33 - IPV6_ADDR_MC_FLAGS_PREFIX = 0x20 - IPV6_ADDR_MC_FLAGS_TRANSIENT = 0x10 - IPV6_ADDR_MC_FLAGS_UNICAST_BASED = 0x30 - IPV6_AUTOFLOWLABEL = 0x3b - IPV6_BINDV6ONLY = 0x1b - IPV6_BOUND_IF = 0x7d - IPV6_CHECKSUM = 0x1a - IPV6_DEFAULT_MULTICAST_HOPS = 0x1 - IPV6_DEFAULT_MULTICAST_LOOP = 0x1 - IPV6_DEFHLIM = 0x40 - IPV6_DONTFRAG = 0x3e - IPV6_DSTOPTS = 0x32 - IPV6_FAITH = 0x1d - IPV6_FLOWINFO_MASK = 0xffffff0f - IPV6_FLOWLABEL_MASK = 0xffff0f00 - IPV6_FLOW_ECN_MASK = 0x3000 - IPV6_FRAGTTL = 0x3c - IPV6_FW_ADD = 0x1e - IPV6_FW_DEL = 0x1f - IPV6_FW_FLUSH = 0x20 - IPV6_FW_GET = 0x22 - IPV6_FW_ZERO = 0x21 - IPV6_HLIMDEC = 0x1 - IPV6_HOPLIMIT = 0x2f - IPV6_HOPOPTS = 0x31 - IPV6_IPSEC_POLICY = 0x1c - IPV6_JOIN_GROUP = 0xc - IPV6_LEAVE_GROUP = 0xd - IPV6_MAXHLIM = 0xff - IPV6_MAXOPTHDR = 0x800 - IPV6_MAXPACKET = 0xffff - IPV6_MAX_GROUP_SRC_FILTER = 0x200 - IPV6_MAX_MEMBERSHIPS = 0xfff - IPV6_MAX_SOCK_SRC_FILTER = 0x80 - IPV6_MIN_MEMBERSHIPS = 0x1f - IPV6_MMTU = 0x500 - IPV6_MSFILTER = 0x4a - IPV6_MULTICAST_HOPS = 0xa - IPV6_MULTICAST_IF = 0x9 - IPV6_MULTICAST_LOOP = 0xb - IPV6_NEXTHOP = 0x30 - IPV6_PATHMTU = 0x2c - IPV6_PKTINFO = 0x2e - IPV6_PORTRANGE = 0xe - IPV6_PORTRANGE_DEFAULT = 0x0 - IPV6_PORTRANGE_HIGH = 0x1 - IPV6_PORTRANGE_LOW = 0x2 - IPV6_PREFER_TEMPADDR = 0x3f - IPV6_RECVDSTOPTS = 0x28 - IPV6_RECVHOPLIMIT = 0x25 - IPV6_RECVHOPOPTS = 0x27 - IPV6_RECVPATHMTU = 0x2b - IPV6_RECVPKTINFO = 0x3d - IPV6_RECVRTHDR = 0x26 - IPV6_RECVTCLASS = 0x23 - IPV6_RTHDR = 0x33 - IPV6_RTHDRDSTOPTS = 0x39 - IPV6_RTHDR_LOOSE = 0x0 - IPV6_RTHDR_STRICT = 0x1 - IPV6_RTHDR_TYPE_0 = 0x0 - IPV6_SOCKOPT_RESERVED1 = 0x3 - IPV6_TCLASS = 0x24 - IPV6_UNICAST_HOPS = 0x4 - IPV6_USE_MIN_MTU = 0x2a - IPV6_V6ONLY = 0x1b - IPV6_VERSION = 0x60 - IPV6_VERSION_MASK = 0xf0 - IP_ADD_MEMBERSHIP = 0xc - IP_ADD_SOURCE_MEMBERSHIP = 0x46 - IP_BLOCK_SOURCE = 0x48 - IP_BOUND_IF = 0x19 - IP_DEFAULT_MULTICAST_LOOP = 0x1 - IP_DEFAULT_MULTICAST_TTL = 0x1 - IP_DF = 0x4000 - IP_DONTFRAG = 0x1c - IP_DROP_MEMBERSHIP = 0xd - IP_DROP_SOURCE_MEMBERSHIP = 0x47 - IP_DUMMYNET_CONFIGURE = 0x3c - IP_DUMMYNET_DEL = 0x3d - IP_DUMMYNET_FLUSH = 0x3e - IP_DUMMYNET_GET = 0x40 - IP_FAITH = 0x16 - IP_FW_ADD = 0x28 - IP_FW_DEL = 0x29 - IP_FW_FLUSH = 0x2a - IP_FW_GET = 0x2c - IP_FW_RESETLOG = 0x2d - IP_FW_ZERO = 0x2b - IP_HDRINCL = 0x2 - IP_IPSEC_POLICY = 0x15 - IP_MAXPACKET = 0xffff - IP_MAX_GROUP_SRC_FILTER = 0x200 - IP_MAX_MEMBERSHIPS = 0xfff - IP_MAX_SOCK_MUTE_FILTER = 0x80 - IP_MAX_SOCK_SRC_FILTER = 0x80 - IP_MF = 0x2000 - IP_MIN_MEMBERSHIPS = 0x1f - IP_MSFILTER = 0x4a - IP_MSS = 0x240 - IP_MULTICAST_IF = 0x9 - IP_MULTICAST_IFINDEX = 0x42 - IP_MULTICAST_LOOP = 0xb - IP_MULTICAST_TTL = 0xa - IP_MULTICAST_VIF = 0xe - IP_NAT__XXX = 0x37 - IP_OFFMASK = 0x1fff - IP_OLD_FW_ADD = 0x32 - IP_OLD_FW_DEL = 0x33 - IP_OLD_FW_FLUSH = 0x34 - IP_OLD_FW_GET = 0x36 - IP_OLD_FW_RESETLOG = 0x38 - IP_OLD_FW_ZERO = 0x35 - IP_OPTIONS = 0x1 - IP_PKTINFO = 0x1a - IP_PORTRANGE = 0x13 - IP_PORTRANGE_DEFAULT = 0x0 - IP_PORTRANGE_HIGH = 0x1 - IP_PORTRANGE_LOW = 0x2 - IP_RECVDSTADDR = 0x7 - IP_RECVIF = 0x14 - IP_RECVOPTS = 0x5 - IP_RECVPKTINFO = 0x1a - IP_RECVRETOPTS = 0x6 - IP_RECVTOS = 0x1b - IP_RECVTTL = 0x18 - IP_RETOPTS = 0x8 - IP_RF = 0x8000 - IP_RSVP_OFF = 0x10 - IP_RSVP_ON = 0xf - IP_RSVP_VIF_OFF = 0x12 - IP_RSVP_VIF_ON = 0x11 - IP_STRIPHDR = 0x17 - IP_TOS = 0x3 - IP_TRAFFIC_MGT_BACKGROUND = 0x41 - IP_TTL = 0x4 - IP_UNBLOCK_SOURCE = 0x49 - ISIG = 0x80 - ISTRIP = 0x20 - IUTF8 = 0x4000 - IXANY = 0x800 - IXOFF = 0x400 - IXON = 0x200 - KERN_HOSTNAME = 0xa - KERN_OSRELEASE = 0x2 - KERN_OSTYPE = 0x1 - KERN_VERSION = 0x4 - LOCAL_PEERCRED = 0x1 - LOCAL_PEEREPID = 0x3 - LOCAL_PEEREUUID = 0x5 - LOCAL_PEERPID = 0x2 - LOCAL_PEERTOKEN = 0x6 - LOCAL_PEERUUID = 0x4 - LOCK_EX = 0x2 - LOCK_NB = 0x4 - LOCK_SH = 0x1 - LOCK_UN = 0x8 - MADV_CAN_REUSE = 0x9 - MADV_DONTNEED = 0x4 - MADV_FREE = 0x5 - MADV_FREE_REUSABLE = 0x7 - MADV_FREE_REUSE = 0x8 - MADV_NORMAL = 0x0 - MADV_PAGEOUT = 0xa - MADV_RANDOM = 0x1 - MADV_SEQUENTIAL = 0x2 - MADV_WILLNEED = 0x3 - MADV_ZERO_WIRED_PAGES = 0x6 - MAP_32BIT = 0x8000 - MAP_ANON = 0x1000 - MAP_ANONYMOUS = 0x1000 - MAP_COPY = 0x2 - MAP_FILE = 0x0 - MAP_FIXED = 0x10 - MAP_HASSEMAPHORE = 0x200 - MAP_JIT = 0x800 - MAP_NOCACHE = 0x400 - MAP_NOEXTEND = 0x100 - MAP_NORESERVE = 0x40 - MAP_PRIVATE = 0x2 - MAP_RENAME = 0x20 - MAP_RESERVED0080 = 0x80 - MAP_RESILIENT_CODESIGN = 0x2000 - MAP_RESILIENT_MEDIA = 0x4000 - MAP_SHARED = 0x1 - MAP_TRANSLATED_ALLOW_EXECUTE = 0x20000 - MAP_UNIX03 = 0x40000 - MCAST_BLOCK_SOURCE = 0x54 - MCAST_EXCLUDE = 0x2 - MCAST_INCLUDE = 0x1 - MCAST_JOIN_GROUP = 0x50 - MCAST_JOIN_SOURCE_GROUP = 0x52 - MCAST_LEAVE_GROUP = 0x51 - MCAST_LEAVE_SOURCE_GROUP = 0x53 - MCAST_UNBLOCK_SOURCE = 0x55 - MCAST_UNDEFINED = 0x0 - MCL_CURRENT = 0x1 - MCL_FUTURE = 0x2 - MNT_ASYNC = 0x40 - MNT_AUTOMOUNTED = 0x400000 - MNT_CMDFLAGS = 0xf0000 - MNT_CPROTECT = 0x80 - MNT_DEFWRITE = 0x2000000 - MNT_DONTBROWSE = 0x100000 - MNT_DOVOLFS = 0x8000 - MNT_DWAIT = 0x4 - MNT_EXPORTED = 0x100 - MNT_EXT_ROOT_DATA_VOL = 0x1 - MNT_FORCE = 0x80000 - MNT_IGNORE_OWNERSHIP = 0x200000 - MNT_JOURNALED = 0x800000 - MNT_LOCAL = 0x1000 - MNT_MULTILABEL = 0x4000000 - MNT_NOATIME = 0x10000000 - MNT_NOBLOCK = 0x20000 - MNT_NODEV = 0x10 - MNT_NOEXEC = 0x4 - MNT_NOSUID = 0x8 - MNT_NOUSERXATTR = 0x1000000 - MNT_NOWAIT = 0x2 - MNT_QUARANTINE = 0x400 - MNT_QUOTA = 0x2000 - MNT_RDONLY = 0x1 - MNT_RELOAD = 0x40000 - MNT_REMOVABLE = 0x200 - MNT_ROOTFS = 0x4000 - MNT_SNAPSHOT = 0x40000000 - MNT_STRICTATIME = 0x80000000 - MNT_SYNCHRONOUS = 0x2 - MNT_UNION = 0x20 - MNT_UNKNOWNPERMISSIONS = 0x200000 - MNT_UPDATE = 0x10000 - MNT_VISFLAGMASK = 0xd7f0f7ff - MNT_WAIT = 0x1 - MSG_CTRUNC = 0x20 - MSG_DONTROUTE = 0x4 - MSG_DONTWAIT = 0x80 - MSG_EOF = 0x100 - MSG_EOR = 0x8 - MSG_FLUSH = 0x400 - MSG_HAVEMORE = 0x2000 - MSG_HOLD = 0x800 - MSG_NEEDSA = 0x10000 - MSG_NOSIGNAL = 0x80000 - MSG_OOB = 0x1 - MSG_PEEK = 0x2 - MSG_RCVMORE = 0x4000 - MSG_SEND = 0x1000 - MSG_TRUNC = 0x10 - MSG_WAITALL = 0x40 - MSG_WAITSTREAM = 0x200 - MS_ASYNC = 0x1 - MS_DEACTIVATE = 0x8 - MS_INVALIDATE = 0x2 - MS_KILLPAGES = 0x4 - MS_SYNC = 0x10 - NAME_MAX = 0xff - NET_RT_DUMP = 0x1 - NET_RT_DUMP2 = 0x7 - NET_RT_FLAGS = 0x2 - NET_RT_FLAGS_PRIV = 0xa - NET_RT_IFLIST = 0x3 - NET_RT_IFLIST2 = 0x6 - NET_RT_MAXID = 0xb - NET_RT_STAT = 0x4 - NET_RT_TRASH = 0x5 - NFDBITS = 0x20 - NL0 = 0x0 - NL1 = 0x100 - NL2 = 0x200 - NL3 = 0x300 - NLDLY = 0x300 - NOFLSH = 0x80000000 - NOKERNINFO = 0x2000000 - NOTE_ABSOLUTE = 0x8 - NOTE_ATTRIB = 0x8 - NOTE_BACKGROUND = 0x40 - NOTE_CHILD = 0x4 - NOTE_CRITICAL = 0x20 - NOTE_DELETE = 0x1 - NOTE_EXEC = 0x20000000 - NOTE_EXIT = 0x80000000 - NOTE_EXITSTATUS = 0x4000000 - NOTE_EXIT_CSERROR = 0x40000 - NOTE_EXIT_DECRYPTFAIL = 0x10000 - NOTE_EXIT_DETAIL = 0x2000000 - NOTE_EXIT_DETAIL_MASK = 0x70000 - NOTE_EXIT_MEMORY = 0x20000 - NOTE_EXIT_REPARENTED = 0x80000 - NOTE_EXTEND = 0x4 - NOTE_FFAND = 0x40000000 - NOTE_FFCOPY = 0xc0000000 - NOTE_FFCTRLMASK = 0xc0000000 - NOTE_FFLAGSMASK = 0xffffff - NOTE_FFNOP = 0x0 - NOTE_FFOR = 0x80000000 - NOTE_FORK = 0x40000000 - NOTE_FUNLOCK = 0x100 - NOTE_LEEWAY = 0x10 - NOTE_LINK = 0x10 - NOTE_LOWAT = 0x1 - NOTE_MACHTIME = 0x100 - NOTE_MACH_CONTINUOUS_TIME = 0x80 - NOTE_NONE = 0x80 - NOTE_NSECONDS = 0x4 - NOTE_OOB = 0x2 - NOTE_PCTRLMASK = -0x100000 - NOTE_PDATAMASK = 0xfffff - NOTE_REAP = 0x10000000 - NOTE_RENAME = 0x20 - NOTE_REVOKE = 0x40 - NOTE_SECONDS = 0x1 - NOTE_SIGNAL = 0x8000000 - NOTE_TRACK = 0x1 - NOTE_TRACKERR = 0x2 - NOTE_TRIGGER = 0x1000000 - NOTE_USECONDS = 0x2 - NOTE_VM_ERROR = 0x10000000 - NOTE_VM_PRESSURE = 0x80000000 - NOTE_VM_PRESSURE_SUDDEN_TERMINATE = 0x20000000 - NOTE_VM_PRESSURE_TERMINATE = 0x40000000 - NOTE_WRITE = 0x2 - OCRNL = 0x10 - OFDEL = 0x20000 - OFILL = 0x80 - ONLCR = 0x2 - ONLRET = 0x40 - ONOCR = 0x20 - ONOEOT = 0x8 - OPOST = 0x1 - OXTABS = 0x4 - O_ACCMODE = 0x3 - O_ALERT = 0x20000000 - O_APPEND = 0x8 - O_ASYNC = 0x40 - O_CLOEXEC = 0x1000000 - O_CREAT = 0x200 - O_DIRECTORY = 0x100000 - O_DP_GETRAWENCRYPTED = 0x1 - O_DP_GETRAWUNENCRYPTED = 0x2 - O_DSYNC = 0x400000 - O_EVTONLY = 0x8000 - O_EXCL = 0x800 - O_EXLOCK = 0x20 - O_FSYNC = 0x80 - O_NDELAY = 0x4 - O_NOCTTY = 0x20000 - O_NOFOLLOW = 0x100 - O_NOFOLLOW_ANY = 0x20000000 - O_NONBLOCK = 0x4 - O_POPUP = 0x80000000 - O_RDONLY = 0x0 - O_RDWR = 0x2 - O_SHLOCK = 0x10 - O_SYMLINK = 0x200000 - O_SYNC = 0x80 - O_TRUNC = 0x400 - O_WRONLY = 0x1 - PARENB = 0x1000 - PARMRK = 0x8 - PARODD = 0x2000 - PENDIN = 0x20000000 - PRIO_PGRP = 0x1 - PRIO_PROCESS = 0x0 - PRIO_USER = 0x2 - PROT_EXEC = 0x4 - PROT_NONE = 0x0 - PROT_READ = 0x1 - PROT_WRITE = 0x2 - PT_ATTACH = 0xa - PT_ATTACHEXC = 0xe - PT_CONTINUE = 0x7 - PT_DENY_ATTACH = 0x1f - PT_DETACH = 0xb - PT_FIRSTMACH = 0x20 - PT_FORCEQUOTA = 0x1e - PT_KILL = 0x8 - PT_READ_D = 0x2 - PT_READ_I = 0x1 - PT_READ_U = 0x3 - PT_SIGEXC = 0xc - PT_STEP = 0x9 - PT_THUPDATE = 0xd - PT_TRACE_ME = 0x0 - PT_WRITE_D = 0x5 - PT_WRITE_I = 0x4 - PT_WRITE_U = 0x6 - RLIMIT_AS = 0x5 - RLIMIT_CORE = 0x4 - RLIMIT_CPU = 0x0 - RLIMIT_CPU_USAGE_MONITOR = 0x2 - RLIMIT_DATA = 0x2 - RLIMIT_FSIZE = 0x1 - RLIMIT_MEMLOCK = 0x6 - RLIMIT_NOFILE = 0x8 - RLIMIT_NPROC = 0x7 - RLIMIT_RSS = 0x5 - RLIMIT_STACK = 0x3 - RLIM_INFINITY = 0x7fffffffffffffff - RTAX_AUTHOR = 0x6 - RTAX_BRD = 0x7 - RTAX_DST = 0x0 - RTAX_GATEWAY = 0x1 - RTAX_GENMASK = 0x3 - RTAX_IFA = 0x5 - RTAX_IFP = 0x4 - RTAX_MAX = 0x8 - RTAX_NETMASK = 0x2 - RTA_AUTHOR = 0x40 - RTA_BRD = 0x80 - RTA_DST = 0x1 - RTA_GATEWAY = 0x2 - RTA_GENMASK = 0x8 - RTA_IFA = 0x20 - RTA_IFP = 0x10 - RTA_NETMASK = 0x4 - RTF_BLACKHOLE = 0x1000 - RTF_BROADCAST = 0x400000 - RTF_CLONING = 0x100 - RTF_CONDEMNED = 0x2000000 - RTF_DEAD = 0x20000000 - RTF_DELCLONE = 0x80 - RTF_DONE = 0x40 - RTF_DYNAMIC = 0x10 - RTF_GATEWAY = 0x2 - RTF_GLOBAL = 0x40000000 - RTF_HOST = 0x4 - RTF_IFREF = 0x4000000 - RTF_IFSCOPE = 0x1000000 - RTF_LLDATA = 0x400 - RTF_LLINFO = 0x400 - RTF_LOCAL = 0x200000 - RTF_MODIFIED = 0x20 - RTF_MULTICAST = 0x800000 - RTF_NOIFREF = 0x2000 - RTF_PINNED = 0x100000 - RTF_PRCLONING = 0x10000 - RTF_PROTO1 = 0x8000 - RTF_PROTO2 = 0x4000 - RTF_PROTO3 = 0x40000 - RTF_PROXY = 0x8000000 - RTF_REJECT = 0x8 - RTF_ROUTER = 0x10000000 - RTF_STATIC = 0x800 - RTF_UP = 0x1 - RTF_WASCLONED = 0x20000 - RTF_XRESOLVE = 0x200 - RTM_ADD = 0x1 - RTM_CHANGE = 0x3 - RTM_DELADDR = 0xd - RTM_DELETE = 0x2 - RTM_DELMADDR = 0x10 - RTM_GET = 0x4 - RTM_GET2 = 0x14 - RTM_IFINFO = 0xe - RTM_IFINFO2 = 0x12 - RTM_LOCK = 0x8 - RTM_LOSING = 0x5 - RTM_MISS = 0x7 - RTM_NEWADDR = 0xc - RTM_NEWMADDR = 0xf - RTM_NEWMADDR2 = 0x13 - RTM_OLDADD = 0x9 - RTM_OLDDEL = 0xa - RTM_REDIRECT = 0x6 - RTM_RESOLVE = 0xb - RTM_RTTUNIT = 0xf4240 - RTM_VERSION = 0x5 - RTV_EXPIRE = 0x4 - RTV_HOPCOUNT = 0x2 - RTV_MTU = 0x1 - RTV_RPIPE = 0x8 - RTV_RTT = 0x40 - RTV_RTTVAR = 0x80 - RTV_SPIPE = 0x10 - RTV_SSTHRESH = 0x20 - RUSAGE_CHILDREN = -0x1 - RUSAGE_SELF = 0x0 - SCM_CREDS = 0x3 - SCM_RIGHTS = 0x1 - SCM_TIMESTAMP = 0x2 - SCM_TIMESTAMP_MONOTONIC = 0x4 - SEEK_CUR = 0x1 - SEEK_DATA = 0x4 - SEEK_END = 0x2 - SEEK_HOLE = 0x3 - SEEK_SET = 0x0 - SHUT_RD = 0x0 - SHUT_RDWR = 0x2 - SHUT_WR = 0x1 - SIOCADDMULTI = 0x80206931 - SIOCAIFADDR = 0x8040691a - SIOCARPIPLL = 0xc0206928 - SIOCATMARK = 0x40047307 - SIOCAUTOADDR = 0xc0206926 - SIOCAUTONETMASK = 0x80206927 - SIOCDELMULTI = 0x80206932 - SIOCDIFADDR = 0x80206919 - SIOCDIFPHYADDR = 0x80206941 - SIOCGDRVSPEC = 0xc028697b - SIOCGETVLAN = 0xc020697f - SIOCGHIWAT = 0x40047301 - SIOCGIF6LOWPAN = 0xc02069c5 - SIOCGIFADDR = 0xc0206921 - SIOCGIFALTMTU = 0xc0206948 - SIOCGIFASYNCMAP = 0xc020697c - SIOCGIFBOND = 0xc0206947 - SIOCGIFBRDADDR = 0xc0206923 - SIOCGIFCAP = 0xc020695b - SIOCGIFCONF = 0xc00c6924 - SIOCGIFDEVMTU = 0xc0206944 - SIOCGIFDSTADDR = 0xc0206922 - SIOCGIFFLAGS = 0xc0206911 - SIOCGIFFUNCTIONALTYPE = 0xc02069ad - SIOCGIFGENERIC = 0xc020693a - SIOCGIFKPI = 0xc0206987 - SIOCGIFMAC = 0xc0206982 - SIOCGIFMEDIA = 0xc02c6938 - SIOCGIFMETRIC = 0xc0206917 - SIOCGIFMTU = 0xc0206933 - SIOCGIFNETMASK = 0xc0206925 - SIOCGIFPDSTADDR = 0xc0206940 - SIOCGIFPHYS = 0xc0206935 - SIOCGIFPSRCADDR = 0xc020693f - SIOCGIFSTATUS = 0xc331693d - SIOCGIFVLAN = 0xc020697f - SIOCGIFWAKEFLAGS = 0xc0206988 - SIOCGIFXMEDIA = 0xc02c6948 - SIOCGLOWAT = 0x40047303 - SIOCGPGRP = 0x40047309 - SIOCIFCREATE = 0xc0206978 - SIOCIFCREATE2 = 0xc020697a - SIOCIFDESTROY = 0x80206979 - SIOCIFGCLONERS = 0xc0106981 - SIOCRSLVMULTI = 0xc010693b - SIOCSDRVSPEC = 0x8028697b - SIOCSETVLAN = 0x8020697e - SIOCSHIWAT = 0x80047300 - SIOCSIF6LOWPAN = 0x802069c4 - SIOCSIFADDR = 0x8020690c - SIOCSIFALTMTU = 0x80206945 - SIOCSIFASYNCMAP = 0x8020697d - SIOCSIFBOND = 0x80206946 - SIOCSIFBRDADDR = 0x80206913 - SIOCSIFCAP = 0x8020695a - SIOCSIFDSTADDR = 0x8020690e - SIOCSIFFLAGS = 0x80206910 - SIOCSIFGENERIC = 0x80206939 - SIOCSIFKPI = 0x80206986 - SIOCSIFLLADDR = 0x8020693c - SIOCSIFMAC = 0x80206983 - SIOCSIFMEDIA = 0xc0206937 - SIOCSIFMETRIC = 0x80206918 - SIOCSIFMTU = 0x80206934 - SIOCSIFNETMASK = 0x80206916 - SIOCSIFPHYADDR = 0x8040693e - SIOCSIFPHYS = 0x80206936 - SIOCSIFVLAN = 0x8020697e - SIOCSLOWAT = 0x80047302 - SIOCSPGRP = 0x80047308 - SOCK_DGRAM = 0x2 - SOCK_MAXADDRLEN = 0xff - SOCK_RAW = 0x3 - SOCK_RDM = 0x4 - SOCK_SEQPACKET = 0x5 - SOCK_STREAM = 0x1 - SOL_LOCAL = 0x0 - SOL_SOCKET = 0xffff - SOMAXCONN = 0x80 - SO_ACCEPTCONN = 0x2 - SO_BROADCAST = 0x20 - SO_DEBUG = 0x1 - SO_DONTROUTE = 0x10 - SO_DONTTRUNC = 0x2000 - SO_ERROR = 0x1007 - SO_KEEPALIVE = 0x8 - SO_LABEL = 0x1010 - SO_LINGER = 0x80 - SO_LINGER_SEC = 0x1080 - SO_NETSVC_MARKING_LEVEL = 0x1119 - SO_NET_SERVICE_TYPE = 0x1116 - SO_NKE = 0x1021 - SO_NOADDRERR = 0x1023 - SO_NOSIGPIPE = 0x1022 - SO_NOTIFYCONFLICT = 0x1026 - SO_NP_EXTENSIONS = 0x1083 - SO_NREAD = 0x1020 - SO_NUMRCVPKT = 0x1112 - SO_NWRITE = 0x1024 - SO_OOBINLINE = 0x100 - SO_PEERLABEL = 0x1011 - SO_RANDOMPORT = 0x1082 - SO_RCVBUF = 0x1002 - SO_RCVLOWAT = 0x1004 - SO_RCVTIMEO = 0x1006 - SO_REUSEADDR = 0x4 - SO_REUSEPORT = 0x200 - SO_REUSESHAREUID = 0x1025 - SO_SNDBUF = 0x1001 - SO_SNDLOWAT = 0x1003 - SO_SNDTIMEO = 0x1005 - SO_TIMESTAMP = 0x400 - SO_TIMESTAMP_MONOTONIC = 0x800 - SO_TYPE = 0x1008 - SO_UPCALLCLOSEWAIT = 0x1027 - SO_USELOOPBACK = 0x40 - SO_WANTMORE = 0x4000 - SO_WANTOOBFLAG = 0x8000 - S_IEXEC = 0x40 - S_IFBLK = 0x6000 - S_IFCHR = 0x2000 - S_IFDIR = 0x4000 - S_IFIFO = 0x1000 - S_IFLNK = 0xa000 - S_IFMT = 0xf000 - S_IFREG = 0x8000 - S_IFSOCK = 0xc000 - S_IFWHT = 0xe000 - S_IREAD = 0x100 - S_IRGRP = 0x20 - S_IROTH = 0x4 - S_IRUSR = 0x100 - S_IRWXG = 0x38 - S_IRWXO = 0x7 - S_IRWXU = 0x1c0 - S_ISGID = 0x400 - S_ISTXT = 0x200 - S_ISUID = 0x800 - S_ISVTX = 0x200 - S_IWGRP = 0x10 - S_IWOTH = 0x2 - S_IWRITE = 0x80 - S_IWUSR = 0x80 - S_IXGRP = 0x8 - S_IXOTH = 0x1 - S_IXUSR = 0x40 - TAB0 = 0x0 - TAB1 = 0x400 - TAB2 = 0x800 - TAB3 = 0x4 - TABDLY = 0xc04 - TCIFLUSH = 0x1 - TCIOFF = 0x3 - TCIOFLUSH = 0x3 - TCION = 0x4 - TCOFLUSH = 0x2 - TCOOFF = 0x1 - TCOON = 0x2 - TCP_CONNECTIONTIMEOUT = 0x20 - TCP_CONNECTION_INFO = 0x106 - TCP_ENABLE_ECN = 0x104 - TCP_FASTOPEN = 0x105 - TCP_KEEPALIVE = 0x10 - TCP_KEEPCNT = 0x102 - TCP_KEEPINTVL = 0x101 - TCP_MAXHLEN = 0x3c - TCP_MAXOLEN = 0x28 - TCP_MAXSEG = 0x2 - TCP_MAXWIN = 0xffff - TCP_MAX_SACK = 0x4 - TCP_MAX_WINSHIFT = 0xe - TCP_MINMSS = 0xd8 - TCP_MSS = 0x200 - TCP_NODELAY = 0x1 - TCP_NOOPT = 0x8 - TCP_NOPUSH = 0x4 - TCP_NOTSENT_LOWAT = 0x201 - TCP_RXT_CONNDROPTIME = 0x80 - TCP_RXT_FINDROP = 0x100 - TCP_SENDMOREACKS = 0x103 - TCSAFLUSH = 0x2 - TIOCCBRK = 0x2000747a - TIOCCDTR = 0x20007478 - TIOCCONS = 0x80047462 - TIOCDCDTIMESTAMP = 0x40107458 - TIOCDRAIN = 0x2000745e - TIOCDSIMICROCODE = 0x20007455 - TIOCEXCL = 0x2000740d - TIOCEXT = 0x80047460 - TIOCFLUSH = 0x80047410 - TIOCGDRAINWAIT = 0x40047456 - TIOCGETA = 0x40487413 - TIOCGETD = 0x4004741a - TIOCGPGRP = 0x40047477 - TIOCGWINSZ = 0x40087468 - TIOCIXOFF = 0x20007480 - TIOCIXON = 0x20007481 - TIOCMBIC = 0x8004746b - TIOCMBIS = 0x8004746c - TIOCMGDTRWAIT = 0x4004745a - TIOCMGET = 0x4004746a - TIOCMODG = 0x40047403 - TIOCMODS = 0x80047404 - TIOCMSDTRWAIT = 0x8004745b - TIOCMSET = 0x8004746d - TIOCM_CAR = 0x40 - TIOCM_CD = 0x40 - TIOCM_CTS = 0x20 - TIOCM_DSR = 0x100 - TIOCM_DTR = 0x2 - TIOCM_LE = 0x1 - TIOCM_RI = 0x80 - TIOCM_RNG = 0x80 - TIOCM_RTS = 0x4 - TIOCM_SR = 0x10 - TIOCM_ST = 0x8 - TIOCNOTTY = 0x20007471 - TIOCNXCL = 0x2000740e - TIOCOUTQ = 0x40047473 - TIOCPKT = 0x80047470 - TIOCPKT_DATA = 0x0 - TIOCPKT_DOSTOP = 0x20 - TIOCPKT_FLUSHREAD = 0x1 - TIOCPKT_FLUSHWRITE = 0x2 - TIOCPKT_IOCTL = 0x40 - TIOCPKT_NOSTOP = 0x10 - TIOCPKT_START = 0x8 - TIOCPKT_STOP = 0x4 - TIOCPTYGNAME = 0x40807453 - TIOCPTYGRANT = 0x20007454 - TIOCPTYUNLK = 0x20007452 - TIOCREMOTE = 0x80047469 - TIOCSBRK = 0x2000747b - TIOCSCONS = 0x20007463 - TIOCSCTTY = 0x20007461 - TIOCSDRAINWAIT = 0x80047457 - TIOCSDTR = 0x20007479 - TIOCSETA = 0x80487414 - TIOCSETAF = 0x80487416 - TIOCSETAW = 0x80487415 - TIOCSETD = 0x8004741b - TIOCSIG = 0x2000745f - TIOCSPGRP = 0x80047476 - TIOCSTART = 0x2000746e - TIOCSTAT = 0x20007465 - TIOCSTI = 0x80017472 - TIOCSTOP = 0x2000746f - TIOCSWINSZ = 0x80087467 - TIOCTIMESTAMP = 0x40107459 - TIOCUCNTL = 0x80047466 - TOSTOP = 0x400000 - VDISCARD = 0xf - VDSUSP = 0xb - VEOF = 0x0 - VEOL = 0x1 - VEOL2 = 0x2 - VERASE = 0x3 - VINTR = 0x8 - VKILL = 0x5 - VLNEXT = 0xe - VMIN = 0x10 - VM_LOADAVG = 0x2 - VM_MACHFACTOR = 0x4 - VM_MAXID = 0x6 - VM_METER = 0x1 - VM_SWAPUSAGE = 0x5 - VQUIT = 0x9 - VREPRINT = 0x6 - VSTART = 0xc - VSTATUS = 0x12 - VSTOP = 0xd - VSUSP = 0xa - VT0 = 0x0 - VT1 = 0x10000 - VTDLY = 0x10000 - VTIME = 0x11 - VWERASE = 0x4 - WCONTINUED = 0x10 - WCOREFLAG = 0x80 - WEXITED = 0x4 - WNOHANG = 0x1 - WNOWAIT = 0x20 - WORDSIZE = 0x40 - WSTOPPED = 0x8 - WUNTRACED = 0x2 - XATTR_CREATE = 0x2 - XATTR_NODEFAULT = 0x10 - XATTR_NOFOLLOW = 0x1 - XATTR_NOSECURITY = 0x8 - XATTR_REPLACE = 0x4 - XATTR_SHOWCOMPRESSION = 0x20 + AF_APPLETALK = 0x10 + AF_CCITT = 0xa + AF_CHAOS = 0x5 + AF_CNT = 0x15 + AF_COIP = 0x14 + AF_DATAKIT = 0x9 + AF_DECnet = 0xc + AF_DLI = 0xd + AF_E164 = 0x1c + AF_ECMA = 0x8 + AF_HYLINK = 0xf + AF_IEEE80211 = 0x25 + AF_IMPLINK = 0x3 + AF_INET = 0x2 + AF_INET6 = 0x1e + AF_IPX = 0x17 + AF_ISDN = 0x1c + AF_ISO = 0x7 + AF_LAT = 0xe + AF_LINK = 0x12 + AF_LOCAL = 0x1 + AF_MAX = 0x29 + AF_NATM = 0x1f + AF_NDRV = 0x1b + AF_NETBIOS = 0x21 + AF_NS = 0x6 + AF_OSI = 0x7 + AF_PPP = 0x22 + AF_PUP = 0x4 + AF_RESERVED_36 = 0x24 + AF_ROUTE = 0x11 + AF_SIP = 0x18 + AF_SNA = 0xb + AF_SYSTEM = 0x20 + AF_SYS_CONTROL = 0x2 + AF_UNIX = 0x1 + AF_UNSPEC = 0x0 + AF_UTUN = 0x26 + AF_VSOCK = 0x28 + ALTWERASE = 0x200 + ATTR_BIT_MAP_COUNT = 0x5 + ATTR_CMN_ACCESSMASK = 0x20000 + ATTR_CMN_ACCTIME = 0x1000 + ATTR_CMN_ADDEDTIME = 0x10000000 + ATTR_CMN_BKUPTIME = 0x2000 + ATTR_CMN_CHGTIME = 0x800 + ATTR_CMN_CRTIME = 0x200 + ATTR_CMN_DATA_PROTECT_FLAGS = 0x40000000 + ATTR_CMN_DEVID = 0x2 + ATTR_CMN_DOCUMENT_ID = 0x100000 + ATTR_CMN_ERROR = 0x20000000 + ATTR_CMN_EXTENDED_SECURITY = 0x400000 + ATTR_CMN_FILEID = 0x2000000 + ATTR_CMN_FLAGS = 0x40000 + ATTR_CMN_FNDRINFO = 0x4000 + ATTR_CMN_FSID = 0x4 + ATTR_CMN_FULLPATH = 0x8000000 + ATTR_CMN_GEN_COUNT = 0x80000 + ATTR_CMN_GRPID = 0x10000 + ATTR_CMN_GRPUUID = 0x1000000 + ATTR_CMN_MODTIME = 0x400 + ATTR_CMN_NAME = 0x1 + ATTR_CMN_NAMEDATTRCOUNT = 0x80000 + ATTR_CMN_NAMEDATTRLIST = 0x100000 + ATTR_CMN_OBJID = 0x20 + ATTR_CMN_OBJPERMANENTID = 0x40 + ATTR_CMN_OBJTAG = 0x10 + ATTR_CMN_OBJTYPE = 0x8 + ATTR_CMN_OWNERID = 0x8000 + ATTR_CMN_PARENTID = 0x4000000 + ATTR_CMN_PAROBJID = 0x80 + ATTR_CMN_RETURNED_ATTRS = 0x80000000 + ATTR_CMN_SCRIPT = 0x100 + ATTR_CMN_SETMASK = 0x51c7ff00 + ATTR_CMN_USERACCESS = 0x200000 + ATTR_CMN_UUID = 0x800000 + ATTR_CMN_VALIDMASK = 0xffffffff + ATTR_CMN_VOLSETMASK = 0x6700 + ATTR_FILE_ALLOCSIZE = 0x4 + ATTR_FILE_CLUMPSIZE = 0x10 + ATTR_FILE_DATAALLOCSIZE = 0x400 + ATTR_FILE_DATAEXTENTS = 0x800 + ATTR_FILE_DATALENGTH = 0x200 + ATTR_FILE_DEVTYPE = 0x20 + ATTR_FILE_FILETYPE = 0x40 + ATTR_FILE_FORKCOUNT = 0x80 + ATTR_FILE_FORKLIST = 0x100 + ATTR_FILE_IOBLOCKSIZE = 0x8 + ATTR_FILE_LINKCOUNT = 0x1 + ATTR_FILE_RSRCALLOCSIZE = 0x2000 + ATTR_FILE_RSRCEXTENTS = 0x4000 + ATTR_FILE_RSRCLENGTH = 0x1000 + ATTR_FILE_SETMASK = 0x20 + ATTR_FILE_TOTALSIZE = 0x2 + ATTR_FILE_VALIDMASK = 0x37ff + ATTR_VOL_ALLOCATIONCLUMP = 0x40 + ATTR_VOL_ATTRIBUTES = 0x40000000 + ATTR_VOL_CAPABILITIES = 0x20000 + ATTR_VOL_DIRCOUNT = 0x400 + ATTR_VOL_ENCODINGSUSED = 0x10000 + ATTR_VOL_FILECOUNT = 0x200 + ATTR_VOL_FSTYPE = 0x1 + ATTR_VOL_INFO = 0x80000000 + ATTR_VOL_IOBLOCKSIZE = 0x80 + ATTR_VOL_MAXOBJCOUNT = 0x800 + ATTR_VOL_MINALLOCATION = 0x20 + ATTR_VOL_MOUNTEDDEVICE = 0x8000 + ATTR_VOL_MOUNTFLAGS = 0x4000 + ATTR_VOL_MOUNTPOINT = 0x1000 + ATTR_VOL_NAME = 0x2000 + ATTR_VOL_OBJCOUNT = 0x100 + ATTR_VOL_QUOTA_SIZE = 0x10000000 + ATTR_VOL_RESERVED_SIZE = 0x20000000 + ATTR_VOL_SETMASK = 0x80002000 + ATTR_VOL_SIGNATURE = 0x2 + ATTR_VOL_SIZE = 0x4 + ATTR_VOL_SPACEAVAIL = 0x10 + ATTR_VOL_SPACEFREE = 0x8 + ATTR_VOL_SPACEUSED = 0x800000 + ATTR_VOL_UUID = 0x40000 + ATTR_VOL_VALIDMASK = 0xf087ffff + B0 = 0x0 + B110 = 0x6e + B115200 = 0x1c200 + B1200 = 0x4b0 + B134 = 0x86 + B14400 = 0x3840 + B150 = 0x96 + B1800 = 0x708 + B19200 = 0x4b00 + B200 = 0xc8 + B230400 = 0x38400 + B2400 = 0x960 + B28800 = 0x7080 + B300 = 0x12c + B38400 = 0x9600 + B4800 = 0x12c0 + B50 = 0x32 + B57600 = 0xe100 + B600 = 0x258 + B7200 = 0x1c20 + B75 = 0x4b + B76800 = 0x12c00 + B9600 = 0x2580 + BIOCFLUSH = 0x20004268 + BIOCGBLEN = 0x40044266 + BIOCGDLT = 0x4004426a + BIOCGDLTLIST = 0xc00c4279 + BIOCGETIF = 0x4020426b + BIOCGHDRCMPLT = 0x40044274 + BIOCGRSIG = 0x40044272 + BIOCGRTIMEOUT = 0x4010426e + BIOCGSEESENT = 0x40044276 + BIOCGSTATS = 0x4008426f + BIOCIMMEDIATE = 0x80044270 + BIOCPROMISC = 0x20004269 + BIOCSBLEN = 0xc0044266 + BIOCSDLT = 0x80044278 + BIOCSETF = 0x80104267 + BIOCSETFNR = 0x8010427e + BIOCSETIF = 0x8020426c + BIOCSHDRCMPLT = 0x80044275 + BIOCSRSIG = 0x80044273 + BIOCSRTIMEOUT = 0x8010426d + BIOCSSEESENT = 0x80044277 + BIOCVERSION = 0x40044271 + BPF_A = 0x10 + BPF_ABS = 0x20 + BPF_ADD = 0x0 + BPF_ALIGNMENT = 0x4 + BPF_ALU = 0x4 + BPF_AND = 0x50 + BPF_B = 0x10 + BPF_DIV = 0x30 + BPF_H = 0x8 + BPF_IMM = 0x0 + BPF_IND = 0x40 + BPF_JA = 0x0 + BPF_JEQ = 0x10 + BPF_JGE = 0x30 + BPF_JGT = 0x20 + BPF_JMP = 0x5 + BPF_JSET = 0x40 + BPF_K = 0x0 + BPF_LD = 0x0 + BPF_LDX = 0x1 + BPF_LEN = 0x80 + BPF_LSH = 0x60 + BPF_MAJOR_VERSION = 0x1 + BPF_MAXBUFSIZE = 0x80000 + BPF_MAXINSNS = 0x200 + BPF_MEM = 0x60 + BPF_MEMWORDS = 0x10 + BPF_MINBUFSIZE = 0x20 + BPF_MINOR_VERSION = 0x1 + BPF_MISC = 0x7 + BPF_MSH = 0xa0 + BPF_MUL = 0x20 + BPF_NEG = 0x80 + BPF_OR = 0x40 + BPF_RELEASE = 0x30bb6 + BPF_RET = 0x6 + BPF_RSH = 0x70 + BPF_ST = 0x2 + BPF_STX = 0x3 + BPF_SUB = 0x10 + BPF_TAX = 0x0 + BPF_TXA = 0x80 + BPF_W = 0x0 + BPF_X = 0x8 + BRKINT = 0x2 + BS0 = 0x0 + BS1 = 0x8000 + BSDLY = 0x8000 + CFLUSH = 0xf + CLOCAL = 0x8000 + CLOCK_MONOTONIC = 0x6 + CLOCK_MONOTONIC_RAW = 0x4 + CLOCK_MONOTONIC_RAW_APPROX = 0x5 + CLOCK_PROCESS_CPUTIME_ID = 0xc + CLOCK_REALTIME = 0x0 + CLOCK_THREAD_CPUTIME_ID = 0x10 + CLOCK_UPTIME_RAW = 0x8 + CLOCK_UPTIME_RAW_APPROX = 0x9 + CLONE_NOFOLLOW = 0x1 + CLONE_NOOWNERCOPY = 0x2 + CR0 = 0x0 + CR1 = 0x1000 + CR2 = 0x2000 + CR3 = 0x3000 + CRDLY = 0x3000 + CREAD = 0x800 + CRTSCTS = 0x30000 + CS5 = 0x0 + CS6 = 0x100 + CS7 = 0x200 + CS8 = 0x300 + CSIZE = 0x300 + CSTART = 0x11 + CSTATUS = 0x14 + CSTOP = 0x13 + CSTOPB = 0x400 + CSUSP = 0x1a + CTLIOCGINFO = 0xc0644e03 + CTL_HW = 0x6 + CTL_KERN = 0x1 + CTL_MAXNAME = 0xc + CTL_NET = 0x4 + DLT_A429 = 0xb8 + DLT_A653_ICM = 0xb9 + DLT_AIRONET_HEADER = 0x78 + DLT_AOS = 0xde + DLT_APPLE_IP_OVER_IEEE1394 = 0x8a + DLT_ARCNET = 0x7 + DLT_ARCNET_LINUX = 0x81 + DLT_ATM_CLIP = 0x13 + DLT_ATM_RFC1483 = 0xb + DLT_AURORA = 0x7e + DLT_AX25 = 0x3 + DLT_AX25_KISS = 0xca + DLT_BACNET_MS_TP = 0xa5 + DLT_BLUETOOTH_HCI_H4 = 0xbb + DLT_BLUETOOTH_HCI_H4_WITH_PHDR = 0xc9 + DLT_CAN20B = 0xbe + DLT_CAN_SOCKETCAN = 0xe3 + DLT_CHAOS = 0x5 + DLT_CHDLC = 0x68 + DLT_CISCO_IOS = 0x76 + DLT_C_HDLC = 0x68 + DLT_C_HDLC_WITH_DIR = 0xcd + DLT_DBUS = 0xe7 + DLT_DECT = 0xdd + DLT_DOCSIS = 0x8f + DLT_DVB_CI = 0xeb + DLT_ECONET = 0x73 + DLT_EN10MB = 0x1 + DLT_EN3MB = 0x2 + DLT_ENC = 0x6d + DLT_ERF = 0xc5 + DLT_ERF_ETH = 0xaf + DLT_ERF_POS = 0xb0 + DLT_FC_2 = 0xe0 + DLT_FC_2_WITH_FRAME_DELIMS = 0xe1 + DLT_FDDI = 0xa + DLT_FLEXRAY = 0xd2 + DLT_FRELAY = 0x6b + DLT_FRELAY_WITH_DIR = 0xce + DLT_GCOM_SERIAL = 0xad + DLT_GCOM_T1E1 = 0xac + DLT_GPF_F = 0xab + DLT_GPF_T = 0xaa + DLT_GPRS_LLC = 0xa9 + DLT_GSMTAP_ABIS = 0xda + DLT_GSMTAP_UM = 0xd9 + DLT_HHDLC = 0x79 + DLT_IBM_SN = 0x92 + DLT_IBM_SP = 0x91 + DLT_IEEE802 = 0x6 + DLT_IEEE802_11 = 0x69 + DLT_IEEE802_11_RADIO = 0x7f + DLT_IEEE802_11_RADIO_AVS = 0xa3 + DLT_IEEE802_15_4 = 0xc3 + DLT_IEEE802_15_4_LINUX = 0xbf + DLT_IEEE802_15_4_NOFCS = 0xe6 + DLT_IEEE802_15_4_NONASK_PHY = 0xd7 + DLT_IEEE802_16_MAC_CPS = 0xbc + DLT_IEEE802_16_MAC_CPS_RADIO = 0xc1 + DLT_IPFILTER = 0x74 + DLT_IPMB = 0xc7 + DLT_IPMB_LINUX = 0xd1 + DLT_IPNET = 0xe2 + DLT_IPOIB = 0xf2 + DLT_IPV4 = 0xe4 + DLT_IPV6 = 0xe5 + DLT_IP_OVER_FC = 0x7a + DLT_JUNIPER_ATM1 = 0x89 + DLT_JUNIPER_ATM2 = 0x87 + DLT_JUNIPER_ATM_CEMIC = 0xee + DLT_JUNIPER_CHDLC = 0xb5 + DLT_JUNIPER_ES = 0x84 + DLT_JUNIPER_ETHER = 0xb2 + DLT_JUNIPER_FIBRECHANNEL = 0xea + DLT_JUNIPER_FRELAY = 0xb4 + DLT_JUNIPER_GGSN = 0x85 + DLT_JUNIPER_ISM = 0xc2 + DLT_JUNIPER_MFR = 0x86 + DLT_JUNIPER_MLFR = 0x83 + DLT_JUNIPER_MLPPP = 0x82 + DLT_JUNIPER_MONITOR = 0xa4 + DLT_JUNIPER_PIC_PEER = 0xae + DLT_JUNIPER_PPP = 0xb3 + DLT_JUNIPER_PPPOE = 0xa7 + DLT_JUNIPER_PPPOE_ATM = 0xa8 + DLT_JUNIPER_SERVICES = 0x88 + DLT_JUNIPER_SRX_E2E = 0xe9 + DLT_JUNIPER_ST = 0xc8 + DLT_JUNIPER_VP = 0xb7 + DLT_JUNIPER_VS = 0xe8 + DLT_LAPB_WITH_DIR = 0xcf + DLT_LAPD = 0xcb + DLT_LIN = 0xd4 + DLT_LINUX_EVDEV = 0xd8 + DLT_LINUX_IRDA = 0x90 + DLT_LINUX_LAPD = 0xb1 + DLT_LINUX_PPP_WITHDIRECTION = 0xa6 + DLT_LINUX_SLL = 0x71 + DLT_LOOP = 0x6c + DLT_LTALK = 0x72 + DLT_MATCHING_MAX = 0x10a + DLT_MATCHING_MIN = 0x68 + DLT_MFR = 0xb6 + DLT_MOST = 0xd3 + DLT_MPEG_2_TS = 0xf3 + DLT_MPLS = 0xdb + DLT_MTP2 = 0x8c + DLT_MTP2_WITH_PHDR = 0x8b + DLT_MTP3 = 0x8d + DLT_MUX27010 = 0xec + DLT_NETANALYZER = 0xf0 + DLT_NETANALYZER_TRANSPARENT = 0xf1 + DLT_NFC_LLCP = 0xf5 + DLT_NFLOG = 0xef + DLT_NG40 = 0xf4 + DLT_NULL = 0x0 + DLT_PCI_EXP = 0x7d + DLT_PFLOG = 0x75 + DLT_PFSYNC = 0x12 + DLT_PPI = 0xc0 + DLT_PPP = 0x9 + DLT_PPP_BSDOS = 0x10 + DLT_PPP_ETHER = 0x33 + DLT_PPP_PPPD = 0xa6 + DLT_PPP_SERIAL = 0x32 + DLT_PPP_WITH_DIR = 0xcc + DLT_PPP_WITH_DIRECTION = 0xa6 + DLT_PRISM_HEADER = 0x77 + DLT_PRONET = 0x4 + DLT_RAIF1 = 0xc6 + DLT_RAW = 0xc + DLT_RIO = 0x7c + DLT_SCCP = 0x8e + DLT_SITA = 0xc4 + DLT_SLIP = 0x8 + DLT_SLIP_BSDOS = 0xf + DLT_STANAG_5066_D_PDU = 0xed + DLT_SUNATM = 0x7b + DLT_SYMANTEC_FIREWALL = 0x63 + DLT_TZSP = 0x80 + DLT_USB = 0xba + DLT_USB_DARWIN = 0x10a + DLT_USB_LINUX = 0xbd + DLT_USB_LINUX_MMAPPED = 0xdc + DLT_USER0 = 0x93 + DLT_USER1 = 0x94 + DLT_USER10 = 0x9d + DLT_USER11 = 0x9e + DLT_USER12 = 0x9f + DLT_USER13 = 0xa0 + DLT_USER14 = 0xa1 + DLT_USER15 = 0xa2 + DLT_USER2 = 0x95 + DLT_USER3 = 0x96 + DLT_USER4 = 0x97 + DLT_USER5 = 0x98 + DLT_USER6 = 0x99 + DLT_USER7 = 0x9a + DLT_USER8 = 0x9b + DLT_USER9 = 0x9c + DLT_WIHART = 0xdf + DLT_X2E_SERIAL = 0xd5 + DLT_X2E_XORAYA = 0xd6 + DT_BLK = 0x6 + DT_CHR = 0x2 + DT_DIR = 0x4 + DT_FIFO = 0x1 + DT_LNK = 0xa + DT_REG = 0x8 + DT_SOCK = 0xc + DT_UNKNOWN = 0x0 + DT_WHT = 0xe + ECHO = 0x8 + ECHOCTL = 0x40 + ECHOE = 0x2 + ECHOK = 0x4 + ECHOKE = 0x1 + ECHONL = 0x10 + ECHOPRT = 0x20 + EVFILT_AIO = -0x3 + EVFILT_EXCEPT = -0xf + EVFILT_FS = -0x9 + EVFILT_MACHPORT = -0x8 + EVFILT_PROC = -0x5 + EVFILT_READ = -0x1 + EVFILT_SIGNAL = -0x6 + EVFILT_SYSCOUNT = 0x11 + EVFILT_THREADMARKER = 0x11 + EVFILT_TIMER = -0x7 + EVFILT_USER = -0xa + EVFILT_VM = -0xc + EVFILT_VNODE = -0x4 + EVFILT_WRITE = -0x2 + EV_ADD = 0x1 + EV_CLEAR = 0x20 + EV_DELETE = 0x2 + EV_DISABLE = 0x8 + EV_DISPATCH = 0x80 + EV_DISPATCH2 = 0x180 + EV_ENABLE = 0x4 + EV_EOF = 0x8000 + EV_ERROR = 0x4000 + EV_FLAG0 = 0x1000 + EV_FLAG1 = 0x2000 + EV_ONESHOT = 0x10 + EV_OOBAND = 0x2000 + EV_POLL = 0x1000 + EV_RECEIPT = 0x40 + EV_SYSFLAGS = 0xf000 + EV_UDATA_SPECIFIC = 0x100 + EV_VANISHED = 0x200 + EXTA = 0x4b00 + EXTB = 0x9600 + EXTPROC = 0x800 + FD_CLOEXEC = 0x1 + FD_SETSIZE = 0x400 + FF0 = 0x0 + FF1 = 0x4000 + FFDLY = 0x4000 + FLUSHO = 0x800000 + FSOPT_ATTR_CMN_EXTENDED = 0x20 + FSOPT_NOFOLLOW = 0x1 + FSOPT_NOINMEMUPDATE = 0x2 + FSOPT_PACK_INVAL_ATTRS = 0x8 + FSOPT_REPORT_FULLSIZE = 0x4 + FSOPT_RETURN_REALDEV = 0x200 + F_ADDFILESIGS = 0x3d + F_ADDFILESIGS_FOR_DYLD_SIM = 0x53 + F_ADDFILESIGS_INFO = 0x67 + F_ADDFILESIGS_RETURN = 0x61 + F_ADDFILESUPPL = 0x68 + F_ADDSIGS = 0x3b + F_ALLOCATEALL = 0x4 + F_ALLOCATECONTIG = 0x2 + F_BARRIERFSYNC = 0x55 + F_CHECK_LV = 0x62 + F_CHKCLEAN = 0x29 + F_DUPFD = 0x0 + F_DUPFD_CLOEXEC = 0x43 + F_FINDSIGS = 0x4e + F_FLUSH_DATA = 0x28 + F_FREEZE_FS = 0x35 + F_FULLFSYNC = 0x33 + F_GETCODEDIR = 0x48 + F_GETFD = 0x1 + F_GETFL = 0x3 + F_GETLK = 0x7 + F_GETLKPID = 0x42 + F_GETNOSIGPIPE = 0x4a + F_GETOWN = 0x5 + F_GETPATH = 0x32 + F_GETPATH_MTMINFO = 0x47 + F_GETPATH_NOFIRMLINK = 0x66 + F_GETPROTECTIONCLASS = 0x3f + F_GETPROTECTIONLEVEL = 0x4d + F_GETSIGSINFO = 0x69 + F_GLOBAL_NOCACHE = 0x37 + F_LOG2PHYS = 0x31 + F_LOG2PHYS_EXT = 0x41 + F_NOCACHE = 0x30 + F_NODIRECT = 0x3e + F_OK = 0x0 + F_PATHPKG_CHECK = 0x34 + F_PEOFPOSMODE = 0x3 + F_PREALLOCATE = 0x2a + F_PUNCHHOLE = 0x63 + F_RDADVISE = 0x2c + F_RDAHEAD = 0x2d + F_RDLCK = 0x1 + F_SETBACKINGSTORE = 0x46 + F_SETFD = 0x2 + F_SETFL = 0x4 + F_SETLK = 0x8 + F_SETLKW = 0x9 + F_SETLKWTIMEOUT = 0xa + F_SETNOSIGPIPE = 0x49 + F_SETOWN = 0x6 + F_SETPROTECTIONCLASS = 0x40 + F_SETSIZE = 0x2b + F_SINGLE_WRITER = 0x4c + F_SPECULATIVE_READ = 0x65 + F_THAW_FS = 0x36 + F_TRANSCODEKEY = 0x4b + F_TRIM_ACTIVE_FILE = 0x64 + F_UNLCK = 0x2 + F_VOLPOSMODE = 0x4 + F_WRLCK = 0x3 + HUPCL = 0x4000 + HW_MACHINE = 0x1 + ICANON = 0x100 + ICMP6_FILTER = 0x12 + ICRNL = 0x100 + IEXTEN = 0x400 + IFF_ALLMULTI = 0x200 + IFF_ALTPHYS = 0x4000 + IFF_BROADCAST = 0x2 + IFF_DEBUG = 0x4 + IFF_LINK0 = 0x1000 + IFF_LINK1 = 0x2000 + IFF_LINK2 = 0x4000 + IFF_LOOPBACK = 0x8 + IFF_MULTICAST = 0x8000 + IFF_NOARP = 0x80 + IFF_NOTRAILERS = 0x20 + IFF_OACTIVE = 0x400 + IFF_POINTOPOINT = 0x10 + IFF_PROMISC = 0x100 + IFF_RUNNING = 0x40 + IFF_SIMPLEX = 0x800 + IFF_UP = 0x1 + IFNAMSIZ = 0x10 + IFT_1822 = 0x2 + IFT_6LOWPAN = 0x40 + IFT_AAL5 = 0x31 + IFT_ARCNET = 0x23 + IFT_ARCNETPLUS = 0x24 + IFT_ATM = 0x25 + IFT_BRIDGE = 0xd1 + IFT_CARP = 0xf8 + IFT_CELLULAR = 0xff + IFT_CEPT = 0x13 + IFT_DS3 = 0x1e + IFT_ENC = 0xf4 + IFT_EON = 0x19 + IFT_ETHER = 0x6 + IFT_FAITH = 0x38 + IFT_FDDI = 0xf + IFT_FRELAY = 0x20 + IFT_FRELAYDCE = 0x2c + IFT_GIF = 0x37 + IFT_HDH1822 = 0x3 + IFT_HIPPI = 0x2f + IFT_HSSI = 0x2e + IFT_HY = 0xe + IFT_IEEE1394 = 0x90 + IFT_IEEE8023ADLAG = 0x88 + IFT_ISDNBASIC = 0x14 + IFT_ISDNPRIMARY = 0x15 + IFT_ISO88022LLC = 0x29 + IFT_ISO88023 = 0x7 + IFT_ISO88024 = 0x8 + IFT_ISO88025 = 0x9 + IFT_ISO88026 = 0xa + IFT_L2VLAN = 0x87 + IFT_LAPB = 0x10 + IFT_LOCALTALK = 0x2a + IFT_LOOP = 0x18 + IFT_MIOX25 = 0x26 + IFT_MODEM = 0x30 + IFT_NSIP = 0x1b + IFT_OTHER = 0x1 + IFT_P10 = 0xc + IFT_P80 = 0xd + IFT_PARA = 0x22 + IFT_PDP = 0xff + IFT_PFLOG = 0xf5 + IFT_PFSYNC = 0xf6 + IFT_PKTAP = 0xfe + IFT_PPP = 0x17 + IFT_PROPMUX = 0x36 + IFT_PROPVIRTUAL = 0x35 + IFT_PTPSERIAL = 0x16 + IFT_RS232 = 0x21 + IFT_SDLC = 0x11 + IFT_SIP = 0x1f + IFT_SLIP = 0x1c + IFT_SMDSDXI = 0x2b + IFT_SMDSICIP = 0x34 + IFT_SONET = 0x27 + IFT_SONETPATH = 0x32 + IFT_SONETVT = 0x33 + IFT_STARLAN = 0xb + IFT_STF = 0x39 + IFT_T1 = 0x12 + IFT_ULTRA = 0x1d + IFT_V35 = 0x2d + IFT_X25 = 0x5 + IFT_X25DDN = 0x4 + IFT_X25PLE = 0x28 + IFT_XETHER = 0x1a + IGNBRK = 0x1 + IGNCR = 0x80 + IGNPAR = 0x4 + IMAXBEL = 0x2000 + INLCR = 0x40 + INPCK = 0x10 + IN_CLASSA_HOST = 0xffffff + IN_CLASSA_MAX = 0x80 + IN_CLASSA_NET = 0xff000000 + IN_CLASSA_NSHIFT = 0x18 + IN_CLASSB_HOST = 0xffff + IN_CLASSB_MAX = 0x10000 + IN_CLASSB_NET = 0xffff0000 + IN_CLASSB_NSHIFT = 0x10 + IN_CLASSC_HOST = 0xff + IN_CLASSC_NET = 0xffffff00 + IN_CLASSC_NSHIFT = 0x8 + IN_CLASSD_HOST = 0xfffffff + IN_CLASSD_NET = 0xf0000000 + IN_CLASSD_NSHIFT = 0x1c + IN_LINKLOCALNETNUM = 0xa9fe0000 + IN_LOOPBACKNET = 0x7f + IOCTL_VM_SOCKETS_GET_LOCAL_CID = 0x400473d1 + IPPROTO_3PC = 0x22 + IPPROTO_ADFS = 0x44 + IPPROTO_AH = 0x33 + IPPROTO_AHIP = 0x3d + IPPROTO_APES = 0x63 + IPPROTO_ARGUS = 0xd + IPPROTO_AX25 = 0x5d + IPPROTO_BHA = 0x31 + IPPROTO_BLT = 0x1e + IPPROTO_BRSATMON = 0x4c + IPPROTO_CFTP = 0x3e + IPPROTO_CHAOS = 0x10 + IPPROTO_CMTP = 0x26 + IPPROTO_CPHB = 0x49 + IPPROTO_CPNX = 0x48 + IPPROTO_DDP = 0x25 + IPPROTO_DGP = 0x56 + IPPROTO_DIVERT = 0xfe + IPPROTO_DONE = 0x101 + IPPROTO_DSTOPTS = 0x3c + IPPROTO_EGP = 0x8 + IPPROTO_EMCON = 0xe + IPPROTO_ENCAP = 0x62 + IPPROTO_EON = 0x50 + IPPROTO_ESP = 0x32 + IPPROTO_ETHERIP = 0x61 + IPPROTO_FRAGMENT = 0x2c + IPPROTO_GGP = 0x3 + IPPROTO_GMTP = 0x64 + IPPROTO_GRE = 0x2f + IPPROTO_HELLO = 0x3f + IPPROTO_HMP = 0x14 + IPPROTO_HOPOPTS = 0x0 + IPPROTO_ICMP = 0x1 + IPPROTO_ICMPV6 = 0x3a + IPPROTO_IDP = 0x16 + IPPROTO_IDPR = 0x23 + IPPROTO_IDRP = 0x2d + IPPROTO_IGMP = 0x2 + IPPROTO_IGP = 0x55 + IPPROTO_IGRP = 0x58 + IPPROTO_IL = 0x28 + IPPROTO_INLSP = 0x34 + IPPROTO_INP = 0x20 + IPPROTO_IP = 0x0 + IPPROTO_IPCOMP = 0x6c + IPPROTO_IPCV = 0x47 + IPPROTO_IPEIP = 0x5e + IPPROTO_IPIP = 0x4 + IPPROTO_IPPC = 0x43 + IPPROTO_IPV4 = 0x4 + IPPROTO_IPV6 = 0x29 + IPPROTO_IRTP = 0x1c + IPPROTO_KRYPTOLAN = 0x41 + IPPROTO_LARP = 0x5b + IPPROTO_LEAF1 = 0x19 + IPPROTO_LEAF2 = 0x1a + IPPROTO_MAX = 0x100 + IPPROTO_MAXID = 0x34 + IPPROTO_MEAS = 0x13 + IPPROTO_MHRP = 0x30 + IPPROTO_MICP = 0x5f + IPPROTO_MTP = 0x5c + IPPROTO_MUX = 0x12 + IPPROTO_ND = 0x4d + IPPROTO_NHRP = 0x36 + IPPROTO_NONE = 0x3b + IPPROTO_NSP = 0x1f + IPPROTO_NVPII = 0xb + IPPROTO_OSPFIGP = 0x59 + IPPROTO_PGM = 0x71 + IPPROTO_PIGP = 0x9 + IPPROTO_PIM = 0x67 + IPPROTO_PRM = 0x15 + IPPROTO_PUP = 0xc + IPPROTO_PVP = 0x4b + IPPROTO_RAW = 0xff + IPPROTO_RCCMON = 0xa + IPPROTO_RDP = 0x1b + IPPROTO_ROUTING = 0x2b + IPPROTO_RSVP = 0x2e + IPPROTO_RVD = 0x42 + IPPROTO_SATEXPAK = 0x40 + IPPROTO_SATMON = 0x45 + IPPROTO_SCCSP = 0x60 + IPPROTO_SCTP = 0x84 + IPPROTO_SDRP = 0x2a + IPPROTO_SEP = 0x21 + IPPROTO_SRPC = 0x5a + IPPROTO_ST = 0x7 + IPPROTO_SVMTP = 0x52 + IPPROTO_SWIPE = 0x35 + IPPROTO_TCF = 0x57 + IPPROTO_TCP = 0x6 + IPPROTO_TP = 0x1d + IPPROTO_TPXX = 0x27 + IPPROTO_TRUNK1 = 0x17 + IPPROTO_TRUNK2 = 0x18 + IPPROTO_TTP = 0x54 + IPPROTO_UDP = 0x11 + IPPROTO_VINES = 0x53 + IPPROTO_VISA = 0x46 + IPPROTO_VMTP = 0x51 + IPPROTO_WBEXPAK = 0x4f + IPPROTO_WBMON = 0x4e + IPPROTO_WSN = 0x4a + IPPROTO_XNET = 0xf + IPPROTO_XTP = 0x24 + IPV6_2292DSTOPTS = 0x17 + IPV6_2292HOPLIMIT = 0x14 + IPV6_2292HOPOPTS = 0x16 + IPV6_2292NEXTHOP = 0x15 + IPV6_2292PKTINFO = 0x13 + IPV6_2292PKTOPTIONS = 0x19 + IPV6_2292RTHDR = 0x18 + IPV6_3542DSTOPTS = 0x32 + IPV6_3542HOPLIMIT = 0x2f + IPV6_3542HOPOPTS = 0x31 + IPV6_3542NEXTHOP = 0x30 + IPV6_3542PKTINFO = 0x2e + IPV6_3542RTHDR = 0x33 + IPV6_ADDR_MC_FLAGS_PREFIX = 0x20 + IPV6_ADDR_MC_FLAGS_TRANSIENT = 0x10 + IPV6_ADDR_MC_FLAGS_UNICAST_BASED = 0x30 + IPV6_AUTOFLOWLABEL = 0x3b + IPV6_BINDV6ONLY = 0x1b + IPV6_BOUND_IF = 0x7d + IPV6_CHECKSUM = 0x1a + IPV6_DEFAULT_MULTICAST_HOPS = 0x1 + IPV6_DEFAULT_MULTICAST_LOOP = 0x1 + IPV6_DEFHLIM = 0x40 + IPV6_DONTFRAG = 0x3e + IPV6_DSTOPTS = 0x32 + IPV6_FAITH = 0x1d + IPV6_FLOWINFO_MASK = 0xffffff0f + IPV6_FLOWLABEL_MASK = 0xffff0f00 + IPV6_FLOW_ECN_MASK = 0x3000 + IPV6_FRAGTTL = 0x3c + IPV6_FW_ADD = 0x1e + IPV6_FW_DEL = 0x1f + IPV6_FW_FLUSH = 0x20 + IPV6_FW_GET = 0x22 + IPV6_FW_ZERO = 0x21 + IPV6_HLIMDEC = 0x1 + IPV6_HOPLIMIT = 0x2f + IPV6_HOPOPTS = 0x31 + IPV6_IPSEC_POLICY = 0x1c + IPV6_JOIN_GROUP = 0xc + IPV6_LEAVE_GROUP = 0xd + IPV6_MAXHLIM = 0xff + IPV6_MAXOPTHDR = 0x800 + IPV6_MAXPACKET = 0xffff + IPV6_MAX_GROUP_SRC_FILTER = 0x200 + IPV6_MAX_MEMBERSHIPS = 0xfff + IPV6_MAX_SOCK_SRC_FILTER = 0x80 + IPV6_MIN_MEMBERSHIPS = 0x1f + IPV6_MMTU = 0x500 + IPV6_MSFILTER = 0x4a + IPV6_MULTICAST_HOPS = 0xa + IPV6_MULTICAST_IF = 0x9 + IPV6_MULTICAST_LOOP = 0xb + IPV6_NEXTHOP = 0x30 + IPV6_PATHMTU = 0x2c + IPV6_PKTINFO = 0x2e + IPV6_PORTRANGE = 0xe + IPV6_PORTRANGE_DEFAULT = 0x0 + IPV6_PORTRANGE_HIGH = 0x1 + IPV6_PORTRANGE_LOW = 0x2 + IPV6_PREFER_TEMPADDR = 0x3f + IPV6_RECVDSTOPTS = 0x28 + IPV6_RECVHOPLIMIT = 0x25 + IPV6_RECVHOPOPTS = 0x27 + IPV6_RECVPATHMTU = 0x2b + IPV6_RECVPKTINFO = 0x3d + IPV6_RECVRTHDR = 0x26 + IPV6_RECVTCLASS = 0x23 + IPV6_RTHDR = 0x33 + IPV6_RTHDRDSTOPTS = 0x39 + IPV6_RTHDR_LOOSE = 0x0 + IPV6_RTHDR_STRICT = 0x1 + IPV6_RTHDR_TYPE_0 = 0x0 + IPV6_SOCKOPT_RESERVED1 = 0x3 + IPV6_TCLASS = 0x24 + IPV6_UNICAST_HOPS = 0x4 + IPV6_USE_MIN_MTU = 0x2a + IPV6_V6ONLY = 0x1b + IPV6_VERSION = 0x60 + IPV6_VERSION_MASK = 0xf0 + IP_ADD_MEMBERSHIP = 0xc + IP_ADD_SOURCE_MEMBERSHIP = 0x46 + IP_BLOCK_SOURCE = 0x48 + IP_BOUND_IF = 0x19 + IP_DEFAULT_MULTICAST_LOOP = 0x1 + IP_DEFAULT_MULTICAST_TTL = 0x1 + IP_DF = 0x4000 + IP_DONTFRAG = 0x1c + IP_DROP_MEMBERSHIP = 0xd + IP_DROP_SOURCE_MEMBERSHIP = 0x47 + IP_DUMMYNET_CONFIGURE = 0x3c + IP_DUMMYNET_DEL = 0x3d + IP_DUMMYNET_FLUSH = 0x3e + IP_DUMMYNET_GET = 0x40 + IP_FAITH = 0x16 + IP_FW_ADD = 0x28 + IP_FW_DEL = 0x29 + IP_FW_FLUSH = 0x2a + IP_FW_GET = 0x2c + IP_FW_RESETLOG = 0x2d + IP_FW_ZERO = 0x2b + IP_HDRINCL = 0x2 + IP_IPSEC_POLICY = 0x15 + IP_MAXPACKET = 0xffff + IP_MAX_GROUP_SRC_FILTER = 0x200 + IP_MAX_MEMBERSHIPS = 0xfff + IP_MAX_SOCK_MUTE_FILTER = 0x80 + IP_MAX_SOCK_SRC_FILTER = 0x80 + IP_MF = 0x2000 + IP_MIN_MEMBERSHIPS = 0x1f + IP_MSFILTER = 0x4a + IP_MSS = 0x240 + IP_MULTICAST_IF = 0x9 + IP_MULTICAST_IFINDEX = 0x42 + IP_MULTICAST_LOOP = 0xb + IP_MULTICAST_TTL = 0xa + IP_MULTICAST_VIF = 0xe + IP_NAT__XXX = 0x37 + IP_OFFMASK = 0x1fff + IP_OLD_FW_ADD = 0x32 + IP_OLD_FW_DEL = 0x33 + IP_OLD_FW_FLUSH = 0x34 + IP_OLD_FW_GET = 0x36 + IP_OLD_FW_RESETLOG = 0x38 + IP_OLD_FW_ZERO = 0x35 + IP_OPTIONS = 0x1 + IP_PKTINFO = 0x1a + IP_PORTRANGE = 0x13 + IP_PORTRANGE_DEFAULT = 0x0 + IP_PORTRANGE_HIGH = 0x1 + IP_PORTRANGE_LOW = 0x2 + IP_RECVDSTADDR = 0x7 + IP_RECVIF = 0x14 + IP_RECVOPTS = 0x5 + IP_RECVPKTINFO = 0x1a + IP_RECVRETOPTS = 0x6 + IP_RECVTOS = 0x1b + IP_RECVTTL = 0x18 + IP_RETOPTS = 0x8 + IP_RF = 0x8000 + IP_RSVP_OFF = 0x10 + IP_RSVP_ON = 0xf + IP_RSVP_VIF_OFF = 0x12 + IP_RSVP_VIF_ON = 0x11 + IP_STRIPHDR = 0x17 + IP_TOS = 0x3 + IP_TRAFFIC_MGT_BACKGROUND = 0x41 + IP_TTL = 0x4 + IP_UNBLOCK_SOURCE = 0x49 + ISIG = 0x80 + ISTRIP = 0x20 + IUTF8 = 0x4000 + IXANY = 0x800 + IXOFF = 0x400 + IXON = 0x200 + KERN_HOSTNAME = 0xa + KERN_OSRELEASE = 0x2 + KERN_OSTYPE = 0x1 + KERN_VERSION = 0x4 + LOCAL_PEERCRED = 0x1 + LOCAL_PEEREPID = 0x3 + LOCAL_PEEREUUID = 0x5 + LOCAL_PEERPID = 0x2 + LOCAL_PEERTOKEN = 0x6 + LOCAL_PEERUUID = 0x4 + LOCK_EX = 0x2 + LOCK_NB = 0x4 + LOCK_SH = 0x1 + LOCK_UN = 0x8 + MADV_CAN_REUSE = 0x9 + MADV_DONTNEED = 0x4 + MADV_FREE = 0x5 + MADV_FREE_REUSABLE = 0x7 + MADV_FREE_REUSE = 0x8 + MADV_NORMAL = 0x0 + MADV_PAGEOUT = 0xa + MADV_RANDOM = 0x1 + MADV_SEQUENTIAL = 0x2 + MADV_WILLNEED = 0x3 + MADV_ZERO_WIRED_PAGES = 0x6 + MAP_32BIT = 0x8000 + MAP_ANON = 0x1000 + MAP_ANONYMOUS = 0x1000 + MAP_COPY = 0x2 + MAP_FILE = 0x0 + MAP_FIXED = 0x10 + MAP_HASSEMAPHORE = 0x200 + MAP_JIT = 0x800 + MAP_NOCACHE = 0x400 + MAP_NOEXTEND = 0x100 + MAP_NORESERVE = 0x40 + MAP_PRIVATE = 0x2 + MAP_RENAME = 0x20 + MAP_RESERVED0080 = 0x80 + MAP_RESILIENT_CODESIGN = 0x2000 + MAP_RESILIENT_MEDIA = 0x4000 + MAP_SHARED = 0x1 + MAP_TRANSLATED_ALLOW_EXECUTE = 0x20000 + MAP_UNIX03 = 0x40000 + MCAST_BLOCK_SOURCE = 0x54 + MCAST_EXCLUDE = 0x2 + MCAST_INCLUDE = 0x1 + MCAST_JOIN_GROUP = 0x50 + MCAST_JOIN_SOURCE_GROUP = 0x52 + MCAST_LEAVE_GROUP = 0x51 + MCAST_LEAVE_SOURCE_GROUP = 0x53 + MCAST_UNBLOCK_SOURCE = 0x55 + MCAST_UNDEFINED = 0x0 + MCL_CURRENT = 0x1 + MCL_FUTURE = 0x2 + MNT_ASYNC = 0x40 + MNT_AUTOMOUNTED = 0x400000 + MNT_CMDFLAGS = 0xf0000 + MNT_CPROTECT = 0x80 + MNT_DEFWRITE = 0x2000000 + MNT_DONTBROWSE = 0x100000 + MNT_DOVOLFS = 0x8000 + MNT_DWAIT = 0x4 + MNT_EXPORTED = 0x100 + MNT_EXT_ROOT_DATA_VOL = 0x1 + MNT_FORCE = 0x80000 + MNT_IGNORE_OWNERSHIP = 0x200000 + MNT_JOURNALED = 0x800000 + MNT_LOCAL = 0x1000 + MNT_MULTILABEL = 0x4000000 + MNT_NOATIME = 0x10000000 + MNT_NOBLOCK = 0x20000 + MNT_NODEV = 0x10 + MNT_NOEXEC = 0x4 + MNT_NOSUID = 0x8 + MNT_NOUSERXATTR = 0x1000000 + MNT_NOWAIT = 0x2 + MNT_QUARANTINE = 0x400 + MNT_QUOTA = 0x2000 + MNT_RDONLY = 0x1 + MNT_RELOAD = 0x40000 + MNT_REMOVABLE = 0x200 + MNT_ROOTFS = 0x4000 + MNT_SNAPSHOT = 0x40000000 + MNT_STRICTATIME = 0x80000000 + MNT_SYNCHRONOUS = 0x2 + MNT_UNION = 0x20 + MNT_UNKNOWNPERMISSIONS = 0x200000 + MNT_UPDATE = 0x10000 + MNT_VISFLAGMASK = 0xd7f0f7ff + MNT_WAIT = 0x1 + MSG_CTRUNC = 0x20 + MSG_DONTROUTE = 0x4 + MSG_DONTWAIT = 0x80 + MSG_EOF = 0x100 + MSG_EOR = 0x8 + MSG_FLUSH = 0x400 + MSG_HAVEMORE = 0x2000 + MSG_HOLD = 0x800 + MSG_NEEDSA = 0x10000 + MSG_NOSIGNAL = 0x80000 + MSG_OOB = 0x1 + MSG_PEEK = 0x2 + MSG_RCVMORE = 0x4000 + MSG_SEND = 0x1000 + MSG_TRUNC = 0x10 + MSG_WAITALL = 0x40 + MSG_WAITSTREAM = 0x200 + MS_ASYNC = 0x1 + MS_DEACTIVATE = 0x8 + MS_INVALIDATE = 0x2 + MS_KILLPAGES = 0x4 + MS_SYNC = 0x10 + NAME_MAX = 0xff + NET_RT_DUMP = 0x1 + NET_RT_DUMP2 = 0x7 + NET_RT_FLAGS = 0x2 + NET_RT_FLAGS_PRIV = 0xa + NET_RT_IFLIST = 0x3 + NET_RT_IFLIST2 = 0x6 + NET_RT_MAXID = 0xb + NET_RT_STAT = 0x4 + NET_RT_TRASH = 0x5 + NFDBITS = 0x20 + NL0 = 0x0 + NL1 = 0x100 + NL2 = 0x200 + NL3 = 0x300 + NLDLY = 0x300 + NOFLSH = 0x80000000 + NOKERNINFO = 0x2000000 + NOTE_ABSOLUTE = 0x8 + NOTE_ATTRIB = 0x8 + NOTE_BACKGROUND = 0x40 + NOTE_CHILD = 0x4 + NOTE_CRITICAL = 0x20 + NOTE_DELETE = 0x1 + NOTE_EXEC = 0x20000000 + NOTE_EXIT = 0x80000000 + NOTE_EXITSTATUS = 0x4000000 + NOTE_EXIT_CSERROR = 0x40000 + NOTE_EXIT_DECRYPTFAIL = 0x10000 + NOTE_EXIT_DETAIL = 0x2000000 + NOTE_EXIT_DETAIL_MASK = 0x70000 + NOTE_EXIT_MEMORY = 0x20000 + NOTE_EXIT_REPARENTED = 0x80000 + NOTE_EXTEND = 0x4 + NOTE_FFAND = 0x40000000 + NOTE_FFCOPY = 0xc0000000 + NOTE_FFCTRLMASK = 0xc0000000 + NOTE_FFLAGSMASK = 0xffffff + NOTE_FFNOP = 0x0 + NOTE_FFOR = 0x80000000 + NOTE_FORK = 0x40000000 + NOTE_FUNLOCK = 0x100 + NOTE_LEEWAY = 0x10 + NOTE_LINK = 0x10 + NOTE_LOWAT = 0x1 + NOTE_MACHTIME = 0x100 + NOTE_MACH_CONTINUOUS_TIME = 0x80 + NOTE_NONE = 0x80 + NOTE_NSECONDS = 0x4 + NOTE_OOB = 0x2 + NOTE_PCTRLMASK = -0x100000 + NOTE_PDATAMASK = 0xfffff + NOTE_REAP = 0x10000000 + NOTE_RENAME = 0x20 + NOTE_REVOKE = 0x40 + NOTE_SECONDS = 0x1 + NOTE_SIGNAL = 0x8000000 + NOTE_TRACK = 0x1 + NOTE_TRACKERR = 0x2 + NOTE_TRIGGER = 0x1000000 + NOTE_USECONDS = 0x2 + NOTE_VM_ERROR = 0x10000000 + NOTE_VM_PRESSURE = 0x80000000 + NOTE_VM_PRESSURE_SUDDEN_TERMINATE = 0x20000000 + NOTE_VM_PRESSURE_TERMINATE = 0x40000000 + NOTE_WRITE = 0x2 + OCRNL = 0x10 + OFDEL = 0x20000 + OFILL = 0x80 + ONLCR = 0x2 + ONLRET = 0x40 + ONOCR = 0x20 + ONOEOT = 0x8 + OPOST = 0x1 + OXTABS = 0x4 + O_ACCMODE = 0x3 + O_ALERT = 0x20000000 + O_APPEND = 0x8 + O_ASYNC = 0x40 + O_CLOEXEC = 0x1000000 + O_CREAT = 0x200 + O_DIRECTORY = 0x100000 + O_DP_GETRAWENCRYPTED = 0x1 + O_DP_GETRAWUNENCRYPTED = 0x2 + O_DSYNC = 0x400000 + O_EVTONLY = 0x8000 + O_EXCL = 0x800 + O_EXLOCK = 0x20 + O_FSYNC = 0x80 + O_NDELAY = 0x4 + O_NOCTTY = 0x20000 + O_NOFOLLOW = 0x100 + O_NOFOLLOW_ANY = 0x20000000 + O_NONBLOCK = 0x4 + O_POPUP = 0x80000000 + O_RDONLY = 0x0 + O_RDWR = 0x2 + O_SHLOCK = 0x10 + O_SYMLINK = 0x200000 + O_SYNC = 0x80 + O_TRUNC = 0x400 + O_WRONLY = 0x1 + PARENB = 0x1000 + PARMRK = 0x8 + PARODD = 0x2000 + PENDIN = 0x20000000 + PRIO_PGRP = 0x1 + PRIO_PROCESS = 0x0 + PRIO_USER = 0x2 + PROT_EXEC = 0x4 + PROT_NONE = 0x0 + PROT_READ = 0x1 + PROT_WRITE = 0x2 + PT_ATTACH = 0xa + PT_ATTACHEXC = 0xe + PT_CONTINUE = 0x7 + PT_DENY_ATTACH = 0x1f + PT_DETACH = 0xb + PT_FIRSTMACH = 0x20 + PT_FORCEQUOTA = 0x1e + PT_KILL = 0x8 + PT_READ_D = 0x2 + PT_READ_I = 0x1 + PT_READ_U = 0x3 + PT_SIGEXC = 0xc + PT_STEP = 0x9 + PT_THUPDATE = 0xd + PT_TRACE_ME = 0x0 + PT_WRITE_D = 0x5 + PT_WRITE_I = 0x4 + PT_WRITE_U = 0x6 + RLIMIT_AS = 0x5 + RLIMIT_CORE = 0x4 + RLIMIT_CPU = 0x0 + RLIMIT_CPU_USAGE_MONITOR = 0x2 + RLIMIT_DATA = 0x2 + RLIMIT_FSIZE = 0x1 + RLIMIT_MEMLOCK = 0x6 + RLIMIT_NOFILE = 0x8 + RLIMIT_NPROC = 0x7 + RLIMIT_RSS = 0x5 + RLIMIT_STACK = 0x3 + RLIM_INFINITY = 0x7fffffffffffffff + RTAX_AUTHOR = 0x6 + RTAX_BRD = 0x7 + RTAX_DST = 0x0 + RTAX_GATEWAY = 0x1 + RTAX_GENMASK = 0x3 + RTAX_IFA = 0x5 + RTAX_IFP = 0x4 + RTAX_MAX = 0x8 + RTAX_NETMASK = 0x2 + RTA_AUTHOR = 0x40 + RTA_BRD = 0x80 + RTA_DST = 0x1 + RTA_GATEWAY = 0x2 + RTA_GENMASK = 0x8 + RTA_IFA = 0x20 + RTA_IFP = 0x10 + RTA_NETMASK = 0x4 + RTF_BLACKHOLE = 0x1000 + RTF_BROADCAST = 0x400000 + RTF_CLONING = 0x100 + RTF_CONDEMNED = 0x2000000 + RTF_DEAD = 0x20000000 + RTF_DELCLONE = 0x80 + RTF_DONE = 0x40 + RTF_DYNAMIC = 0x10 + RTF_GATEWAY = 0x2 + RTF_GLOBAL = 0x40000000 + RTF_HOST = 0x4 + RTF_IFREF = 0x4000000 + RTF_IFSCOPE = 0x1000000 + RTF_LLDATA = 0x400 + RTF_LLINFO = 0x400 + RTF_LOCAL = 0x200000 + RTF_MODIFIED = 0x20 + RTF_MULTICAST = 0x800000 + RTF_NOIFREF = 0x2000 + RTF_PINNED = 0x100000 + RTF_PRCLONING = 0x10000 + RTF_PROTO1 = 0x8000 + RTF_PROTO2 = 0x4000 + RTF_PROTO3 = 0x40000 + RTF_PROXY = 0x8000000 + RTF_REJECT = 0x8 + RTF_ROUTER = 0x10000000 + RTF_STATIC = 0x800 + RTF_UP = 0x1 + RTF_WASCLONED = 0x20000 + RTF_XRESOLVE = 0x200 + RTM_ADD = 0x1 + RTM_CHANGE = 0x3 + RTM_DELADDR = 0xd + RTM_DELETE = 0x2 + RTM_DELMADDR = 0x10 + RTM_GET = 0x4 + RTM_GET2 = 0x14 + RTM_IFINFO = 0xe + RTM_IFINFO2 = 0x12 + RTM_LOCK = 0x8 + RTM_LOSING = 0x5 + RTM_MISS = 0x7 + RTM_NEWADDR = 0xc + RTM_NEWMADDR = 0xf + RTM_NEWMADDR2 = 0x13 + RTM_OLDADD = 0x9 + RTM_OLDDEL = 0xa + RTM_REDIRECT = 0x6 + RTM_RESOLVE = 0xb + RTM_RTTUNIT = 0xf4240 + RTM_VERSION = 0x5 + RTV_EXPIRE = 0x4 + RTV_HOPCOUNT = 0x2 + RTV_MTU = 0x1 + RTV_RPIPE = 0x8 + RTV_RTT = 0x40 + RTV_RTTVAR = 0x80 + RTV_SPIPE = 0x10 + RTV_SSTHRESH = 0x20 + RUSAGE_CHILDREN = -0x1 + RUSAGE_SELF = 0x0 + SCM_CREDS = 0x3 + SCM_RIGHTS = 0x1 + SCM_TIMESTAMP = 0x2 + SCM_TIMESTAMP_MONOTONIC = 0x4 + SEEK_CUR = 0x1 + SEEK_DATA = 0x4 + SEEK_END = 0x2 + SEEK_HOLE = 0x3 + SEEK_SET = 0x0 + SHUT_RD = 0x0 + SHUT_RDWR = 0x2 + SHUT_WR = 0x1 + SIOCADDMULTI = 0x80206931 + SIOCAIFADDR = 0x8040691a + SIOCARPIPLL = 0xc0206928 + SIOCATMARK = 0x40047307 + SIOCAUTOADDR = 0xc0206926 + SIOCAUTONETMASK = 0x80206927 + SIOCDELMULTI = 0x80206932 + SIOCDIFADDR = 0x80206919 + SIOCDIFPHYADDR = 0x80206941 + SIOCGDRVSPEC = 0xc028697b + SIOCGETVLAN = 0xc020697f + SIOCGHIWAT = 0x40047301 + SIOCGIF6LOWPAN = 0xc02069c5 + SIOCGIFADDR = 0xc0206921 + SIOCGIFALTMTU = 0xc0206948 + SIOCGIFASYNCMAP = 0xc020697c + SIOCGIFBOND = 0xc0206947 + SIOCGIFBRDADDR = 0xc0206923 + SIOCGIFCAP = 0xc020695b + SIOCGIFCONF = 0xc00c6924 + SIOCGIFDEVMTU = 0xc0206944 + SIOCGIFDSTADDR = 0xc0206922 + SIOCGIFFLAGS = 0xc0206911 + SIOCGIFFUNCTIONALTYPE = 0xc02069ad + SIOCGIFGENERIC = 0xc020693a + SIOCGIFKPI = 0xc0206987 + SIOCGIFMAC = 0xc0206982 + SIOCGIFMEDIA = 0xc02c6938 + SIOCGIFMETRIC = 0xc0206917 + SIOCGIFMTU = 0xc0206933 + SIOCGIFNETMASK = 0xc0206925 + SIOCGIFPDSTADDR = 0xc0206940 + SIOCGIFPHYS = 0xc0206935 + SIOCGIFPSRCADDR = 0xc020693f + SIOCGIFSTATUS = 0xc331693d + SIOCGIFVLAN = 0xc020697f + SIOCGIFWAKEFLAGS = 0xc0206988 + SIOCGIFXMEDIA = 0xc02c6948 + SIOCGLOWAT = 0x40047303 + SIOCGPGRP = 0x40047309 + SIOCIFCREATE = 0xc0206978 + SIOCIFCREATE2 = 0xc020697a + SIOCIFDESTROY = 0x80206979 + SIOCIFGCLONERS = 0xc0106981 + SIOCRSLVMULTI = 0xc010693b + SIOCSDRVSPEC = 0x8028697b + SIOCSETVLAN = 0x8020697e + SIOCSHIWAT = 0x80047300 + SIOCSIF6LOWPAN = 0x802069c4 + SIOCSIFADDR = 0x8020690c + SIOCSIFALTMTU = 0x80206945 + SIOCSIFASYNCMAP = 0x8020697d + SIOCSIFBOND = 0x80206946 + SIOCSIFBRDADDR = 0x80206913 + SIOCSIFCAP = 0x8020695a + SIOCSIFDSTADDR = 0x8020690e + SIOCSIFFLAGS = 0x80206910 + SIOCSIFGENERIC = 0x80206939 + SIOCSIFKPI = 0x80206986 + SIOCSIFLLADDR = 0x8020693c + SIOCSIFMAC = 0x80206983 + SIOCSIFMEDIA = 0xc0206937 + SIOCSIFMETRIC = 0x80206918 + SIOCSIFMTU = 0x80206934 + SIOCSIFNETMASK = 0x80206916 + SIOCSIFPHYADDR = 0x8040693e + SIOCSIFPHYS = 0x80206936 + SIOCSIFVLAN = 0x8020697e + SIOCSLOWAT = 0x80047302 + SIOCSPGRP = 0x80047308 + SOCK_DGRAM = 0x2 + SOCK_MAXADDRLEN = 0xff + SOCK_RAW = 0x3 + SOCK_RDM = 0x4 + SOCK_SEQPACKET = 0x5 + SOCK_STREAM = 0x1 + SOL_LOCAL = 0x0 + SOL_SOCKET = 0xffff + SOMAXCONN = 0x80 + SO_ACCEPTCONN = 0x2 + SO_BROADCAST = 0x20 + SO_DEBUG = 0x1 + SO_DONTROUTE = 0x10 + SO_DONTTRUNC = 0x2000 + SO_ERROR = 0x1007 + SO_KEEPALIVE = 0x8 + SO_LABEL = 0x1010 + SO_LINGER = 0x80 + SO_LINGER_SEC = 0x1080 + SO_NETSVC_MARKING_LEVEL = 0x1119 + SO_NET_SERVICE_TYPE = 0x1116 + SO_NKE = 0x1021 + SO_NOADDRERR = 0x1023 + SO_NOSIGPIPE = 0x1022 + SO_NOTIFYCONFLICT = 0x1026 + SO_NP_EXTENSIONS = 0x1083 + SO_NREAD = 0x1020 + SO_NUMRCVPKT = 0x1112 + SO_NWRITE = 0x1024 + SO_OOBINLINE = 0x100 + SO_PEERLABEL = 0x1011 + SO_RANDOMPORT = 0x1082 + SO_RCVBUF = 0x1002 + SO_RCVLOWAT = 0x1004 + SO_RCVTIMEO = 0x1006 + SO_REUSEADDR = 0x4 + SO_REUSEPORT = 0x200 + SO_REUSESHAREUID = 0x1025 + SO_SNDBUF = 0x1001 + SO_SNDLOWAT = 0x1003 + SO_SNDTIMEO = 0x1005 + SO_TIMESTAMP = 0x400 + SO_TIMESTAMP_MONOTONIC = 0x800 + SO_TRACKER_ATTRIBUTE_FLAGS_APP_APPROVED = 0x1 + SO_TRACKER_ATTRIBUTE_FLAGS_DOMAIN_SHORT = 0x4 + SO_TRACKER_ATTRIBUTE_FLAGS_TRACKER = 0x2 + SO_TRACKER_TRANSPARENCY_VERSION = 0x3 + SO_TYPE = 0x1008 + SO_UPCALLCLOSEWAIT = 0x1027 + SO_USELOOPBACK = 0x40 + SO_WANTMORE = 0x4000 + SO_WANTOOBFLAG = 0x8000 + S_IEXEC = 0x40 + S_IFBLK = 0x6000 + S_IFCHR = 0x2000 + S_IFDIR = 0x4000 + S_IFIFO = 0x1000 + S_IFLNK = 0xa000 + S_IFMT = 0xf000 + S_IFREG = 0x8000 + S_IFSOCK = 0xc000 + S_IFWHT = 0xe000 + S_IREAD = 0x100 + S_IRGRP = 0x20 + S_IROTH = 0x4 + S_IRUSR = 0x100 + S_IRWXG = 0x38 + S_IRWXO = 0x7 + S_IRWXU = 0x1c0 + S_ISGID = 0x400 + S_ISTXT = 0x200 + S_ISUID = 0x800 + S_ISVTX = 0x200 + S_IWGRP = 0x10 + S_IWOTH = 0x2 + S_IWRITE = 0x80 + S_IWUSR = 0x80 + S_IXGRP = 0x8 + S_IXOTH = 0x1 + S_IXUSR = 0x40 + TAB0 = 0x0 + TAB1 = 0x400 + TAB2 = 0x800 + TAB3 = 0x4 + TABDLY = 0xc04 + TCIFLUSH = 0x1 + TCIOFF = 0x3 + TCIOFLUSH = 0x3 + TCION = 0x4 + TCOFLUSH = 0x2 + TCOOFF = 0x1 + TCOON = 0x2 + TCPOPT_CC = 0xb + TCPOPT_CCECHO = 0xd + TCPOPT_CCNEW = 0xc + TCPOPT_EOL = 0x0 + TCPOPT_FASTOPEN = 0x22 + TCPOPT_MAXSEG = 0x2 + TCPOPT_NOP = 0x1 + TCPOPT_SACK = 0x5 + TCPOPT_SACK_HDR = 0x1010500 + TCPOPT_SACK_PERMITTED = 0x4 + TCPOPT_SACK_PERMIT_HDR = 0x1010402 + TCPOPT_SIGNATURE = 0x13 + TCPOPT_TIMESTAMP = 0x8 + TCPOPT_TSTAMP_HDR = 0x101080a + TCPOPT_WINDOW = 0x3 + TCP_CONNECTIONTIMEOUT = 0x20 + TCP_CONNECTION_INFO = 0x106 + TCP_ENABLE_ECN = 0x104 + TCP_FASTOPEN = 0x105 + TCP_KEEPALIVE = 0x10 + TCP_KEEPCNT = 0x102 + TCP_KEEPINTVL = 0x101 + TCP_MAXHLEN = 0x3c + TCP_MAXOLEN = 0x28 + TCP_MAXSEG = 0x2 + TCP_MAXWIN = 0xffff + TCP_MAX_SACK = 0x4 + TCP_MAX_WINSHIFT = 0xe + TCP_MINMSS = 0xd8 + TCP_MSS = 0x200 + TCP_NODELAY = 0x1 + TCP_NOOPT = 0x8 + TCP_NOPUSH = 0x4 + TCP_NOTSENT_LOWAT = 0x201 + TCP_RXT_CONNDROPTIME = 0x80 + TCP_RXT_FINDROP = 0x100 + TCP_SENDMOREACKS = 0x103 + TCSAFLUSH = 0x2 + TIOCCBRK = 0x2000747a + TIOCCDTR = 0x20007478 + TIOCCONS = 0x80047462 + TIOCDCDTIMESTAMP = 0x40107458 + TIOCDRAIN = 0x2000745e + TIOCDSIMICROCODE = 0x20007455 + TIOCEXCL = 0x2000740d + TIOCEXT = 0x80047460 + TIOCFLUSH = 0x80047410 + TIOCGDRAINWAIT = 0x40047456 + TIOCGETA = 0x40487413 + TIOCGETD = 0x4004741a + TIOCGPGRP = 0x40047477 + TIOCGWINSZ = 0x40087468 + TIOCIXOFF = 0x20007480 + TIOCIXON = 0x20007481 + TIOCMBIC = 0x8004746b + TIOCMBIS = 0x8004746c + TIOCMGDTRWAIT = 0x4004745a + TIOCMGET = 0x4004746a + TIOCMODG = 0x40047403 + TIOCMODS = 0x80047404 + TIOCMSDTRWAIT = 0x8004745b + TIOCMSET = 0x8004746d + TIOCM_CAR = 0x40 + TIOCM_CD = 0x40 + TIOCM_CTS = 0x20 + TIOCM_DSR = 0x100 + TIOCM_DTR = 0x2 + TIOCM_LE = 0x1 + TIOCM_RI = 0x80 + TIOCM_RNG = 0x80 + TIOCM_RTS = 0x4 + TIOCM_SR = 0x10 + TIOCM_ST = 0x8 + TIOCNOTTY = 0x20007471 + TIOCNXCL = 0x2000740e + TIOCOUTQ = 0x40047473 + TIOCPKT = 0x80047470 + TIOCPKT_DATA = 0x0 + TIOCPKT_DOSTOP = 0x20 + TIOCPKT_FLUSHREAD = 0x1 + TIOCPKT_FLUSHWRITE = 0x2 + TIOCPKT_IOCTL = 0x40 + TIOCPKT_NOSTOP = 0x10 + TIOCPKT_START = 0x8 + TIOCPKT_STOP = 0x4 + TIOCPTYGNAME = 0x40807453 + TIOCPTYGRANT = 0x20007454 + TIOCPTYUNLK = 0x20007452 + TIOCREMOTE = 0x80047469 + TIOCSBRK = 0x2000747b + TIOCSCONS = 0x20007463 + TIOCSCTTY = 0x20007461 + TIOCSDRAINWAIT = 0x80047457 + TIOCSDTR = 0x20007479 + TIOCSETA = 0x80487414 + TIOCSETAF = 0x80487416 + TIOCSETAW = 0x80487415 + TIOCSETD = 0x8004741b + TIOCSIG = 0x2000745f + TIOCSPGRP = 0x80047476 + TIOCSTART = 0x2000746e + TIOCSTAT = 0x20007465 + TIOCSTI = 0x80017472 + TIOCSTOP = 0x2000746f + TIOCSWINSZ = 0x80087467 + TIOCTIMESTAMP = 0x40107459 + TIOCUCNTL = 0x80047466 + TOSTOP = 0x400000 + VDISCARD = 0xf + VDSUSP = 0xb + VEOF = 0x0 + VEOL = 0x1 + VEOL2 = 0x2 + VERASE = 0x3 + VINTR = 0x8 + VKILL = 0x5 + VLNEXT = 0xe + VMADDR_CID_ANY = 0xffffffff + VMADDR_CID_HOST = 0x2 + VMADDR_CID_HYPERVISOR = 0x0 + VMADDR_CID_RESERVED = 0x1 + VMADDR_PORT_ANY = 0xffffffff + VMIN = 0x10 + VM_LOADAVG = 0x2 + VM_MACHFACTOR = 0x4 + VM_MAXID = 0x6 + VM_METER = 0x1 + VM_SWAPUSAGE = 0x5 + VQUIT = 0x9 + VREPRINT = 0x6 + VSTART = 0xc + VSTATUS = 0x12 + VSTOP = 0xd + VSUSP = 0xa + VT0 = 0x0 + VT1 = 0x10000 + VTDLY = 0x10000 + VTIME = 0x11 + VWERASE = 0x4 + WCONTINUED = 0x10 + WCOREFLAG = 0x80 + WEXITED = 0x4 + WNOHANG = 0x1 + WNOWAIT = 0x20 + WORDSIZE = 0x40 + WSTOPPED = 0x8 + WUNTRACED = 0x2 + XATTR_CREATE = 0x2 + XATTR_NODEFAULT = 0x10 + XATTR_NOFOLLOW = 0x1 + XATTR_NOSECURITY = 0x8 + XATTR_REPLACE = 0x4 + XATTR_SHOWCOMPRESSION = 0x20 ) // Errors diff --git a/vendor/golang.org/x/sys/unix/zerrors_darwin_arm64.go b/vendor/golang.org/x/sys/unix/zerrors_darwin_arm64.go index 31009d7f05..e36f5178d6 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_darwin_arm64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_darwin_arm64.go @@ -12,1556 +12,1582 @@ package unix import "syscall" const ( - AF_APPLETALK = 0x10 - AF_CCITT = 0xa - AF_CHAOS = 0x5 - AF_CNT = 0x15 - AF_COIP = 0x14 - AF_DATAKIT = 0x9 - AF_DECnet = 0xc - AF_DLI = 0xd - AF_E164 = 0x1c - AF_ECMA = 0x8 - AF_HYLINK = 0xf - AF_IEEE80211 = 0x25 - AF_IMPLINK = 0x3 - AF_INET = 0x2 - AF_INET6 = 0x1e - AF_IPX = 0x17 - AF_ISDN = 0x1c - AF_ISO = 0x7 - AF_LAT = 0xe - AF_LINK = 0x12 - AF_LOCAL = 0x1 - AF_MAX = 0x29 - AF_NATM = 0x1f - AF_NDRV = 0x1b - AF_NETBIOS = 0x21 - AF_NS = 0x6 - AF_OSI = 0x7 - AF_PPP = 0x22 - AF_PUP = 0x4 - AF_RESERVED_36 = 0x24 - AF_ROUTE = 0x11 - AF_SIP = 0x18 - AF_SNA = 0xb - AF_SYSTEM = 0x20 - AF_SYS_CONTROL = 0x2 - AF_UNIX = 0x1 - AF_UNSPEC = 0x0 - AF_UTUN = 0x26 - AF_VSOCK = 0x28 - ALTWERASE = 0x200 - ATTR_BIT_MAP_COUNT = 0x5 - ATTR_CMN_ACCESSMASK = 0x20000 - ATTR_CMN_ACCTIME = 0x1000 - ATTR_CMN_ADDEDTIME = 0x10000000 - ATTR_CMN_BKUPTIME = 0x2000 - ATTR_CMN_CHGTIME = 0x800 - ATTR_CMN_CRTIME = 0x200 - ATTR_CMN_DATA_PROTECT_FLAGS = 0x40000000 - ATTR_CMN_DEVID = 0x2 - ATTR_CMN_DOCUMENT_ID = 0x100000 - ATTR_CMN_ERROR = 0x20000000 - ATTR_CMN_EXTENDED_SECURITY = 0x400000 - ATTR_CMN_FILEID = 0x2000000 - ATTR_CMN_FLAGS = 0x40000 - ATTR_CMN_FNDRINFO = 0x4000 - ATTR_CMN_FSID = 0x4 - ATTR_CMN_FULLPATH = 0x8000000 - ATTR_CMN_GEN_COUNT = 0x80000 - ATTR_CMN_GRPID = 0x10000 - ATTR_CMN_GRPUUID = 0x1000000 - ATTR_CMN_MODTIME = 0x400 - ATTR_CMN_NAME = 0x1 - ATTR_CMN_NAMEDATTRCOUNT = 0x80000 - ATTR_CMN_NAMEDATTRLIST = 0x100000 - ATTR_CMN_OBJID = 0x20 - ATTR_CMN_OBJPERMANENTID = 0x40 - ATTR_CMN_OBJTAG = 0x10 - ATTR_CMN_OBJTYPE = 0x8 - ATTR_CMN_OWNERID = 0x8000 - ATTR_CMN_PARENTID = 0x4000000 - ATTR_CMN_PAROBJID = 0x80 - ATTR_CMN_RETURNED_ATTRS = 0x80000000 - ATTR_CMN_SCRIPT = 0x100 - ATTR_CMN_SETMASK = 0x51c7ff00 - ATTR_CMN_USERACCESS = 0x200000 - ATTR_CMN_UUID = 0x800000 - ATTR_CMN_VALIDMASK = 0xffffffff - ATTR_CMN_VOLSETMASK = 0x6700 - ATTR_FILE_ALLOCSIZE = 0x4 - ATTR_FILE_CLUMPSIZE = 0x10 - ATTR_FILE_DATAALLOCSIZE = 0x400 - ATTR_FILE_DATAEXTENTS = 0x800 - ATTR_FILE_DATALENGTH = 0x200 - ATTR_FILE_DEVTYPE = 0x20 - ATTR_FILE_FILETYPE = 0x40 - ATTR_FILE_FORKCOUNT = 0x80 - ATTR_FILE_FORKLIST = 0x100 - ATTR_FILE_IOBLOCKSIZE = 0x8 - ATTR_FILE_LINKCOUNT = 0x1 - ATTR_FILE_RSRCALLOCSIZE = 0x2000 - ATTR_FILE_RSRCEXTENTS = 0x4000 - ATTR_FILE_RSRCLENGTH = 0x1000 - ATTR_FILE_SETMASK = 0x20 - ATTR_FILE_TOTALSIZE = 0x2 - ATTR_FILE_VALIDMASK = 0x37ff - ATTR_VOL_ALLOCATIONCLUMP = 0x40 - ATTR_VOL_ATTRIBUTES = 0x40000000 - ATTR_VOL_CAPABILITIES = 0x20000 - ATTR_VOL_DIRCOUNT = 0x400 - ATTR_VOL_ENCODINGSUSED = 0x10000 - ATTR_VOL_FILECOUNT = 0x200 - ATTR_VOL_FSTYPE = 0x1 - ATTR_VOL_INFO = 0x80000000 - ATTR_VOL_IOBLOCKSIZE = 0x80 - ATTR_VOL_MAXOBJCOUNT = 0x800 - ATTR_VOL_MINALLOCATION = 0x20 - ATTR_VOL_MOUNTEDDEVICE = 0x8000 - ATTR_VOL_MOUNTFLAGS = 0x4000 - ATTR_VOL_MOUNTPOINT = 0x1000 - ATTR_VOL_NAME = 0x2000 - ATTR_VOL_OBJCOUNT = 0x100 - ATTR_VOL_QUOTA_SIZE = 0x10000000 - ATTR_VOL_RESERVED_SIZE = 0x20000000 - ATTR_VOL_SETMASK = 0x80002000 - ATTR_VOL_SIGNATURE = 0x2 - ATTR_VOL_SIZE = 0x4 - ATTR_VOL_SPACEAVAIL = 0x10 - ATTR_VOL_SPACEFREE = 0x8 - ATTR_VOL_UUID = 0x40000 - ATTR_VOL_VALIDMASK = 0xf007ffff - B0 = 0x0 - B110 = 0x6e - B115200 = 0x1c200 - B1200 = 0x4b0 - B134 = 0x86 - B14400 = 0x3840 - B150 = 0x96 - B1800 = 0x708 - B19200 = 0x4b00 - B200 = 0xc8 - B230400 = 0x38400 - B2400 = 0x960 - B28800 = 0x7080 - B300 = 0x12c - B38400 = 0x9600 - B4800 = 0x12c0 - B50 = 0x32 - B57600 = 0xe100 - B600 = 0x258 - B7200 = 0x1c20 - B75 = 0x4b - B76800 = 0x12c00 - B9600 = 0x2580 - BIOCFLUSH = 0x20004268 - BIOCGBLEN = 0x40044266 - BIOCGDLT = 0x4004426a - BIOCGDLTLIST = 0xc00c4279 - BIOCGETIF = 0x4020426b - BIOCGHDRCMPLT = 0x40044274 - BIOCGRSIG = 0x40044272 - BIOCGRTIMEOUT = 0x4010426e - BIOCGSEESENT = 0x40044276 - BIOCGSTATS = 0x4008426f - BIOCIMMEDIATE = 0x80044270 - BIOCPROMISC = 0x20004269 - BIOCSBLEN = 0xc0044266 - BIOCSDLT = 0x80044278 - BIOCSETF = 0x80104267 - BIOCSETFNR = 0x8010427e - BIOCSETIF = 0x8020426c - BIOCSHDRCMPLT = 0x80044275 - BIOCSRSIG = 0x80044273 - BIOCSRTIMEOUT = 0x8010426d - BIOCSSEESENT = 0x80044277 - BIOCVERSION = 0x40044271 - BPF_A = 0x10 - BPF_ABS = 0x20 - BPF_ADD = 0x0 - BPF_ALIGNMENT = 0x4 - BPF_ALU = 0x4 - BPF_AND = 0x50 - BPF_B = 0x10 - BPF_DIV = 0x30 - BPF_H = 0x8 - BPF_IMM = 0x0 - BPF_IND = 0x40 - BPF_JA = 0x0 - BPF_JEQ = 0x10 - BPF_JGE = 0x30 - BPF_JGT = 0x20 - BPF_JMP = 0x5 - BPF_JSET = 0x40 - BPF_K = 0x0 - BPF_LD = 0x0 - BPF_LDX = 0x1 - BPF_LEN = 0x80 - BPF_LSH = 0x60 - BPF_MAJOR_VERSION = 0x1 - BPF_MAXBUFSIZE = 0x80000 - BPF_MAXINSNS = 0x200 - BPF_MEM = 0x60 - BPF_MEMWORDS = 0x10 - BPF_MINBUFSIZE = 0x20 - BPF_MINOR_VERSION = 0x1 - BPF_MISC = 0x7 - BPF_MSH = 0xa0 - BPF_MUL = 0x20 - BPF_NEG = 0x80 - BPF_OR = 0x40 - BPF_RELEASE = 0x30bb6 - BPF_RET = 0x6 - BPF_RSH = 0x70 - BPF_ST = 0x2 - BPF_STX = 0x3 - BPF_SUB = 0x10 - BPF_TAX = 0x0 - BPF_TXA = 0x80 - BPF_W = 0x0 - BPF_X = 0x8 - BRKINT = 0x2 - BS0 = 0x0 - BS1 = 0x8000 - BSDLY = 0x8000 - CFLUSH = 0xf - CLOCAL = 0x8000 - CLOCK_MONOTONIC = 0x6 - CLOCK_MONOTONIC_RAW = 0x4 - CLOCK_MONOTONIC_RAW_APPROX = 0x5 - CLOCK_PROCESS_CPUTIME_ID = 0xc - CLOCK_REALTIME = 0x0 - CLOCK_THREAD_CPUTIME_ID = 0x10 - CLOCK_UPTIME_RAW = 0x8 - CLOCK_UPTIME_RAW_APPROX = 0x9 - CLONE_NOFOLLOW = 0x1 - CLONE_NOOWNERCOPY = 0x2 - CR0 = 0x0 - CR1 = 0x1000 - CR2 = 0x2000 - CR3 = 0x3000 - CRDLY = 0x3000 - CREAD = 0x800 - CRTSCTS = 0x30000 - CS5 = 0x0 - CS6 = 0x100 - CS7 = 0x200 - CS8 = 0x300 - CSIZE = 0x300 - CSTART = 0x11 - CSTATUS = 0x14 - CSTOP = 0x13 - CSTOPB = 0x400 - CSUSP = 0x1a - CTLIOCGINFO = 0xc0644e03 - CTL_HW = 0x6 - CTL_KERN = 0x1 - CTL_MAXNAME = 0xc - CTL_NET = 0x4 - DLT_A429 = 0xb8 - DLT_A653_ICM = 0xb9 - DLT_AIRONET_HEADER = 0x78 - DLT_AOS = 0xde - DLT_APPLE_IP_OVER_IEEE1394 = 0x8a - DLT_ARCNET = 0x7 - DLT_ARCNET_LINUX = 0x81 - DLT_ATM_CLIP = 0x13 - DLT_ATM_RFC1483 = 0xb - DLT_AURORA = 0x7e - DLT_AX25 = 0x3 - DLT_AX25_KISS = 0xca - DLT_BACNET_MS_TP = 0xa5 - DLT_BLUETOOTH_HCI_H4 = 0xbb - DLT_BLUETOOTH_HCI_H4_WITH_PHDR = 0xc9 - DLT_CAN20B = 0xbe - DLT_CAN_SOCKETCAN = 0xe3 - DLT_CHAOS = 0x5 - DLT_CHDLC = 0x68 - DLT_CISCO_IOS = 0x76 - DLT_C_HDLC = 0x68 - DLT_C_HDLC_WITH_DIR = 0xcd - DLT_DBUS = 0xe7 - DLT_DECT = 0xdd - DLT_DOCSIS = 0x8f - DLT_DVB_CI = 0xeb - DLT_ECONET = 0x73 - DLT_EN10MB = 0x1 - DLT_EN3MB = 0x2 - DLT_ENC = 0x6d - DLT_ERF = 0xc5 - DLT_ERF_ETH = 0xaf - DLT_ERF_POS = 0xb0 - DLT_FC_2 = 0xe0 - DLT_FC_2_WITH_FRAME_DELIMS = 0xe1 - DLT_FDDI = 0xa - DLT_FLEXRAY = 0xd2 - DLT_FRELAY = 0x6b - DLT_FRELAY_WITH_DIR = 0xce - DLT_GCOM_SERIAL = 0xad - DLT_GCOM_T1E1 = 0xac - DLT_GPF_F = 0xab - DLT_GPF_T = 0xaa - DLT_GPRS_LLC = 0xa9 - DLT_GSMTAP_ABIS = 0xda - DLT_GSMTAP_UM = 0xd9 - DLT_HHDLC = 0x79 - DLT_IBM_SN = 0x92 - DLT_IBM_SP = 0x91 - DLT_IEEE802 = 0x6 - DLT_IEEE802_11 = 0x69 - DLT_IEEE802_11_RADIO = 0x7f - DLT_IEEE802_11_RADIO_AVS = 0xa3 - DLT_IEEE802_15_4 = 0xc3 - DLT_IEEE802_15_4_LINUX = 0xbf - DLT_IEEE802_15_4_NOFCS = 0xe6 - DLT_IEEE802_15_4_NONASK_PHY = 0xd7 - DLT_IEEE802_16_MAC_CPS = 0xbc - DLT_IEEE802_16_MAC_CPS_RADIO = 0xc1 - DLT_IPFILTER = 0x74 - DLT_IPMB = 0xc7 - DLT_IPMB_LINUX = 0xd1 - DLT_IPNET = 0xe2 - DLT_IPOIB = 0xf2 - DLT_IPV4 = 0xe4 - DLT_IPV6 = 0xe5 - DLT_IP_OVER_FC = 0x7a - DLT_JUNIPER_ATM1 = 0x89 - DLT_JUNIPER_ATM2 = 0x87 - DLT_JUNIPER_ATM_CEMIC = 0xee - DLT_JUNIPER_CHDLC = 0xb5 - DLT_JUNIPER_ES = 0x84 - DLT_JUNIPER_ETHER = 0xb2 - DLT_JUNIPER_FIBRECHANNEL = 0xea - DLT_JUNIPER_FRELAY = 0xb4 - DLT_JUNIPER_GGSN = 0x85 - DLT_JUNIPER_ISM = 0xc2 - DLT_JUNIPER_MFR = 0x86 - DLT_JUNIPER_MLFR = 0x83 - DLT_JUNIPER_MLPPP = 0x82 - DLT_JUNIPER_MONITOR = 0xa4 - DLT_JUNIPER_PIC_PEER = 0xae - DLT_JUNIPER_PPP = 0xb3 - DLT_JUNIPER_PPPOE = 0xa7 - DLT_JUNIPER_PPPOE_ATM = 0xa8 - DLT_JUNIPER_SERVICES = 0x88 - DLT_JUNIPER_SRX_E2E = 0xe9 - DLT_JUNIPER_ST = 0xc8 - DLT_JUNIPER_VP = 0xb7 - DLT_JUNIPER_VS = 0xe8 - DLT_LAPB_WITH_DIR = 0xcf - DLT_LAPD = 0xcb - DLT_LIN = 0xd4 - DLT_LINUX_EVDEV = 0xd8 - DLT_LINUX_IRDA = 0x90 - DLT_LINUX_LAPD = 0xb1 - DLT_LINUX_PPP_WITHDIRECTION = 0xa6 - DLT_LINUX_SLL = 0x71 - DLT_LOOP = 0x6c - DLT_LTALK = 0x72 - DLT_MATCHING_MAX = 0x10a - DLT_MATCHING_MIN = 0x68 - DLT_MFR = 0xb6 - DLT_MOST = 0xd3 - DLT_MPEG_2_TS = 0xf3 - DLT_MPLS = 0xdb - DLT_MTP2 = 0x8c - DLT_MTP2_WITH_PHDR = 0x8b - DLT_MTP3 = 0x8d - DLT_MUX27010 = 0xec - DLT_NETANALYZER = 0xf0 - DLT_NETANALYZER_TRANSPARENT = 0xf1 - DLT_NFC_LLCP = 0xf5 - DLT_NFLOG = 0xef - DLT_NG40 = 0xf4 - DLT_NULL = 0x0 - DLT_PCI_EXP = 0x7d - DLT_PFLOG = 0x75 - DLT_PFSYNC = 0x12 - DLT_PPI = 0xc0 - DLT_PPP = 0x9 - DLT_PPP_BSDOS = 0x10 - DLT_PPP_ETHER = 0x33 - DLT_PPP_PPPD = 0xa6 - DLT_PPP_SERIAL = 0x32 - DLT_PPP_WITH_DIR = 0xcc - DLT_PPP_WITH_DIRECTION = 0xa6 - DLT_PRISM_HEADER = 0x77 - DLT_PRONET = 0x4 - DLT_RAIF1 = 0xc6 - DLT_RAW = 0xc - DLT_RIO = 0x7c - DLT_SCCP = 0x8e - DLT_SITA = 0xc4 - DLT_SLIP = 0x8 - DLT_SLIP_BSDOS = 0xf - DLT_STANAG_5066_D_PDU = 0xed - DLT_SUNATM = 0x7b - DLT_SYMANTEC_FIREWALL = 0x63 - DLT_TZSP = 0x80 - DLT_USB = 0xba - DLT_USB_DARWIN = 0x10a - DLT_USB_LINUX = 0xbd - DLT_USB_LINUX_MMAPPED = 0xdc - DLT_USER0 = 0x93 - DLT_USER1 = 0x94 - DLT_USER10 = 0x9d - DLT_USER11 = 0x9e - DLT_USER12 = 0x9f - DLT_USER13 = 0xa0 - DLT_USER14 = 0xa1 - DLT_USER15 = 0xa2 - DLT_USER2 = 0x95 - DLT_USER3 = 0x96 - DLT_USER4 = 0x97 - DLT_USER5 = 0x98 - DLT_USER6 = 0x99 - DLT_USER7 = 0x9a - DLT_USER8 = 0x9b - DLT_USER9 = 0x9c - DLT_WIHART = 0xdf - DLT_X2E_SERIAL = 0xd5 - DLT_X2E_XORAYA = 0xd6 - DT_BLK = 0x6 - DT_CHR = 0x2 - DT_DIR = 0x4 - DT_FIFO = 0x1 - DT_LNK = 0xa - DT_REG = 0x8 - DT_SOCK = 0xc - DT_UNKNOWN = 0x0 - DT_WHT = 0xe - ECHO = 0x8 - ECHOCTL = 0x40 - ECHOE = 0x2 - ECHOK = 0x4 - ECHOKE = 0x1 - ECHONL = 0x10 - ECHOPRT = 0x20 - EVFILT_AIO = -0x3 - EVFILT_EXCEPT = -0xf - EVFILT_FS = -0x9 - EVFILT_MACHPORT = -0x8 - EVFILT_PROC = -0x5 - EVFILT_READ = -0x1 - EVFILT_SIGNAL = -0x6 - EVFILT_SYSCOUNT = 0x11 - EVFILT_THREADMARKER = 0x11 - EVFILT_TIMER = -0x7 - EVFILT_USER = -0xa - EVFILT_VM = -0xc - EVFILT_VNODE = -0x4 - EVFILT_WRITE = -0x2 - EV_ADD = 0x1 - EV_CLEAR = 0x20 - EV_DELETE = 0x2 - EV_DISABLE = 0x8 - EV_DISPATCH = 0x80 - EV_DISPATCH2 = 0x180 - EV_ENABLE = 0x4 - EV_EOF = 0x8000 - EV_ERROR = 0x4000 - EV_FLAG0 = 0x1000 - EV_FLAG1 = 0x2000 - EV_ONESHOT = 0x10 - EV_OOBAND = 0x2000 - EV_POLL = 0x1000 - EV_RECEIPT = 0x40 - EV_SYSFLAGS = 0xf000 - EV_UDATA_SPECIFIC = 0x100 - EV_VANISHED = 0x200 - EXTA = 0x4b00 - EXTB = 0x9600 - EXTPROC = 0x800 - FD_CLOEXEC = 0x1 - FD_SETSIZE = 0x400 - FF0 = 0x0 - FF1 = 0x4000 - FFDLY = 0x4000 - FLUSHO = 0x800000 - FSOPT_ATTR_CMN_EXTENDED = 0x20 - FSOPT_NOFOLLOW = 0x1 - FSOPT_NOINMEMUPDATE = 0x2 - FSOPT_PACK_INVAL_ATTRS = 0x8 - FSOPT_REPORT_FULLSIZE = 0x4 - FSOPT_RETURN_REALDEV = 0x200 - F_ADDFILESIGS = 0x3d - F_ADDFILESIGS_FOR_DYLD_SIM = 0x53 - F_ADDFILESIGS_INFO = 0x67 - F_ADDFILESIGS_RETURN = 0x61 - F_ADDFILESUPPL = 0x68 - F_ADDSIGS = 0x3b - F_ALLOCATEALL = 0x4 - F_ALLOCATECONTIG = 0x2 - F_BARRIERFSYNC = 0x55 - F_CHECK_LV = 0x62 - F_CHKCLEAN = 0x29 - F_DUPFD = 0x0 - F_DUPFD_CLOEXEC = 0x43 - F_FINDSIGS = 0x4e - F_FLUSH_DATA = 0x28 - F_FREEZE_FS = 0x35 - F_FULLFSYNC = 0x33 - F_GETCODEDIR = 0x48 - F_GETFD = 0x1 - F_GETFL = 0x3 - F_GETLK = 0x7 - F_GETLKPID = 0x42 - F_GETNOSIGPIPE = 0x4a - F_GETOWN = 0x5 - F_GETPATH = 0x32 - F_GETPATH_MTMINFO = 0x47 - F_GETPATH_NOFIRMLINK = 0x66 - F_GETPROTECTIONCLASS = 0x3f - F_GETPROTECTIONLEVEL = 0x4d - F_GETSIGSINFO = 0x69 - F_GLOBAL_NOCACHE = 0x37 - F_LOG2PHYS = 0x31 - F_LOG2PHYS_EXT = 0x41 - F_NOCACHE = 0x30 - F_NODIRECT = 0x3e - F_OK = 0x0 - F_PATHPKG_CHECK = 0x34 - F_PEOFPOSMODE = 0x3 - F_PREALLOCATE = 0x2a - F_PUNCHHOLE = 0x63 - F_RDADVISE = 0x2c - F_RDAHEAD = 0x2d - F_RDLCK = 0x1 - F_SETBACKINGSTORE = 0x46 - F_SETFD = 0x2 - F_SETFL = 0x4 - F_SETLK = 0x8 - F_SETLKW = 0x9 - F_SETLKWTIMEOUT = 0xa - F_SETNOSIGPIPE = 0x49 - F_SETOWN = 0x6 - F_SETPROTECTIONCLASS = 0x40 - F_SETSIZE = 0x2b - F_SINGLE_WRITER = 0x4c - F_SPECULATIVE_READ = 0x65 - F_THAW_FS = 0x36 - F_TRANSCODEKEY = 0x4b - F_TRIM_ACTIVE_FILE = 0x64 - F_UNLCK = 0x2 - F_VOLPOSMODE = 0x4 - F_WRLCK = 0x3 - HUPCL = 0x4000 - HW_MACHINE = 0x1 - ICANON = 0x100 - ICMP6_FILTER = 0x12 - ICRNL = 0x100 - IEXTEN = 0x400 - IFF_ALLMULTI = 0x200 - IFF_ALTPHYS = 0x4000 - IFF_BROADCAST = 0x2 - IFF_DEBUG = 0x4 - IFF_LINK0 = 0x1000 - IFF_LINK1 = 0x2000 - IFF_LINK2 = 0x4000 - IFF_LOOPBACK = 0x8 - IFF_MULTICAST = 0x8000 - IFF_NOARP = 0x80 - IFF_NOTRAILERS = 0x20 - IFF_OACTIVE = 0x400 - IFF_POINTOPOINT = 0x10 - IFF_PROMISC = 0x100 - IFF_RUNNING = 0x40 - IFF_SIMPLEX = 0x800 - IFF_UP = 0x1 - IFNAMSIZ = 0x10 - IFT_1822 = 0x2 - IFT_6LOWPAN = 0x40 - IFT_AAL5 = 0x31 - IFT_ARCNET = 0x23 - IFT_ARCNETPLUS = 0x24 - IFT_ATM = 0x25 - IFT_BRIDGE = 0xd1 - IFT_CARP = 0xf8 - IFT_CELLULAR = 0xff - IFT_CEPT = 0x13 - IFT_DS3 = 0x1e - IFT_ENC = 0xf4 - IFT_EON = 0x19 - IFT_ETHER = 0x6 - IFT_FAITH = 0x38 - IFT_FDDI = 0xf - IFT_FRELAY = 0x20 - IFT_FRELAYDCE = 0x2c - IFT_GIF = 0x37 - IFT_HDH1822 = 0x3 - IFT_HIPPI = 0x2f - IFT_HSSI = 0x2e - IFT_HY = 0xe - IFT_IEEE1394 = 0x90 - IFT_IEEE8023ADLAG = 0x88 - IFT_ISDNBASIC = 0x14 - IFT_ISDNPRIMARY = 0x15 - IFT_ISO88022LLC = 0x29 - IFT_ISO88023 = 0x7 - IFT_ISO88024 = 0x8 - IFT_ISO88025 = 0x9 - IFT_ISO88026 = 0xa - IFT_L2VLAN = 0x87 - IFT_LAPB = 0x10 - IFT_LOCALTALK = 0x2a - IFT_LOOP = 0x18 - IFT_MIOX25 = 0x26 - IFT_MODEM = 0x30 - IFT_NSIP = 0x1b - IFT_OTHER = 0x1 - IFT_P10 = 0xc - IFT_P80 = 0xd - IFT_PARA = 0x22 - IFT_PDP = 0xff - IFT_PFLOG = 0xf5 - IFT_PFSYNC = 0xf6 - IFT_PKTAP = 0xfe - IFT_PPP = 0x17 - IFT_PROPMUX = 0x36 - IFT_PROPVIRTUAL = 0x35 - IFT_PTPSERIAL = 0x16 - IFT_RS232 = 0x21 - IFT_SDLC = 0x11 - IFT_SIP = 0x1f - IFT_SLIP = 0x1c - IFT_SMDSDXI = 0x2b - IFT_SMDSICIP = 0x34 - IFT_SONET = 0x27 - IFT_SONETPATH = 0x32 - IFT_SONETVT = 0x33 - IFT_STARLAN = 0xb - IFT_STF = 0x39 - IFT_T1 = 0x12 - IFT_ULTRA = 0x1d - IFT_V35 = 0x2d - IFT_X25 = 0x5 - IFT_X25DDN = 0x4 - IFT_X25PLE = 0x28 - IFT_XETHER = 0x1a - IGNBRK = 0x1 - IGNCR = 0x80 - IGNPAR = 0x4 - IMAXBEL = 0x2000 - INLCR = 0x40 - INPCK = 0x10 - IN_CLASSA_HOST = 0xffffff - IN_CLASSA_MAX = 0x80 - IN_CLASSA_NET = 0xff000000 - IN_CLASSA_NSHIFT = 0x18 - IN_CLASSB_HOST = 0xffff - IN_CLASSB_MAX = 0x10000 - IN_CLASSB_NET = 0xffff0000 - IN_CLASSB_NSHIFT = 0x10 - IN_CLASSC_HOST = 0xff - IN_CLASSC_NET = 0xffffff00 - IN_CLASSC_NSHIFT = 0x8 - IN_CLASSD_HOST = 0xfffffff - IN_CLASSD_NET = 0xf0000000 - IN_CLASSD_NSHIFT = 0x1c - IN_LINKLOCALNETNUM = 0xa9fe0000 - IN_LOOPBACKNET = 0x7f - IPPROTO_3PC = 0x22 - IPPROTO_ADFS = 0x44 - IPPROTO_AH = 0x33 - IPPROTO_AHIP = 0x3d - IPPROTO_APES = 0x63 - IPPROTO_ARGUS = 0xd - IPPROTO_AX25 = 0x5d - IPPROTO_BHA = 0x31 - IPPROTO_BLT = 0x1e - IPPROTO_BRSATMON = 0x4c - IPPROTO_CFTP = 0x3e - IPPROTO_CHAOS = 0x10 - IPPROTO_CMTP = 0x26 - IPPROTO_CPHB = 0x49 - IPPROTO_CPNX = 0x48 - IPPROTO_DDP = 0x25 - IPPROTO_DGP = 0x56 - IPPROTO_DIVERT = 0xfe - IPPROTO_DONE = 0x101 - IPPROTO_DSTOPTS = 0x3c - IPPROTO_EGP = 0x8 - IPPROTO_EMCON = 0xe - IPPROTO_ENCAP = 0x62 - IPPROTO_EON = 0x50 - IPPROTO_ESP = 0x32 - IPPROTO_ETHERIP = 0x61 - IPPROTO_FRAGMENT = 0x2c - IPPROTO_GGP = 0x3 - IPPROTO_GMTP = 0x64 - IPPROTO_GRE = 0x2f - IPPROTO_HELLO = 0x3f - IPPROTO_HMP = 0x14 - IPPROTO_HOPOPTS = 0x0 - IPPROTO_ICMP = 0x1 - IPPROTO_ICMPV6 = 0x3a - IPPROTO_IDP = 0x16 - IPPROTO_IDPR = 0x23 - IPPROTO_IDRP = 0x2d - IPPROTO_IGMP = 0x2 - IPPROTO_IGP = 0x55 - IPPROTO_IGRP = 0x58 - IPPROTO_IL = 0x28 - IPPROTO_INLSP = 0x34 - IPPROTO_INP = 0x20 - IPPROTO_IP = 0x0 - IPPROTO_IPCOMP = 0x6c - IPPROTO_IPCV = 0x47 - IPPROTO_IPEIP = 0x5e - IPPROTO_IPIP = 0x4 - IPPROTO_IPPC = 0x43 - IPPROTO_IPV4 = 0x4 - IPPROTO_IPV6 = 0x29 - IPPROTO_IRTP = 0x1c - IPPROTO_KRYPTOLAN = 0x41 - IPPROTO_LARP = 0x5b - IPPROTO_LEAF1 = 0x19 - IPPROTO_LEAF2 = 0x1a - IPPROTO_MAX = 0x100 - IPPROTO_MAXID = 0x34 - IPPROTO_MEAS = 0x13 - IPPROTO_MHRP = 0x30 - IPPROTO_MICP = 0x5f - IPPROTO_MTP = 0x5c - IPPROTO_MUX = 0x12 - IPPROTO_ND = 0x4d - IPPROTO_NHRP = 0x36 - IPPROTO_NONE = 0x3b - IPPROTO_NSP = 0x1f - IPPROTO_NVPII = 0xb - IPPROTO_OSPFIGP = 0x59 - IPPROTO_PGM = 0x71 - IPPROTO_PIGP = 0x9 - IPPROTO_PIM = 0x67 - IPPROTO_PRM = 0x15 - IPPROTO_PUP = 0xc - IPPROTO_PVP = 0x4b - IPPROTO_RAW = 0xff - IPPROTO_RCCMON = 0xa - IPPROTO_RDP = 0x1b - IPPROTO_ROUTING = 0x2b - IPPROTO_RSVP = 0x2e - IPPROTO_RVD = 0x42 - IPPROTO_SATEXPAK = 0x40 - IPPROTO_SATMON = 0x45 - IPPROTO_SCCSP = 0x60 - IPPROTO_SCTP = 0x84 - IPPROTO_SDRP = 0x2a - IPPROTO_SEP = 0x21 - IPPROTO_SRPC = 0x5a - IPPROTO_ST = 0x7 - IPPROTO_SVMTP = 0x52 - IPPROTO_SWIPE = 0x35 - IPPROTO_TCF = 0x57 - IPPROTO_TCP = 0x6 - IPPROTO_TP = 0x1d - IPPROTO_TPXX = 0x27 - IPPROTO_TRUNK1 = 0x17 - IPPROTO_TRUNK2 = 0x18 - IPPROTO_TTP = 0x54 - IPPROTO_UDP = 0x11 - IPPROTO_VINES = 0x53 - IPPROTO_VISA = 0x46 - IPPROTO_VMTP = 0x51 - IPPROTO_WBEXPAK = 0x4f - IPPROTO_WBMON = 0x4e - IPPROTO_WSN = 0x4a - IPPROTO_XNET = 0xf - IPPROTO_XTP = 0x24 - IPV6_2292DSTOPTS = 0x17 - IPV6_2292HOPLIMIT = 0x14 - IPV6_2292HOPOPTS = 0x16 - IPV6_2292NEXTHOP = 0x15 - IPV6_2292PKTINFO = 0x13 - IPV6_2292PKTOPTIONS = 0x19 - IPV6_2292RTHDR = 0x18 - IPV6_3542DSTOPTS = 0x32 - IPV6_3542HOPLIMIT = 0x2f - IPV6_3542HOPOPTS = 0x31 - IPV6_3542NEXTHOP = 0x30 - IPV6_3542PKTINFO = 0x2e - IPV6_3542RTHDR = 0x33 - IPV6_ADDR_MC_FLAGS_PREFIX = 0x20 - IPV6_ADDR_MC_FLAGS_TRANSIENT = 0x10 - IPV6_ADDR_MC_FLAGS_UNICAST_BASED = 0x30 - IPV6_AUTOFLOWLABEL = 0x3b - IPV6_BINDV6ONLY = 0x1b - IPV6_BOUND_IF = 0x7d - IPV6_CHECKSUM = 0x1a - IPV6_DEFAULT_MULTICAST_HOPS = 0x1 - IPV6_DEFAULT_MULTICAST_LOOP = 0x1 - IPV6_DEFHLIM = 0x40 - IPV6_DONTFRAG = 0x3e - IPV6_DSTOPTS = 0x32 - IPV6_FAITH = 0x1d - IPV6_FLOWINFO_MASK = 0xffffff0f - IPV6_FLOWLABEL_MASK = 0xffff0f00 - IPV6_FLOW_ECN_MASK = 0x3000 - IPV6_FRAGTTL = 0x3c - IPV6_FW_ADD = 0x1e - IPV6_FW_DEL = 0x1f - IPV6_FW_FLUSH = 0x20 - IPV6_FW_GET = 0x22 - IPV6_FW_ZERO = 0x21 - IPV6_HLIMDEC = 0x1 - IPV6_HOPLIMIT = 0x2f - IPV6_HOPOPTS = 0x31 - IPV6_IPSEC_POLICY = 0x1c - IPV6_JOIN_GROUP = 0xc - IPV6_LEAVE_GROUP = 0xd - IPV6_MAXHLIM = 0xff - IPV6_MAXOPTHDR = 0x800 - IPV6_MAXPACKET = 0xffff - IPV6_MAX_GROUP_SRC_FILTER = 0x200 - IPV6_MAX_MEMBERSHIPS = 0xfff - IPV6_MAX_SOCK_SRC_FILTER = 0x80 - IPV6_MIN_MEMBERSHIPS = 0x1f - IPV6_MMTU = 0x500 - IPV6_MSFILTER = 0x4a - IPV6_MULTICAST_HOPS = 0xa - IPV6_MULTICAST_IF = 0x9 - IPV6_MULTICAST_LOOP = 0xb - IPV6_NEXTHOP = 0x30 - IPV6_PATHMTU = 0x2c - IPV6_PKTINFO = 0x2e - IPV6_PORTRANGE = 0xe - IPV6_PORTRANGE_DEFAULT = 0x0 - IPV6_PORTRANGE_HIGH = 0x1 - IPV6_PORTRANGE_LOW = 0x2 - IPV6_PREFER_TEMPADDR = 0x3f - IPV6_RECVDSTOPTS = 0x28 - IPV6_RECVHOPLIMIT = 0x25 - IPV6_RECVHOPOPTS = 0x27 - IPV6_RECVPATHMTU = 0x2b - IPV6_RECVPKTINFO = 0x3d - IPV6_RECVRTHDR = 0x26 - IPV6_RECVTCLASS = 0x23 - IPV6_RTHDR = 0x33 - IPV6_RTHDRDSTOPTS = 0x39 - IPV6_RTHDR_LOOSE = 0x0 - IPV6_RTHDR_STRICT = 0x1 - IPV6_RTHDR_TYPE_0 = 0x0 - IPV6_SOCKOPT_RESERVED1 = 0x3 - IPV6_TCLASS = 0x24 - IPV6_UNICAST_HOPS = 0x4 - IPV6_USE_MIN_MTU = 0x2a - IPV6_V6ONLY = 0x1b - IPV6_VERSION = 0x60 - IPV6_VERSION_MASK = 0xf0 - IP_ADD_MEMBERSHIP = 0xc - IP_ADD_SOURCE_MEMBERSHIP = 0x46 - IP_BLOCK_SOURCE = 0x48 - IP_BOUND_IF = 0x19 - IP_DEFAULT_MULTICAST_LOOP = 0x1 - IP_DEFAULT_MULTICAST_TTL = 0x1 - IP_DF = 0x4000 - IP_DONTFRAG = 0x1c - IP_DROP_MEMBERSHIP = 0xd - IP_DROP_SOURCE_MEMBERSHIP = 0x47 - IP_DUMMYNET_CONFIGURE = 0x3c - IP_DUMMYNET_DEL = 0x3d - IP_DUMMYNET_FLUSH = 0x3e - IP_DUMMYNET_GET = 0x40 - IP_FAITH = 0x16 - IP_FW_ADD = 0x28 - IP_FW_DEL = 0x29 - IP_FW_FLUSH = 0x2a - IP_FW_GET = 0x2c - IP_FW_RESETLOG = 0x2d - IP_FW_ZERO = 0x2b - IP_HDRINCL = 0x2 - IP_IPSEC_POLICY = 0x15 - IP_MAXPACKET = 0xffff - IP_MAX_GROUP_SRC_FILTER = 0x200 - IP_MAX_MEMBERSHIPS = 0xfff - IP_MAX_SOCK_MUTE_FILTER = 0x80 - IP_MAX_SOCK_SRC_FILTER = 0x80 - IP_MF = 0x2000 - IP_MIN_MEMBERSHIPS = 0x1f - IP_MSFILTER = 0x4a - IP_MSS = 0x240 - IP_MULTICAST_IF = 0x9 - IP_MULTICAST_IFINDEX = 0x42 - IP_MULTICAST_LOOP = 0xb - IP_MULTICAST_TTL = 0xa - IP_MULTICAST_VIF = 0xe - IP_NAT__XXX = 0x37 - IP_OFFMASK = 0x1fff - IP_OLD_FW_ADD = 0x32 - IP_OLD_FW_DEL = 0x33 - IP_OLD_FW_FLUSH = 0x34 - IP_OLD_FW_GET = 0x36 - IP_OLD_FW_RESETLOG = 0x38 - IP_OLD_FW_ZERO = 0x35 - IP_OPTIONS = 0x1 - IP_PKTINFO = 0x1a - IP_PORTRANGE = 0x13 - IP_PORTRANGE_DEFAULT = 0x0 - IP_PORTRANGE_HIGH = 0x1 - IP_PORTRANGE_LOW = 0x2 - IP_RECVDSTADDR = 0x7 - IP_RECVIF = 0x14 - IP_RECVOPTS = 0x5 - IP_RECVPKTINFO = 0x1a - IP_RECVRETOPTS = 0x6 - IP_RECVTOS = 0x1b - IP_RECVTTL = 0x18 - IP_RETOPTS = 0x8 - IP_RF = 0x8000 - IP_RSVP_OFF = 0x10 - IP_RSVP_ON = 0xf - IP_RSVP_VIF_OFF = 0x12 - IP_RSVP_VIF_ON = 0x11 - IP_STRIPHDR = 0x17 - IP_TOS = 0x3 - IP_TRAFFIC_MGT_BACKGROUND = 0x41 - IP_TTL = 0x4 - IP_UNBLOCK_SOURCE = 0x49 - ISIG = 0x80 - ISTRIP = 0x20 - IUTF8 = 0x4000 - IXANY = 0x800 - IXOFF = 0x400 - IXON = 0x200 - KERN_HOSTNAME = 0xa - KERN_OSRELEASE = 0x2 - KERN_OSTYPE = 0x1 - KERN_VERSION = 0x4 - LOCAL_PEERCRED = 0x1 - LOCAL_PEEREPID = 0x3 - LOCAL_PEEREUUID = 0x5 - LOCAL_PEERPID = 0x2 - LOCAL_PEERTOKEN = 0x6 - LOCAL_PEERUUID = 0x4 - LOCK_EX = 0x2 - LOCK_NB = 0x4 - LOCK_SH = 0x1 - LOCK_UN = 0x8 - MADV_CAN_REUSE = 0x9 - MADV_DONTNEED = 0x4 - MADV_FREE = 0x5 - MADV_FREE_REUSABLE = 0x7 - MADV_FREE_REUSE = 0x8 - MADV_NORMAL = 0x0 - MADV_PAGEOUT = 0xa - MADV_RANDOM = 0x1 - MADV_SEQUENTIAL = 0x2 - MADV_WILLNEED = 0x3 - MADV_ZERO_WIRED_PAGES = 0x6 - MAP_32BIT = 0x8000 - MAP_ANON = 0x1000 - MAP_ANONYMOUS = 0x1000 - MAP_COPY = 0x2 - MAP_FILE = 0x0 - MAP_FIXED = 0x10 - MAP_HASSEMAPHORE = 0x200 - MAP_JIT = 0x800 - MAP_NOCACHE = 0x400 - MAP_NOEXTEND = 0x100 - MAP_NORESERVE = 0x40 - MAP_PRIVATE = 0x2 - MAP_RENAME = 0x20 - MAP_RESERVED0080 = 0x80 - MAP_RESILIENT_CODESIGN = 0x2000 - MAP_RESILIENT_MEDIA = 0x4000 - MAP_SHARED = 0x1 - MAP_TRANSLATED_ALLOW_EXECUTE = 0x20000 - MAP_UNIX03 = 0x40000 - MCAST_BLOCK_SOURCE = 0x54 - MCAST_EXCLUDE = 0x2 - MCAST_INCLUDE = 0x1 - MCAST_JOIN_GROUP = 0x50 - MCAST_JOIN_SOURCE_GROUP = 0x52 - MCAST_LEAVE_GROUP = 0x51 - MCAST_LEAVE_SOURCE_GROUP = 0x53 - MCAST_UNBLOCK_SOURCE = 0x55 - MCAST_UNDEFINED = 0x0 - MCL_CURRENT = 0x1 - MCL_FUTURE = 0x2 - MNT_ASYNC = 0x40 - MNT_AUTOMOUNTED = 0x400000 - MNT_CMDFLAGS = 0xf0000 - MNT_CPROTECT = 0x80 - MNT_DEFWRITE = 0x2000000 - MNT_DONTBROWSE = 0x100000 - MNT_DOVOLFS = 0x8000 - MNT_DWAIT = 0x4 - MNT_EXPORTED = 0x100 - MNT_EXT_ROOT_DATA_VOL = 0x1 - MNT_FORCE = 0x80000 - MNT_IGNORE_OWNERSHIP = 0x200000 - MNT_JOURNALED = 0x800000 - MNT_LOCAL = 0x1000 - MNT_MULTILABEL = 0x4000000 - MNT_NOATIME = 0x10000000 - MNT_NOBLOCK = 0x20000 - MNT_NODEV = 0x10 - MNT_NOEXEC = 0x4 - MNT_NOSUID = 0x8 - MNT_NOUSERXATTR = 0x1000000 - MNT_NOWAIT = 0x2 - MNT_QUARANTINE = 0x400 - MNT_QUOTA = 0x2000 - MNT_RDONLY = 0x1 - MNT_RELOAD = 0x40000 - MNT_REMOVABLE = 0x200 - MNT_ROOTFS = 0x4000 - MNT_SNAPSHOT = 0x40000000 - MNT_STRICTATIME = 0x80000000 - MNT_SYNCHRONOUS = 0x2 - MNT_UNION = 0x20 - MNT_UNKNOWNPERMISSIONS = 0x200000 - MNT_UPDATE = 0x10000 - MNT_VISFLAGMASK = 0xd7f0f7ff - MNT_WAIT = 0x1 - MSG_CTRUNC = 0x20 - MSG_DONTROUTE = 0x4 - MSG_DONTWAIT = 0x80 - MSG_EOF = 0x100 - MSG_EOR = 0x8 - MSG_FLUSH = 0x400 - MSG_HAVEMORE = 0x2000 - MSG_HOLD = 0x800 - MSG_NEEDSA = 0x10000 - MSG_NOSIGNAL = 0x80000 - MSG_OOB = 0x1 - MSG_PEEK = 0x2 - MSG_RCVMORE = 0x4000 - MSG_SEND = 0x1000 - MSG_TRUNC = 0x10 - MSG_WAITALL = 0x40 - MSG_WAITSTREAM = 0x200 - MS_ASYNC = 0x1 - MS_DEACTIVATE = 0x8 - MS_INVALIDATE = 0x2 - MS_KILLPAGES = 0x4 - MS_SYNC = 0x10 - NAME_MAX = 0xff - NET_RT_DUMP = 0x1 - NET_RT_DUMP2 = 0x7 - NET_RT_FLAGS = 0x2 - NET_RT_FLAGS_PRIV = 0xa - NET_RT_IFLIST = 0x3 - NET_RT_IFLIST2 = 0x6 - NET_RT_MAXID = 0xb - NET_RT_STAT = 0x4 - NET_RT_TRASH = 0x5 - NFDBITS = 0x20 - NL0 = 0x0 - NL1 = 0x100 - NL2 = 0x200 - NL3 = 0x300 - NLDLY = 0x300 - NOFLSH = 0x80000000 - NOKERNINFO = 0x2000000 - NOTE_ABSOLUTE = 0x8 - NOTE_ATTRIB = 0x8 - NOTE_BACKGROUND = 0x40 - NOTE_CHILD = 0x4 - NOTE_CRITICAL = 0x20 - NOTE_DELETE = 0x1 - NOTE_EXEC = 0x20000000 - NOTE_EXIT = 0x80000000 - NOTE_EXITSTATUS = 0x4000000 - NOTE_EXIT_CSERROR = 0x40000 - NOTE_EXIT_DECRYPTFAIL = 0x10000 - NOTE_EXIT_DETAIL = 0x2000000 - NOTE_EXIT_DETAIL_MASK = 0x70000 - NOTE_EXIT_MEMORY = 0x20000 - NOTE_EXIT_REPARENTED = 0x80000 - NOTE_EXTEND = 0x4 - NOTE_FFAND = 0x40000000 - NOTE_FFCOPY = 0xc0000000 - NOTE_FFCTRLMASK = 0xc0000000 - NOTE_FFLAGSMASK = 0xffffff - NOTE_FFNOP = 0x0 - NOTE_FFOR = 0x80000000 - NOTE_FORK = 0x40000000 - NOTE_FUNLOCK = 0x100 - NOTE_LEEWAY = 0x10 - NOTE_LINK = 0x10 - NOTE_LOWAT = 0x1 - NOTE_MACHTIME = 0x100 - NOTE_MACH_CONTINUOUS_TIME = 0x80 - NOTE_NONE = 0x80 - NOTE_NSECONDS = 0x4 - NOTE_OOB = 0x2 - NOTE_PCTRLMASK = -0x100000 - NOTE_PDATAMASK = 0xfffff - NOTE_REAP = 0x10000000 - NOTE_RENAME = 0x20 - NOTE_REVOKE = 0x40 - NOTE_SECONDS = 0x1 - NOTE_SIGNAL = 0x8000000 - NOTE_TRACK = 0x1 - NOTE_TRACKERR = 0x2 - NOTE_TRIGGER = 0x1000000 - NOTE_USECONDS = 0x2 - NOTE_VM_ERROR = 0x10000000 - NOTE_VM_PRESSURE = 0x80000000 - NOTE_VM_PRESSURE_SUDDEN_TERMINATE = 0x20000000 - NOTE_VM_PRESSURE_TERMINATE = 0x40000000 - NOTE_WRITE = 0x2 - OCRNL = 0x10 - OFDEL = 0x20000 - OFILL = 0x80 - ONLCR = 0x2 - ONLRET = 0x40 - ONOCR = 0x20 - ONOEOT = 0x8 - OPOST = 0x1 - OXTABS = 0x4 - O_ACCMODE = 0x3 - O_ALERT = 0x20000000 - O_APPEND = 0x8 - O_ASYNC = 0x40 - O_CLOEXEC = 0x1000000 - O_CREAT = 0x200 - O_DIRECTORY = 0x100000 - O_DP_GETRAWENCRYPTED = 0x1 - O_DP_GETRAWUNENCRYPTED = 0x2 - O_DSYNC = 0x400000 - O_EVTONLY = 0x8000 - O_EXCL = 0x800 - O_EXLOCK = 0x20 - O_FSYNC = 0x80 - O_NDELAY = 0x4 - O_NOCTTY = 0x20000 - O_NOFOLLOW = 0x100 - O_NOFOLLOW_ANY = 0x20000000 - O_NONBLOCK = 0x4 - O_POPUP = 0x80000000 - O_RDONLY = 0x0 - O_RDWR = 0x2 - O_SHLOCK = 0x10 - O_SYMLINK = 0x200000 - O_SYNC = 0x80 - O_TRUNC = 0x400 - O_WRONLY = 0x1 - PARENB = 0x1000 - PARMRK = 0x8 - PARODD = 0x2000 - PENDIN = 0x20000000 - PRIO_PGRP = 0x1 - PRIO_PROCESS = 0x0 - PRIO_USER = 0x2 - PROT_EXEC = 0x4 - PROT_NONE = 0x0 - PROT_READ = 0x1 - PROT_WRITE = 0x2 - PT_ATTACH = 0xa - PT_ATTACHEXC = 0xe - PT_CONTINUE = 0x7 - PT_DENY_ATTACH = 0x1f - PT_DETACH = 0xb - PT_FIRSTMACH = 0x20 - PT_FORCEQUOTA = 0x1e - PT_KILL = 0x8 - PT_READ_D = 0x2 - PT_READ_I = 0x1 - PT_READ_U = 0x3 - PT_SIGEXC = 0xc - PT_STEP = 0x9 - PT_THUPDATE = 0xd - PT_TRACE_ME = 0x0 - PT_WRITE_D = 0x5 - PT_WRITE_I = 0x4 - PT_WRITE_U = 0x6 - RLIMIT_AS = 0x5 - RLIMIT_CORE = 0x4 - RLIMIT_CPU = 0x0 - RLIMIT_CPU_USAGE_MONITOR = 0x2 - RLIMIT_DATA = 0x2 - RLIMIT_FSIZE = 0x1 - RLIMIT_MEMLOCK = 0x6 - RLIMIT_NOFILE = 0x8 - RLIMIT_NPROC = 0x7 - RLIMIT_RSS = 0x5 - RLIMIT_STACK = 0x3 - RLIM_INFINITY = 0x7fffffffffffffff - RTAX_AUTHOR = 0x6 - RTAX_BRD = 0x7 - RTAX_DST = 0x0 - RTAX_GATEWAY = 0x1 - RTAX_GENMASK = 0x3 - RTAX_IFA = 0x5 - RTAX_IFP = 0x4 - RTAX_MAX = 0x8 - RTAX_NETMASK = 0x2 - RTA_AUTHOR = 0x40 - RTA_BRD = 0x80 - RTA_DST = 0x1 - RTA_GATEWAY = 0x2 - RTA_GENMASK = 0x8 - RTA_IFA = 0x20 - RTA_IFP = 0x10 - RTA_NETMASK = 0x4 - RTF_BLACKHOLE = 0x1000 - RTF_BROADCAST = 0x400000 - RTF_CLONING = 0x100 - RTF_CONDEMNED = 0x2000000 - RTF_DEAD = 0x20000000 - RTF_DELCLONE = 0x80 - RTF_DONE = 0x40 - RTF_DYNAMIC = 0x10 - RTF_GATEWAY = 0x2 - RTF_GLOBAL = 0x40000000 - RTF_HOST = 0x4 - RTF_IFREF = 0x4000000 - RTF_IFSCOPE = 0x1000000 - RTF_LLDATA = 0x400 - RTF_LLINFO = 0x400 - RTF_LOCAL = 0x200000 - RTF_MODIFIED = 0x20 - RTF_MULTICAST = 0x800000 - RTF_NOIFREF = 0x2000 - RTF_PINNED = 0x100000 - RTF_PRCLONING = 0x10000 - RTF_PROTO1 = 0x8000 - RTF_PROTO2 = 0x4000 - RTF_PROTO3 = 0x40000 - RTF_PROXY = 0x8000000 - RTF_REJECT = 0x8 - RTF_ROUTER = 0x10000000 - RTF_STATIC = 0x800 - RTF_UP = 0x1 - RTF_WASCLONED = 0x20000 - RTF_XRESOLVE = 0x200 - RTM_ADD = 0x1 - RTM_CHANGE = 0x3 - RTM_DELADDR = 0xd - RTM_DELETE = 0x2 - RTM_DELMADDR = 0x10 - RTM_GET = 0x4 - RTM_GET2 = 0x14 - RTM_IFINFO = 0xe - RTM_IFINFO2 = 0x12 - RTM_LOCK = 0x8 - RTM_LOSING = 0x5 - RTM_MISS = 0x7 - RTM_NEWADDR = 0xc - RTM_NEWMADDR = 0xf - RTM_NEWMADDR2 = 0x13 - RTM_OLDADD = 0x9 - RTM_OLDDEL = 0xa - RTM_REDIRECT = 0x6 - RTM_RESOLVE = 0xb - RTM_RTTUNIT = 0xf4240 - RTM_VERSION = 0x5 - RTV_EXPIRE = 0x4 - RTV_HOPCOUNT = 0x2 - RTV_MTU = 0x1 - RTV_RPIPE = 0x8 - RTV_RTT = 0x40 - RTV_RTTVAR = 0x80 - RTV_SPIPE = 0x10 - RTV_SSTHRESH = 0x20 - RUSAGE_CHILDREN = -0x1 - RUSAGE_SELF = 0x0 - SCM_CREDS = 0x3 - SCM_RIGHTS = 0x1 - SCM_TIMESTAMP = 0x2 - SCM_TIMESTAMP_MONOTONIC = 0x4 - SEEK_CUR = 0x1 - SEEK_DATA = 0x4 - SEEK_END = 0x2 - SEEK_HOLE = 0x3 - SEEK_SET = 0x0 - SHUT_RD = 0x0 - SHUT_RDWR = 0x2 - SHUT_WR = 0x1 - SIOCADDMULTI = 0x80206931 - SIOCAIFADDR = 0x8040691a - SIOCARPIPLL = 0xc0206928 - SIOCATMARK = 0x40047307 - SIOCAUTOADDR = 0xc0206926 - SIOCAUTONETMASK = 0x80206927 - SIOCDELMULTI = 0x80206932 - SIOCDIFADDR = 0x80206919 - SIOCDIFPHYADDR = 0x80206941 - SIOCGDRVSPEC = 0xc028697b - SIOCGETVLAN = 0xc020697f - SIOCGHIWAT = 0x40047301 - SIOCGIF6LOWPAN = 0xc02069c5 - SIOCGIFADDR = 0xc0206921 - SIOCGIFALTMTU = 0xc0206948 - SIOCGIFASYNCMAP = 0xc020697c - SIOCGIFBOND = 0xc0206947 - SIOCGIFBRDADDR = 0xc0206923 - SIOCGIFCAP = 0xc020695b - SIOCGIFCONF = 0xc00c6924 - SIOCGIFDEVMTU = 0xc0206944 - SIOCGIFDSTADDR = 0xc0206922 - SIOCGIFFLAGS = 0xc0206911 - SIOCGIFFUNCTIONALTYPE = 0xc02069ad - SIOCGIFGENERIC = 0xc020693a - SIOCGIFKPI = 0xc0206987 - SIOCGIFMAC = 0xc0206982 - SIOCGIFMEDIA = 0xc02c6938 - SIOCGIFMETRIC = 0xc0206917 - SIOCGIFMTU = 0xc0206933 - SIOCGIFNETMASK = 0xc0206925 - SIOCGIFPDSTADDR = 0xc0206940 - SIOCGIFPHYS = 0xc0206935 - SIOCGIFPSRCADDR = 0xc020693f - SIOCGIFSTATUS = 0xc331693d - SIOCGIFVLAN = 0xc020697f - SIOCGIFWAKEFLAGS = 0xc0206988 - SIOCGIFXMEDIA = 0xc02c6948 - SIOCGLOWAT = 0x40047303 - SIOCGPGRP = 0x40047309 - SIOCIFCREATE = 0xc0206978 - SIOCIFCREATE2 = 0xc020697a - SIOCIFDESTROY = 0x80206979 - SIOCIFGCLONERS = 0xc0106981 - SIOCRSLVMULTI = 0xc010693b - SIOCSDRVSPEC = 0x8028697b - SIOCSETVLAN = 0x8020697e - SIOCSHIWAT = 0x80047300 - SIOCSIF6LOWPAN = 0x802069c4 - SIOCSIFADDR = 0x8020690c - SIOCSIFALTMTU = 0x80206945 - SIOCSIFASYNCMAP = 0x8020697d - SIOCSIFBOND = 0x80206946 - SIOCSIFBRDADDR = 0x80206913 - SIOCSIFCAP = 0x8020695a - SIOCSIFDSTADDR = 0x8020690e - SIOCSIFFLAGS = 0x80206910 - SIOCSIFGENERIC = 0x80206939 - SIOCSIFKPI = 0x80206986 - SIOCSIFLLADDR = 0x8020693c - SIOCSIFMAC = 0x80206983 - SIOCSIFMEDIA = 0xc0206937 - SIOCSIFMETRIC = 0x80206918 - SIOCSIFMTU = 0x80206934 - SIOCSIFNETMASK = 0x80206916 - SIOCSIFPHYADDR = 0x8040693e - SIOCSIFPHYS = 0x80206936 - SIOCSIFVLAN = 0x8020697e - SIOCSLOWAT = 0x80047302 - SIOCSPGRP = 0x80047308 - SOCK_DGRAM = 0x2 - SOCK_MAXADDRLEN = 0xff - SOCK_RAW = 0x3 - SOCK_RDM = 0x4 - SOCK_SEQPACKET = 0x5 - SOCK_STREAM = 0x1 - SOL_LOCAL = 0x0 - SOL_SOCKET = 0xffff - SOMAXCONN = 0x80 - SO_ACCEPTCONN = 0x2 - SO_BROADCAST = 0x20 - SO_DEBUG = 0x1 - SO_DONTROUTE = 0x10 - SO_DONTTRUNC = 0x2000 - SO_ERROR = 0x1007 - SO_KEEPALIVE = 0x8 - SO_LABEL = 0x1010 - SO_LINGER = 0x80 - SO_LINGER_SEC = 0x1080 - SO_NETSVC_MARKING_LEVEL = 0x1119 - SO_NET_SERVICE_TYPE = 0x1116 - SO_NKE = 0x1021 - SO_NOADDRERR = 0x1023 - SO_NOSIGPIPE = 0x1022 - SO_NOTIFYCONFLICT = 0x1026 - SO_NP_EXTENSIONS = 0x1083 - SO_NREAD = 0x1020 - SO_NUMRCVPKT = 0x1112 - SO_NWRITE = 0x1024 - SO_OOBINLINE = 0x100 - SO_PEERLABEL = 0x1011 - SO_RANDOMPORT = 0x1082 - SO_RCVBUF = 0x1002 - SO_RCVLOWAT = 0x1004 - SO_RCVTIMEO = 0x1006 - SO_REUSEADDR = 0x4 - SO_REUSEPORT = 0x200 - SO_REUSESHAREUID = 0x1025 - SO_SNDBUF = 0x1001 - SO_SNDLOWAT = 0x1003 - SO_SNDTIMEO = 0x1005 - SO_TIMESTAMP = 0x400 - SO_TIMESTAMP_MONOTONIC = 0x800 - SO_TYPE = 0x1008 - SO_UPCALLCLOSEWAIT = 0x1027 - SO_USELOOPBACK = 0x40 - SO_WANTMORE = 0x4000 - SO_WANTOOBFLAG = 0x8000 - S_IEXEC = 0x40 - S_IFBLK = 0x6000 - S_IFCHR = 0x2000 - S_IFDIR = 0x4000 - S_IFIFO = 0x1000 - S_IFLNK = 0xa000 - S_IFMT = 0xf000 - S_IFREG = 0x8000 - S_IFSOCK = 0xc000 - S_IFWHT = 0xe000 - S_IREAD = 0x100 - S_IRGRP = 0x20 - S_IROTH = 0x4 - S_IRUSR = 0x100 - S_IRWXG = 0x38 - S_IRWXO = 0x7 - S_IRWXU = 0x1c0 - S_ISGID = 0x400 - S_ISTXT = 0x200 - S_ISUID = 0x800 - S_ISVTX = 0x200 - S_IWGRP = 0x10 - S_IWOTH = 0x2 - S_IWRITE = 0x80 - S_IWUSR = 0x80 - S_IXGRP = 0x8 - S_IXOTH = 0x1 - S_IXUSR = 0x40 - TAB0 = 0x0 - TAB1 = 0x400 - TAB2 = 0x800 - TAB3 = 0x4 - TABDLY = 0xc04 - TCIFLUSH = 0x1 - TCIOFF = 0x3 - TCIOFLUSH = 0x3 - TCION = 0x4 - TCOFLUSH = 0x2 - TCOOFF = 0x1 - TCOON = 0x2 - TCP_CONNECTIONTIMEOUT = 0x20 - TCP_CONNECTION_INFO = 0x106 - TCP_ENABLE_ECN = 0x104 - TCP_FASTOPEN = 0x105 - TCP_KEEPALIVE = 0x10 - TCP_KEEPCNT = 0x102 - TCP_KEEPINTVL = 0x101 - TCP_MAXHLEN = 0x3c - TCP_MAXOLEN = 0x28 - TCP_MAXSEG = 0x2 - TCP_MAXWIN = 0xffff - TCP_MAX_SACK = 0x4 - TCP_MAX_WINSHIFT = 0xe - TCP_MINMSS = 0xd8 - TCP_MSS = 0x200 - TCP_NODELAY = 0x1 - TCP_NOOPT = 0x8 - TCP_NOPUSH = 0x4 - TCP_NOTSENT_LOWAT = 0x201 - TCP_RXT_CONNDROPTIME = 0x80 - TCP_RXT_FINDROP = 0x100 - TCP_SENDMOREACKS = 0x103 - TCSAFLUSH = 0x2 - TIOCCBRK = 0x2000747a - TIOCCDTR = 0x20007478 - TIOCCONS = 0x80047462 - TIOCDCDTIMESTAMP = 0x40107458 - TIOCDRAIN = 0x2000745e - TIOCDSIMICROCODE = 0x20007455 - TIOCEXCL = 0x2000740d - TIOCEXT = 0x80047460 - TIOCFLUSH = 0x80047410 - TIOCGDRAINWAIT = 0x40047456 - TIOCGETA = 0x40487413 - TIOCGETD = 0x4004741a - TIOCGPGRP = 0x40047477 - TIOCGWINSZ = 0x40087468 - TIOCIXOFF = 0x20007480 - TIOCIXON = 0x20007481 - TIOCMBIC = 0x8004746b - TIOCMBIS = 0x8004746c - TIOCMGDTRWAIT = 0x4004745a - TIOCMGET = 0x4004746a - TIOCMODG = 0x40047403 - TIOCMODS = 0x80047404 - TIOCMSDTRWAIT = 0x8004745b - TIOCMSET = 0x8004746d - TIOCM_CAR = 0x40 - TIOCM_CD = 0x40 - TIOCM_CTS = 0x20 - TIOCM_DSR = 0x100 - TIOCM_DTR = 0x2 - TIOCM_LE = 0x1 - TIOCM_RI = 0x80 - TIOCM_RNG = 0x80 - TIOCM_RTS = 0x4 - TIOCM_SR = 0x10 - TIOCM_ST = 0x8 - TIOCNOTTY = 0x20007471 - TIOCNXCL = 0x2000740e - TIOCOUTQ = 0x40047473 - TIOCPKT = 0x80047470 - TIOCPKT_DATA = 0x0 - TIOCPKT_DOSTOP = 0x20 - TIOCPKT_FLUSHREAD = 0x1 - TIOCPKT_FLUSHWRITE = 0x2 - TIOCPKT_IOCTL = 0x40 - TIOCPKT_NOSTOP = 0x10 - TIOCPKT_START = 0x8 - TIOCPKT_STOP = 0x4 - TIOCPTYGNAME = 0x40807453 - TIOCPTYGRANT = 0x20007454 - TIOCPTYUNLK = 0x20007452 - TIOCREMOTE = 0x80047469 - TIOCSBRK = 0x2000747b - TIOCSCONS = 0x20007463 - TIOCSCTTY = 0x20007461 - TIOCSDRAINWAIT = 0x80047457 - TIOCSDTR = 0x20007479 - TIOCSETA = 0x80487414 - TIOCSETAF = 0x80487416 - TIOCSETAW = 0x80487415 - TIOCSETD = 0x8004741b - TIOCSIG = 0x2000745f - TIOCSPGRP = 0x80047476 - TIOCSTART = 0x2000746e - TIOCSTAT = 0x20007465 - TIOCSTI = 0x80017472 - TIOCSTOP = 0x2000746f - TIOCSWINSZ = 0x80087467 - TIOCTIMESTAMP = 0x40107459 - TIOCUCNTL = 0x80047466 - TOSTOP = 0x400000 - VDISCARD = 0xf - VDSUSP = 0xb - VEOF = 0x0 - VEOL = 0x1 - VEOL2 = 0x2 - VERASE = 0x3 - VINTR = 0x8 - VKILL = 0x5 - VLNEXT = 0xe - VMIN = 0x10 - VM_LOADAVG = 0x2 - VM_MACHFACTOR = 0x4 - VM_MAXID = 0x6 - VM_METER = 0x1 - VM_SWAPUSAGE = 0x5 - VQUIT = 0x9 - VREPRINT = 0x6 - VSTART = 0xc - VSTATUS = 0x12 - VSTOP = 0xd - VSUSP = 0xa - VT0 = 0x0 - VT1 = 0x10000 - VTDLY = 0x10000 - VTIME = 0x11 - VWERASE = 0x4 - WCONTINUED = 0x10 - WCOREFLAG = 0x80 - WEXITED = 0x4 - WNOHANG = 0x1 - WNOWAIT = 0x20 - WORDSIZE = 0x40 - WSTOPPED = 0x8 - WUNTRACED = 0x2 - XATTR_CREATE = 0x2 - XATTR_NODEFAULT = 0x10 - XATTR_NOFOLLOW = 0x1 - XATTR_NOSECURITY = 0x8 - XATTR_REPLACE = 0x4 - XATTR_SHOWCOMPRESSION = 0x20 + AF_APPLETALK = 0x10 + AF_CCITT = 0xa + AF_CHAOS = 0x5 + AF_CNT = 0x15 + AF_COIP = 0x14 + AF_DATAKIT = 0x9 + AF_DECnet = 0xc + AF_DLI = 0xd + AF_E164 = 0x1c + AF_ECMA = 0x8 + AF_HYLINK = 0xf + AF_IEEE80211 = 0x25 + AF_IMPLINK = 0x3 + AF_INET = 0x2 + AF_INET6 = 0x1e + AF_IPX = 0x17 + AF_ISDN = 0x1c + AF_ISO = 0x7 + AF_LAT = 0xe + AF_LINK = 0x12 + AF_LOCAL = 0x1 + AF_MAX = 0x29 + AF_NATM = 0x1f + AF_NDRV = 0x1b + AF_NETBIOS = 0x21 + AF_NS = 0x6 + AF_OSI = 0x7 + AF_PPP = 0x22 + AF_PUP = 0x4 + AF_RESERVED_36 = 0x24 + AF_ROUTE = 0x11 + AF_SIP = 0x18 + AF_SNA = 0xb + AF_SYSTEM = 0x20 + AF_SYS_CONTROL = 0x2 + AF_UNIX = 0x1 + AF_UNSPEC = 0x0 + AF_UTUN = 0x26 + AF_VSOCK = 0x28 + ALTWERASE = 0x200 + ATTR_BIT_MAP_COUNT = 0x5 + ATTR_CMN_ACCESSMASK = 0x20000 + ATTR_CMN_ACCTIME = 0x1000 + ATTR_CMN_ADDEDTIME = 0x10000000 + ATTR_CMN_BKUPTIME = 0x2000 + ATTR_CMN_CHGTIME = 0x800 + ATTR_CMN_CRTIME = 0x200 + ATTR_CMN_DATA_PROTECT_FLAGS = 0x40000000 + ATTR_CMN_DEVID = 0x2 + ATTR_CMN_DOCUMENT_ID = 0x100000 + ATTR_CMN_ERROR = 0x20000000 + ATTR_CMN_EXTENDED_SECURITY = 0x400000 + ATTR_CMN_FILEID = 0x2000000 + ATTR_CMN_FLAGS = 0x40000 + ATTR_CMN_FNDRINFO = 0x4000 + ATTR_CMN_FSID = 0x4 + ATTR_CMN_FULLPATH = 0x8000000 + ATTR_CMN_GEN_COUNT = 0x80000 + ATTR_CMN_GRPID = 0x10000 + ATTR_CMN_GRPUUID = 0x1000000 + ATTR_CMN_MODTIME = 0x400 + ATTR_CMN_NAME = 0x1 + ATTR_CMN_NAMEDATTRCOUNT = 0x80000 + ATTR_CMN_NAMEDATTRLIST = 0x100000 + ATTR_CMN_OBJID = 0x20 + ATTR_CMN_OBJPERMANENTID = 0x40 + ATTR_CMN_OBJTAG = 0x10 + ATTR_CMN_OBJTYPE = 0x8 + ATTR_CMN_OWNERID = 0x8000 + ATTR_CMN_PARENTID = 0x4000000 + ATTR_CMN_PAROBJID = 0x80 + ATTR_CMN_RETURNED_ATTRS = 0x80000000 + ATTR_CMN_SCRIPT = 0x100 + ATTR_CMN_SETMASK = 0x51c7ff00 + ATTR_CMN_USERACCESS = 0x200000 + ATTR_CMN_UUID = 0x800000 + ATTR_CMN_VALIDMASK = 0xffffffff + ATTR_CMN_VOLSETMASK = 0x6700 + ATTR_FILE_ALLOCSIZE = 0x4 + ATTR_FILE_CLUMPSIZE = 0x10 + ATTR_FILE_DATAALLOCSIZE = 0x400 + ATTR_FILE_DATAEXTENTS = 0x800 + ATTR_FILE_DATALENGTH = 0x200 + ATTR_FILE_DEVTYPE = 0x20 + ATTR_FILE_FILETYPE = 0x40 + ATTR_FILE_FORKCOUNT = 0x80 + ATTR_FILE_FORKLIST = 0x100 + ATTR_FILE_IOBLOCKSIZE = 0x8 + ATTR_FILE_LINKCOUNT = 0x1 + ATTR_FILE_RSRCALLOCSIZE = 0x2000 + ATTR_FILE_RSRCEXTENTS = 0x4000 + ATTR_FILE_RSRCLENGTH = 0x1000 + ATTR_FILE_SETMASK = 0x20 + ATTR_FILE_TOTALSIZE = 0x2 + ATTR_FILE_VALIDMASK = 0x37ff + ATTR_VOL_ALLOCATIONCLUMP = 0x40 + ATTR_VOL_ATTRIBUTES = 0x40000000 + ATTR_VOL_CAPABILITIES = 0x20000 + ATTR_VOL_DIRCOUNT = 0x400 + ATTR_VOL_ENCODINGSUSED = 0x10000 + ATTR_VOL_FILECOUNT = 0x200 + ATTR_VOL_FSTYPE = 0x1 + ATTR_VOL_INFO = 0x80000000 + ATTR_VOL_IOBLOCKSIZE = 0x80 + ATTR_VOL_MAXOBJCOUNT = 0x800 + ATTR_VOL_MINALLOCATION = 0x20 + ATTR_VOL_MOUNTEDDEVICE = 0x8000 + ATTR_VOL_MOUNTFLAGS = 0x4000 + ATTR_VOL_MOUNTPOINT = 0x1000 + ATTR_VOL_NAME = 0x2000 + ATTR_VOL_OBJCOUNT = 0x100 + ATTR_VOL_QUOTA_SIZE = 0x10000000 + ATTR_VOL_RESERVED_SIZE = 0x20000000 + ATTR_VOL_SETMASK = 0x80002000 + ATTR_VOL_SIGNATURE = 0x2 + ATTR_VOL_SIZE = 0x4 + ATTR_VOL_SPACEAVAIL = 0x10 + ATTR_VOL_SPACEFREE = 0x8 + ATTR_VOL_SPACEUSED = 0x800000 + ATTR_VOL_UUID = 0x40000 + ATTR_VOL_VALIDMASK = 0xf087ffff + B0 = 0x0 + B110 = 0x6e + B115200 = 0x1c200 + B1200 = 0x4b0 + B134 = 0x86 + B14400 = 0x3840 + B150 = 0x96 + B1800 = 0x708 + B19200 = 0x4b00 + B200 = 0xc8 + B230400 = 0x38400 + B2400 = 0x960 + B28800 = 0x7080 + B300 = 0x12c + B38400 = 0x9600 + B4800 = 0x12c0 + B50 = 0x32 + B57600 = 0xe100 + B600 = 0x258 + B7200 = 0x1c20 + B75 = 0x4b + B76800 = 0x12c00 + B9600 = 0x2580 + BIOCFLUSH = 0x20004268 + BIOCGBLEN = 0x40044266 + BIOCGDLT = 0x4004426a + BIOCGDLTLIST = 0xc00c4279 + BIOCGETIF = 0x4020426b + BIOCGHDRCMPLT = 0x40044274 + BIOCGRSIG = 0x40044272 + BIOCGRTIMEOUT = 0x4010426e + BIOCGSEESENT = 0x40044276 + BIOCGSTATS = 0x4008426f + BIOCIMMEDIATE = 0x80044270 + BIOCPROMISC = 0x20004269 + BIOCSBLEN = 0xc0044266 + BIOCSDLT = 0x80044278 + BIOCSETF = 0x80104267 + BIOCSETFNR = 0x8010427e + BIOCSETIF = 0x8020426c + BIOCSHDRCMPLT = 0x80044275 + BIOCSRSIG = 0x80044273 + BIOCSRTIMEOUT = 0x8010426d + BIOCSSEESENT = 0x80044277 + BIOCVERSION = 0x40044271 + BPF_A = 0x10 + BPF_ABS = 0x20 + BPF_ADD = 0x0 + BPF_ALIGNMENT = 0x4 + BPF_ALU = 0x4 + BPF_AND = 0x50 + BPF_B = 0x10 + BPF_DIV = 0x30 + BPF_H = 0x8 + BPF_IMM = 0x0 + BPF_IND = 0x40 + BPF_JA = 0x0 + BPF_JEQ = 0x10 + BPF_JGE = 0x30 + BPF_JGT = 0x20 + BPF_JMP = 0x5 + BPF_JSET = 0x40 + BPF_K = 0x0 + BPF_LD = 0x0 + BPF_LDX = 0x1 + BPF_LEN = 0x80 + BPF_LSH = 0x60 + BPF_MAJOR_VERSION = 0x1 + BPF_MAXBUFSIZE = 0x80000 + BPF_MAXINSNS = 0x200 + BPF_MEM = 0x60 + BPF_MEMWORDS = 0x10 + BPF_MINBUFSIZE = 0x20 + BPF_MINOR_VERSION = 0x1 + BPF_MISC = 0x7 + BPF_MSH = 0xa0 + BPF_MUL = 0x20 + BPF_NEG = 0x80 + BPF_OR = 0x40 + BPF_RELEASE = 0x30bb6 + BPF_RET = 0x6 + BPF_RSH = 0x70 + BPF_ST = 0x2 + BPF_STX = 0x3 + BPF_SUB = 0x10 + BPF_TAX = 0x0 + BPF_TXA = 0x80 + BPF_W = 0x0 + BPF_X = 0x8 + BRKINT = 0x2 + BS0 = 0x0 + BS1 = 0x8000 + BSDLY = 0x8000 + CFLUSH = 0xf + CLOCAL = 0x8000 + CLOCK_MONOTONIC = 0x6 + CLOCK_MONOTONIC_RAW = 0x4 + CLOCK_MONOTONIC_RAW_APPROX = 0x5 + CLOCK_PROCESS_CPUTIME_ID = 0xc + CLOCK_REALTIME = 0x0 + CLOCK_THREAD_CPUTIME_ID = 0x10 + CLOCK_UPTIME_RAW = 0x8 + CLOCK_UPTIME_RAW_APPROX = 0x9 + CLONE_NOFOLLOW = 0x1 + CLONE_NOOWNERCOPY = 0x2 + CR0 = 0x0 + CR1 = 0x1000 + CR2 = 0x2000 + CR3 = 0x3000 + CRDLY = 0x3000 + CREAD = 0x800 + CRTSCTS = 0x30000 + CS5 = 0x0 + CS6 = 0x100 + CS7 = 0x200 + CS8 = 0x300 + CSIZE = 0x300 + CSTART = 0x11 + CSTATUS = 0x14 + CSTOP = 0x13 + CSTOPB = 0x400 + CSUSP = 0x1a + CTLIOCGINFO = 0xc0644e03 + CTL_HW = 0x6 + CTL_KERN = 0x1 + CTL_MAXNAME = 0xc + CTL_NET = 0x4 + DLT_A429 = 0xb8 + DLT_A653_ICM = 0xb9 + DLT_AIRONET_HEADER = 0x78 + DLT_AOS = 0xde + DLT_APPLE_IP_OVER_IEEE1394 = 0x8a + DLT_ARCNET = 0x7 + DLT_ARCNET_LINUX = 0x81 + DLT_ATM_CLIP = 0x13 + DLT_ATM_RFC1483 = 0xb + DLT_AURORA = 0x7e + DLT_AX25 = 0x3 + DLT_AX25_KISS = 0xca + DLT_BACNET_MS_TP = 0xa5 + DLT_BLUETOOTH_HCI_H4 = 0xbb + DLT_BLUETOOTH_HCI_H4_WITH_PHDR = 0xc9 + DLT_CAN20B = 0xbe + DLT_CAN_SOCKETCAN = 0xe3 + DLT_CHAOS = 0x5 + DLT_CHDLC = 0x68 + DLT_CISCO_IOS = 0x76 + DLT_C_HDLC = 0x68 + DLT_C_HDLC_WITH_DIR = 0xcd + DLT_DBUS = 0xe7 + DLT_DECT = 0xdd + DLT_DOCSIS = 0x8f + DLT_DVB_CI = 0xeb + DLT_ECONET = 0x73 + DLT_EN10MB = 0x1 + DLT_EN3MB = 0x2 + DLT_ENC = 0x6d + DLT_ERF = 0xc5 + DLT_ERF_ETH = 0xaf + DLT_ERF_POS = 0xb0 + DLT_FC_2 = 0xe0 + DLT_FC_2_WITH_FRAME_DELIMS = 0xe1 + DLT_FDDI = 0xa + DLT_FLEXRAY = 0xd2 + DLT_FRELAY = 0x6b + DLT_FRELAY_WITH_DIR = 0xce + DLT_GCOM_SERIAL = 0xad + DLT_GCOM_T1E1 = 0xac + DLT_GPF_F = 0xab + DLT_GPF_T = 0xaa + DLT_GPRS_LLC = 0xa9 + DLT_GSMTAP_ABIS = 0xda + DLT_GSMTAP_UM = 0xd9 + DLT_HHDLC = 0x79 + DLT_IBM_SN = 0x92 + DLT_IBM_SP = 0x91 + DLT_IEEE802 = 0x6 + DLT_IEEE802_11 = 0x69 + DLT_IEEE802_11_RADIO = 0x7f + DLT_IEEE802_11_RADIO_AVS = 0xa3 + DLT_IEEE802_15_4 = 0xc3 + DLT_IEEE802_15_4_LINUX = 0xbf + DLT_IEEE802_15_4_NOFCS = 0xe6 + DLT_IEEE802_15_4_NONASK_PHY = 0xd7 + DLT_IEEE802_16_MAC_CPS = 0xbc + DLT_IEEE802_16_MAC_CPS_RADIO = 0xc1 + DLT_IPFILTER = 0x74 + DLT_IPMB = 0xc7 + DLT_IPMB_LINUX = 0xd1 + DLT_IPNET = 0xe2 + DLT_IPOIB = 0xf2 + DLT_IPV4 = 0xe4 + DLT_IPV6 = 0xe5 + DLT_IP_OVER_FC = 0x7a + DLT_JUNIPER_ATM1 = 0x89 + DLT_JUNIPER_ATM2 = 0x87 + DLT_JUNIPER_ATM_CEMIC = 0xee + DLT_JUNIPER_CHDLC = 0xb5 + DLT_JUNIPER_ES = 0x84 + DLT_JUNIPER_ETHER = 0xb2 + DLT_JUNIPER_FIBRECHANNEL = 0xea + DLT_JUNIPER_FRELAY = 0xb4 + DLT_JUNIPER_GGSN = 0x85 + DLT_JUNIPER_ISM = 0xc2 + DLT_JUNIPER_MFR = 0x86 + DLT_JUNIPER_MLFR = 0x83 + DLT_JUNIPER_MLPPP = 0x82 + DLT_JUNIPER_MONITOR = 0xa4 + DLT_JUNIPER_PIC_PEER = 0xae + DLT_JUNIPER_PPP = 0xb3 + DLT_JUNIPER_PPPOE = 0xa7 + DLT_JUNIPER_PPPOE_ATM = 0xa8 + DLT_JUNIPER_SERVICES = 0x88 + DLT_JUNIPER_SRX_E2E = 0xe9 + DLT_JUNIPER_ST = 0xc8 + DLT_JUNIPER_VP = 0xb7 + DLT_JUNIPER_VS = 0xe8 + DLT_LAPB_WITH_DIR = 0xcf + DLT_LAPD = 0xcb + DLT_LIN = 0xd4 + DLT_LINUX_EVDEV = 0xd8 + DLT_LINUX_IRDA = 0x90 + DLT_LINUX_LAPD = 0xb1 + DLT_LINUX_PPP_WITHDIRECTION = 0xa6 + DLT_LINUX_SLL = 0x71 + DLT_LOOP = 0x6c + DLT_LTALK = 0x72 + DLT_MATCHING_MAX = 0x10a + DLT_MATCHING_MIN = 0x68 + DLT_MFR = 0xb6 + DLT_MOST = 0xd3 + DLT_MPEG_2_TS = 0xf3 + DLT_MPLS = 0xdb + DLT_MTP2 = 0x8c + DLT_MTP2_WITH_PHDR = 0x8b + DLT_MTP3 = 0x8d + DLT_MUX27010 = 0xec + DLT_NETANALYZER = 0xf0 + DLT_NETANALYZER_TRANSPARENT = 0xf1 + DLT_NFC_LLCP = 0xf5 + DLT_NFLOG = 0xef + DLT_NG40 = 0xf4 + DLT_NULL = 0x0 + DLT_PCI_EXP = 0x7d + DLT_PFLOG = 0x75 + DLT_PFSYNC = 0x12 + DLT_PPI = 0xc0 + DLT_PPP = 0x9 + DLT_PPP_BSDOS = 0x10 + DLT_PPP_ETHER = 0x33 + DLT_PPP_PPPD = 0xa6 + DLT_PPP_SERIAL = 0x32 + DLT_PPP_WITH_DIR = 0xcc + DLT_PPP_WITH_DIRECTION = 0xa6 + DLT_PRISM_HEADER = 0x77 + DLT_PRONET = 0x4 + DLT_RAIF1 = 0xc6 + DLT_RAW = 0xc + DLT_RIO = 0x7c + DLT_SCCP = 0x8e + DLT_SITA = 0xc4 + DLT_SLIP = 0x8 + DLT_SLIP_BSDOS = 0xf + DLT_STANAG_5066_D_PDU = 0xed + DLT_SUNATM = 0x7b + DLT_SYMANTEC_FIREWALL = 0x63 + DLT_TZSP = 0x80 + DLT_USB = 0xba + DLT_USB_DARWIN = 0x10a + DLT_USB_LINUX = 0xbd + DLT_USB_LINUX_MMAPPED = 0xdc + DLT_USER0 = 0x93 + DLT_USER1 = 0x94 + DLT_USER10 = 0x9d + DLT_USER11 = 0x9e + DLT_USER12 = 0x9f + DLT_USER13 = 0xa0 + DLT_USER14 = 0xa1 + DLT_USER15 = 0xa2 + DLT_USER2 = 0x95 + DLT_USER3 = 0x96 + DLT_USER4 = 0x97 + DLT_USER5 = 0x98 + DLT_USER6 = 0x99 + DLT_USER7 = 0x9a + DLT_USER8 = 0x9b + DLT_USER9 = 0x9c + DLT_WIHART = 0xdf + DLT_X2E_SERIAL = 0xd5 + DLT_X2E_XORAYA = 0xd6 + DT_BLK = 0x6 + DT_CHR = 0x2 + DT_DIR = 0x4 + DT_FIFO = 0x1 + DT_LNK = 0xa + DT_REG = 0x8 + DT_SOCK = 0xc + DT_UNKNOWN = 0x0 + DT_WHT = 0xe + ECHO = 0x8 + ECHOCTL = 0x40 + ECHOE = 0x2 + ECHOK = 0x4 + ECHOKE = 0x1 + ECHONL = 0x10 + ECHOPRT = 0x20 + EVFILT_AIO = -0x3 + EVFILT_EXCEPT = -0xf + EVFILT_FS = -0x9 + EVFILT_MACHPORT = -0x8 + EVFILT_PROC = -0x5 + EVFILT_READ = -0x1 + EVFILT_SIGNAL = -0x6 + EVFILT_SYSCOUNT = 0x11 + EVFILT_THREADMARKER = 0x11 + EVFILT_TIMER = -0x7 + EVFILT_USER = -0xa + EVFILT_VM = -0xc + EVFILT_VNODE = -0x4 + EVFILT_WRITE = -0x2 + EV_ADD = 0x1 + EV_CLEAR = 0x20 + EV_DELETE = 0x2 + EV_DISABLE = 0x8 + EV_DISPATCH = 0x80 + EV_DISPATCH2 = 0x180 + EV_ENABLE = 0x4 + EV_EOF = 0x8000 + EV_ERROR = 0x4000 + EV_FLAG0 = 0x1000 + EV_FLAG1 = 0x2000 + EV_ONESHOT = 0x10 + EV_OOBAND = 0x2000 + EV_POLL = 0x1000 + EV_RECEIPT = 0x40 + EV_SYSFLAGS = 0xf000 + EV_UDATA_SPECIFIC = 0x100 + EV_VANISHED = 0x200 + EXTA = 0x4b00 + EXTB = 0x9600 + EXTPROC = 0x800 + FD_CLOEXEC = 0x1 + FD_SETSIZE = 0x400 + FF0 = 0x0 + FF1 = 0x4000 + FFDLY = 0x4000 + FLUSHO = 0x800000 + FSOPT_ATTR_CMN_EXTENDED = 0x20 + FSOPT_NOFOLLOW = 0x1 + FSOPT_NOINMEMUPDATE = 0x2 + FSOPT_PACK_INVAL_ATTRS = 0x8 + FSOPT_REPORT_FULLSIZE = 0x4 + FSOPT_RETURN_REALDEV = 0x200 + F_ADDFILESIGS = 0x3d + F_ADDFILESIGS_FOR_DYLD_SIM = 0x53 + F_ADDFILESIGS_INFO = 0x67 + F_ADDFILESIGS_RETURN = 0x61 + F_ADDFILESUPPL = 0x68 + F_ADDSIGS = 0x3b + F_ALLOCATEALL = 0x4 + F_ALLOCATECONTIG = 0x2 + F_BARRIERFSYNC = 0x55 + F_CHECK_LV = 0x62 + F_CHKCLEAN = 0x29 + F_DUPFD = 0x0 + F_DUPFD_CLOEXEC = 0x43 + F_FINDSIGS = 0x4e + F_FLUSH_DATA = 0x28 + F_FREEZE_FS = 0x35 + F_FULLFSYNC = 0x33 + F_GETCODEDIR = 0x48 + F_GETFD = 0x1 + F_GETFL = 0x3 + F_GETLK = 0x7 + F_GETLKPID = 0x42 + F_GETNOSIGPIPE = 0x4a + F_GETOWN = 0x5 + F_GETPATH = 0x32 + F_GETPATH_MTMINFO = 0x47 + F_GETPATH_NOFIRMLINK = 0x66 + F_GETPROTECTIONCLASS = 0x3f + F_GETPROTECTIONLEVEL = 0x4d + F_GETSIGSINFO = 0x69 + F_GLOBAL_NOCACHE = 0x37 + F_LOG2PHYS = 0x31 + F_LOG2PHYS_EXT = 0x41 + F_NOCACHE = 0x30 + F_NODIRECT = 0x3e + F_OK = 0x0 + F_PATHPKG_CHECK = 0x34 + F_PEOFPOSMODE = 0x3 + F_PREALLOCATE = 0x2a + F_PUNCHHOLE = 0x63 + F_RDADVISE = 0x2c + F_RDAHEAD = 0x2d + F_RDLCK = 0x1 + F_SETBACKINGSTORE = 0x46 + F_SETFD = 0x2 + F_SETFL = 0x4 + F_SETLK = 0x8 + F_SETLKW = 0x9 + F_SETLKWTIMEOUT = 0xa + F_SETNOSIGPIPE = 0x49 + F_SETOWN = 0x6 + F_SETPROTECTIONCLASS = 0x40 + F_SETSIZE = 0x2b + F_SINGLE_WRITER = 0x4c + F_SPECULATIVE_READ = 0x65 + F_THAW_FS = 0x36 + F_TRANSCODEKEY = 0x4b + F_TRIM_ACTIVE_FILE = 0x64 + F_UNLCK = 0x2 + F_VOLPOSMODE = 0x4 + F_WRLCK = 0x3 + HUPCL = 0x4000 + HW_MACHINE = 0x1 + ICANON = 0x100 + ICMP6_FILTER = 0x12 + ICRNL = 0x100 + IEXTEN = 0x400 + IFF_ALLMULTI = 0x200 + IFF_ALTPHYS = 0x4000 + IFF_BROADCAST = 0x2 + IFF_DEBUG = 0x4 + IFF_LINK0 = 0x1000 + IFF_LINK1 = 0x2000 + IFF_LINK2 = 0x4000 + IFF_LOOPBACK = 0x8 + IFF_MULTICAST = 0x8000 + IFF_NOARP = 0x80 + IFF_NOTRAILERS = 0x20 + IFF_OACTIVE = 0x400 + IFF_POINTOPOINT = 0x10 + IFF_PROMISC = 0x100 + IFF_RUNNING = 0x40 + IFF_SIMPLEX = 0x800 + IFF_UP = 0x1 + IFNAMSIZ = 0x10 + IFT_1822 = 0x2 + IFT_6LOWPAN = 0x40 + IFT_AAL5 = 0x31 + IFT_ARCNET = 0x23 + IFT_ARCNETPLUS = 0x24 + IFT_ATM = 0x25 + IFT_BRIDGE = 0xd1 + IFT_CARP = 0xf8 + IFT_CELLULAR = 0xff + IFT_CEPT = 0x13 + IFT_DS3 = 0x1e + IFT_ENC = 0xf4 + IFT_EON = 0x19 + IFT_ETHER = 0x6 + IFT_FAITH = 0x38 + IFT_FDDI = 0xf + IFT_FRELAY = 0x20 + IFT_FRELAYDCE = 0x2c + IFT_GIF = 0x37 + IFT_HDH1822 = 0x3 + IFT_HIPPI = 0x2f + IFT_HSSI = 0x2e + IFT_HY = 0xe + IFT_IEEE1394 = 0x90 + IFT_IEEE8023ADLAG = 0x88 + IFT_ISDNBASIC = 0x14 + IFT_ISDNPRIMARY = 0x15 + IFT_ISO88022LLC = 0x29 + IFT_ISO88023 = 0x7 + IFT_ISO88024 = 0x8 + IFT_ISO88025 = 0x9 + IFT_ISO88026 = 0xa + IFT_L2VLAN = 0x87 + IFT_LAPB = 0x10 + IFT_LOCALTALK = 0x2a + IFT_LOOP = 0x18 + IFT_MIOX25 = 0x26 + IFT_MODEM = 0x30 + IFT_NSIP = 0x1b + IFT_OTHER = 0x1 + IFT_P10 = 0xc + IFT_P80 = 0xd + IFT_PARA = 0x22 + IFT_PDP = 0xff + IFT_PFLOG = 0xf5 + IFT_PFSYNC = 0xf6 + IFT_PKTAP = 0xfe + IFT_PPP = 0x17 + IFT_PROPMUX = 0x36 + IFT_PROPVIRTUAL = 0x35 + IFT_PTPSERIAL = 0x16 + IFT_RS232 = 0x21 + IFT_SDLC = 0x11 + IFT_SIP = 0x1f + IFT_SLIP = 0x1c + IFT_SMDSDXI = 0x2b + IFT_SMDSICIP = 0x34 + IFT_SONET = 0x27 + IFT_SONETPATH = 0x32 + IFT_SONETVT = 0x33 + IFT_STARLAN = 0xb + IFT_STF = 0x39 + IFT_T1 = 0x12 + IFT_ULTRA = 0x1d + IFT_V35 = 0x2d + IFT_X25 = 0x5 + IFT_X25DDN = 0x4 + IFT_X25PLE = 0x28 + IFT_XETHER = 0x1a + IGNBRK = 0x1 + IGNCR = 0x80 + IGNPAR = 0x4 + IMAXBEL = 0x2000 + INLCR = 0x40 + INPCK = 0x10 + IN_CLASSA_HOST = 0xffffff + IN_CLASSA_MAX = 0x80 + IN_CLASSA_NET = 0xff000000 + IN_CLASSA_NSHIFT = 0x18 + IN_CLASSB_HOST = 0xffff + IN_CLASSB_MAX = 0x10000 + IN_CLASSB_NET = 0xffff0000 + IN_CLASSB_NSHIFT = 0x10 + IN_CLASSC_HOST = 0xff + IN_CLASSC_NET = 0xffffff00 + IN_CLASSC_NSHIFT = 0x8 + IN_CLASSD_HOST = 0xfffffff + IN_CLASSD_NET = 0xf0000000 + IN_CLASSD_NSHIFT = 0x1c + IN_LINKLOCALNETNUM = 0xa9fe0000 + IN_LOOPBACKNET = 0x7f + IOCTL_VM_SOCKETS_GET_LOCAL_CID = 0x400473d1 + IPPROTO_3PC = 0x22 + IPPROTO_ADFS = 0x44 + IPPROTO_AH = 0x33 + IPPROTO_AHIP = 0x3d + IPPROTO_APES = 0x63 + IPPROTO_ARGUS = 0xd + IPPROTO_AX25 = 0x5d + IPPROTO_BHA = 0x31 + IPPROTO_BLT = 0x1e + IPPROTO_BRSATMON = 0x4c + IPPROTO_CFTP = 0x3e + IPPROTO_CHAOS = 0x10 + IPPROTO_CMTP = 0x26 + IPPROTO_CPHB = 0x49 + IPPROTO_CPNX = 0x48 + IPPROTO_DDP = 0x25 + IPPROTO_DGP = 0x56 + IPPROTO_DIVERT = 0xfe + IPPROTO_DONE = 0x101 + IPPROTO_DSTOPTS = 0x3c + IPPROTO_EGP = 0x8 + IPPROTO_EMCON = 0xe + IPPROTO_ENCAP = 0x62 + IPPROTO_EON = 0x50 + IPPROTO_ESP = 0x32 + IPPROTO_ETHERIP = 0x61 + IPPROTO_FRAGMENT = 0x2c + IPPROTO_GGP = 0x3 + IPPROTO_GMTP = 0x64 + IPPROTO_GRE = 0x2f + IPPROTO_HELLO = 0x3f + IPPROTO_HMP = 0x14 + IPPROTO_HOPOPTS = 0x0 + IPPROTO_ICMP = 0x1 + IPPROTO_ICMPV6 = 0x3a + IPPROTO_IDP = 0x16 + IPPROTO_IDPR = 0x23 + IPPROTO_IDRP = 0x2d + IPPROTO_IGMP = 0x2 + IPPROTO_IGP = 0x55 + IPPROTO_IGRP = 0x58 + IPPROTO_IL = 0x28 + IPPROTO_INLSP = 0x34 + IPPROTO_INP = 0x20 + IPPROTO_IP = 0x0 + IPPROTO_IPCOMP = 0x6c + IPPROTO_IPCV = 0x47 + IPPROTO_IPEIP = 0x5e + IPPROTO_IPIP = 0x4 + IPPROTO_IPPC = 0x43 + IPPROTO_IPV4 = 0x4 + IPPROTO_IPV6 = 0x29 + IPPROTO_IRTP = 0x1c + IPPROTO_KRYPTOLAN = 0x41 + IPPROTO_LARP = 0x5b + IPPROTO_LEAF1 = 0x19 + IPPROTO_LEAF2 = 0x1a + IPPROTO_MAX = 0x100 + IPPROTO_MAXID = 0x34 + IPPROTO_MEAS = 0x13 + IPPROTO_MHRP = 0x30 + IPPROTO_MICP = 0x5f + IPPROTO_MTP = 0x5c + IPPROTO_MUX = 0x12 + IPPROTO_ND = 0x4d + IPPROTO_NHRP = 0x36 + IPPROTO_NONE = 0x3b + IPPROTO_NSP = 0x1f + IPPROTO_NVPII = 0xb + IPPROTO_OSPFIGP = 0x59 + IPPROTO_PGM = 0x71 + IPPROTO_PIGP = 0x9 + IPPROTO_PIM = 0x67 + IPPROTO_PRM = 0x15 + IPPROTO_PUP = 0xc + IPPROTO_PVP = 0x4b + IPPROTO_RAW = 0xff + IPPROTO_RCCMON = 0xa + IPPROTO_RDP = 0x1b + IPPROTO_ROUTING = 0x2b + IPPROTO_RSVP = 0x2e + IPPROTO_RVD = 0x42 + IPPROTO_SATEXPAK = 0x40 + IPPROTO_SATMON = 0x45 + IPPROTO_SCCSP = 0x60 + IPPROTO_SCTP = 0x84 + IPPROTO_SDRP = 0x2a + IPPROTO_SEP = 0x21 + IPPROTO_SRPC = 0x5a + IPPROTO_ST = 0x7 + IPPROTO_SVMTP = 0x52 + IPPROTO_SWIPE = 0x35 + IPPROTO_TCF = 0x57 + IPPROTO_TCP = 0x6 + IPPROTO_TP = 0x1d + IPPROTO_TPXX = 0x27 + IPPROTO_TRUNK1 = 0x17 + IPPROTO_TRUNK2 = 0x18 + IPPROTO_TTP = 0x54 + IPPROTO_UDP = 0x11 + IPPROTO_VINES = 0x53 + IPPROTO_VISA = 0x46 + IPPROTO_VMTP = 0x51 + IPPROTO_WBEXPAK = 0x4f + IPPROTO_WBMON = 0x4e + IPPROTO_WSN = 0x4a + IPPROTO_XNET = 0xf + IPPROTO_XTP = 0x24 + IPV6_2292DSTOPTS = 0x17 + IPV6_2292HOPLIMIT = 0x14 + IPV6_2292HOPOPTS = 0x16 + IPV6_2292NEXTHOP = 0x15 + IPV6_2292PKTINFO = 0x13 + IPV6_2292PKTOPTIONS = 0x19 + IPV6_2292RTHDR = 0x18 + IPV6_3542DSTOPTS = 0x32 + IPV6_3542HOPLIMIT = 0x2f + IPV6_3542HOPOPTS = 0x31 + IPV6_3542NEXTHOP = 0x30 + IPV6_3542PKTINFO = 0x2e + IPV6_3542RTHDR = 0x33 + IPV6_ADDR_MC_FLAGS_PREFIX = 0x20 + IPV6_ADDR_MC_FLAGS_TRANSIENT = 0x10 + IPV6_ADDR_MC_FLAGS_UNICAST_BASED = 0x30 + IPV6_AUTOFLOWLABEL = 0x3b + IPV6_BINDV6ONLY = 0x1b + IPV6_BOUND_IF = 0x7d + IPV6_CHECKSUM = 0x1a + IPV6_DEFAULT_MULTICAST_HOPS = 0x1 + IPV6_DEFAULT_MULTICAST_LOOP = 0x1 + IPV6_DEFHLIM = 0x40 + IPV6_DONTFRAG = 0x3e + IPV6_DSTOPTS = 0x32 + IPV6_FAITH = 0x1d + IPV6_FLOWINFO_MASK = 0xffffff0f + IPV6_FLOWLABEL_MASK = 0xffff0f00 + IPV6_FLOW_ECN_MASK = 0x3000 + IPV6_FRAGTTL = 0x3c + IPV6_FW_ADD = 0x1e + IPV6_FW_DEL = 0x1f + IPV6_FW_FLUSH = 0x20 + IPV6_FW_GET = 0x22 + IPV6_FW_ZERO = 0x21 + IPV6_HLIMDEC = 0x1 + IPV6_HOPLIMIT = 0x2f + IPV6_HOPOPTS = 0x31 + IPV6_IPSEC_POLICY = 0x1c + IPV6_JOIN_GROUP = 0xc + IPV6_LEAVE_GROUP = 0xd + IPV6_MAXHLIM = 0xff + IPV6_MAXOPTHDR = 0x800 + IPV6_MAXPACKET = 0xffff + IPV6_MAX_GROUP_SRC_FILTER = 0x200 + IPV6_MAX_MEMBERSHIPS = 0xfff + IPV6_MAX_SOCK_SRC_FILTER = 0x80 + IPV6_MIN_MEMBERSHIPS = 0x1f + IPV6_MMTU = 0x500 + IPV6_MSFILTER = 0x4a + IPV6_MULTICAST_HOPS = 0xa + IPV6_MULTICAST_IF = 0x9 + IPV6_MULTICAST_LOOP = 0xb + IPV6_NEXTHOP = 0x30 + IPV6_PATHMTU = 0x2c + IPV6_PKTINFO = 0x2e + IPV6_PORTRANGE = 0xe + IPV6_PORTRANGE_DEFAULT = 0x0 + IPV6_PORTRANGE_HIGH = 0x1 + IPV6_PORTRANGE_LOW = 0x2 + IPV6_PREFER_TEMPADDR = 0x3f + IPV6_RECVDSTOPTS = 0x28 + IPV6_RECVHOPLIMIT = 0x25 + IPV6_RECVHOPOPTS = 0x27 + IPV6_RECVPATHMTU = 0x2b + IPV6_RECVPKTINFO = 0x3d + IPV6_RECVRTHDR = 0x26 + IPV6_RECVTCLASS = 0x23 + IPV6_RTHDR = 0x33 + IPV6_RTHDRDSTOPTS = 0x39 + IPV6_RTHDR_LOOSE = 0x0 + IPV6_RTHDR_STRICT = 0x1 + IPV6_RTHDR_TYPE_0 = 0x0 + IPV6_SOCKOPT_RESERVED1 = 0x3 + IPV6_TCLASS = 0x24 + IPV6_UNICAST_HOPS = 0x4 + IPV6_USE_MIN_MTU = 0x2a + IPV6_V6ONLY = 0x1b + IPV6_VERSION = 0x60 + IPV6_VERSION_MASK = 0xf0 + IP_ADD_MEMBERSHIP = 0xc + IP_ADD_SOURCE_MEMBERSHIP = 0x46 + IP_BLOCK_SOURCE = 0x48 + IP_BOUND_IF = 0x19 + IP_DEFAULT_MULTICAST_LOOP = 0x1 + IP_DEFAULT_MULTICAST_TTL = 0x1 + IP_DF = 0x4000 + IP_DONTFRAG = 0x1c + IP_DROP_MEMBERSHIP = 0xd + IP_DROP_SOURCE_MEMBERSHIP = 0x47 + IP_DUMMYNET_CONFIGURE = 0x3c + IP_DUMMYNET_DEL = 0x3d + IP_DUMMYNET_FLUSH = 0x3e + IP_DUMMYNET_GET = 0x40 + IP_FAITH = 0x16 + IP_FW_ADD = 0x28 + IP_FW_DEL = 0x29 + IP_FW_FLUSH = 0x2a + IP_FW_GET = 0x2c + IP_FW_RESETLOG = 0x2d + IP_FW_ZERO = 0x2b + IP_HDRINCL = 0x2 + IP_IPSEC_POLICY = 0x15 + IP_MAXPACKET = 0xffff + IP_MAX_GROUP_SRC_FILTER = 0x200 + IP_MAX_MEMBERSHIPS = 0xfff + IP_MAX_SOCK_MUTE_FILTER = 0x80 + IP_MAX_SOCK_SRC_FILTER = 0x80 + IP_MF = 0x2000 + IP_MIN_MEMBERSHIPS = 0x1f + IP_MSFILTER = 0x4a + IP_MSS = 0x240 + IP_MULTICAST_IF = 0x9 + IP_MULTICAST_IFINDEX = 0x42 + IP_MULTICAST_LOOP = 0xb + IP_MULTICAST_TTL = 0xa + IP_MULTICAST_VIF = 0xe + IP_NAT__XXX = 0x37 + IP_OFFMASK = 0x1fff + IP_OLD_FW_ADD = 0x32 + IP_OLD_FW_DEL = 0x33 + IP_OLD_FW_FLUSH = 0x34 + IP_OLD_FW_GET = 0x36 + IP_OLD_FW_RESETLOG = 0x38 + IP_OLD_FW_ZERO = 0x35 + IP_OPTIONS = 0x1 + IP_PKTINFO = 0x1a + IP_PORTRANGE = 0x13 + IP_PORTRANGE_DEFAULT = 0x0 + IP_PORTRANGE_HIGH = 0x1 + IP_PORTRANGE_LOW = 0x2 + IP_RECVDSTADDR = 0x7 + IP_RECVIF = 0x14 + IP_RECVOPTS = 0x5 + IP_RECVPKTINFO = 0x1a + IP_RECVRETOPTS = 0x6 + IP_RECVTOS = 0x1b + IP_RECVTTL = 0x18 + IP_RETOPTS = 0x8 + IP_RF = 0x8000 + IP_RSVP_OFF = 0x10 + IP_RSVP_ON = 0xf + IP_RSVP_VIF_OFF = 0x12 + IP_RSVP_VIF_ON = 0x11 + IP_STRIPHDR = 0x17 + IP_TOS = 0x3 + IP_TRAFFIC_MGT_BACKGROUND = 0x41 + IP_TTL = 0x4 + IP_UNBLOCK_SOURCE = 0x49 + ISIG = 0x80 + ISTRIP = 0x20 + IUTF8 = 0x4000 + IXANY = 0x800 + IXOFF = 0x400 + IXON = 0x200 + KERN_HOSTNAME = 0xa + KERN_OSRELEASE = 0x2 + KERN_OSTYPE = 0x1 + KERN_VERSION = 0x4 + LOCAL_PEERCRED = 0x1 + LOCAL_PEEREPID = 0x3 + LOCAL_PEEREUUID = 0x5 + LOCAL_PEERPID = 0x2 + LOCAL_PEERTOKEN = 0x6 + LOCAL_PEERUUID = 0x4 + LOCK_EX = 0x2 + LOCK_NB = 0x4 + LOCK_SH = 0x1 + LOCK_UN = 0x8 + MADV_CAN_REUSE = 0x9 + MADV_DONTNEED = 0x4 + MADV_FREE = 0x5 + MADV_FREE_REUSABLE = 0x7 + MADV_FREE_REUSE = 0x8 + MADV_NORMAL = 0x0 + MADV_PAGEOUT = 0xa + MADV_RANDOM = 0x1 + MADV_SEQUENTIAL = 0x2 + MADV_WILLNEED = 0x3 + MADV_ZERO_WIRED_PAGES = 0x6 + MAP_32BIT = 0x8000 + MAP_ANON = 0x1000 + MAP_ANONYMOUS = 0x1000 + MAP_COPY = 0x2 + MAP_FILE = 0x0 + MAP_FIXED = 0x10 + MAP_HASSEMAPHORE = 0x200 + MAP_JIT = 0x800 + MAP_NOCACHE = 0x400 + MAP_NOEXTEND = 0x100 + MAP_NORESERVE = 0x40 + MAP_PRIVATE = 0x2 + MAP_RENAME = 0x20 + MAP_RESERVED0080 = 0x80 + MAP_RESILIENT_CODESIGN = 0x2000 + MAP_RESILIENT_MEDIA = 0x4000 + MAP_SHARED = 0x1 + MAP_TRANSLATED_ALLOW_EXECUTE = 0x20000 + MAP_UNIX03 = 0x40000 + MCAST_BLOCK_SOURCE = 0x54 + MCAST_EXCLUDE = 0x2 + MCAST_INCLUDE = 0x1 + MCAST_JOIN_GROUP = 0x50 + MCAST_JOIN_SOURCE_GROUP = 0x52 + MCAST_LEAVE_GROUP = 0x51 + MCAST_LEAVE_SOURCE_GROUP = 0x53 + MCAST_UNBLOCK_SOURCE = 0x55 + MCAST_UNDEFINED = 0x0 + MCL_CURRENT = 0x1 + MCL_FUTURE = 0x2 + MNT_ASYNC = 0x40 + MNT_AUTOMOUNTED = 0x400000 + MNT_CMDFLAGS = 0xf0000 + MNT_CPROTECT = 0x80 + MNT_DEFWRITE = 0x2000000 + MNT_DONTBROWSE = 0x100000 + MNT_DOVOLFS = 0x8000 + MNT_DWAIT = 0x4 + MNT_EXPORTED = 0x100 + MNT_EXT_ROOT_DATA_VOL = 0x1 + MNT_FORCE = 0x80000 + MNT_IGNORE_OWNERSHIP = 0x200000 + MNT_JOURNALED = 0x800000 + MNT_LOCAL = 0x1000 + MNT_MULTILABEL = 0x4000000 + MNT_NOATIME = 0x10000000 + MNT_NOBLOCK = 0x20000 + MNT_NODEV = 0x10 + MNT_NOEXEC = 0x4 + MNT_NOSUID = 0x8 + MNT_NOUSERXATTR = 0x1000000 + MNT_NOWAIT = 0x2 + MNT_QUARANTINE = 0x400 + MNT_QUOTA = 0x2000 + MNT_RDONLY = 0x1 + MNT_RELOAD = 0x40000 + MNT_REMOVABLE = 0x200 + MNT_ROOTFS = 0x4000 + MNT_SNAPSHOT = 0x40000000 + MNT_STRICTATIME = 0x80000000 + MNT_SYNCHRONOUS = 0x2 + MNT_UNION = 0x20 + MNT_UNKNOWNPERMISSIONS = 0x200000 + MNT_UPDATE = 0x10000 + MNT_VISFLAGMASK = 0xd7f0f7ff + MNT_WAIT = 0x1 + MSG_CTRUNC = 0x20 + MSG_DONTROUTE = 0x4 + MSG_DONTWAIT = 0x80 + MSG_EOF = 0x100 + MSG_EOR = 0x8 + MSG_FLUSH = 0x400 + MSG_HAVEMORE = 0x2000 + MSG_HOLD = 0x800 + MSG_NEEDSA = 0x10000 + MSG_NOSIGNAL = 0x80000 + MSG_OOB = 0x1 + MSG_PEEK = 0x2 + MSG_RCVMORE = 0x4000 + MSG_SEND = 0x1000 + MSG_TRUNC = 0x10 + MSG_WAITALL = 0x40 + MSG_WAITSTREAM = 0x200 + MS_ASYNC = 0x1 + MS_DEACTIVATE = 0x8 + MS_INVALIDATE = 0x2 + MS_KILLPAGES = 0x4 + MS_SYNC = 0x10 + NAME_MAX = 0xff + NET_RT_DUMP = 0x1 + NET_RT_DUMP2 = 0x7 + NET_RT_FLAGS = 0x2 + NET_RT_FLAGS_PRIV = 0xa + NET_RT_IFLIST = 0x3 + NET_RT_IFLIST2 = 0x6 + NET_RT_MAXID = 0xb + NET_RT_STAT = 0x4 + NET_RT_TRASH = 0x5 + NFDBITS = 0x20 + NL0 = 0x0 + NL1 = 0x100 + NL2 = 0x200 + NL3 = 0x300 + NLDLY = 0x300 + NOFLSH = 0x80000000 + NOKERNINFO = 0x2000000 + NOTE_ABSOLUTE = 0x8 + NOTE_ATTRIB = 0x8 + NOTE_BACKGROUND = 0x40 + NOTE_CHILD = 0x4 + NOTE_CRITICAL = 0x20 + NOTE_DELETE = 0x1 + NOTE_EXEC = 0x20000000 + NOTE_EXIT = 0x80000000 + NOTE_EXITSTATUS = 0x4000000 + NOTE_EXIT_CSERROR = 0x40000 + NOTE_EXIT_DECRYPTFAIL = 0x10000 + NOTE_EXIT_DETAIL = 0x2000000 + NOTE_EXIT_DETAIL_MASK = 0x70000 + NOTE_EXIT_MEMORY = 0x20000 + NOTE_EXIT_REPARENTED = 0x80000 + NOTE_EXTEND = 0x4 + NOTE_FFAND = 0x40000000 + NOTE_FFCOPY = 0xc0000000 + NOTE_FFCTRLMASK = 0xc0000000 + NOTE_FFLAGSMASK = 0xffffff + NOTE_FFNOP = 0x0 + NOTE_FFOR = 0x80000000 + NOTE_FORK = 0x40000000 + NOTE_FUNLOCK = 0x100 + NOTE_LEEWAY = 0x10 + NOTE_LINK = 0x10 + NOTE_LOWAT = 0x1 + NOTE_MACHTIME = 0x100 + NOTE_MACH_CONTINUOUS_TIME = 0x80 + NOTE_NONE = 0x80 + NOTE_NSECONDS = 0x4 + NOTE_OOB = 0x2 + NOTE_PCTRLMASK = -0x100000 + NOTE_PDATAMASK = 0xfffff + NOTE_REAP = 0x10000000 + NOTE_RENAME = 0x20 + NOTE_REVOKE = 0x40 + NOTE_SECONDS = 0x1 + NOTE_SIGNAL = 0x8000000 + NOTE_TRACK = 0x1 + NOTE_TRACKERR = 0x2 + NOTE_TRIGGER = 0x1000000 + NOTE_USECONDS = 0x2 + NOTE_VM_ERROR = 0x10000000 + NOTE_VM_PRESSURE = 0x80000000 + NOTE_VM_PRESSURE_SUDDEN_TERMINATE = 0x20000000 + NOTE_VM_PRESSURE_TERMINATE = 0x40000000 + NOTE_WRITE = 0x2 + OCRNL = 0x10 + OFDEL = 0x20000 + OFILL = 0x80 + ONLCR = 0x2 + ONLRET = 0x40 + ONOCR = 0x20 + ONOEOT = 0x8 + OPOST = 0x1 + OXTABS = 0x4 + O_ACCMODE = 0x3 + O_ALERT = 0x20000000 + O_APPEND = 0x8 + O_ASYNC = 0x40 + O_CLOEXEC = 0x1000000 + O_CREAT = 0x200 + O_DIRECTORY = 0x100000 + O_DP_GETRAWENCRYPTED = 0x1 + O_DP_GETRAWUNENCRYPTED = 0x2 + O_DSYNC = 0x400000 + O_EVTONLY = 0x8000 + O_EXCL = 0x800 + O_EXLOCK = 0x20 + O_FSYNC = 0x80 + O_NDELAY = 0x4 + O_NOCTTY = 0x20000 + O_NOFOLLOW = 0x100 + O_NOFOLLOW_ANY = 0x20000000 + O_NONBLOCK = 0x4 + O_POPUP = 0x80000000 + O_RDONLY = 0x0 + O_RDWR = 0x2 + O_SHLOCK = 0x10 + O_SYMLINK = 0x200000 + O_SYNC = 0x80 + O_TRUNC = 0x400 + O_WRONLY = 0x1 + PARENB = 0x1000 + PARMRK = 0x8 + PARODD = 0x2000 + PENDIN = 0x20000000 + PRIO_PGRP = 0x1 + PRIO_PROCESS = 0x0 + PRIO_USER = 0x2 + PROT_EXEC = 0x4 + PROT_NONE = 0x0 + PROT_READ = 0x1 + PROT_WRITE = 0x2 + PT_ATTACH = 0xa + PT_ATTACHEXC = 0xe + PT_CONTINUE = 0x7 + PT_DENY_ATTACH = 0x1f + PT_DETACH = 0xb + PT_FIRSTMACH = 0x20 + PT_FORCEQUOTA = 0x1e + PT_KILL = 0x8 + PT_READ_D = 0x2 + PT_READ_I = 0x1 + PT_READ_U = 0x3 + PT_SIGEXC = 0xc + PT_STEP = 0x9 + PT_THUPDATE = 0xd + PT_TRACE_ME = 0x0 + PT_WRITE_D = 0x5 + PT_WRITE_I = 0x4 + PT_WRITE_U = 0x6 + RLIMIT_AS = 0x5 + RLIMIT_CORE = 0x4 + RLIMIT_CPU = 0x0 + RLIMIT_CPU_USAGE_MONITOR = 0x2 + RLIMIT_DATA = 0x2 + RLIMIT_FSIZE = 0x1 + RLIMIT_MEMLOCK = 0x6 + RLIMIT_NOFILE = 0x8 + RLIMIT_NPROC = 0x7 + RLIMIT_RSS = 0x5 + RLIMIT_STACK = 0x3 + RLIM_INFINITY = 0x7fffffffffffffff + RTAX_AUTHOR = 0x6 + RTAX_BRD = 0x7 + RTAX_DST = 0x0 + RTAX_GATEWAY = 0x1 + RTAX_GENMASK = 0x3 + RTAX_IFA = 0x5 + RTAX_IFP = 0x4 + RTAX_MAX = 0x8 + RTAX_NETMASK = 0x2 + RTA_AUTHOR = 0x40 + RTA_BRD = 0x80 + RTA_DST = 0x1 + RTA_GATEWAY = 0x2 + RTA_GENMASK = 0x8 + RTA_IFA = 0x20 + RTA_IFP = 0x10 + RTA_NETMASK = 0x4 + RTF_BLACKHOLE = 0x1000 + RTF_BROADCAST = 0x400000 + RTF_CLONING = 0x100 + RTF_CONDEMNED = 0x2000000 + RTF_DEAD = 0x20000000 + RTF_DELCLONE = 0x80 + RTF_DONE = 0x40 + RTF_DYNAMIC = 0x10 + RTF_GATEWAY = 0x2 + RTF_GLOBAL = 0x40000000 + RTF_HOST = 0x4 + RTF_IFREF = 0x4000000 + RTF_IFSCOPE = 0x1000000 + RTF_LLDATA = 0x400 + RTF_LLINFO = 0x400 + RTF_LOCAL = 0x200000 + RTF_MODIFIED = 0x20 + RTF_MULTICAST = 0x800000 + RTF_NOIFREF = 0x2000 + RTF_PINNED = 0x100000 + RTF_PRCLONING = 0x10000 + RTF_PROTO1 = 0x8000 + RTF_PROTO2 = 0x4000 + RTF_PROTO3 = 0x40000 + RTF_PROXY = 0x8000000 + RTF_REJECT = 0x8 + RTF_ROUTER = 0x10000000 + RTF_STATIC = 0x800 + RTF_UP = 0x1 + RTF_WASCLONED = 0x20000 + RTF_XRESOLVE = 0x200 + RTM_ADD = 0x1 + RTM_CHANGE = 0x3 + RTM_DELADDR = 0xd + RTM_DELETE = 0x2 + RTM_DELMADDR = 0x10 + RTM_GET = 0x4 + RTM_GET2 = 0x14 + RTM_IFINFO = 0xe + RTM_IFINFO2 = 0x12 + RTM_LOCK = 0x8 + RTM_LOSING = 0x5 + RTM_MISS = 0x7 + RTM_NEWADDR = 0xc + RTM_NEWMADDR = 0xf + RTM_NEWMADDR2 = 0x13 + RTM_OLDADD = 0x9 + RTM_OLDDEL = 0xa + RTM_REDIRECT = 0x6 + RTM_RESOLVE = 0xb + RTM_RTTUNIT = 0xf4240 + RTM_VERSION = 0x5 + RTV_EXPIRE = 0x4 + RTV_HOPCOUNT = 0x2 + RTV_MTU = 0x1 + RTV_RPIPE = 0x8 + RTV_RTT = 0x40 + RTV_RTTVAR = 0x80 + RTV_SPIPE = 0x10 + RTV_SSTHRESH = 0x20 + RUSAGE_CHILDREN = -0x1 + RUSAGE_SELF = 0x0 + SCM_CREDS = 0x3 + SCM_RIGHTS = 0x1 + SCM_TIMESTAMP = 0x2 + SCM_TIMESTAMP_MONOTONIC = 0x4 + SEEK_CUR = 0x1 + SEEK_DATA = 0x4 + SEEK_END = 0x2 + SEEK_HOLE = 0x3 + SEEK_SET = 0x0 + SHUT_RD = 0x0 + SHUT_RDWR = 0x2 + SHUT_WR = 0x1 + SIOCADDMULTI = 0x80206931 + SIOCAIFADDR = 0x8040691a + SIOCARPIPLL = 0xc0206928 + SIOCATMARK = 0x40047307 + SIOCAUTOADDR = 0xc0206926 + SIOCAUTONETMASK = 0x80206927 + SIOCDELMULTI = 0x80206932 + SIOCDIFADDR = 0x80206919 + SIOCDIFPHYADDR = 0x80206941 + SIOCGDRVSPEC = 0xc028697b + SIOCGETVLAN = 0xc020697f + SIOCGHIWAT = 0x40047301 + SIOCGIF6LOWPAN = 0xc02069c5 + SIOCGIFADDR = 0xc0206921 + SIOCGIFALTMTU = 0xc0206948 + SIOCGIFASYNCMAP = 0xc020697c + SIOCGIFBOND = 0xc0206947 + SIOCGIFBRDADDR = 0xc0206923 + SIOCGIFCAP = 0xc020695b + SIOCGIFCONF = 0xc00c6924 + SIOCGIFDEVMTU = 0xc0206944 + SIOCGIFDSTADDR = 0xc0206922 + SIOCGIFFLAGS = 0xc0206911 + SIOCGIFFUNCTIONALTYPE = 0xc02069ad + SIOCGIFGENERIC = 0xc020693a + SIOCGIFKPI = 0xc0206987 + SIOCGIFMAC = 0xc0206982 + SIOCGIFMEDIA = 0xc02c6938 + SIOCGIFMETRIC = 0xc0206917 + SIOCGIFMTU = 0xc0206933 + SIOCGIFNETMASK = 0xc0206925 + SIOCGIFPDSTADDR = 0xc0206940 + SIOCGIFPHYS = 0xc0206935 + SIOCGIFPSRCADDR = 0xc020693f + SIOCGIFSTATUS = 0xc331693d + SIOCGIFVLAN = 0xc020697f + SIOCGIFWAKEFLAGS = 0xc0206988 + SIOCGIFXMEDIA = 0xc02c6948 + SIOCGLOWAT = 0x40047303 + SIOCGPGRP = 0x40047309 + SIOCIFCREATE = 0xc0206978 + SIOCIFCREATE2 = 0xc020697a + SIOCIFDESTROY = 0x80206979 + SIOCIFGCLONERS = 0xc0106981 + SIOCRSLVMULTI = 0xc010693b + SIOCSDRVSPEC = 0x8028697b + SIOCSETVLAN = 0x8020697e + SIOCSHIWAT = 0x80047300 + SIOCSIF6LOWPAN = 0x802069c4 + SIOCSIFADDR = 0x8020690c + SIOCSIFALTMTU = 0x80206945 + SIOCSIFASYNCMAP = 0x8020697d + SIOCSIFBOND = 0x80206946 + SIOCSIFBRDADDR = 0x80206913 + SIOCSIFCAP = 0x8020695a + SIOCSIFDSTADDR = 0x8020690e + SIOCSIFFLAGS = 0x80206910 + SIOCSIFGENERIC = 0x80206939 + SIOCSIFKPI = 0x80206986 + SIOCSIFLLADDR = 0x8020693c + SIOCSIFMAC = 0x80206983 + SIOCSIFMEDIA = 0xc0206937 + SIOCSIFMETRIC = 0x80206918 + SIOCSIFMTU = 0x80206934 + SIOCSIFNETMASK = 0x80206916 + SIOCSIFPHYADDR = 0x8040693e + SIOCSIFPHYS = 0x80206936 + SIOCSIFVLAN = 0x8020697e + SIOCSLOWAT = 0x80047302 + SIOCSPGRP = 0x80047308 + SOCK_DGRAM = 0x2 + SOCK_MAXADDRLEN = 0xff + SOCK_RAW = 0x3 + SOCK_RDM = 0x4 + SOCK_SEQPACKET = 0x5 + SOCK_STREAM = 0x1 + SOL_LOCAL = 0x0 + SOL_SOCKET = 0xffff + SOMAXCONN = 0x80 + SO_ACCEPTCONN = 0x2 + SO_BROADCAST = 0x20 + SO_DEBUG = 0x1 + SO_DONTROUTE = 0x10 + SO_DONTTRUNC = 0x2000 + SO_ERROR = 0x1007 + SO_KEEPALIVE = 0x8 + SO_LABEL = 0x1010 + SO_LINGER = 0x80 + SO_LINGER_SEC = 0x1080 + SO_NETSVC_MARKING_LEVEL = 0x1119 + SO_NET_SERVICE_TYPE = 0x1116 + SO_NKE = 0x1021 + SO_NOADDRERR = 0x1023 + SO_NOSIGPIPE = 0x1022 + SO_NOTIFYCONFLICT = 0x1026 + SO_NP_EXTENSIONS = 0x1083 + SO_NREAD = 0x1020 + SO_NUMRCVPKT = 0x1112 + SO_NWRITE = 0x1024 + SO_OOBINLINE = 0x100 + SO_PEERLABEL = 0x1011 + SO_RANDOMPORT = 0x1082 + SO_RCVBUF = 0x1002 + SO_RCVLOWAT = 0x1004 + SO_RCVTIMEO = 0x1006 + SO_REUSEADDR = 0x4 + SO_REUSEPORT = 0x200 + SO_REUSESHAREUID = 0x1025 + SO_SNDBUF = 0x1001 + SO_SNDLOWAT = 0x1003 + SO_SNDTIMEO = 0x1005 + SO_TIMESTAMP = 0x400 + SO_TIMESTAMP_MONOTONIC = 0x800 + SO_TRACKER_ATTRIBUTE_FLAGS_APP_APPROVED = 0x1 + SO_TRACKER_ATTRIBUTE_FLAGS_DOMAIN_SHORT = 0x4 + SO_TRACKER_ATTRIBUTE_FLAGS_TRACKER = 0x2 + SO_TRACKER_TRANSPARENCY_VERSION = 0x3 + SO_TYPE = 0x1008 + SO_UPCALLCLOSEWAIT = 0x1027 + SO_USELOOPBACK = 0x40 + SO_WANTMORE = 0x4000 + SO_WANTOOBFLAG = 0x8000 + S_IEXEC = 0x40 + S_IFBLK = 0x6000 + S_IFCHR = 0x2000 + S_IFDIR = 0x4000 + S_IFIFO = 0x1000 + S_IFLNK = 0xa000 + S_IFMT = 0xf000 + S_IFREG = 0x8000 + S_IFSOCK = 0xc000 + S_IFWHT = 0xe000 + S_IREAD = 0x100 + S_IRGRP = 0x20 + S_IROTH = 0x4 + S_IRUSR = 0x100 + S_IRWXG = 0x38 + S_IRWXO = 0x7 + S_IRWXU = 0x1c0 + S_ISGID = 0x400 + S_ISTXT = 0x200 + S_ISUID = 0x800 + S_ISVTX = 0x200 + S_IWGRP = 0x10 + S_IWOTH = 0x2 + S_IWRITE = 0x80 + S_IWUSR = 0x80 + S_IXGRP = 0x8 + S_IXOTH = 0x1 + S_IXUSR = 0x40 + TAB0 = 0x0 + TAB1 = 0x400 + TAB2 = 0x800 + TAB3 = 0x4 + TABDLY = 0xc04 + TCIFLUSH = 0x1 + TCIOFF = 0x3 + TCIOFLUSH = 0x3 + TCION = 0x4 + TCOFLUSH = 0x2 + TCOOFF = 0x1 + TCOON = 0x2 + TCPOPT_CC = 0xb + TCPOPT_CCECHO = 0xd + TCPOPT_CCNEW = 0xc + TCPOPT_EOL = 0x0 + TCPOPT_FASTOPEN = 0x22 + TCPOPT_MAXSEG = 0x2 + TCPOPT_NOP = 0x1 + TCPOPT_SACK = 0x5 + TCPOPT_SACK_HDR = 0x1010500 + TCPOPT_SACK_PERMITTED = 0x4 + TCPOPT_SACK_PERMIT_HDR = 0x1010402 + TCPOPT_SIGNATURE = 0x13 + TCPOPT_TIMESTAMP = 0x8 + TCPOPT_TSTAMP_HDR = 0x101080a + TCPOPT_WINDOW = 0x3 + TCP_CONNECTIONTIMEOUT = 0x20 + TCP_CONNECTION_INFO = 0x106 + TCP_ENABLE_ECN = 0x104 + TCP_FASTOPEN = 0x105 + TCP_KEEPALIVE = 0x10 + TCP_KEEPCNT = 0x102 + TCP_KEEPINTVL = 0x101 + TCP_MAXHLEN = 0x3c + TCP_MAXOLEN = 0x28 + TCP_MAXSEG = 0x2 + TCP_MAXWIN = 0xffff + TCP_MAX_SACK = 0x4 + TCP_MAX_WINSHIFT = 0xe + TCP_MINMSS = 0xd8 + TCP_MSS = 0x200 + TCP_NODELAY = 0x1 + TCP_NOOPT = 0x8 + TCP_NOPUSH = 0x4 + TCP_NOTSENT_LOWAT = 0x201 + TCP_RXT_CONNDROPTIME = 0x80 + TCP_RXT_FINDROP = 0x100 + TCP_SENDMOREACKS = 0x103 + TCSAFLUSH = 0x2 + TIOCCBRK = 0x2000747a + TIOCCDTR = 0x20007478 + TIOCCONS = 0x80047462 + TIOCDCDTIMESTAMP = 0x40107458 + TIOCDRAIN = 0x2000745e + TIOCDSIMICROCODE = 0x20007455 + TIOCEXCL = 0x2000740d + TIOCEXT = 0x80047460 + TIOCFLUSH = 0x80047410 + TIOCGDRAINWAIT = 0x40047456 + TIOCGETA = 0x40487413 + TIOCGETD = 0x4004741a + TIOCGPGRP = 0x40047477 + TIOCGWINSZ = 0x40087468 + TIOCIXOFF = 0x20007480 + TIOCIXON = 0x20007481 + TIOCMBIC = 0x8004746b + TIOCMBIS = 0x8004746c + TIOCMGDTRWAIT = 0x4004745a + TIOCMGET = 0x4004746a + TIOCMODG = 0x40047403 + TIOCMODS = 0x80047404 + TIOCMSDTRWAIT = 0x8004745b + TIOCMSET = 0x8004746d + TIOCM_CAR = 0x40 + TIOCM_CD = 0x40 + TIOCM_CTS = 0x20 + TIOCM_DSR = 0x100 + TIOCM_DTR = 0x2 + TIOCM_LE = 0x1 + TIOCM_RI = 0x80 + TIOCM_RNG = 0x80 + TIOCM_RTS = 0x4 + TIOCM_SR = 0x10 + TIOCM_ST = 0x8 + TIOCNOTTY = 0x20007471 + TIOCNXCL = 0x2000740e + TIOCOUTQ = 0x40047473 + TIOCPKT = 0x80047470 + TIOCPKT_DATA = 0x0 + TIOCPKT_DOSTOP = 0x20 + TIOCPKT_FLUSHREAD = 0x1 + TIOCPKT_FLUSHWRITE = 0x2 + TIOCPKT_IOCTL = 0x40 + TIOCPKT_NOSTOP = 0x10 + TIOCPKT_START = 0x8 + TIOCPKT_STOP = 0x4 + TIOCPTYGNAME = 0x40807453 + TIOCPTYGRANT = 0x20007454 + TIOCPTYUNLK = 0x20007452 + TIOCREMOTE = 0x80047469 + TIOCSBRK = 0x2000747b + TIOCSCONS = 0x20007463 + TIOCSCTTY = 0x20007461 + TIOCSDRAINWAIT = 0x80047457 + TIOCSDTR = 0x20007479 + TIOCSETA = 0x80487414 + TIOCSETAF = 0x80487416 + TIOCSETAW = 0x80487415 + TIOCSETD = 0x8004741b + TIOCSIG = 0x2000745f + TIOCSPGRP = 0x80047476 + TIOCSTART = 0x2000746e + TIOCSTAT = 0x20007465 + TIOCSTI = 0x80017472 + TIOCSTOP = 0x2000746f + TIOCSWINSZ = 0x80087467 + TIOCTIMESTAMP = 0x40107459 + TIOCUCNTL = 0x80047466 + TOSTOP = 0x400000 + VDISCARD = 0xf + VDSUSP = 0xb + VEOF = 0x0 + VEOL = 0x1 + VEOL2 = 0x2 + VERASE = 0x3 + VINTR = 0x8 + VKILL = 0x5 + VLNEXT = 0xe + VMADDR_CID_ANY = 0xffffffff + VMADDR_CID_HOST = 0x2 + VMADDR_CID_HYPERVISOR = 0x0 + VMADDR_CID_RESERVED = 0x1 + VMADDR_PORT_ANY = 0xffffffff + VMIN = 0x10 + VM_LOADAVG = 0x2 + VM_MACHFACTOR = 0x4 + VM_MAXID = 0x6 + VM_METER = 0x1 + VM_SWAPUSAGE = 0x5 + VQUIT = 0x9 + VREPRINT = 0x6 + VSTART = 0xc + VSTATUS = 0x12 + VSTOP = 0xd + VSUSP = 0xa + VT0 = 0x0 + VT1 = 0x10000 + VTDLY = 0x10000 + VTIME = 0x11 + VWERASE = 0x4 + WCONTINUED = 0x10 + WCOREFLAG = 0x80 + WEXITED = 0x4 + WNOHANG = 0x1 + WNOWAIT = 0x20 + WORDSIZE = 0x40 + WSTOPPED = 0x8 + WUNTRACED = 0x2 + XATTR_CREATE = 0x2 + XATTR_NODEFAULT = 0x10 + XATTR_NOFOLLOW = 0x1 + XATTR_NOSECURITY = 0x8 + XATTR_REPLACE = 0x4 + XATTR_SHOWCOMPRESSION = 0x20 ) // Errors diff --git a/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.go b/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.go index f2ee2bd33b..cf71be3edb 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.go @@ -734,6 +734,65 @@ var libc_sendfile_trampoline_addr uintptr // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func shmat(id int, addr uintptr, flag int) (ret uintptr, err error) { + r0, _, e1 := syscall_syscall(libc_shmat_trampoline_addr, uintptr(id), uintptr(addr), uintptr(flag)) + ret = uintptr(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_shmat_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_shmat shmat "/usr/lib/libSystem.B.dylib" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func shmctl(id int, cmd int, buf *SysvShmDesc) (result int, err error) { + r0, _, e1 := syscall_syscall(libc_shmctl_trampoline_addr, uintptr(id), uintptr(cmd), uintptr(unsafe.Pointer(buf))) + result = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_shmctl_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_shmctl shmctl "/usr/lib/libSystem.B.dylib" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func shmdt(addr uintptr) (err error) { + _, _, e1 := syscall_syscall(libc_shmdt_trampoline_addr, uintptr(addr), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_shmdt_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_shmdt shmdt "/usr/lib/libSystem.B.dylib" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func shmget(key int, size int, flag int) (id int, err error) { + r0, _, e1 := syscall_syscall(libc_shmget_trampoline_addr, uintptr(key), uintptr(size), uintptr(flag)) + id = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_shmget_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_shmget shmget "/usr/lib/libSystem.B.dylib" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Access(path string, mode uint32) (err error) { var _p0 *byte _p0, err = BytePtrFromString(path) diff --git a/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.s b/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.s index 33e19776db..4ebcf21758 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.s +++ b/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.s @@ -264,6 +264,30 @@ TEXT libc_sendfile_trampoline<>(SB),NOSPLIT,$0-0 GLOBL ·libc_sendfile_trampoline_addr(SB), RODATA, $8 DATA ·libc_sendfile_trampoline_addr(SB)/8, $libc_sendfile_trampoline<>(SB) +TEXT libc_shmat_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_shmat(SB) + +GLOBL ·libc_shmat_trampoline_addr(SB), RODATA, $8 +DATA ·libc_shmat_trampoline_addr(SB)/8, $libc_shmat_trampoline<>(SB) + +TEXT libc_shmctl_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_shmctl(SB) + +GLOBL ·libc_shmctl_trampoline_addr(SB), RODATA, $8 +DATA ·libc_shmctl_trampoline_addr(SB)/8, $libc_shmctl_trampoline<>(SB) + +TEXT libc_shmdt_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_shmdt(SB) + +GLOBL ·libc_shmdt_trampoline_addr(SB), RODATA, $8 +DATA ·libc_shmdt_trampoline_addr(SB)/8, $libc_shmdt_trampoline<>(SB) + +TEXT libc_shmget_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_shmget(SB) + +GLOBL ·libc_shmget_trampoline_addr(SB), RODATA, $8 +DATA ·libc_shmget_trampoline_addr(SB)/8, $libc_shmget_trampoline<>(SB) + TEXT libc_access_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_access(SB) diff --git a/vendor/golang.org/x/sys/unix/ztypes_darwin_amd64.go b/vendor/golang.org/x/sys/unix/ztypes_darwin_amd64.go index 71db853806..7efe5ccba3 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_darwin_amd64.go +++ b/vendor/golang.org/x/sys/unix/ztypes_darwin_amd64.go @@ -209,6 +209,92 @@ type RawSockaddrCtl struct { Sc_reserved [5]uint32 } +type RawSockaddrVM struct { + Len uint8 + Family uint8 + Reserved1 uint16 + Port uint32 + Cid uint32 +} + +type XVSockPCB struct { + Xv_len uint32 + Xv_vsockpp uint64 + Xvp_local_cid uint32 + Xvp_local_port uint32 + Xvp_remote_cid uint32 + Xvp_remote_port uint32 + Xvp_rxcnt uint32 + Xvp_txcnt uint32 + Xvp_peer_rxhiwat uint32 + Xvp_peer_rxcnt uint32 + Xvp_last_pid int32 + Xvp_gencnt uint64 + Xv_socket XSocket + _ [4]byte +} + +type XSocket struct { + Xso_len uint32 + Xso_so uint32 + So_type int16 + So_options int16 + So_linger int16 + So_state int16 + So_pcb uint32 + Xso_protocol int32 + Xso_family int32 + So_qlen int16 + So_incqlen int16 + So_qlimit int16 + So_timeo int16 + So_error uint16 + So_pgid int32 + So_oobmark uint32 + So_rcv XSockbuf + So_snd XSockbuf + So_uid uint32 +} + +type XSocket64 struct { + Xso_len uint32 + _ [8]byte + So_type int16 + So_options int16 + So_linger int16 + So_state int16 + _ [8]byte + Xso_protocol int32 + Xso_family int32 + So_qlen int16 + So_incqlen int16 + So_qlimit int16 + So_timeo int16 + So_error uint16 + So_pgid int32 + So_oobmark uint32 + So_rcv XSockbuf + So_snd XSockbuf + So_uid uint32 +} + +type XSockbuf struct { + Cc uint32 + Hiwat uint32 + Mbcnt uint32 + Mbmax uint32 + Lowat int32 + Flags int16 + Timeo int16 +} + +type XVSockPgen struct { + Len uint32 + Count uint64 + Gen uint64 + Sogen uint64 +} + type _Socklen uint32 type Xucred struct { @@ -287,6 +373,11 @@ const ( SizeofSockaddrUnix = 0x6a SizeofSockaddrDatalink = 0x14 SizeofSockaddrCtl = 0x20 + SizeofSockaddrVM = 0xc + SizeofXvsockpcb = 0xa8 + SizeofXSocket = 0x64 + SizeofXSockbuf = 0x18 + SizeofXVSockPgen = 0x20 SizeofXucred = 0x4c SizeofLinger = 0x8 SizeofIovec = 0x10 diff --git a/vendor/golang.org/x/sys/unix/ztypes_darwin_arm64.go b/vendor/golang.org/x/sys/unix/ztypes_darwin_arm64.go index 96f0e6ae2a..b23a2efe81 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_darwin_arm64.go +++ b/vendor/golang.org/x/sys/unix/ztypes_darwin_arm64.go @@ -209,6 +209,92 @@ type RawSockaddrCtl struct { Sc_reserved [5]uint32 } +type RawSockaddrVM struct { + Len uint8 + Family uint8 + Reserved1 uint16 + Port uint32 + Cid uint32 +} + +type XVSockPCB struct { + Xv_len uint32 + Xv_vsockpp uint64 + Xvp_local_cid uint32 + Xvp_local_port uint32 + Xvp_remote_cid uint32 + Xvp_remote_port uint32 + Xvp_rxcnt uint32 + Xvp_txcnt uint32 + Xvp_peer_rxhiwat uint32 + Xvp_peer_rxcnt uint32 + Xvp_last_pid int32 + Xvp_gencnt uint64 + Xv_socket XSocket + _ [4]byte +} + +type XSocket struct { + Xso_len uint32 + Xso_so uint32 + So_type int16 + So_options int16 + So_linger int16 + So_state int16 + So_pcb uint32 + Xso_protocol int32 + Xso_family int32 + So_qlen int16 + So_incqlen int16 + So_qlimit int16 + So_timeo int16 + So_error uint16 + So_pgid int32 + So_oobmark uint32 + So_rcv XSockbuf + So_snd XSockbuf + So_uid uint32 +} + +type XSocket64 struct { + Xso_len uint32 + _ [8]byte + So_type int16 + So_options int16 + So_linger int16 + So_state int16 + _ [8]byte + Xso_protocol int32 + Xso_family int32 + So_qlen int16 + So_incqlen int16 + So_qlimit int16 + So_timeo int16 + So_error uint16 + So_pgid int32 + So_oobmark uint32 + So_rcv XSockbuf + So_snd XSockbuf + So_uid uint32 +} + +type XSockbuf struct { + Cc uint32 + Hiwat uint32 + Mbcnt uint32 + Mbmax uint32 + Lowat int32 + Flags int16 + Timeo int16 +} + +type XVSockPgen struct { + Len uint32 + Count uint64 + Gen uint64 + Sogen uint64 +} + type _Socklen uint32 type Xucred struct { @@ -287,6 +373,11 @@ const ( SizeofSockaddrUnix = 0x6a SizeofSockaddrDatalink = 0x14 SizeofSockaddrCtl = 0x20 + SizeofSockaddrVM = 0xc + SizeofXvsockpcb = 0xa8 + SizeofXSocket = 0x64 + SizeofXSockbuf = 0x18 + SizeofXVSockPgen = 0x20 SizeofXucred = 0x4c SizeofLinger = 0x8 SizeofIovec = 0x10 @@ -639,3 +730,39 @@ type Ucred struct { Ngroups int16 Groups [16]uint32 } + +type SysvIpcPerm struct { + Uid uint32 + Gid uint32 + Cuid uint32 + Cgid uint32 + Mode uint16 + _ uint16 + _ int32 +} +type SysvShmDesc struct { + Perm SysvIpcPerm + Segsz uint64 + Lpid int32 + Cpid int32 + Nattch uint16 + _ [34]byte +} + +const ( + IPC_CREAT = 0x200 + IPC_EXCL = 0x400 + IPC_NOWAIT = 0x800 + IPC_PRIVATE = 0x0 +) + +const ( + IPC_RMID = 0x0 + IPC_SET = 0x1 + IPC_STAT = 0x2 +) + +const ( + SHM_RDONLY = 0x1000 + SHM_RND = 0x2000 +) diff --git a/vendor/golang.org/x/sys/windows/aliases.go b/vendor/golang.org/x/sys/windows/aliases.go index af3af60db9..a20ebea633 100644 --- a/vendor/golang.org/x/sys/windows/aliases.go +++ b/vendor/golang.org/x/sys/windows/aliases.go @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build windows -// +build go1.9 +//go:build windows && go1.9 +// +build windows,go1.9 package windows diff --git a/vendor/golang.org/x/sys/windows/eventlog.go b/vendor/golang.org/x/sys/windows/eventlog.go index 40af946e16..2cd60645ee 100644 --- a/vendor/golang.org/x/sys/windows/eventlog.go +++ b/vendor/golang.org/x/sys/windows/eventlog.go @@ -2,6 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. +//go:build windows // +build windows package windows diff --git a/vendor/golang.org/x/sys/windows/memory_windows.go b/vendor/golang.org/x/sys/windows/memory_windows.go index 1adb60739a..6dc0920a84 100644 --- a/vendor/golang.org/x/sys/windows/memory_windows.go +++ b/vendor/golang.org/x/sys/windows/memory_windows.go @@ -35,3 +35,14 @@ const ( QUOTA_LIMITS_HARDWS_MAX_DISABLE = 0x00000008 QUOTA_LIMITS_HARDWS_MAX_ENABLE = 0x00000004 ) + +type MemoryBasicInformation struct { + BaseAddress uintptr + AllocationBase uintptr + AllocationProtect uint32 + PartitionId uint16 + RegionSize uintptr + State uint32 + Protect uint32 + Type uint32 +} diff --git a/vendor/golang.org/x/sys/windows/mksyscall.go b/vendor/golang.org/x/sys/windows/mksyscall.go index 328e3b2ace..6102910989 100644 --- a/vendor/golang.org/x/sys/windows/mksyscall.go +++ b/vendor/golang.org/x/sys/windows/mksyscall.go @@ -2,6 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. +//go:build generate // +build generate package windows diff --git a/vendor/golang.org/x/sys/windows/race.go b/vendor/golang.org/x/sys/windows/race.go index a74e3e24b5..9196b089ca 100644 --- a/vendor/golang.org/x/sys/windows/race.go +++ b/vendor/golang.org/x/sys/windows/race.go @@ -2,6 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. +//go:build windows && race // +build windows,race package windows diff --git a/vendor/golang.org/x/sys/windows/race0.go b/vendor/golang.org/x/sys/windows/race0.go index e44a3cbf67..7bae4817a0 100644 --- a/vendor/golang.org/x/sys/windows/race0.go +++ b/vendor/golang.org/x/sys/windows/race0.go @@ -2,6 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. +//go:build windows && !race // +build windows,!race package windows diff --git a/vendor/golang.org/x/sys/windows/service.go b/vendor/golang.org/x/sys/windows/service.go index b269850d06..5b28ae168a 100644 --- a/vendor/golang.org/x/sys/windows/service.go +++ b/vendor/golang.org/x/sys/windows/service.go @@ -2,6 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. +//go:build windows // +build windows package windows @@ -235,3 +236,4 @@ type QUERY_SERVICE_LOCK_STATUS struct { //sys NotifyServiceStatusChange(service Handle, notifyMask uint32, notifier *SERVICE_NOTIFY) (ret error) = advapi32.NotifyServiceStatusChangeW //sys SubscribeServiceChangeNotifications(service Handle, eventType uint32, callback uintptr, callbackCtx uintptr, subscription *uintptr) (ret error) = sechost.SubscribeServiceChangeNotifications? //sys UnsubscribeServiceChangeNotifications(subscription uintptr) = sechost.UnsubscribeServiceChangeNotifications? +//sys RegisterServiceCtrlHandlerEx(serviceName *uint16, handlerProc uintptr, context uintptr) (handle Handle, err error) = advapi32.RegisterServiceCtrlHandlerExW diff --git a/vendor/golang.org/x/sys/windows/str.go b/vendor/golang.org/x/sys/windows/str.go index 917cc2aae4..4fc01434e4 100644 --- a/vendor/golang.org/x/sys/windows/str.go +++ b/vendor/golang.org/x/sys/windows/str.go @@ -2,6 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. +//go:build windows // +build windows package windows diff --git a/vendor/golang.org/x/sys/windows/syscall.go b/vendor/golang.org/x/sys/windows/syscall.go index 6122f557a0..72074d582f 100644 --- a/vendor/golang.org/x/sys/windows/syscall.go +++ b/vendor/golang.org/x/sys/windows/syscall.go @@ -2,6 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. +//go:build windows // +build windows // Package windows contains an interface to the low-level operating system diff --git a/vendor/golang.org/x/sys/windows/syscall_windows.go b/vendor/golang.org/x/sys/windows/syscall_windows.go index ff2d45d436..53ee74e08b 100644 --- a/vendor/golang.org/x/sys/windows/syscall_windows.go +++ b/vendor/golang.org/x/sys/windows/syscall_windows.go @@ -274,6 +274,11 @@ func NewCallbackCDecl(fn interface{}) uintptr { //sys VirtualAlloc(address uintptr, size uintptr, alloctype uint32, protect uint32) (value uintptr, err error) = kernel32.VirtualAlloc //sys VirtualFree(address uintptr, size uintptr, freetype uint32) (err error) = kernel32.VirtualFree //sys VirtualProtect(address uintptr, size uintptr, newprotect uint32, oldprotect *uint32) (err error) = kernel32.VirtualProtect +//sys VirtualProtectEx(process Handle, address uintptr, size uintptr, newProtect uint32, oldProtect *uint32) (err error) = kernel32.VirtualProtectEx +//sys VirtualQuery(address uintptr, buffer *MemoryBasicInformation, length uintptr) (err error) = kernel32.VirtualQuery +//sys VirtualQueryEx(process Handle, address uintptr, buffer *MemoryBasicInformation, length uintptr) (err error) = kernel32.VirtualQueryEx +//sys ReadProcessMemory(process Handle, baseAddress uintptr, buffer *byte, size uintptr, numberOfBytesRead *uintptr) (err error) = kernel32.ReadProcessMemory +//sys WriteProcessMemory(process Handle, baseAddress uintptr, buffer *byte, size uintptr, numberOfBytesWritten *uintptr) (err error) = kernel32.WriteProcessMemory //sys TransmitFile(s Handle, handle Handle, bytesToWrite uint32, bytsPerSend uint32, overlapped *Overlapped, transmitFileBuf *TransmitFileBuffers, flags uint32) (err error) = mswsock.TransmitFile //sys ReadDirectoryChanges(handle Handle, buf *byte, buflen uint32, watchSubTree bool, mask uint32, retlen *uint32, overlapped *Overlapped, completionRoutine uintptr) (err error) = kernel32.ReadDirectoryChangesW //sys FindFirstChangeNotification(path string, watchSubtree bool, notifyFilter uint32) (handle Handle, err error) [failretval==InvalidHandle] = kernel32.FindFirstChangeNotificationW @@ -396,6 +401,11 @@ func NewCallbackCDecl(fn interface{}) uintptr { //sys LoadResource(module Handle, resInfo Handle) (resData Handle, err error) = kernel32.LoadResource //sys LockResource(resData Handle) (addr uintptr, err error) = kernel32.LockResource +// Version APIs +//sys GetFileVersionInfoSize(filename string, zeroHandle *Handle) (bufSize uint32, err error) = version.GetFileVersionInfoSizeW +//sys GetFileVersionInfo(filename string, handle uint32, bufSize uint32, buffer unsafe.Pointer) (err error) = version.GetFileVersionInfoW +//sys VerQueryValue(block unsafe.Pointer, subBlock string, pointerToBufferPointer unsafe.Pointer, bufSize *uint32) (err error) = version.VerQueryValueW + // Process Status API (PSAPI) //sys EnumProcesses(processIds []uint32, bytesReturned *uint32) (err error) = psapi.EnumProcesses //sys EnumProcessModules(process Handle, module *Handle, cb uint32, cbNeeded *uint32) (err error) = psapi.EnumProcessModules @@ -413,11 +423,16 @@ func NewCallbackCDecl(fn interface{}) uintptr { //sys RtlInitString(destinationString *NTString, sourceString *byte) = ntdll.RtlInitString //sys NtCreateFile(handle *Handle, access uint32, oa *OBJECT_ATTRIBUTES, iosb *IO_STATUS_BLOCK, allocationSize *int64, attributes uint32, share uint32, disposition uint32, options uint32, eabuffer uintptr, ealength uint32) (ntstatus error) = ntdll.NtCreateFile //sys NtCreateNamedPipeFile(pipe *Handle, access uint32, oa *OBJECT_ATTRIBUTES, iosb *IO_STATUS_BLOCK, share uint32, disposition uint32, options uint32, typ uint32, readMode uint32, completionMode uint32, maxInstances uint32, inboundQuota uint32, outputQuota uint32, timeout *int64) (ntstatus error) = ntdll.NtCreateNamedPipeFile +//sys NtSetInformationFile(handle Handle, iosb *IO_STATUS_BLOCK, inBuffer *byte, inBufferLen uint32, class uint32) (ntstatus error) = ntdll.NtSetInformationFile //sys RtlDosPathNameToNtPathName(dosName *uint16, ntName *NTUnicodeString, ntFileNamePart *uint16, relativeName *RTL_RELATIVE_NAME) (ntstatus error) = ntdll.RtlDosPathNameToNtPathName_U_WithStatus //sys RtlDosPathNameToRelativeNtPathName(dosName *uint16, ntName *NTUnicodeString, ntFileNamePart *uint16, relativeName *RTL_RELATIVE_NAME) (ntstatus error) = ntdll.RtlDosPathNameToRelativeNtPathName_U_WithStatus //sys RtlDefaultNpAcl(acl **ACL) (ntstatus error) = ntdll.RtlDefaultNpAcl //sys NtQueryInformationProcess(proc Handle, procInfoClass int32, procInfo unsafe.Pointer, procInfoLen uint32, retLen *uint32) (ntstatus error) = ntdll.NtQueryInformationProcess //sys NtSetInformationProcess(proc Handle, procInfoClass int32, procInfo unsafe.Pointer, procInfoLen uint32) (ntstatus error) = ntdll.NtSetInformationProcess +//sys NtQuerySystemInformation(sysInfoClass int32, sysInfo unsafe.Pointer, sysInfoLen uint32, retLen *uint32) (ntstatus error) = ntdll.NtQuerySystemInformation +//sys NtSetSystemInformation(sysInfoClass int32, sysInfo unsafe.Pointer, sysInfoLen uint32) (ntstatus error) = ntdll.NtSetSystemInformation +//sys RtlAddFunctionTable(functionTable *RUNTIME_FUNCTION, entryCount uint32, baseAddress uintptr) (ret bool) = ntdll.RtlAddFunctionTable +//sys RtlDeleteFunctionTable(functionTable *RUNTIME_FUNCTION) (ret bool) = ntdll.RtlDeleteFunctionTable // syscall interface implementation for other packages diff --git a/vendor/golang.org/x/sys/windows/types_windows.go b/vendor/golang.org/x/sys/windows/types_windows.go index 88e0ce5d0d..286dd1eab9 100644 --- a/vendor/golang.org/x/sys/windows/types_windows.go +++ b/vendor/golang.org/x/sys/windows/types_windows.go @@ -66,9 +66,21 @@ var signals = [...]string{ } const ( - FILE_LIST_DIRECTORY = 0x00000001 - FILE_APPEND_DATA = 0x00000004 + FILE_READ_DATA = 0x00000001 + FILE_READ_ATTRIBUTES = 0x00000080 + FILE_READ_EA = 0x00000008 + FILE_WRITE_DATA = 0x00000002 FILE_WRITE_ATTRIBUTES = 0x00000100 + FILE_WRITE_EA = 0x00000010 + FILE_APPEND_DATA = 0x00000004 + FILE_EXECUTE = 0x00000020 + + FILE_GENERIC_READ = STANDARD_RIGHTS_READ | FILE_READ_DATA | FILE_READ_ATTRIBUTES | FILE_READ_EA | SYNCHRONIZE + FILE_GENERIC_WRITE = STANDARD_RIGHTS_WRITE | FILE_WRITE_DATA | FILE_WRITE_ATTRIBUTES | FILE_WRITE_EA | FILE_APPEND_DATA | SYNCHRONIZE + FILE_GENERIC_EXECUTE = STANDARD_RIGHTS_EXECUTE | FILE_READ_ATTRIBUTES | FILE_EXECUTE | SYNCHRONIZE + + FILE_LIST_DIRECTORY = 0x00000001 + FILE_TRAVERSE = 0x00000020 FILE_SHARE_READ = 0x00000001 FILE_SHARE_WRITE = 0x00000002 @@ -1789,7 +1801,53 @@ type reparseDataBuffer struct { } const ( - FSCTL_GET_REPARSE_POINT = 0x900A8 + FSCTL_CREATE_OR_GET_OBJECT_ID = 0x0900C0 + FSCTL_DELETE_OBJECT_ID = 0x0900A0 + FSCTL_DELETE_REPARSE_POINT = 0x0900AC + FSCTL_DUPLICATE_EXTENTS_TO_FILE = 0x098344 + FSCTL_DUPLICATE_EXTENTS_TO_FILE_EX = 0x0983E8 + FSCTL_FILESYSTEM_GET_STATISTICS = 0x090060 + FSCTL_FILE_LEVEL_TRIM = 0x098208 + FSCTL_FIND_FILES_BY_SID = 0x09008F + FSCTL_GET_COMPRESSION = 0x09003C + FSCTL_GET_INTEGRITY_INFORMATION = 0x09027C + FSCTL_GET_NTFS_VOLUME_DATA = 0x090064 + FSCTL_GET_REFS_VOLUME_DATA = 0x0902D8 + FSCTL_GET_OBJECT_ID = 0x09009C + FSCTL_GET_REPARSE_POINT = 0x0900A8 + FSCTL_GET_RETRIEVAL_POINTER_COUNT = 0x09042B + FSCTL_GET_RETRIEVAL_POINTERS = 0x090073 + FSCTL_GET_RETRIEVAL_POINTERS_AND_REFCOUNT = 0x0903D3 + FSCTL_IS_PATHNAME_VALID = 0x09002C + FSCTL_LMR_SET_LINK_TRACKING_INFORMATION = 0x1400EC + FSCTL_MARK_HANDLE = 0x0900FC + FSCTL_OFFLOAD_READ = 0x094264 + FSCTL_OFFLOAD_WRITE = 0x098268 + FSCTL_PIPE_PEEK = 0x11400C + FSCTL_PIPE_TRANSCEIVE = 0x11C017 + FSCTL_PIPE_WAIT = 0x110018 + FSCTL_QUERY_ALLOCATED_RANGES = 0x0940CF + FSCTL_QUERY_FAT_BPB = 0x090058 + FSCTL_QUERY_FILE_REGIONS = 0x090284 + FSCTL_QUERY_ON_DISK_VOLUME_INFO = 0x09013C + FSCTL_QUERY_SPARING_INFO = 0x090138 + FSCTL_READ_FILE_USN_DATA = 0x0900EB + FSCTL_RECALL_FILE = 0x090117 + FSCTL_REFS_STREAM_SNAPSHOT_MANAGEMENT = 0x090440 + FSCTL_SET_COMPRESSION = 0x09C040 + FSCTL_SET_DEFECT_MANAGEMENT = 0x098134 + FSCTL_SET_ENCRYPTION = 0x0900D7 + FSCTL_SET_INTEGRITY_INFORMATION = 0x09C280 + FSCTL_SET_INTEGRITY_INFORMATION_EX = 0x090380 + FSCTL_SET_OBJECT_ID = 0x090098 + FSCTL_SET_OBJECT_ID_EXTENDED = 0x0900BC + FSCTL_SET_REPARSE_POINT = 0x0900A4 + FSCTL_SET_SPARSE = 0x0900C4 + FSCTL_SET_ZERO_DATA = 0x0980C8 + FSCTL_SET_ZERO_ON_DEALLOCATION = 0x090194 + FSCTL_SIS_COPYFILE = 0x090100 + FSCTL_WRITE_USN_CLOSE_RECORD = 0x0900EF + MAXIMUM_REPARSE_DATA_BUFFER_SIZE = 16 * 1024 IO_REPARSE_TAG_MOUNT_POINT = 0xA0000003 IO_REPARSE_TAG_SYMLINK = 0xA000000C @@ -2308,6 +2366,12 @@ type LIST_ENTRY struct { Blink *LIST_ENTRY } +type RUNTIME_FUNCTION struct { + BeginAddress uint32 + EndAddress uint32 + UnwindData uint32 +} + type LDR_DATA_TABLE_ENTRY struct { reserved1 [2]uintptr InMemoryOrderLinks LIST_ENTRY @@ -2498,6 +2562,60 @@ const ( FILE_PIPE_SERVER_END = 0x00000001 ) +const ( + // FileInformationClass for NtSetInformationFile + FileBasicInformation = 4 + FileRenameInformation = 10 + FileDispositionInformation = 13 + FilePositionInformation = 14 + FileEndOfFileInformation = 20 + FileValidDataLengthInformation = 39 + FileShortNameInformation = 40 + FileIoPriorityHintInformation = 43 + FileReplaceCompletionInformation = 61 + FileDispositionInformationEx = 64 + FileCaseSensitiveInformation = 71 + FileLinkInformation = 72 + FileCaseSensitiveInformationForceAccessCheck = 75 + FileKnownFolderInformation = 76 + + // Flags for FILE_RENAME_INFORMATION + FILE_RENAME_REPLACE_IF_EXISTS = 0x00000001 + FILE_RENAME_POSIX_SEMANTICS = 0x00000002 + FILE_RENAME_SUPPRESS_PIN_STATE_INHERITANCE = 0x00000004 + FILE_RENAME_SUPPRESS_STORAGE_RESERVE_INHERITANCE = 0x00000008 + FILE_RENAME_NO_INCREASE_AVAILABLE_SPACE = 0x00000010 + FILE_RENAME_NO_DECREASE_AVAILABLE_SPACE = 0x00000020 + FILE_RENAME_PRESERVE_AVAILABLE_SPACE = 0x00000030 + FILE_RENAME_IGNORE_READONLY_ATTRIBUTE = 0x00000040 + FILE_RENAME_FORCE_RESIZE_TARGET_SR = 0x00000080 + FILE_RENAME_FORCE_RESIZE_SOURCE_SR = 0x00000100 + FILE_RENAME_FORCE_RESIZE_SR = 0x00000180 + + // Flags for FILE_DISPOSITION_INFORMATION_EX + FILE_DISPOSITION_DO_NOT_DELETE = 0x00000000 + FILE_DISPOSITION_DELETE = 0x00000001 + FILE_DISPOSITION_POSIX_SEMANTICS = 0x00000002 + FILE_DISPOSITION_FORCE_IMAGE_SECTION_CHECK = 0x00000004 + FILE_DISPOSITION_ON_CLOSE = 0x00000008 + FILE_DISPOSITION_IGNORE_READONLY_ATTRIBUTE = 0x00000010 + + // Flags for FILE_CASE_SENSITIVE_INFORMATION + FILE_CS_FLAG_CASE_SENSITIVE_DIR = 0x00000001 + + // Flags for FILE_LINK_INFORMATION + FILE_LINK_REPLACE_IF_EXISTS = 0x00000001 + FILE_LINK_POSIX_SEMANTICS = 0x00000002 + FILE_LINK_SUPPRESS_STORAGE_RESERVE_INHERITANCE = 0x00000008 + FILE_LINK_NO_INCREASE_AVAILABLE_SPACE = 0x00000010 + FILE_LINK_NO_DECREASE_AVAILABLE_SPACE = 0x00000020 + FILE_LINK_PRESERVE_AVAILABLE_SPACE = 0x00000030 + FILE_LINK_IGNORE_READONLY_ATTRIBUTE = 0x00000040 + FILE_LINK_FORCE_RESIZE_TARGET_SR = 0x00000080 + FILE_LINK_FORCE_RESIZE_SOURCE_SR = 0x00000100 + FILE_LINK_FORCE_RESIZE_SR = 0x00000180 +) + // ProcessInformationClasses for NtQueryInformationProcess and NtSetInformationProcess. const ( ProcessBasicInformation = iota @@ -2614,6 +2732,203 @@ type PROCESS_BASIC_INFORMATION struct { InheritedFromUniqueProcessId uintptr } +// SystemInformationClasses for NtQuerySystemInformation and NtSetSystemInformation +const ( + SystemBasicInformation = iota + SystemProcessorInformation + SystemPerformanceInformation + SystemTimeOfDayInformation + SystemPathInformation + SystemProcessInformation + SystemCallCountInformation + SystemDeviceInformation + SystemProcessorPerformanceInformation + SystemFlagsInformation + SystemCallTimeInformation + SystemModuleInformation + SystemLocksInformation + SystemStackTraceInformation + SystemPagedPoolInformation + SystemNonPagedPoolInformation + SystemHandleInformation + SystemObjectInformation + SystemPageFileInformation + SystemVdmInstemulInformation + SystemVdmBopInformation + SystemFileCacheInformation + SystemPoolTagInformation + SystemInterruptInformation + SystemDpcBehaviorInformation + SystemFullMemoryInformation + SystemLoadGdiDriverInformation + SystemUnloadGdiDriverInformation + SystemTimeAdjustmentInformation + SystemSummaryMemoryInformation + SystemMirrorMemoryInformation + SystemPerformanceTraceInformation + systemObsolete0 + SystemExceptionInformation + SystemCrashDumpStateInformation + SystemKernelDebuggerInformation + SystemContextSwitchInformation + SystemRegistryQuotaInformation + SystemExtendServiceTableInformation + SystemPrioritySeperation + SystemVerifierAddDriverInformation + SystemVerifierRemoveDriverInformation + SystemProcessorIdleInformation + SystemLegacyDriverInformation + SystemCurrentTimeZoneInformation + SystemLookasideInformation + SystemTimeSlipNotification + SystemSessionCreate + SystemSessionDetach + SystemSessionInformation + SystemRangeStartInformation + SystemVerifierInformation + SystemVerifierThunkExtend + SystemSessionProcessInformation + SystemLoadGdiDriverInSystemSpace + SystemNumaProcessorMap + SystemPrefetcherInformation + SystemExtendedProcessInformation + SystemRecommendedSharedDataAlignment + SystemComPlusPackage + SystemNumaAvailableMemory + SystemProcessorPowerInformation + SystemEmulationBasicInformation + SystemEmulationProcessorInformation + SystemExtendedHandleInformation + SystemLostDelayedWriteInformation + SystemBigPoolInformation + SystemSessionPoolTagInformation + SystemSessionMappedViewInformation + SystemHotpatchInformation + SystemObjectSecurityMode + SystemWatchdogTimerHandler + SystemWatchdogTimerInformation + SystemLogicalProcessorInformation + SystemWow64SharedInformationObsolete + SystemRegisterFirmwareTableInformationHandler + SystemFirmwareTableInformation + SystemModuleInformationEx + SystemVerifierTriageInformation + SystemSuperfetchInformation + SystemMemoryListInformation + SystemFileCacheInformationEx + SystemThreadPriorityClientIdInformation + SystemProcessorIdleCycleTimeInformation + SystemVerifierCancellationInformation + SystemProcessorPowerInformationEx + SystemRefTraceInformation + SystemSpecialPoolInformation + SystemProcessIdInformation + SystemErrorPortInformation + SystemBootEnvironmentInformation + SystemHypervisorInformation + SystemVerifierInformationEx + SystemTimeZoneInformation + SystemImageFileExecutionOptionsInformation + SystemCoverageInformation + SystemPrefetchPatchInformation + SystemVerifierFaultsInformation + SystemSystemPartitionInformation + SystemSystemDiskInformation + SystemProcessorPerformanceDistribution + SystemNumaProximityNodeInformation + SystemDynamicTimeZoneInformation + SystemCodeIntegrityInformation + SystemProcessorMicrocodeUpdateInformation + SystemProcessorBrandString + SystemVirtualAddressInformation + SystemLogicalProcessorAndGroupInformation + SystemProcessorCycleTimeInformation + SystemStoreInformation + SystemRegistryAppendString + SystemAitSamplingValue + SystemVhdBootInformation + SystemCpuQuotaInformation + SystemNativeBasicInformation + systemSpare1 + SystemLowPriorityIoInformation + SystemTpmBootEntropyInformation + SystemVerifierCountersInformation + SystemPagedPoolInformationEx + SystemSystemPtesInformationEx + SystemNodeDistanceInformation + SystemAcpiAuditInformation + SystemBasicPerformanceInformation + SystemQueryPerformanceCounterInformation + SystemSessionBigPoolInformation + SystemBootGraphicsInformation + SystemScrubPhysicalMemoryInformation + SystemBadPageInformation + SystemProcessorProfileControlArea + SystemCombinePhysicalMemoryInformation + SystemEntropyInterruptTimingCallback + SystemConsoleInformation + SystemPlatformBinaryInformation + SystemThrottleNotificationInformation + SystemHypervisorProcessorCountInformation + SystemDeviceDataInformation + SystemDeviceDataEnumerationInformation + SystemMemoryTopologyInformation + SystemMemoryChannelInformation + SystemBootLogoInformation + SystemProcessorPerformanceInformationEx + systemSpare0 + SystemSecureBootPolicyInformation + SystemPageFileInformationEx + SystemSecureBootInformation + SystemEntropyInterruptTimingRawInformation + SystemPortableWorkspaceEfiLauncherInformation + SystemFullProcessInformation + SystemKernelDebuggerInformationEx + SystemBootMetadataInformation + SystemSoftRebootInformation + SystemElamCertificateInformation + SystemOfflineDumpConfigInformation + SystemProcessorFeaturesInformation + SystemRegistryReconciliationInformation + SystemEdidInformation + SystemManufacturingInformation + SystemEnergyEstimationConfigInformation + SystemHypervisorDetailInformation + SystemProcessorCycleStatsInformation + SystemVmGenerationCountInformation + SystemTrustedPlatformModuleInformation + SystemKernelDebuggerFlags + SystemCodeIntegrityPolicyInformation + SystemIsolatedUserModeInformation + SystemHardwareSecurityTestInterfaceResultsInformation + SystemSingleModuleInformation + SystemAllowedCpuSetsInformation + SystemDmaProtectionInformation + SystemInterruptCpuSetsInformation + SystemSecureBootPolicyFullInformation + SystemCodeIntegrityPolicyFullInformation + SystemAffinitizedInterruptProcessorInformation + SystemRootSiloInformation +) + +type RTL_PROCESS_MODULE_INFORMATION struct { + Section Handle + MappedBase uintptr + ImageBase uintptr + ImageSize uint32 + Flags uint32 + LoadOrderIndex uint16 + InitOrderIndex uint16 + LoadCount uint16 + OffsetToFileName uint16 + FullPathName [256]byte +} + +type RTL_PROCESS_MODULES struct { + NumberOfModules uint32 + Modules [1]RTL_PROCESS_MODULE_INFORMATION +} + // Constants for LocalAlloc flags. const ( LMEM_FIXED = 0x0 @@ -2708,6 +3023,22 @@ var ( RT_MANIFEST ResourceID = 24 ) +type VS_FIXEDFILEINFO struct { + Signature uint32 + StrucVersion uint32 + FileVersionMS uint32 + FileVersionLS uint32 + ProductVersionMS uint32 + ProductVersionLS uint32 + FileFlagsMask uint32 + FileFlags uint32 + FileOS uint32 + FileType uint32 + FileSubtype uint32 + FileDateMS uint32 + FileDateLS uint32 +} + type COAUTHIDENTITY struct { User *uint16 UserLength uint32 diff --git a/vendor/golang.org/x/sys/windows/zsyscall_windows.go b/vendor/golang.org/x/sys/windows/zsyscall_windows.go index e282e246b9..ef3cfcfb2b 100644 --- a/vendor/golang.org/x/sys/windows/zsyscall_windows.go +++ b/vendor/golang.org/x/sys/windows/zsyscall_windows.go @@ -51,6 +51,7 @@ var ( modshell32 = NewLazySystemDLL("shell32.dll") moduser32 = NewLazySystemDLL("user32.dll") moduserenv = NewLazySystemDLL("userenv.dll") + modversion = NewLazySystemDLL("version.dll") modwintrust = NewLazySystemDLL("wintrust.dll") modws2_32 = NewLazySystemDLL("ws2_32.dll") modwtsapi32 = NewLazySystemDLL("wtsapi32.dll") @@ -124,6 +125,7 @@ var ( procRegQueryInfoKeyW = modadvapi32.NewProc("RegQueryInfoKeyW") procRegQueryValueExW = modadvapi32.NewProc("RegQueryValueExW") procRegisterEventSourceW = modadvapi32.NewProc("RegisterEventSourceW") + procRegisterServiceCtrlHandlerExW = modadvapi32.NewProc("RegisterServiceCtrlHandlerExW") procReportEventW = modadvapi32.NewProc("ReportEventW") procRevertToSelf = modadvapi32.NewProc("RevertToSelf") procSetEntriesInAclW = modadvapi32.NewProc("SetEntriesInAclW") @@ -303,6 +305,7 @@ var ( procReadConsoleW = modkernel32.NewProc("ReadConsoleW") procReadDirectoryChangesW = modkernel32.NewProc("ReadDirectoryChangesW") procReadFile = modkernel32.NewProc("ReadFile") + procReadProcessMemory = modkernel32.NewProc("ReadProcessMemory") procReleaseMutex = modkernel32.NewProc("ReleaseMutex") procRemoveDirectoryW = modkernel32.NewProc("RemoveDirectoryW") procResetEvent = modkernel32.NewProc("ResetEvent") @@ -345,12 +348,16 @@ var ( procVirtualFree = modkernel32.NewProc("VirtualFree") procVirtualLock = modkernel32.NewProc("VirtualLock") procVirtualProtect = modkernel32.NewProc("VirtualProtect") + procVirtualProtectEx = modkernel32.NewProc("VirtualProtectEx") + procVirtualQuery = modkernel32.NewProc("VirtualQuery") + procVirtualQueryEx = modkernel32.NewProc("VirtualQueryEx") procVirtualUnlock = modkernel32.NewProc("VirtualUnlock") procWTSGetActiveConsoleSessionId = modkernel32.NewProc("WTSGetActiveConsoleSessionId") procWaitForMultipleObjects = modkernel32.NewProc("WaitForMultipleObjects") procWaitForSingleObject = modkernel32.NewProc("WaitForSingleObject") procWriteConsoleW = modkernel32.NewProc("WriteConsoleW") procWriteFile = modkernel32.NewProc("WriteFile") + procWriteProcessMemory = modkernel32.NewProc("WriteProcessMemory") procAcceptEx = modmswsock.NewProc("AcceptEx") procGetAcceptExSockaddrs = modmswsock.NewProc("GetAcceptExSockaddrs") procTransmitFile = modmswsock.NewProc("TransmitFile") @@ -359,9 +366,14 @@ var ( procNetUserGetInfo = modnetapi32.NewProc("NetUserGetInfo") procNtCreateFile = modntdll.NewProc("NtCreateFile") procNtCreateNamedPipeFile = modntdll.NewProc("NtCreateNamedPipeFile") + procNtSetInformationFile = modntdll.NewProc("NtSetInformationFile") procNtQueryInformationProcess = modntdll.NewProc("NtQueryInformationProcess") + procNtQuerySystemInformation = modntdll.NewProc("NtQuerySystemInformation") procNtSetInformationProcess = modntdll.NewProc("NtSetInformationProcess") + procNtSetSystemInformation = modntdll.NewProc("NtSetSystemInformation") + procRtlAddFunctionTable = modntdll.NewProc("RtlAddFunctionTable") procRtlDefaultNpAcl = modntdll.NewProc("RtlDefaultNpAcl") + procRtlDeleteFunctionTable = modntdll.NewProc("RtlDeleteFunctionTable") procRtlDosPathNameToNtPathName_U_WithStatus = modntdll.NewProc("RtlDosPathNameToNtPathName_U_WithStatus") procRtlDosPathNameToRelativeNtPathName_U_WithStatus = modntdll.NewProc("RtlDosPathNameToRelativeNtPathName_U_WithStatus") procRtlGetCurrentPeb = modntdll.NewProc("RtlGetCurrentPeb") @@ -397,6 +409,9 @@ var ( procCreateEnvironmentBlock = moduserenv.NewProc("CreateEnvironmentBlock") procDestroyEnvironmentBlock = moduserenv.NewProc("DestroyEnvironmentBlock") procGetUserProfileDirectoryW = moduserenv.NewProc("GetUserProfileDirectoryW") + procGetFileVersionInfoSizeW = modversion.NewProc("GetFileVersionInfoSizeW") + procGetFileVersionInfoW = modversion.NewProc("GetFileVersionInfoW") + procVerQueryValueW = modversion.NewProc("VerQueryValueW") procWinVerifyTrustEx = modwintrust.NewProc("WinVerifyTrustEx") procFreeAddrInfoW = modws2_32.NewProc("FreeAddrInfoW") procGetAddrInfoW = modws2_32.NewProc("GetAddrInfoW") @@ -1050,6 +1065,15 @@ func RegisterEventSource(uncServerName *uint16, sourceName *uint16) (handle Hand return } +func RegisterServiceCtrlHandlerEx(serviceName *uint16, handlerProc uintptr, context uintptr) (handle Handle, err error) { + r0, _, e1 := syscall.Syscall(procRegisterServiceCtrlHandlerExW.Addr(), 3, uintptr(unsafe.Pointer(serviceName)), uintptr(handlerProc), uintptr(context)) + handle = Handle(r0) + if handle == 0 { + err = errnoErr(e1) + } + return +} + func ReportEvent(log Handle, etype uint16, category uint16, eventId uint32, usrSId uintptr, numStrings uint16, dataSize uint32, strings **uint16, rawData *byte) (err error) { r1, _, e1 := syscall.Syscall9(procReportEventW.Addr(), 9, uintptr(log), uintptr(etype), uintptr(category), uintptr(eventId), uintptr(usrSId), uintptr(numStrings), uintptr(dataSize), uintptr(unsafe.Pointer(strings)), uintptr(unsafe.Pointer(rawData))) if r1 == 0 { @@ -2636,6 +2660,14 @@ func ReadFile(handle Handle, buf []byte, done *uint32, overlapped *Overlapped) ( return } +func ReadProcessMemory(process Handle, baseAddress uintptr, buffer *byte, size uintptr, numberOfBytesRead *uintptr) (err error) { + r1, _, e1 := syscall.Syscall6(procReadProcessMemory.Addr(), 5, uintptr(process), uintptr(baseAddress), uintptr(unsafe.Pointer(buffer)), uintptr(size), uintptr(unsafe.Pointer(numberOfBytesRead)), 0) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + func ReleaseMutex(mutex Handle) (err error) { r1, _, e1 := syscall.Syscall(procReleaseMutex.Addr(), 1, uintptr(mutex), 0, 0) if r1 == 0 { @@ -2990,6 +3022,30 @@ func VirtualProtect(address uintptr, size uintptr, newprotect uint32, oldprotect return } +func VirtualProtectEx(process Handle, address uintptr, size uintptr, newProtect uint32, oldProtect *uint32) (err error) { + r1, _, e1 := syscall.Syscall6(procVirtualProtectEx.Addr(), 5, uintptr(process), uintptr(address), uintptr(size), uintptr(newProtect), uintptr(unsafe.Pointer(oldProtect)), 0) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func VirtualQuery(address uintptr, buffer *MemoryBasicInformation, length uintptr) (err error) { + r1, _, e1 := syscall.Syscall(procVirtualQuery.Addr(), 3, uintptr(address), uintptr(unsafe.Pointer(buffer)), uintptr(length)) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func VirtualQueryEx(process Handle, address uintptr, buffer *MemoryBasicInformation, length uintptr) (err error) { + r1, _, e1 := syscall.Syscall6(procVirtualQueryEx.Addr(), 4, uintptr(process), uintptr(address), uintptr(unsafe.Pointer(buffer)), uintptr(length), 0, 0) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + func VirtualUnlock(addr uintptr, length uintptr) (err error) { r1, _, e1 := syscall.Syscall(procVirtualUnlock.Addr(), 2, uintptr(addr), uintptr(length), 0) if r1 == 0 { @@ -3046,6 +3102,14 @@ func WriteFile(handle Handle, buf []byte, done *uint32, overlapped *Overlapped) return } +func WriteProcessMemory(process Handle, baseAddress uintptr, buffer *byte, size uintptr, numberOfBytesWritten *uintptr) (err error) { + r1, _, e1 := syscall.Syscall6(procWriteProcessMemory.Addr(), 5, uintptr(process), uintptr(baseAddress), uintptr(unsafe.Pointer(buffer)), uintptr(size), uintptr(unsafe.Pointer(numberOfBytesWritten)), 0) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + func AcceptEx(ls Handle, as Handle, buf *byte, rxdatalen uint32, laddrlen uint32, raddrlen uint32, recvd *uint32, overlapped *Overlapped) (err error) { r1, _, e1 := syscall.Syscall9(procAcceptEx.Addr(), 8, uintptr(ls), uintptr(as), uintptr(unsafe.Pointer(buf)), uintptr(rxdatalen), uintptr(laddrlen), uintptr(raddrlen), uintptr(unsafe.Pointer(recvd)), uintptr(unsafe.Pointer(overlapped)), 0) if r1 == 0 { @@ -3107,6 +3171,14 @@ func NtCreateNamedPipeFile(pipe *Handle, access uint32, oa *OBJECT_ATTRIBUTES, i return } +func NtSetInformationFile(handle Handle, iosb *IO_STATUS_BLOCK, inBuffer *byte, inBufferLen uint32, class uint32) (ntstatus error) { + r0, _, _ := syscall.Syscall6(procNtSetInformationFile.Addr(), 5, uintptr(handle), uintptr(unsafe.Pointer(iosb)), uintptr(unsafe.Pointer(inBuffer)), uintptr(inBufferLen), uintptr(class), 0) + if r0 != 0 { + ntstatus = NTStatus(r0) + } + return +} + func NtQueryInformationProcess(proc Handle, procInfoClass int32, procInfo unsafe.Pointer, procInfoLen uint32, retLen *uint32) (ntstatus error) { r0, _, _ := syscall.Syscall6(procNtQueryInformationProcess.Addr(), 5, uintptr(proc), uintptr(procInfoClass), uintptr(procInfo), uintptr(procInfoLen), uintptr(unsafe.Pointer(retLen)), 0) if r0 != 0 { @@ -3115,6 +3187,14 @@ func NtQueryInformationProcess(proc Handle, procInfoClass int32, procInfo unsafe return } +func NtQuerySystemInformation(sysInfoClass int32, sysInfo unsafe.Pointer, sysInfoLen uint32, retLen *uint32) (ntstatus error) { + r0, _, _ := syscall.Syscall6(procNtQuerySystemInformation.Addr(), 4, uintptr(sysInfoClass), uintptr(sysInfo), uintptr(sysInfoLen), uintptr(unsafe.Pointer(retLen)), 0, 0) + if r0 != 0 { + ntstatus = NTStatus(r0) + } + return +} + func NtSetInformationProcess(proc Handle, procInfoClass int32, procInfo unsafe.Pointer, procInfoLen uint32) (ntstatus error) { r0, _, _ := syscall.Syscall6(procNtSetInformationProcess.Addr(), 4, uintptr(proc), uintptr(procInfoClass), uintptr(procInfo), uintptr(procInfoLen), 0, 0) if r0 != 0 { @@ -3123,6 +3203,20 @@ func NtSetInformationProcess(proc Handle, procInfoClass int32, procInfo unsafe.P return } +func NtSetSystemInformation(sysInfoClass int32, sysInfo unsafe.Pointer, sysInfoLen uint32) (ntstatus error) { + r0, _, _ := syscall.Syscall(procNtSetSystemInformation.Addr(), 3, uintptr(sysInfoClass), uintptr(sysInfo), uintptr(sysInfoLen)) + if r0 != 0 { + ntstatus = NTStatus(r0) + } + return +} + +func RtlAddFunctionTable(functionTable *RUNTIME_FUNCTION, entryCount uint32, baseAddress uintptr) (ret bool) { + r0, _, _ := syscall.Syscall(procRtlAddFunctionTable.Addr(), 3, uintptr(unsafe.Pointer(functionTable)), uintptr(entryCount), uintptr(baseAddress)) + ret = r0 != 0 + return +} + func RtlDefaultNpAcl(acl **ACL) (ntstatus error) { r0, _, _ := syscall.Syscall(procRtlDefaultNpAcl.Addr(), 1, uintptr(unsafe.Pointer(acl)), 0, 0) if r0 != 0 { @@ -3131,6 +3225,12 @@ func RtlDefaultNpAcl(acl **ACL) (ntstatus error) { return } +func RtlDeleteFunctionTable(functionTable *RUNTIME_FUNCTION) (ret bool) { + r0, _, _ := syscall.Syscall(procRtlDeleteFunctionTable.Addr(), 1, uintptr(unsafe.Pointer(functionTable)), 0, 0) + ret = r0 != 0 + return +} + func RtlDosPathNameToNtPathName(dosName *uint16, ntName *NTUnicodeString, ntFileNamePart *uint16, relativeName *RTL_RELATIVE_NAME) (ntstatus error) { r0, _, _ := syscall.Syscall6(procRtlDosPathNameToNtPathName_U_WithStatus.Addr(), 4, uintptr(unsafe.Pointer(dosName)), uintptr(unsafe.Pointer(ntName)), uintptr(unsafe.Pointer(ntFileNamePart)), uintptr(unsafe.Pointer(relativeName)), 0, 0) if r0 != 0 { @@ -3404,6 +3504,58 @@ func GetUserProfileDirectory(t Token, dir *uint16, dirLen *uint32) (err error) { return } +func GetFileVersionInfoSize(filename string, zeroHandle *Handle) (bufSize uint32, err error) { + var _p0 *uint16 + _p0, err = syscall.UTF16PtrFromString(filename) + if err != nil { + return + } + return _GetFileVersionInfoSize(_p0, zeroHandle) +} + +func _GetFileVersionInfoSize(filename *uint16, zeroHandle *Handle) (bufSize uint32, err error) { + r0, _, e1 := syscall.Syscall(procGetFileVersionInfoSizeW.Addr(), 2, uintptr(unsafe.Pointer(filename)), uintptr(unsafe.Pointer(zeroHandle)), 0) + bufSize = uint32(r0) + if bufSize == 0 { + err = errnoErr(e1) + } + return +} + +func GetFileVersionInfo(filename string, handle uint32, bufSize uint32, buffer unsafe.Pointer) (err error) { + var _p0 *uint16 + _p0, err = syscall.UTF16PtrFromString(filename) + if err != nil { + return + } + return _GetFileVersionInfo(_p0, handle, bufSize, buffer) +} + +func _GetFileVersionInfo(filename *uint16, handle uint32, bufSize uint32, buffer unsafe.Pointer) (err error) { + r1, _, e1 := syscall.Syscall6(procGetFileVersionInfoW.Addr(), 4, uintptr(unsafe.Pointer(filename)), uintptr(handle), uintptr(bufSize), uintptr(buffer), 0, 0) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func VerQueryValue(block unsafe.Pointer, subBlock string, pointerToBufferPointer unsafe.Pointer, bufSize *uint32) (err error) { + var _p0 *uint16 + _p0, err = syscall.UTF16PtrFromString(subBlock) + if err != nil { + return + } + return _VerQueryValue(block, _p0, pointerToBufferPointer, bufSize) +} + +func _VerQueryValue(block unsafe.Pointer, subBlock *uint16, pointerToBufferPointer unsafe.Pointer, bufSize *uint32) (err error) { + r1, _, e1 := syscall.Syscall6(procVerQueryValueW.Addr(), 4, uintptr(block), uintptr(unsafe.Pointer(subBlock)), uintptr(pointerToBufferPointer), uintptr(unsafe.Pointer(bufSize)), 0, 0) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + func WinVerifyTrustEx(hwnd HWND, actionId *GUID, data *WinTrustData) (ret error) { r0, _, _ := syscall.Syscall(procWinVerifyTrustEx.Addr(), 3, uintptr(hwnd), uintptr(unsafe.Pointer(actionId)), uintptr(unsafe.Pointer(data))) if r0 != 0 { diff --git a/vendor/google.golang.org/genproto/googleapis/api/httpbody/httpbody.pb.go b/vendor/google.golang.org/genproto/googleapis/api/httpbody/httpbody.pb.go index b47efe82b2..7ea5ced87e 100644 --- a/vendor/google.golang.org/genproto/googleapis/api/httpbody/httpbody.pb.go +++ b/vendor/google.golang.org/genproto/googleapis/api/httpbody/httpbody.pb.go @@ -56,12 +56,15 @@ const ( // // // The raw HTTP body is bound to this field. // google.api.HttpBody http_body = 2; +// // } // // service ResourceService { -// rpc GetResource(GetResourceRequest) returns (google.api.HttpBody); -// rpc UpdateResource(google.api.HttpBody) returns -// (google.protobuf.Empty); +// rpc GetResource(GetResourceRequest) +// returns (google.api.HttpBody); +// rpc UpdateResource(google.api.HttpBody) +// returns (google.protobuf.Empty); +// // } // // Example with streaming methods: @@ -71,6 +74,7 @@ const ( // returns (stream google.api.HttpBody); // rpc UpdateCalendar(stream google.api.HttpBody) // returns (stream google.api.HttpBody); +// // } // // Use of this type only changes how the request and response bodies are diff --git a/vendor/google.golang.org/grpc/MAINTAINERS.md b/vendor/google.golang.org/grpc/MAINTAINERS.md index 093c82b3af..c6672c0a3e 100644 --- a/vendor/google.golang.org/grpc/MAINTAINERS.md +++ b/vendor/google.golang.org/grpc/MAINTAINERS.md @@ -8,17 +8,18 @@ See [CONTRIBUTING.md](https://github.com/grpc/grpc-community/blob/master/CONTRIB for general contribution guidelines. ## Maintainers (in alphabetical order) -- [canguler](https://github.com/canguler), Google LLC + - [cesarghali](https://github.com/cesarghali), Google LLC - [dfawley](https://github.com/dfawley), Google LLC - [easwars](https://github.com/easwars), Google LLC -- [jadekler](https://github.com/jadekler), Google LLC - [menghanl](https://github.com/menghanl), Google LLC - [srini100](https://github.com/srini100), Google LLC ## Emeritus Maintainers (in alphabetical order) - [adelez](https://github.com/adelez), Google LLC +- [canguler](https://github.com/canguler), Google LLC - [iamqizhao](https://github.com/iamqizhao), Google LLC +- [jadekler](https://github.com/jadekler), Google LLC - [jtattermusch](https://github.com/jtattermusch), Google LLC - [lyuxuan](https://github.com/lyuxuan), Google LLC - [makmukhi](https://github.com/makmukhi), Google LLC diff --git a/vendor/google.golang.org/grpc/Makefile b/vendor/google.golang.org/grpc/Makefile index 1f0722f162..1f8960922b 100644 --- a/vendor/google.golang.org/grpc/Makefile +++ b/vendor/google.golang.org/grpc/Makefile @@ -41,8 +41,6 @@ vetdeps: clean \ proto \ test \ - testappengine \ - testappenginedeps \ testrace \ vet \ vetdeps diff --git a/vendor/google.golang.org/grpc/NOTICE.txt b/vendor/google.golang.org/grpc/NOTICE.txt new file mode 100644 index 0000000000..530197749e --- /dev/null +++ b/vendor/google.golang.org/grpc/NOTICE.txt @@ -0,0 +1,13 @@ +Copyright 2014 gRPC authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/vendor/google.golang.org/grpc/balancer/balancer.go b/vendor/google.golang.org/grpc/balancer/balancer.go index ab531f4c0b..178de0898a 100644 --- a/vendor/google.golang.org/grpc/balancer/balancer.go +++ b/vendor/google.golang.org/grpc/balancer/balancer.go @@ -75,24 +75,26 @@ func Get(name string) Builder { return nil } -// SubConn represents a gRPC sub connection. -// Each sub connection contains a list of addresses. gRPC will -// try to connect to them (in sequence), and stop trying the -// remainder once one connection is successful. +// A SubConn represents a single connection to a gRPC backend service. // -// The reconnect backoff will be applied on the list, not a single address. -// For example, try_on_all_addresses -> backoff -> try_on_all_addresses. +// Each SubConn contains a list of addresses. // -// All SubConns start in IDLE, and will not try to connect. To trigger -// the connecting, Balancers must call Connect. -// When the connection encounters an error, it will reconnect immediately. -// When the connection becomes IDLE, it will not reconnect unless Connect is -// called. +// All SubConns start in IDLE, and will not try to connect. To trigger the +// connecting, Balancers must call Connect. If a connection re-enters IDLE, +// Balancers must call Connect again to trigger a new connection attempt. // -// This interface is to be implemented by gRPC. Users should not need a -// brand new implementation of this interface. For the situations like -// testing, the new implementation should embed this interface. This allows -// gRPC to add new methods to this interface. +// gRPC will try to connect to the addresses in sequence, and stop trying the +// remainder once the first connection is successful. If an attempt to connect +// to all addresses encounters an error, the SubConn will enter +// TRANSIENT_FAILURE for a backoff period, and then transition to IDLE. +// +// Once established, if a connection is lost, the SubConn will transition +// directly to IDLE. +// +// This interface is to be implemented by gRPC. Users should not need their own +// implementation of this interface. For situations like testing, any +// implementations should embed this interface. This allows gRPC to add new +// methods to this interface. type SubConn interface { // UpdateAddresses updates the addresses used in this SubConn. // gRPC checks if currently-connected address is still in the new list. @@ -326,6 +328,20 @@ type Balancer interface { Close() } +// ExitIdler is an optional interface for balancers to implement. If +// implemented, ExitIdle will be called when ClientConn.Connect is called, if +// the ClientConn is idle. If unimplemented, ClientConn.Connect will cause +// all SubConns to connect. +// +// Notice: it will be required for all balancers to implement this in a future +// release. +type ExitIdler interface { + // ExitIdle instructs the LB policy to reconnect to backends / exit the + // IDLE state, if appropriate and possible. Note that SubConns that enter + // the IDLE state will not reconnect until SubConn.Connect is called. + ExitIdle() +} + // SubConnState describes the state of a SubConn. type SubConnState struct { // ConnectivityState is the connectivity state of the SubConn. @@ -353,8 +369,10 @@ var ErrBadResolverState = errors.New("bad resolver state") // // It's not thread safe. type ConnectivityStateEvaluator struct { - numReady uint64 // Number of addrConns in ready state. - numConnecting uint64 // Number of addrConns in connecting state. + numReady uint64 // Number of addrConns in ready state. + numConnecting uint64 // Number of addrConns in connecting state. + numTransientFailure uint64 // Number of addrConns in transient failure state. + numIdle uint64 // Number of addrConns in idle state. } // RecordTransition records state change happening in subConn and based on that @@ -362,9 +380,11 @@ type ConnectivityStateEvaluator struct { // // - If at least one SubConn in Ready, the aggregated state is Ready; // - Else if at least one SubConn in Connecting, the aggregated state is Connecting; -// - Else the aggregated state is TransientFailure. +// - Else if at least one SubConn is TransientFailure, the aggregated state is Transient Failure; +// - Else if at least one SubConn is Idle, the aggregated state is Idle; +// - Else there are no subconns and the aggregated state is Transient Failure // -// Idle and Shutdown are not considered. +// Shutdown is not considered. func (cse *ConnectivityStateEvaluator) RecordTransition(oldState, newState connectivity.State) connectivity.State { // Update counters. for idx, state := range []connectivity.State{oldState, newState} { @@ -374,6 +394,10 @@ func (cse *ConnectivityStateEvaluator) RecordTransition(oldState, newState conne cse.numReady += updateVal case connectivity.Connecting: cse.numConnecting += updateVal + case connectivity.TransientFailure: + cse.numTransientFailure += updateVal + case connectivity.Idle: + cse.numIdle += updateVal } } @@ -384,5 +408,11 @@ func (cse *ConnectivityStateEvaluator) RecordTransition(oldState, newState conne if cse.numConnecting > 0 { return connectivity.Connecting } + if cse.numTransientFailure > 0 { + return connectivity.TransientFailure + } + if cse.numIdle > 0 { + return connectivity.Idle + } return connectivity.TransientFailure } diff --git a/vendor/google.golang.org/grpc/balancer/base/balancer.go b/vendor/google.golang.org/grpc/balancer/base/balancer.go index c883efa0bb..8dd504299f 100644 --- a/vendor/google.golang.org/grpc/balancer/base/balancer.go +++ b/vendor/google.golang.org/grpc/balancer/base/balancer.go @@ -133,6 +133,7 @@ func (b *baseBalancer) UpdateClientConnState(s balancer.ClientConnState) error { } b.subConns[aNoAttrs] = subConnInfo{subConn: sc, attrs: a.Attributes} b.scStates[sc] = connectivity.Idle + b.csEvltr.RecordTransition(connectivity.Shutdown, connectivity.Idle) sc.Connect() } else { // Always update the subconn's address in case the attributes @@ -213,10 +214,14 @@ func (b *baseBalancer) UpdateSubConnState(sc balancer.SubConn, state balancer.Su } return } - if oldS == connectivity.TransientFailure && s == connectivity.Connecting { - // Once a subconn enters TRANSIENT_FAILURE, ignore subsequent + if oldS == connectivity.TransientFailure && + (s == connectivity.Connecting || s == connectivity.Idle) { + // Once a subconn enters TRANSIENT_FAILURE, ignore subsequent IDLE or // CONNECTING transitions to prevent the aggregated state from being // always CONNECTING when many backends exist but are all down. + if s == connectivity.Idle { + sc.Connect() + } return } b.scStates[sc] = s @@ -242,7 +247,6 @@ func (b *baseBalancer) UpdateSubConnState(sc balancer.SubConn, state balancer.Su b.state == connectivity.TransientFailure { b.regeneratePicker() } - b.cc.UpdateState(balancer.State{ConnectivityState: b.state, Picker: b.picker}) } @@ -251,6 +255,11 @@ func (b *baseBalancer) UpdateSubConnState(sc balancer.SubConn, state balancer.Su func (b *baseBalancer) Close() { } +// ExitIdle is a nop because the base balancer attempts to stay connected to +// all SubConns at all times. +func (b *baseBalancer) ExitIdle() { +} + // NewErrPicker returns a Picker that always returns err on Pick(). func NewErrPicker(err error) balancer.Picker { return &errPicker{err: err} diff --git a/vendor/google.golang.org/grpc/balancer/roundrobin/roundrobin.go b/vendor/google.golang.org/grpc/balancer/roundrobin/roundrobin.go index 43c2a15373..274eb2f858 100644 --- a/vendor/google.golang.org/grpc/balancer/roundrobin/roundrobin.go +++ b/vendor/google.golang.org/grpc/balancer/roundrobin/roundrobin.go @@ -47,11 +47,11 @@ func init() { type rrPickerBuilder struct{} func (*rrPickerBuilder) Build(info base.PickerBuildInfo) balancer.Picker { - logger.Infof("roundrobinPicker: newPicker called with info: %v", info) + logger.Infof("roundrobinPicker: Build called with info: %v", info) if len(info.ReadySCs) == 0 { return base.NewErrPicker(balancer.ErrNoSubConnAvailable) } - var scs []balancer.SubConn + scs := make([]balancer.SubConn, 0, len(info.ReadySCs)) for sc := range info.ReadySCs { scs = append(scs, sc) } diff --git a/vendor/google.golang.org/grpc/balancer_conn_wrappers.go b/vendor/google.golang.org/grpc/balancer_conn_wrappers.go index dd83979639..f4ea617468 100644 --- a/vendor/google.golang.org/grpc/balancer_conn_wrappers.go +++ b/vendor/google.golang.org/grpc/balancer_conn_wrappers.go @@ -37,15 +37,20 @@ type scStateUpdate struct { err error } +// exitIdle contains no data and is just a signal sent on the updateCh in +// ccBalancerWrapper to instruct the balancer to exit idle. +type exitIdle struct{} + // ccBalancerWrapper is a wrapper on top of cc for balancers. // It implements balancer.ClientConn interface. type ccBalancerWrapper struct { - cc *ClientConn - balancerMu sync.Mutex // synchronizes calls to the balancer - balancer balancer.Balancer - updateCh *buffer.Unbounded - closed *grpcsync.Event - done *grpcsync.Event + cc *ClientConn + balancerMu sync.Mutex // synchronizes calls to the balancer + balancer balancer.Balancer + hasExitIdle bool + updateCh *buffer.Unbounded + closed *grpcsync.Event + done *grpcsync.Event mu sync.Mutex subConns map[*acBalancerWrapper]struct{} @@ -61,6 +66,7 @@ func newCCBalancerWrapper(cc *ClientConn, b balancer.Builder, bopts balancer.Bui } go ccb.watcher() ccb.balancer = b.Build(ccb, bopts) + _, ccb.hasExitIdle = ccb.balancer.(balancer.ExitIdler) return ccb } @@ -86,6 +92,17 @@ func (ccb *ccBalancerWrapper) watcher() { ccb.cc.removeAddrConn(u.getAddrConn(), errConnDrain) } ccb.mu.Unlock() + case exitIdle: + if ccb.cc.GetState() == connectivity.Idle { + if ei, ok := ccb.balancer.(balancer.ExitIdler); ok { + // We already checked that the balancer implements + // ExitIdle before pushing the event to updateCh, but + // check conditionally again as defensive programming. + ccb.balancerMu.Lock() + ei.ExitIdle() + ccb.balancerMu.Unlock() + } + } default: logger.Errorf("ccBalancerWrapper.watcher: unknown update %+v, type %T", t, t) } @@ -118,6 +135,14 @@ func (ccb *ccBalancerWrapper) close() { <-ccb.done.Done() } +func (ccb *ccBalancerWrapper) exitIdle() bool { + if !ccb.hasExitIdle { + return false + } + ccb.updateCh.Put(exitIdle{}) + return true +} + func (ccb *ccBalancerWrapper) handleSubConnStateChange(sc balancer.SubConn, s connectivity.State, err error) { // When updating addresses for a SubConn, if the address in use is not in // the new addresses, the old ac will be tearDown() and a new ac will be @@ -144,8 +169,8 @@ func (ccb *ccBalancerWrapper) updateClientConnState(ccs *balancer.ClientConnStat func (ccb *ccBalancerWrapper) resolverError(err error) { ccb.balancerMu.Lock() + defer ccb.balancerMu.Unlock() ccb.balancer.ResolverError(err) - ccb.balancerMu.Unlock() } func (ccb *ccBalancerWrapper) NewSubConn(addrs []resolver.Address, opts balancer.NewSubConnOptions) (balancer.SubConn, error) { @@ -239,17 +264,17 @@ func (acbw *acBalancerWrapper) UpdateAddresses(addrs []resolver.Address) { return } - ac, err := cc.newAddrConn(addrs, opts) + newAC, err := cc.newAddrConn(addrs, opts) if err != nil { channelz.Warningf(logger, acbw.ac.channelzID, "acBalancerWrapper: UpdateAddresses: failed to newAddrConn: %v", err) return } - acbw.ac = ac - ac.mu.Lock() - ac.acbw = acbw - ac.mu.Unlock() + acbw.ac = newAC + newAC.mu.Lock() + newAC.acbw = acbw + newAC.mu.Unlock() if acState != connectivity.Idle { - ac.connect() + go newAC.connect() } } } @@ -257,7 +282,7 @@ func (acbw *acBalancerWrapper) UpdateAddresses(addrs []resolver.Address) { func (acbw *acBalancerWrapper) Connect() { acbw.mu.Lock() defer acbw.mu.Unlock() - acbw.ac.connect() + go acbw.ac.connect() } func (acbw *acBalancerWrapper) getAddrConn() *addrConn { diff --git a/vendor/google.golang.org/grpc/clientconn.go b/vendor/google.golang.org/grpc/clientconn.go index b2bccfed13..34cc4c948d 100644 --- a/vendor/google.golang.org/grpc/clientconn.go +++ b/vendor/google.golang.org/grpc/clientconn.go @@ -322,6 +322,7 @@ func DialContext(ctx context.Context, target string, opts ...DialOption) (conn * // A blocking dial blocks until the clientConn is ready. if cc.dopts.block { for { + cc.Connect() s := cc.GetState() if s == connectivity.Ready { break @@ -539,12 +540,31 @@ func (cc *ClientConn) WaitForStateChange(ctx context.Context, sourceState connec // // Experimental // -// Notice: This API is EXPERIMENTAL and may be changed or removed in a -// later release. +// Notice: This API is EXPERIMENTAL and may be changed or removed in a later +// release. func (cc *ClientConn) GetState() connectivity.State { return cc.csMgr.getState() } +// Connect causes all subchannels in the ClientConn to attempt to connect if +// the channel is idle. Does not wait for the connection attempts to begin +// before returning. +// +// Experimental +// +// Notice: This API is EXPERIMENTAL and may be changed or removed in a later +// release. +func (cc *ClientConn) Connect() { + cc.mu.Lock() + defer cc.mu.Unlock() + if cc.balancerWrapper != nil && cc.balancerWrapper.exitIdle() { + return + } + for ac := range cc.conns { + go ac.connect() + } +} + func (cc *ClientConn) scWatcher() { for { select { @@ -845,8 +865,7 @@ func (ac *addrConn) connect() error { ac.updateConnectivityState(connectivity.Connecting, nil) ac.mu.Unlock() - // Start a goroutine connecting to the server asynchronously. - go ac.resetTransport() + ac.resetTransport() return nil } @@ -883,6 +902,10 @@ func (ac *addrConn) tryUpdateAddrs(addrs []resolver.Address) bool { // ac.state is Ready, try to find the connected address. var curAddrFound bool for _, a := range addrs { + // a.ServerName takes precedent over ClientConn authority, if present. + if a.ServerName == "" { + a.ServerName = ac.cc.authority + } if reflect.DeepEqual(ac.curAddr, a) { curAddrFound = true break @@ -1135,112 +1158,86 @@ func (ac *addrConn) adjustParams(r transport.GoAwayReason) { } func (ac *addrConn) resetTransport() { - for i := 0; ; i++ { - if i > 0 { - ac.cc.resolveNow(resolver.ResolveNowOptions{}) - } + ac.mu.Lock() + if ac.state == connectivity.Shutdown { + ac.mu.Unlock() + return + } + + addrs := ac.addrs + backoffFor := ac.dopts.bs.Backoff(ac.backoffIdx) + // This will be the duration that dial gets to finish. + dialDuration := minConnectTimeout + if ac.dopts.minConnectTimeout != nil { + dialDuration = ac.dopts.minConnectTimeout() + } + + if dialDuration < backoffFor { + // Give dial more time as we keep failing to connect. + dialDuration = backoffFor + } + // We can potentially spend all the time trying the first address, and + // if the server accepts the connection and then hangs, the following + // addresses will never be tried. + // + // The spec doesn't mention what should be done for multiple addresses. + // https://github.com/grpc/grpc/blob/master/doc/connection-backoff.md#proposed-backoff-algorithm + connectDeadline := time.Now().Add(dialDuration) + + ac.updateConnectivityState(connectivity.Connecting, nil) + ac.mu.Unlock() + if err := ac.tryAllAddrs(addrs, connectDeadline); err != nil { + ac.cc.resolveNow(resolver.ResolveNowOptions{}) + // After exhausting all addresses, the addrConn enters + // TRANSIENT_FAILURE. ac.mu.Lock() if ac.state == connectivity.Shutdown { ac.mu.Unlock() return } + ac.updateConnectivityState(connectivity.TransientFailure, err) - addrs := ac.addrs - backoffFor := ac.dopts.bs.Backoff(ac.backoffIdx) - // This will be the duration that dial gets to finish. - dialDuration := minConnectTimeout - if ac.dopts.minConnectTimeout != nil { - dialDuration = ac.dopts.minConnectTimeout() - } - - if dialDuration < backoffFor { - // Give dial more time as we keep failing to connect. - dialDuration = backoffFor - } - // We can potentially spend all the time trying the first address, and - // if the server accepts the connection and then hangs, the following - // addresses will never be tried. - // - // The spec doesn't mention what should be done for multiple addresses. - // https://github.com/grpc/grpc/blob/master/doc/connection-backoff.md#proposed-backoff-algorithm - connectDeadline := time.Now().Add(dialDuration) - - ac.updateConnectivityState(connectivity.Connecting, nil) - ac.transport = nil + // Backoff. + b := ac.resetBackoff ac.mu.Unlock() - newTr, addr, reconnect, err := ac.tryAllAddrs(addrs, connectDeadline) - if err != nil { - // After exhausting all addresses, the addrConn enters - // TRANSIENT_FAILURE. + timer := time.NewTimer(backoffFor) + select { + case <-timer.C: ac.mu.Lock() - if ac.state == connectivity.Shutdown { - ac.mu.Unlock() - return - } - ac.updateConnectivityState(connectivity.TransientFailure, err) - - // Backoff. - b := ac.resetBackoff + ac.backoffIdx++ ac.mu.Unlock() - - timer := time.NewTimer(backoffFor) - select { - case <-timer.C: - ac.mu.Lock() - ac.backoffIdx++ - ac.mu.Unlock() - case <-b: - timer.Stop() - case <-ac.ctx.Done(): - timer.Stop() - return - } - continue + case <-b: + timer.Stop() + case <-ac.ctx.Done(): + timer.Stop() + return } ac.mu.Lock() - if ac.state == connectivity.Shutdown { - ac.mu.Unlock() - newTr.Close(fmt.Errorf("reached connectivity state: SHUTDOWN")) - return + if ac.state != connectivity.Shutdown { + ac.updateConnectivityState(connectivity.Idle, err) } - ac.curAddr = addr - ac.transport = newTr - ac.backoffIdx = 0 - - hctx, hcancel := context.WithCancel(ac.ctx) - ac.startHealthCheck(hctx) ac.mu.Unlock() - - // Block until the created transport is down. And when this happens, - // we restart from the top of the addr list. - <-reconnect.Done() - hcancel() - // restart connecting - the top of the loop will set state to - // CONNECTING. This is against the current connectivity semantics doc, - // however it allows for graceful behavior for RPCs not yet dispatched - // - unfortunate timing would otherwise lead to the RPC failing even - // though the TRANSIENT_FAILURE state (called for by the doc) would be - // instantaneous. - // - // Ideally we should transition to Idle here and block until there is - // RPC activity that leads to the balancer requesting a reconnect of - // the associated SubConn. + return } + // Success; reset backoff. + ac.mu.Lock() + ac.backoffIdx = 0 + ac.mu.Unlock() } -// tryAllAddrs tries to creates a connection to the addresses, and stop when at the -// first successful one. It returns the transport, the address and a Event in -// the successful case. The Event fires when the returned transport disconnects. -func (ac *addrConn) tryAllAddrs(addrs []resolver.Address, connectDeadline time.Time) (transport.ClientTransport, resolver.Address, *grpcsync.Event, error) { +// tryAllAddrs tries to creates a connection to the addresses, and stop when at +// the first successful one. It returns an error if no address was successfully +// connected, or updates ac appropriately with the new transport. +func (ac *addrConn) tryAllAddrs(addrs []resolver.Address, connectDeadline time.Time) error { var firstConnErr error for _, addr := range addrs { ac.mu.Lock() if ac.state == connectivity.Shutdown { ac.mu.Unlock() - return nil, resolver.Address{}, nil, errConnClosing + return errConnClosing } ac.cc.mu.RLock() @@ -1255,9 +1252,9 @@ func (ac *addrConn) tryAllAddrs(addrs []resolver.Address, connectDeadline time.T channelz.Infof(logger, ac.channelzID, "Subchannel picks a new address %q to connect", addr.Addr) - newTr, reconnect, err := ac.createTransport(addr, copts, connectDeadline) + err := ac.createTransport(addr, copts, connectDeadline) if err == nil { - return newTr, addr, reconnect, nil + return nil } if firstConnErr == nil { firstConnErr = err @@ -1266,57 +1263,54 @@ func (ac *addrConn) tryAllAddrs(addrs []resolver.Address, connectDeadline time.T } // Couldn't connect to any address. - return nil, resolver.Address{}, nil, firstConnErr + return firstConnErr } -// createTransport creates a connection to addr. It returns the transport and a -// Event in the successful case. The Event fires when the returned transport -// disconnects. -func (ac *addrConn) createTransport(addr resolver.Address, copts transport.ConnectOptions, connectDeadline time.Time) (transport.ClientTransport, *grpcsync.Event, error) { - prefaceReceived := make(chan struct{}) - onCloseCalled := make(chan struct{}) - reconnect := grpcsync.NewEvent() +// createTransport creates a connection to addr. It returns an error if the +// address was not successfully connected, or updates ac appropriately with the +// new transport. +func (ac *addrConn) createTransport(addr resolver.Address, copts transport.ConnectOptions, connectDeadline time.Time) error { + // TODO: Delete prefaceReceived and move the logic to wait for it into the + // transport. + prefaceReceived := grpcsync.NewEvent() + connClosed := grpcsync.NewEvent() // addr.ServerName takes precedent over ClientConn authority, if present. if addr.ServerName == "" { addr.ServerName = ac.cc.authority } - once := sync.Once{} - onGoAway := func(r transport.GoAwayReason) { - ac.mu.Lock() - ac.adjustParams(r) - once.Do(func() { - if ac.state == connectivity.Ready { - // Prevent this SubConn from being used for new RPCs by setting its - // state to Connecting. - // - // TODO: this should be Idle when grpc-go properly supports it. - ac.updateConnectivityState(connectivity.Connecting, nil) - } - }) - ac.mu.Unlock() - reconnect.Fire() - } + hctx, hcancel := context.WithCancel(ac.ctx) + hcStarted := false // protected by ac.mu onClose := func() { ac.mu.Lock() - once.Do(func() { - if ac.state == connectivity.Ready { - // Prevent this SubConn from being used for new RPCs by setting its - // state to Connecting. - // - // TODO: this should be Idle when grpc-go properly supports it. - ac.updateConnectivityState(connectivity.Connecting, nil) - } - }) - ac.mu.Unlock() - close(onCloseCalled) - reconnect.Fire() + defer ac.mu.Unlock() + defer connClosed.Fire() + if !hcStarted || hctx.Err() != nil { + // We didn't start the health check or set the state to READY, so + // no need to do anything else here. + // + // OR, we have already cancelled the health check context, meaning + // we have already called onClose once for this transport. In this + // case it would be dangerous to clear the transport and update the + // state, since there may be a new transport in this addrConn. + return + } + hcancel() + ac.transport = nil + // Refresh the name resolver + ac.cc.resolveNow(resolver.ResolveNowOptions{}) + if ac.state != connectivity.Shutdown { + ac.updateConnectivityState(connectivity.Idle, nil) + } } - onPrefaceReceipt := func() { - close(prefaceReceived) + onGoAway := func(r transport.GoAwayReason) { + ac.mu.Lock() + ac.adjustParams(r) + ac.mu.Unlock() + onClose() } connectCtx, cancel := context.WithDeadline(ac.ctx, connectDeadline) @@ -1325,27 +1319,67 @@ func (ac *addrConn) createTransport(addr resolver.Address, copts transport.Conne copts.ChannelzParentID = ac.channelzID } - newTr, err := transport.NewClientTransport(connectCtx, ac.cc.ctx, addr, copts, onPrefaceReceipt, onGoAway, onClose) + newTr, err := transport.NewClientTransport(connectCtx, ac.cc.ctx, addr, copts, func() { prefaceReceived.Fire() }, onGoAway, onClose) if err != nil { // newTr is either nil, or closed. - channelz.Warningf(logger, ac.channelzID, "grpc: addrConn.createTransport failed to connect to %v. Err: %v. Reconnecting...", addr, err) - return nil, nil, err + channelz.Warningf(logger, ac.channelzID, "grpc: addrConn.createTransport failed to connect to %v. Err: %v", addr, err) + return err } select { - case <-time.After(time.Until(connectDeadline)): + case <-connectCtx.Done(): // We didn't get the preface in time. - newTr.Close(fmt.Errorf("failed to receive server preface within timeout")) - channelz.Warningf(logger, ac.channelzID, "grpc: addrConn.createTransport failed to connect to %v: didn't receive server preface in time. Reconnecting...", addr) - return nil, nil, errors.New("timed out waiting for server handshake") - case <-prefaceReceived: + // The error we pass to Close() is immaterial since there are no open + // streams at this point, so no trailers with error details will be sent + // out. We just need to pass a non-nil error. + newTr.Close(transport.ErrConnClosing) + if connectCtx.Err() == context.DeadlineExceeded { + err := errors.New("failed to receive server preface within timeout") + channelz.Warningf(logger, ac.channelzID, "grpc: addrConn.createTransport failed to connect to %v: %v", addr, err) + return err + } + return nil + case <-prefaceReceived.Done(): // We got the preface - huzzah! things are good. - case <-onCloseCalled: - // The transport has already closed - noop. - return nil, nil, errors.New("connection closed") - // TODO(deklerk) this should bail on ac.ctx.Done(). Add a test and fix. + ac.mu.Lock() + defer ac.mu.Unlock() + if connClosed.HasFired() { + // onClose called first; go idle but do nothing else. + if ac.state != connectivity.Shutdown { + ac.updateConnectivityState(connectivity.Idle, nil) + } + return nil + } + if ac.state == connectivity.Shutdown { + // This can happen if the subConn was removed while in `Connecting` + // state. tearDown() would have set the state to `Shutdown`, but + // would not have closed the transport since ac.transport would not + // been set at that point. + // + // We run this in a goroutine because newTr.Close() calls onClose() + // inline, which requires locking ac.mu. + // + // The error we pass to Close() is immaterial since there are no open + // streams at this point, so no trailers with error details will be sent + // out. We just need to pass a non-nil error. + go newTr.Close(transport.ErrConnClosing) + return nil + } + ac.curAddr = addr + ac.transport = newTr + hcStarted = true + ac.startHealthCheck(hctx) // Will set state to READY if appropriate. + return nil + case <-connClosed.Done(): + // The transport has already closed. If we received the preface, too, + // this is not an error. + select { + case <-prefaceReceived.Done(): + return nil + default: + return errors.New("connection closed before server preface received") + } } - return newTr, reconnect, nil } // startHealthCheck starts the health checking stream (RPC) to watch the health diff --git a/vendor/google.golang.org/grpc/connectivity/connectivity.go b/vendor/google.golang.org/grpc/connectivity/connectivity.go index 0101562615..4a89926422 100644 --- a/vendor/google.golang.org/grpc/connectivity/connectivity.go +++ b/vendor/google.golang.org/grpc/connectivity/connectivity.go @@ -18,7 +18,6 @@ // Package connectivity defines connectivity semantics. // For details, see https://github.com/grpc/grpc/blob/master/doc/connectivity-semantics-and-api.md. -// All APIs in this package are experimental. package connectivity import ( @@ -45,7 +44,7 @@ func (s State) String() string { return "SHUTDOWN" default: logger.Errorf("unknown connectivity state: %d", s) - return "Invalid-State" + return "INVALID_STATE" } } @@ -61,3 +60,35 @@ const ( // Shutdown indicates the ClientConn has started shutting down. Shutdown ) + +// ServingMode indicates the current mode of operation of the server. +// +// Only xDS enabled gRPC servers currently report their serving mode. +type ServingMode int + +const ( + // ServingModeStarting indicates that the server is starting up. + ServingModeStarting ServingMode = iota + // ServingModeServing indicates that the server contains all required + // configuration and is serving RPCs. + ServingModeServing + // ServingModeNotServing indicates that the server is not accepting new + // connections. Existing connections will be closed gracefully, allowing + // in-progress RPCs to complete. A server enters this mode when it does not + // contain the required configuration to serve RPCs. + ServingModeNotServing +) + +func (s ServingMode) String() string { + switch s { + case ServingModeStarting: + return "STARTING" + case ServingModeServing: + return "SERVING" + case ServingModeNotServing: + return "NOT_SERVING" + default: + logger.Errorf("unknown serving mode: %d", s) + return "INVALID_MODE" + } +} diff --git a/vendor/google.golang.org/grpc/credentials/go12.go b/vendor/google.golang.org/grpc/credentials/go12.go deleted file mode 100644 index ccbf35b331..0000000000 --- a/vendor/google.golang.org/grpc/credentials/go12.go +++ /dev/null @@ -1,30 +0,0 @@ -// +build go1.12 - -/* - * - * Copyright 2019 gRPC authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -package credentials - -import "crypto/tls" - -// This init function adds cipher suite constants only defined in Go 1.12. -func init() { - cipherSuiteLookup[tls.TLS_AES_128_GCM_SHA256] = "TLS_AES_128_GCM_SHA256" - cipherSuiteLookup[tls.TLS_AES_256_GCM_SHA384] = "TLS_AES_256_GCM_SHA384" - cipherSuiteLookup[tls.TLS_CHACHA20_POLY1305_SHA256] = "TLS_CHACHA20_POLY1305_SHA256" -} diff --git a/vendor/google.golang.org/grpc/credentials/tls.go b/vendor/google.golang.org/grpc/credentials/tls.go index 8ee7124f22..784822d056 100644 --- a/vendor/google.golang.org/grpc/credentials/tls.go +++ b/vendor/google.golang.org/grpc/credentials/tls.go @@ -230,4 +230,7 @@ var cipherSuiteLookup = map[uint16]string{ tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256: "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256", tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305: "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305", tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305: "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305", + tls.TLS_AES_128_GCM_SHA256: "TLS_AES_128_GCM_SHA256", + tls.TLS_AES_256_GCM_SHA384: "TLS_AES_256_GCM_SHA384", + tls.TLS_CHACHA20_POLY1305_SHA256: "TLS_CHACHA20_POLY1305_SHA256", } diff --git a/vendor/google.golang.org/grpc/go.mod b/vendor/google.golang.org/grpc/go.mod index 2f2cf1eb76..022cc9828f 100644 --- a/vendor/google.golang.org/grpc/go.mod +++ b/vendor/google.golang.org/grpc/go.mod @@ -1,11 +1,11 @@ module google.golang.org/grpc -go 1.11 +go 1.14 require ( - github.com/cespare/xxhash v1.1.0 + github.com/cespare/xxhash/v2 v2.1.1 github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403 - github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0 + github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021 github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b github.com/golang/protobuf v1.4.3 github.com/google/go-cmp v0.5.0 diff --git a/vendor/google.golang.org/grpc/go.sum b/vendor/google.golang.org/grpc/go.sum index 372b4ea3d2..6e7ae0db2b 100644 --- a/vendor/google.golang.org/grpc/go.sum +++ b/vendor/google.golang.org/grpc/go.sum @@ -2,27 +2,25 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMT cloud.google.com/go v0.34.0 h1:eOI3/cP2VTU6uZLDYAoic+eyzzB9YyGmJ7eIjl8rOPg= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/OneOfOne/xxhash v1.2.2 h1:KMrpdQIwFcEqXDklaen+P1axHaj9BSKzvpUUfnHldSE= -github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/census-instrumentation/opencensus-proto v0.2.1 h1:glEXhBS5PSLLv4IXzLA5yPRVX4bilULVyxxbrfOtDAk= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= -github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= -github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= +github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY= +github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403 h1:cqQfy1jclcSy/FwLjemeg3SR1yaINm74aQyupQ0Bl8M= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= -github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed h1:OZmjad4L3H8ncOIR8rnb5MREYqG8ixi5+WbeUsquF0c= -github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158 h1:CevA8fI91PAnP8vpnXuB8ZYAZ5wqY86nAbxfgK8tWO4= +github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= -github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0 h1:dulLQAYQFYtG5MTplgNGHWuV2D+OBD+Z8lmDBmbLg+s= -github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ= +github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021 h1:fP+fF0up6oPY49OrjPrhIJ8yQfdIM85NXMLkMg1EXVs= +github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= github.com/envoyproxy/protoc-gen-validate v0.1.0 h1:EQciDnbrYxy13PgWoY8AqoxGiPrpgBZ1R8UNe3ddc+A= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= @@ -54,11 +52,10 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= -github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72 h1:qLC7fQah7D6K1B0ujays3HV9gkFtllcxhzImRR7ArPQ= -github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= @@ -122,7 +119,8 @@ google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlba gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.3 h1:fvjTMHxHEw/mxHbtzPi3JCcKXQRAnQTBRo6YCJSVHKI= gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/vendor/google.golang.org/grpc/install_gae.sh b/vendor/google.golang.org/grpc/install_gae.sh deleted file mode 100644 index 15ff9facdd..0000000000 --- a/vendor/google.golang.org/grpc/install_gae.sh +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/bash - -TMP=$(mktemp -d /tmp/sdk.XXX) \ -&& curl -o $TMP.zip "https://storage.googleapis.com/appengine-sdks/featured/go_appengine_sdk_linux_amd64-1.9.68.zip" \ -&& unzip -q $TMP.zip -d $TMP \ -&& export PATH="$PATH:$TMP/go_appengine" \ No newline at end of file diff --git a/vendor/google.golang.org/grpc/internal/channelz/funcs.go b/vendor/google.golang.org/grpc/internal/channelz/funcs.go index f731413930..6d5760d951 100644 --- a/vendor/google.golang.org/grpc/internal/channelz/funcs.go +++ b/vendor/google.golang.org/grpc/internal/channelz/funcs.go @@ -630,7 +630,7 @@ func (c *channelMap) GetServerSockets(id int64, startID int64, maxResults int64) if count == 0 { end = true } - var s []*SocketMetric + s := make([]*SocketMetric, 0, len(sks)) for _, ns := range sks { sm := &SocketMetric{} sm.SocketData = ns.s.ChannelzMetric() diff --git a/vendor/google.golang.org/grpc/internal/channelz/types_linux.go b/vendor/google.golang.org/grpc/internal/channelz/types_linux.go index 692dd61817..1b1c4cce34 100644 --- a/vendor/google.golang.org/grpc/internal/channelz/types_linux.go +++ b/vendor/google.golang.org/grpc/internal/channelz/types_linux.go @@ -1,5 +1,3 @@ -// +build !appengine - /* * * Copyright 2018 gRPC authors. diff --git a/vendor/google.golang.org/grpc/internal/channelz/types_nonlinux.go b/vendor/google.golang.org/grpc/internal/channelz/types_nonlinux.go index 19c2fc521d..8b06eed1ab 100644 --- a/vendor/google.golang.org/grpc/internal/channelz/types_nonlinux.go +++ b/vendor/google.golang.org/grpc/internal/channelz/types_nonlinux.go @@ -1,4 +1,5 @@ -// +build !linux appengine +//go:build !linux +// +build !linux /* * @@ -37,6 +38,6 @@ type SocketOptionData struct { // Windows OS doesn't support Socket Option func (s *SocketOptionData) Getsockopt(fd uintptr) { once.Do(func() { - logger.Warning("Channelz: socket options are not supported on non-linux os and appengine.") + logger.Warning("Channelz: socket options are not supported on non-linux environments") }) } diff --git a/vendor/google.golang.org/grpc/internal/channelz/util_linux.go b/vendor/google.golang.org/grpc/internal/channelz/util_linux.go index fdf409d55d..8d194e44e1 100644 --- a/vendor/google.golang.org/grpc/internal/channelz/util_linux.go +++ b/vendor/google.golang.org/grpc/internal/channelz/util_linux.go @@ -1,5 +1,3 @@ -// +build linux,!appengine - /* * * Copyright 2018 gRPC authors. diff --git a/vendor/google.golang.org/grpc/internal/channelz/util_nonlinux.go b/vendor/google.golang.org/grpc/internal/channelz/util_nonlinux.go index 8864a08111..837ddc4024 100644 --- a/vendor/google.golang.org/grpc/internal/channelz/util_nonlinux.go +++ b/vendor/google.golang.org/grpc/internal/channelz/util_nonlinux.go @@ -1,4 +1,5 @@ -// +build !linux appengine +//go:build !linux +// +build !linux /* * diff --git a/vendor/google.golang.org/grpc/internal/credentials/spiffe.go b/vendor/google.golang.org/grpc/internal/credentials/spiffe.go index be70b6cdfc..25ade62305 100644 --- a/vendor/google.golang.org/grpc/internal/credentials/spiffe.go +++ b/vendor/google.golang.org/grpc/internal/credentials/spiffe.go @@ -1,5 +1,3 @@ -// +build !appengine - /* * * Copyright 2020 gRPC authors. diff --git a/vendor/google.golang.org/grpc/internal/credentials/spiffe_appengine.go b/vendor/google.golang.org/grpc/internal/credentials/spiffe_appengine.go deleted file mode 100644 index af6f577197..0000000000 --- a/vendor/google.golang.org/grpc/internal/credentials/spiffe_appengine.go +++ /dev/null @@ -1,31 +0,0 @@ -// +build appengine - -/* - * - * Copyright 2020 gRPC authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -package credentials - -import ( - "crypto/tls" - "net/url" -) - -// SPIFFEIDFromState is a no-op for appengine builds. -func SPIFFEIDFromState(state tls.ConnectionState) *url.URL { - return nil -} diff --git a/vendor/google.golang.org/grpc/internal/credentials/syscallconn.go b/vendor/google.golang.org/grpc/internal/credentials/syscallconn.go index f499a614c2..2919632d65 100644 --- a/vendor/google.golang.org/grpc/internal/credentials/syscallconn.go +++ b/vendor/google.golang.org/grpc/internal/credentials/syscallconn.go @@ -1,5 +1,3 @@ -// +build !appengine - /* * * Copyright 2018 gRPC authors. diff --git a/vendor/google.golang.org/grpc/internal/credentials/syscallconn_appengine.go b/vendor/google.golang.org/grpc/internal/credentials/syscallconn_appengine.go deleted file mode 100644 index a6144cd661..0000000000 --- a/vendor/google.golang.org/grpc/internal/credentials/syscallconn_appengine.go +++ /dev/null @@ -1,30 +0,0 @@ -// +build appengine - -/* - * - * Copyright 2018 gRPC authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -package credentials - -import ( - "net" -) - -// WrapSyscallConn returns newConn on appengine. -func WrapSyscallConn(rawConn, newConn net.Conn) net.Conn { - return newConn -} diff --git a/vendor/google.golang.org/grpc/internal/credentials/util.go b/vendor/google.golang.org/grpc/internal/credentials/util.go index 55664fa46b..f792fd22ca 100644 --- a/vendor/google.golang.org/grpc/internal/credentials/util.go +++ b/vendor/google.golang.org/grpc/internal/credentials/util.go @@ -18,7 +18,9 @@ package credentials -import "crypto/tls" +import ( + "crypto/tls" +) const alpnProtoStrH2 = "h2" diff --git a/vendor/google.golang.org/grpc/internal/envconfig/envconfig.go b/vendor/google.golang.org/grpc/internal/envconfig/envconfig.go index 73931a94bc..e766ac04af 100644 --- a/vendor/google.golang.org/grpc/internal/envconfig/envconfig.go +++ b/vendor/google.golang.org/grpc/internal/envconfig/envconfig.go @@ -22,6 +22,8 @@ package envconfig import ( "os" "strings" + + xdsenv "google.golang.org/grpc/internal/xds/env" ) const ( @@ -31,8 +33,8 @@ const ( ) var ( - // Retry is set if retry is explicitly enabled via "GRPC_GO_RETRY=on". - Retry = strings.EqualFold(os.Getenv(retryStr), "on") + // Retry is set if retry is explicitly enabled via "GRPC_GO_RETRY=on" or if XDS retry support is enabled. + Retry = strings.EqualFold(os.Getenv(retryStr), "on") || xdsenv.RetrySupport // TXTErrIgnore is set if TXT errors should be ignored ("GRPC_GO_IGNORE_TXT_ERRORS" is not "false"). TXTErrIgnore = !strings.EqualFold(os.Getenv(txtErrIgnoreStr), "false") ) diff --git a/vendor/google.golang.org/grpc/internal/resolver/config_selector.go b/vendor/google.golang.org/grpc/internal/resolver/config_selector.go index 5e7f36703d..be7e13d585 100644 --- a/vendor/google.golang.org/grpc/internal/resolver/config_selector.go +++ b/vendor/google.golang.org/grpc/internal/resolver/config_selector.go @@ -117,9 +117,12 @@ type ClientInterceptor interface { NewStream(ctx context.Context, ri RPCInfo, done func(), newStream func(ctx context.Context, done func()) (ClientStream, error)) (ClientStream, error) } -// ServerInterceptor is unimplementable; do not use. +// ServerInterceptor is an interceptor for incoming RPC's on gRPC server side. type ServerInterceptor interface { - notDefined() + // AllowRPC checks if an incoming RPC is allowed to proceed based on + // information about connection RPC was received on, and HTTP Headers. This + // information will be piped into context. + AllowRPC(ctx context.Context) error // TODO: Make this a real interceptor for filters such as rate limiting. } type csKeyType string diff --git a/vendor/google.golang.org/grpc/internal/resolver/dns/dns_resolver.go b/vendor/google.golang.org/grpc/internal/resolver/dns/dns_resolver.go index 03825bbe7b..75301c5149 100644 --- a/vendor/google.golang.org/grpc/internal/resolver/dns/dns_resolver.go +++ b/vendor/google.golang.org/grpc/internal/resolver/dns/dns_resolver.go @@ -277,18 +277,13 @@ func (d *dnsResolver) lookupSRV() ([]resolver.Address, error) { return newAddrs, nil } -var filterError = func(err error) error { +func handleDNSError(err error, lookupType string) error { if dnsErr, ok := err.(*net.DNSError); ok && !dnsErr.IsTimeout && !dnsErr.IsTemporary { // Timeouts and temporary errors should be communicated to gRPC to // attempt another DNS query (with backoff). Other errors should be // suppressed (they may represent the absence of a TXT record). return nil } - return err -} - -func handleDNSError(err error, lookupType string) error { - err = filterError(err) if err != nil { err = fmt.Errorf("dns: %v record lookup error: %v", lookupType, err) logger.Info(err) @@ -323,12 +318,12 @@ func (d *dnsResolver) lookupTXT() *serviceconfig.ParseResult { } func (d *dnsResolver) lookupHost() ([]resolver.Address, error) { - var newAddrs []resolver.Address addrs, err := d.resolver.LookupHost(d.ctx, d.host) if err != nil { err = handleDNSError(err, "A") return nil, err } + newAddrs := make([]resolver.Address, 0, len(addrs)) for _, a := range addrs { ip, ok := formatIP(a) if !ok { diff --git a/vendor/google.golang.org/grpc/internal/resolver/dns/go113.go b/vendor/google.golang.org/grpc/internal/resolver/dns/go113.go deleted file mode 100644 index 8783a8cf82..0000000000 --- a/vendor/google.golang.org/grpc/internal/resolver/dns/go113.go +++ /dev/null @@ -1,33 +0,0 @@ -// +build go1.13 - -/* - * - * Copyright 2019 gRPC authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -package dns - -import "net" - -func init() { - filterError = func(err error) error { - if dnsErr, ok := err.(*net.DNSError); ok && dnsErr.IsNotFound { - // The name does not exist; not an error. - return nil - } - return err - } -} diff --git a/vendor/google.golang.org/grpc/internal/serviceconfig/serviceconfig.go b/vendor/google.golang.org/grpc/internal/serviceconfig/serviceconfig.go index c0634d152c..badbdbf597 100644 --- a/vendor/google.golang.org/grpc/internal/serviceconfig/serviceconfig.go +++ b/vendor/google.golang.org/grpc/internal/serviceconfig/serviceconfig.go @@ -78,6 +78,7 @@ func (bc *BalancerConfig) UnmarshalJSON(b []byte) error { return err } + var names []string for i, lbcfg := range ir { if len(lbcfg) != 1 { return fmt.Errorf("invalid loadBalancingConfig: entry %v does not contain exactly 1 policy/config pair: %q", i, lbcfg) @@ -92,6 +93,7 @@ func (bc *BalancerConfig) UnmarshalJSON(b []byte) error { for name, jsonCfg = range lbcfg { } + names = append(names, name) builder := balancer.Get(name) if builder == nil { // If the balancer is not registered, move on to the next config. @@ -120,7 +122,7 @@ func (bc *BalancerConfig) UnmarshalJSON(b []byte) error { // return. This means we had a loadBalancingConfig slice but did not // encounter a registered policy. The config is considered invalid in this // case. - return fmt.Errorf("invalid loadBalancingConfig: no supported policies found") + return fmt.Errorf("invalid loadBalancingConfig: no supported policies found in %v", names) } // MethodConfig defines the configuration recommended by the service providers for a diff --git a/vendor/google.golang.org/grpc/internal/syscall/syscall_linux.go b/vendor/google.golang.org/grpc/internal/syscall/syscall_linux.go index 4b2964f2a1..b3a72276de 100644 --- a/vendor/google.golang.org/grpc/internal/syscall/syscall_linux.go +++ b/vendor/google.golang.org/grpc/internal/syscall/syscall_linux.go @@ -1,5 +1,3 @@ -// +build !appengine - /* * * Copyright 2018 gRPC authors. diff --git a/vendor/google.golang.org/grpc/internal/syscall/syscall_nonlinux.go b/vendor/google.golang.org/grpc/internal/syscall/syscall_nonlinux.go index 7913ef1dbf..999f52cd75 100644 --- a/vendor/google.golang.org/grpc/internal/syscall/syscall_nonlinux.go +++ b/vendor/google.golang.org/grpc/internal/syscall/syscall_nonlinux.go @@ -1,4 +1,5 @@ -// +build !linux appengine +//go:build !linux +// +build !linux /* * @@ -35,41 +36,41 @@ var logger = grpclog.Component("core") func log() { once.Do(func() { - logger.Info("CPU time info is unavailable on non-linux or appengine environment.") + logger.Info("CPU time info is unavailable on non-linux environments.") }) } -// GetCPUTime returns the how much CPU time has passed since the start of this process. -// It always returns 0 under non-linux or appengine environment. +// GetCPUTime returns the how much CPU time has passed since the start of this +// process. It always returns 0 under non-linux environments. func GetCPUTime() int64 { log() return 0 } -// Rusage is an empty struct under non-linux or appengine environment. +// Rusage is an empty struct under non-linux environments. type Rusage struct{} -// GetRusage is a no-op function under non-linux or appengine environment. +// GetRusage is a no-op function under non-linux environments. func GetRusage() *Rusage { log() return nil } // CPUTimeDiff returns the differences of user CPU time and system CPU time used -// between two Rusage structs. It a no-op function for non-linux or appengine environment. +// between two Rusage structs. It a no-op function for non-linux environments. func CPUTimeDiff(first *Rusage, latest *Rusage) (float64, float64) { log() return 0, 0 } -// SetTCPUserTimeout is a no-op function under non-linux or appengine environments +// SetTCPUserTimeout is a no-op function under non-linux environments. func SetTCPUserTimeout(conn net.Conn, timeout time.Duration) error { log() return nil } -// GetTCPUserTimeout is a no-op function under non-linux or appengine environments -// a negative return value indicates the operation is not supported +// GetTCPUserTimeout is a no-op function under non-linux environments. +// A negative return value indicates the operation is not supported func GetTCPUserTimeout(conn net.Conn) (int, error) { log() return -1, nil diff --git a/vendor/google.golang.org/grpc/internal/transport/http2_client.go b/vendor/google.golang.org/grpc/internal/transport/http2_client.go index 0cd6da1e73..7558630743 100644 --- a/vendor/google.golang.org/grpc/internal/transport/http2_client.go +++ b/vendor/google.golang.org/grpc/internal/transport/http2_client.go @@ -616,12 +616,22 @@ func (t *http2Client) getCallAuthData(ctx context.Context, audience string, call return callAuthData, nil } -// NewStreamError wraps an error and reports additional information. +// NewStreamError wraps an error and reports additional information. Typically +// NewStream errors result in transparent retry, as they mean nothing went onto +// the wire. However, there are two notable exceptions: +// +// 1. If the stream headers violate the max header list size allowed by the +// server. In this case there is no reason to retry at all, as it is +// assumed the RPC would continue to fail on subsequent attempts. +// 2. If the credentials errored when requesting their headers. In this case, +// it's possible a retry can fix the problem, but indefinitely transparently +// retrying is not appropriate as it is likely the credentials, if they can +// eventually succeed, would need I/O to do so. type NewStreamError struct { Err error - DoNotRetry bool - PerformedIO bool + DoNotRetry bool + DoNotTransparentRetry bool } func (e NewStreamError) Error() string { @@ -631,24 +641,10 @@ func (e NewStreamError) Error() string { // NewStream creates a stream and registers it into the transport as "active" // streams. All non-nil errors returned will be *NewStreamError. func (t *http2Client) NewStream(ctx context.Context, callHdr *CallHdr) (_ *Stream, err error) { - defer func() { - if err != nil { - nse, ok := err.(*NewStreamError) - if !ok { - nse = &NewStreamError{Err: err} - } - if len(t.perRPCCreds) > 0 || callHdr.Creds != nil { - // We may have performed I/O in the per-RPC creds callback, so do not - // allow transparent retry. - nse.PerformedIO = true - } - err = nse - } - }() ctx = peer.NewContext(ctx, t.getPeer()) headerFields, err := t.createHeaderFields(ctx, callHdr) if err != nil { - return nil, err + return nil, &NewStreamError{Err: err, DoNotTransparentRetry: true} } s := t.newStream(ctx, callHdr) cleanup := func(err error) { @@ -748,7 +744,7 @@ func (t *http2Client) NewStream(ctx context.Context, callHdr *CallHdr) (_ *Strea return true }, hdr) if err != nil { - return nil, err + return nil, &NewStreamError{Err: err} } if success { break @@ -759,12 +755,12 @@ func (t *http2Client) NewStream(ctx context.Context, callHdr *CallHdr) (_ *Strea firstTry = false select { case <-ch: - case <-s.ctx.Done(): - return nil, ContextErr(s.ctx.Err()) + case <-ctx.Done(): + return nil, &NewStreamError{Err: ContextErr(ctx.Err())} case <-t.goAway: - return nil, errStreamDrain + return nil, &NewStreamError{Err: errStreamDrain} case <-t.ctx.Done(): - return nil, ErrConnClosing + return nil, &NewStreamError{Err: ErrConnClosing} } } if t.statsHandler != nil { diff --git a/vendor/google.golang.org/grpc/internal/transport/http2_server.go b/vendor/google.golang.org/grpc/internal/transport/http2_server.go index e3799d50aa..19c13e041d 100644 --- a/vendor/google.golang.org/grpc/internal/transport/http2_server.go +++ b/vendor/google.golang.org/grpc/internal/transport/http2_server.go @@ -133,6 +133,22 @@ type http2Server struct { // underlying conn gets closed before the client preface could be read, it // returns a nil transport and a nil error. func NewServerTransport(conn net.Conn, config *ServerConfig) (_ ServerTransport, err error) { + var authInfo credentials.AuthInfo + rawConn := conn + if config.Credentials != nil { + var err error + conn, authInfo, err = config.Credentials.ServerHandshake(rawConn) + if err != nil { + // ErrConnDispatched means that the connection was dispatched away + // from gRPC; those connections should be left open. io.EOF means + // the connection was closed before handshaking completed, which can + // happen naturally from probers. Return these errors directly. + if err == credentials.ErrConnDispatched || err == io.EOF { + return nil, err + } + return nil, connectionErrorf(false, err, "ServerHandshake(%q) failed: %v", rawConn.RemoteAddr(), err) + } + } writeBufSize := config.WriteBufferSize readBufSize := config.ReadBufferSize maxHeaderListSize := defaultServerMaxHeaderListSize @@ -215,14 +231,15 @@ func NewServerTransport(conn net.Conn, config *ServerConfig) (_ ServerTransport, if kep.MinTime == 0 { kep.MinTime = defaultKeepalivePolicyMinTime } + done := make(chan struct{}) t := &http2Server{ - ctx: context.Background(), + ctx: setConnection(context.Background(), rawConn), done: done, conn: conn, remoteAddr: conn.RemoteAddr(), localAddr: conn.LocalAddr(), - authInfo: config.AuthInfo, + authInfo: authInfo, framer: framer, readerDone: make(chan struct{}), writerDone: make(chan struct{}), @@ -1345,3 +1362,18 @@ func getJitter(v time.Duration) time.Duration { j := grpcrand.Int63n(2*r) - r return time.Duration(j) } + +type connectionKey struct{} + +// GetConnection gets the connection from the context. +func GetConnection(ctx context.Context) net.Conn { + conn, _ := ctx.Value(connectionKey{}).(net.Conn) + return conn +} + +// SetConnection adds the connection to the context to be able to get +// information about the destination ip and port for an incoming RPC. This also +// allows any unary or streaming interceptors to see the connection. +func setConnection(ctx context.Context, conn net.Conn) context.Context { + return context.WithValue(ctx, connectionKey{}, conn) +} diff --git a/vendor/google.golang.org/grpc/internal/transport/transport.go b/vendor/google.golang.org/grpc/internal/transport/transport.go index 1419812645..d3bf65b2bd 100644 --- a/vendor/google.golang.org/grpc/internal/transport/transport.go +++ b/vendor/google.golang.org/grpc/internal/transport/transport.go @@ -30,6 +30,7 @@ import ( "net" "sync" "sync/atomic" + "time" "google.golang.org/grpc/codes" "google.golang.org/grpc/credentials" @@ -518,7 +519,8 @@ const ( // ServerConfig consists of all the configurations to establish a server transport. type ServerConfig struct { MaxStreams uint32 - AuthInfo credentials.AuthInfo + ConnectionTimeout time.Duration + Credentials credentials.TransportCredentials InTapHandle tap.ServerInHandle StatsHandler stats.Handler KeepaliveParams keepalive.ServerParameters diff --git a/vendor/google.golang.org/grpc/internal/xds/env/env.go b/vendor/google.golang.org/grpc/internal/xds/env/env.go new file mode 100644 index 0000000000..b171ac91f1 --- /dev/null +++ b/vendor/google.golang.org/grpc/internal/xds/env/env.go @@ -0,0 +1,95 @@ +/* + * + * Copyright 2020 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +// Package env acts a single source of definition for all environment variables +// related to the xDS implementation in gRPC. +package env + +import ( + "os" + "strings" +) + +const ( + // BootstrapFileNameEnv is the env variable to set bootstrap file name. + // Do not use this and read from env directly. Its value is read and kept in + // variable BootstrapFileName. + // + // When both bootstrap FileName and FileContent are set, FileName is used. + BootstrapFileNameEnv = "GRPC_XDS_BOOTSTRAP" + // BootstrapFileContentEnv is the env variable to set bootstrapp file + // content. Do not use this and read from env directly. Its value is read + // and kept in variable BootstrapFileName. + // + // When both bootstrap FileName and FileContent are set, FileName is used. + BootstrapFileContentEnv = "GRPC_XDS_BOOTSTRAP_CONFIG" + + ringHashSupportEnv = "GRPC_XDS_EXPERIMENTAL_ENABLE_RING_HASH" + clientSideSecuritySupportEnv = "GRPC_XDS_EXPERIMENTAL_SECURITY_SUPPORT" + aggregateAndDNSSupportEnv = "GRPC_XDS_EXPERIMENTAL_ENABLE_AGGREGATE_AND_LOGICAL_DNS_CLUSTER" + retrySupportEnv = "GRPC_XDS_EXPERIMENTAL_ENABLE_RETRY" + rbacSupportEnv = "GRPC_XDS_EXPERIMENTAL_ENABLE_RBAC" + + c2pResolverSupportEnv = "GRPC_EXPERIMENTAL_GOOGLE_C2P_RESOLVER" + c2pResolverTestOnlyTrafficDirectorURIEnv = "GRPC_TEST_ONLY_GOOGLE_C2P_RESOLVER_TRAFFIC_DIRECTOR_URI" +) + +var ( + // BootstrapFileName holds the name of the file which contains xDS bootstrap + // configuration. Users can specify the location of the bootstrap file by + // setting the environment variable "GRPC_XDS_BOOTSTRAP". + // + // When both bootstrap FileName and FileContent are set, FileName is used. + BootstrapFileName = os.Getenv(BootstrapFileNameEnv) + // BootstrapFileContent holds the content of the xDS bootstrap + // configuration. Users can specify the bootstrap config by + // setting the environment variable "GRPC_XDS_BOOTSTRAP_CONFIG". + // + // When both bootstrap FileName and FileContent are set, FileName is used. + BootstrapFileContent = os.Getenv(BootstrapFileContentEnv) + // RingHashSupport indicates whether ring hash support is enabled, which can + // be disabled by setting the environment variable + // "GRPC_XDS_EXPERIMENTAL_ENABLE_RING_HASH" to "false". + RingHashSupport = !strings.EqualFold(os.Getenv(ringHashSupportEnv), "false") + // ClientSideSecuritySupport is used to control processing of security + // configuration on the client-side. + // + // Note that there is no env var protection for the server-side because we + // have a brand new API on the server-side and users explicitly need to use + // the new API to get security integration on the server. + ClientSideSecuritySupport = !strings.EqualFold(os.Getenv(clientSideSecuritySupportEnv), "false") + // AggregateAndDNSSupportEnv indicates whether processing of aggregated + // cluster and DNS cluster is enabled, which can be enabled by setting the + // environment variable + // "GRPC_XDS_EXPERIMENTAL_ENABLE_AGGREGATE_AND_LOGICAL_DNS_CLUSTER" to + // "true". + AggregateAndDNSSupportEnv = strings.EqualFold(os.Getenv(aggregateAndDNSSupportEnv), "true") + + // RetrySupport indicates whether xDS retry is enabled. + RetrySupport = !strings.EqualFold(os.Getenv(retrySupportEnv), "false") + + // RBACSupport indicates whether xDS configured RBAC HTTP Filter is enabled. + RBACSupport = strings.EqualFold(os.Getenv(rbacSupportEnv), "true") + + // C2PResolverSupport indicates whether support for C2P resolver is enabled. + // This can be enabled by setting the environment variable + // "GRPC_EXPERIMENTAL_GOOGLE_C2P_RESOLVER" to "true". + C2PResolverSupport = strings.EqualFold(os.Getenv(c2pResolverSupportEnv), "true") + // C2PResolverTestOnlyTrafficDirectorURI is the TD URI for testing. + C2PResolverTestOnlyTrafficDirectorURI = os.Getenv(c2pResolverTestOnlyTrafficDirectorURIEnv) +) diff --git a/vendor/google.golang.org/grpc/pickfirst.go b/vendor/google.golang.org/grpc/pickfirst.go index b858c2a5e6..f194d14a08 100644 --- a/vendor/google.golang.org/grpc/pickfirst.go +++ b/vendor/google.golang.org/grpc/pickfirst.go @@ -107,10 +107,12 @@ func (b *pickfirstBalancer) UpdateSubConnState(sc balancer.SubConn, s balancer.S } switch s.ConnectivityState { - case connectivity.Ready, connectivity.Idle: + case connectivity.Ready: b.cc.UpdateState(balancer.State{ConnectivityState: s.ConnectivityState, Picker: &picker{result: balancer.PickResult{SubConn: sc}}}) case connectivity.Connecting: b.cc.UpdateState(balancer.State{ConnectivityState: s.ConnectivityState, Picker: &picker{err: balancer.ErrNoSubConnAvailable}}) + case connectivity.Idle: + b.cc.UpdateState(balancer.State{ConnectivityState: s.ConnectivityState, Picker: &idlePicker{sc: sc}}) case connectivity.TransientFailure: b.cc.UpdateState(balancer.State{ ConnectivityState: s.ConnectivityState, @@ -122,6 +124,12 @@ func (b *pickfirstBalancer) UpdateSubConnState(sc balancer.SubConn, s balancer.S func (b *pickfirstBalancer) Close() { } +func (b *pickfirstBalancer) ExitIdle() { + if b.state == connectivity.Idle { + b.sc.Connect() + } +} + type picker struct { result balancer.PickResult err error @@ -131,6 +139,17 @@ func (p *picker) Pick(info balancer.PickInfo) (balancer.PickResult, error) { return p.result, p.err } +// idlePicker is used when the SubConn is IDLE and kicks the SubConn into +// CONNECTING when Pick is called. +type idlePicker struct { + sc balancer.SubConn +} + +func (i *idlePicker) Pick(info balancer.PickInfo) (balancer.PickResult, error) { + i.sc.Connect() + return balancer.PickResult{}, balancer.ErrNoSubConnAvailable +} + func init() { balancer.Register(newPickfirstBuilder()) } diff --git a/vendor/google.golang.org/grpc/server.go b/vendor/google.golang.org/grpc/server.go index 0251f48daf..557f29559d 100644 --- a/vendor/google.golang.org/grpc/server.go +++ b/vendor/google.golang.org/grpc/server.go @@ -710,13 +710,6 @@ func (s *Server) GetServiceInfo() map[string]ServiceInfo { // the server being stopped. var ErrServerStopped = errors.New("grpc: the server has been stopped") -func (s *Server) useTransportAuthenticator(rawConn net.Conn) (net.Conn, credentials.AuthInfo, error) { - if s.opts.creds == nil { - return rawConn, nil, nil - } - return s.opts.creds.ServerHandshake(rawConn) -} - type listenSocket struct { net.Listener channelzID int64 @@ -839,35 +832,14 @@ func (s *Server) handleRawConn(lisAddr string, rawConn net.Conn) { return } rawConn.SetDeadline(time.Now().Add(s.opts.connectionTimeout)) - conn, authInfo, err := s.useTransportAuthenticator(rawConn) - if err != nil { - // ErrConnDispatched means that the connection was dispatched away from - // gRPC; those connections should be left open. - if err != credentials.ErrConnDispatched { - // In deployments where a gRPC server runs behind a cloud load - // balancer which performs regular TCP level health checks, the - // connection is closed immediately by the latter. Skipping the - // error here will help reduce log clutter. - if err != io.EOF { - s.mu.Lock() - s.errorf("ServerHandshake(%q) failed: %v", rawConn.RemoteAddr(), err) - s.mu.Unlock() - channelz.Warningf(logger, s.channelzID, "grpc: Server.Serve failed to complete security handshake from %q: %v", rawConn.RemoteAddr(), err) - } - rawConn.Close() - } - rawConn.SetDeadline(time.Time{}) - return - } // Finish handshaking (HTTP2) - st := s.newHTTP2Transport(conn, authInfo) + st := s.newHTTP2Transport(rawConn) + rawConn.SetDeadline(time.Time{}) if st == nil { - conn.Close() return } - rawConn.SetDeadline(time.Time{}) if !s.addConn(lisAddr, st) { return } @@ -888,10 +860,11 @@ func (s *Server) drainServerTransports(addr string) { // newHTTP2Transport sets up a http/2 transport (using the // gRPC http2 server transport in transport/http2_server.go). -func (s *Server) newHTTP2Transport(c net.Conn, authInfo credentials.AuthInfo) transport.ServerTransport { +func (s *Server) newHTTP2Transport(c net.Conn) transport.ServerTransport { config := &transport.ServerConfig{ MaxStreams: s.opts.maxConcurrentStreams, - AuthInfo: authInfo, + ConnectionTimeout: s.opts.connectionTimeout, + Credentials: s.opts.creds, InTapHandle: s.opts.inTapHandle, StatsHandler: s.opts.statsHandler, KeepaliveParams: s.opts.keepaliveParams, @@ -909,8 +882,17 @@ func (s *Server) newHTTP2Transport(c net.Conn, authInfo credentials.AuthInfo) tr s.mu.Lock() s.errorf("NewServerTransport(%q) failed: %v", c.RemoteAddr(), err) s.mu.Unlock() - c.Close() - channelz.Warning(logger, s.channelzID, "grpc: Server.Serve failed to create ServerTransport: ", err) + // ErrConnDispatched means that the connection was dispatched away from + // gRPC; those connections should be left open. + if err != credentials.ErrConnDispatched { + c.Close() + } + // Don't log on ErrConnDispatched and io.EOF to prevent log spam. + if err != credentials.ErrConnDispatched { + if err != io.EOF { + channelz.Warning(logger, s.channelzID, "grpc: Server.Serve failed to create ServerTransport: ", err) + } + } return nil } diff --git a/vendor/google.golang.org/grpc/stats/stats.go b/vendor/google.golang.org/grpc/stats/stats.go index a5ebeeb693..0285dcc6a2 100644 --- a/vendor/google.golang.org/grpc/stats/stats.go +++ b/vendor/google.golang.org/grpc/stats/stats.go @@ -36,12 +36,12 @@ type RPCStats interface { IsClient() bool } -// Begin contains stats when an RPC begins. +// Begin contains stats when an RPC attempt begins. // FailFast is only valid if this Begin is from client side. type Begin struct { // Client is true if this Begin is from client side. Client bool - // BeginTime is the time when the RPC begins. + // BeginTime is the time when the RPC attempt begins. BeginTime time.Time // FailFast indicates if this RPC is failfast. FailFast bool @@ -49,6 +49,9 @@ type Begin struct { IsClientStream bool // IsServerStream indicates whether the RPC is a server streaming RPC. IsServerStream bool + // IsTransparentRetryAttempt indicates whether this attempt was initiated + // due to transparently retrying a previous attempt. + IsTransparentRetryAttempt bool } // IsClient indicates if the stats information is from client side. diff --git a/vendor/google.golang.org/grpc/stream.go b/vendor/google.golang.org/grpc/stream.go index e224af12d2..625d47b34e 100644 --- a/vendor/google.golang.org/grpc/stream.go +++ b/vendor/google.golang.org/grpc/stream.go @@ -274,35 +274,6 @@ func newClientStreamWithParams(ctx context.Context, desc *StreamDesc, cc *Client if c.creds != nil { callHdr.Creds = c.creds } - var trInfo *traceInfo - if EnableTracing { - trInfo = &traceInfo{ - tr: trace.New("grpc.Sent."+methodFamily(method), method), - firstLine: firstLine{ - client: true, - }, - } - if deadline, ok := ctx.Deadline(); ok { - trInfo.firstLine.deadline = time.Until(deadline) - } - trInfo.tr.LazyLog(&trInfo.firstLine, false) - ctx = trace.NewContext(ctx, trInfo.tr) - } - ctx = newContextWithRPCInfo(ctx, c.failFast, c.codec, cp, comp) - sh := cc.dopts.copts.StatsHandler - var beginTime time.Time - if sh != nil { - ctx = sh.TagRPC(ctx, &stats.RPCTagInfo{FullMethodName: method, FailFast: c.failFast}) - beginTime = time.Now() - begin := &stats.Begin{ - Client: true, - BeginTime: beginTime, - FailFast: c.failFast, - IsClientStream: desc.ClientStreams, - IsServerStream: desc.ServerStreams, - } - sh.HandleRPC(ctx, begin) - } cs := &clientStream{ callHdr: callHdr, @@ -316,7 +287,6 @@ func newClientStreamWithParams(ctx context.Context, desc *StreamDesc, cc *Client cp: cp, comp: comp, cancel: cancel, - beginTime: beginTime, firstAttempt: true, onCommit: onCommit, } @@ -325,9 +295,7 @@ func newClientStreamWithParams(ctx context.Context, desc *StreamDesc, cc *Client } cs.binlog = binarylog.GetMethodLogger(method) - // Only this initial attempt has stats/tracing. - // TODO(dfawley): move to newAttempt when per-attempt stats are implemented. - if err := cs.newAttemptLocked(sh, trInfo); err != nil { + if err := cs.newAttemptLocked(false /* isTransparent */); err != nil { cs.finish(err) return nil, err } @@ -375,8 +343,43 @@ func newClientStreamWithParams(ctx context.Context, desc *StreamDesc, cc *Client // newAttemptLocked creates a new attempt with a transport. // If it succeeds, then it replaces clientStream's attempt with this new attempt. -func (cs *clientStream) newAttemptLocked(sh stats.Handler, trInfo *traceInfo) (retErr error) { +func (cs *clientStream) newAttemptLocked(isTransparent bool) (retErr error) { + ctx := newContextWithRPCInfo(cs.ctx, cs.callInfo.failFast, cs.callInfo.codec, cs.cp, cs.comp) + method := cs.callHdr.Method + sh := cs.cc.dopts.copts.StatsHandler + var beginTime time.Time + if sh != nil { + ctx = sh.TagRPC(ctx, &stats.RPCTagInfo{FullMethodName: method, FailFast: cs.callInfo.failFast}) + beginTime = time.Now() + begin := &stats.Begin{ + Client: true, + BeginTime: beginTime, + FailFast: cs.callInfo.failFast, + IsClientStream: cs.desc.ClientStreams, + IsServerStream: cs.desc.ServerStreams, + IsTransparentRetryAttempt: isTransparent, + } + sh.HandleRPC(ctx, begin) + } + + var trInfo *traceInfo + if EnableTracing { + trInfo = &traceInfo{ + tr: trace.New("grpc.Sent."+methodFamily(method), method), + firstLine: firstLine{ + client: true, + }, + } + if deadline, ok := ctx.Deadline(); ok { + trInfo.firstLine.deadline = time.Until(deadline) + } + trInfo.tr.LazyLog(&trInfo.firstLine, false) + ctx = trace.NewContext(ctx, trInfo.tr) + } + newAttempt := &csAttempt{ + ctx: ctx, + beginTime: beginTime, cs: cs, dc: cs.cc.dopts.dc, statsHandler: sh, @@ -391,15 +394,14 @@ func (cs *clientStream) newAttemptLocked(sh stats.Handler, trInfo *traceInfo) (r } }() - if err := cs.ctx.Err(); err != nil { + if err := ctx.Err(); err != nil { return toRPCErr(err) } - ctx := cs.ctx if cs.cc.parsedTarget.Scheme == "xds" { // Add extra metadata (metadata that will be added by transport) to context // so the balancer can see them. - ctx = grpcutil.WithExtraMetadata(cs.ctx, metadata.Pairs( + ctx = grpcutil.WithExtraMetadata(ctx, metadata.Pairs( "content-type", grpcutil.ContentType(cs.callHdr.ContentSubtype), )) } @@ -419,7 +421,7 @@ func (cs *clientStream) newAttemptLocked(sh stats.Handler, trInfo *traceInfo) (r func (a *csAttempt) newStream() error { cs := a.cs cs.callHdr.PreviousAttempts = cs.numRetries - s, err := a.t.NewStream(cs.ctx, cs.callHdr) + s, err := a.t.NewStream(a.ctx, cs.callHdr) if err != nil { // Return without converting to an RPC error so retry code can // inspect. @@ -444,8 +446,7 @@ type clientStream struct { cancel context.CancelFunc // cancels all attempts - sentLast bool // sent an end stream - beginTime time.Time + sentLast bool // sent an end stream methodConfig *MethodConfig @@ -485,6 +486,7 @@ type clientStream struct { // csAttempt implements a single transport stream attempt within a // clientStream. type csAttempt struct { + ctx context.Context cs *clientStream t transport.ClientTransport s *transport.Stream @@ -503,6 +505,7 @@ type csAttempt struct { trInfo *traceInfo statsHandler stats.Handler + beginTime time.Time } func (cs *clientStream) commitAttemptLocked() { @@ -520,15 +523,16 @@ func (cs *clientStream) commitAttempt() { } // shouldRetry returns nil if the RPC should be retried; otherwise it returns -// the error that should be returned by the operation. -func (cs *clientStream) shouldRetry(err error) error { +// the error that should be returned by the operation. If the RPC should be +// retried, the bool indicates whether it is being retried transparently. +func (cs *clientStream) shouldRetry(err error) (bool, error) { if cs.attempt.s == nil { // Error from NewClientStream. nse, ok := err.(*transport.NewStreamError) if !ok { // Unexpected, but assume no I/O was performed and the RPC is not // fatal, so retry indefinitely. - return nil + return true, nil } // Unwrap and convert error. @@ -537,19 +541,19 @@ func (cs *clientStream) shouldRetry(err error) error { // Never retry DoNotRetry errors, which indicate the RPC should not be // retried due to max header list size violation, etc. if nse.DoNotRetry { - return err + return false, err } // In the event of a non-IO operation error from NewStream, we never // attempted to write anything to the wire, so we can retry // indefinitely. - if !nse.PerformedIO { - return nil + if !nse.DoNotTransparentRetry { + return true, nil } } if cs.finished || cs.committed { // RPC is finished or committed; cannot retry. - return err + return false, err } // Wait for the trailers. unprocessed := false @@ -559,17 +563,17 @@ func (cs *clientStream) shouldRetry(err error) error { } if cs.firstAttempt && unprocessed { // First attempt, stream unprocessed: transparently retry. - return nil + return true, nil } if cs.cc.dopts.disableRetry { - return err + return false, err } pushback := 0 hasPushback := false if cs.attempt.s != nil { if !cs.attempt.s.TrailersOnly() { - return err + return false, err } // TODO(retry): Move down if the spec changes to not check server pushback @@ -580,13 +584,13 @@ func (cs *clientStream) shouldRetry(err error) error { if pushback, e = strconv.Atoi(sps[0]); e != nil || pushback < 0 { channelz.Infof(logger, cs.cc.channelzID, "Server retry pushback specified to abort (%q).", sps[0]) cs.retryThrottler.throttle() // This counts as a failure for throttling. - return err + return false, err } hasPushback = true } else if len(sps) > 1 { channelz.Warningf(logger, cs.cc.channelzID, "Server retry pushback specified multiple values (%q); not retrying.", sps) cs.retryThrottler.throttle() // This counts as a failure for throttling. - return err + return false, err } } @@ -599,16 +603,16 @@ func (cs *clientStream) shouldRetry(err error) error { rp := cs.methodConfig.RetryPolicy if rp == nil || !rp.RetryableStatusCodes[code] { - return err + return false, err } // Note: the ordering here is important; we count this as a failure // only if the code matched a retryable code. if cs.retryThrottler.throttle() { - return err + return false, err } if cs.numRetries+1 >= rp.MaxAttempts { - return err + return false, err } var dur time.Duration @@ -631,10 +635,10 @@ func (cs *clientStream) shouldRetry(err error) error { select { case <-t.C: cs.numRetries++ - return nil + return false, nil case <-cs.ctx.Done(): t.Stop() - return status.FromContextError(cs.ctx.Err()).Err() + return false, status.FromContextError(cs.ctx.Err()).Err() } } @@ -642,12 +646,13 @@ func (cs *clientStream) shouldRetry(err error) error { func (cs *clientStream) retryLocked(lastErr error) error { for { cs.attempt.finish(toRPCErr(lastErr)) - if err := cs.shouldRetry(lastErr); err != nil { + isTransparent, err := cs.shouldRetry(lastErr) + if err != nil { cs.commitAttemptLocked() return err } cs.firstAttempt = false - if err := cs.newAttemptLocked(nil, nil); err != nil { + if err := cs.newAttemptLocked(isTransparent); err != nil { return err } if lastErr = cs.replayBufferLocked(); lastErr == nil { @@ -937,7 +942,7 @@ func (a *csAttempt) sendMsg(m interface{}, hdr, payld, data []byte) error { return io.EOF } if a.statsHandler != nil { - a.statsHandler.HandleRPC(cs.ctx, outPayload(true, m, data, payld, time.Now())) + a.statsHandler.HandleRPC(a.ctx, outPayload(true, m, data, payld, time.Now())) } if channelz.IsOn() { a.t.IncrMsgSent() @@ -985,7 +990,7 @@ func (a *csAttempt) recvMsg(m interface{}, payInfo *payloadInfo) (err error) { a.mu.Unlock() } if a.statsHandler != nil { - a.statsHandler.HandleRPC(cs.ctx, &stats.InPayload{ + a.statsHandler.HandleRPC(a.ctx, &stats.InPayload{ Client: true, RecvTime: time.Now(), Payload: m, @@ -1047,12 +1052,12 @@ func (a *csAttempt) finish(err error) { if a.statsHandler != nil { end := &stats.End{ Client: true, - BeginTime: a.cs.beginTime, + BeginTime: a.beginTime, EndTime: time.Now(), Trailer: tr, Error: err, } - a.statsHandler.HandleRPC(a.cs.ctx, end) + a.statsHandler.HandleRPC(a.ctx, end) } if a.trInfo != nil && a.trInfo.tr != nil { if err == nil { diff --git a/vendor/google.golang.org/grpc/version.go b/vendor/google.golang.org/grpc/version.go index e3510e10f1..48594bc246 100644 --- a/vendor/google.golang.org/grpc/version.go +++ b/vendor/google.golang.org/grpc/version.go @@ -19,4 +19,4 @@ package grpc // Version is the current grpc version. -const Version = "1.40.0" +const Version = "1.41.0" diff --git a/vendor/google.golang.org/grpc/vet.sh b/vendor/google.golang.org/grpc/vet.sh index 5eaa8b05d6..d923187a7b 100644 --- a/vendor/google.golang.org/grpc/vet.sh +++ b/vendor/google.golang.org/grpc/vet.sh @@ -89,10 +89,6 @@ not git grep "\(import \|^\s*\)\"github.com/golang/protobuf/ptypes/" -- "*.go" # - Ensure all xds proto imports are renamed to *pb or *grpc. git grep '"github.com/envoyproxy/go-control-plane/envoy' -- '*.go' ':(exclude)*.pb.go' | not grep -v 'pb "\|grpc "' -# - Check imports that are illegal in appengine (until Go 1.11). -# TODO: Remove when we drop Go 1.10 support -go list -f {{.Dir}} ./... | xargs go run test/go_vet/vet.go - misspell -error . # - Check that generated proto files are up to date. diff --git a/vendor/gopkg.in/ini.v1/.golangci.yml b/vendor/gopkg.in/ini.v1/.golangci.yml new file mode 100644 index 0000000000..b7256bae13 --- /dev/null +++ b/vendor/gopkg.in/ini.v1/.golangci.yml @@ -0,0 +1,21 @@ +linters-settings: + nakedret: + max-func-lines: 0 # Disallow any unnamed return statement + +linters: + enable: + - deadcode + - errcheck + - gosimple + - govet + - ineffassign + - staticcheck + - structcheck + - typecheck + - unused + - varcheck + - nakedret + - gofmt + - rowserrcheck + - unconvert + - goimports diff --git a/vendor/gopkg.in/ini.v1/codecov.yml b/vendor/gopkg.in/ini.v1/codecov.yml index fc947f2308..31f646ee06 100644 --- a/vendor/gopkg.in/ini.v1/codecov.yml +++ b/vendor/gopkg.in/ini.v1/codecov.yml @@ -6,4 +6,4 @@ coverage: threshold: 1% comment: - layout: 'diff, files' + layout: 'diff' diff --git a/vendor/gopkg.in/ini.v1/ini.go b/vendor/gopkg.in/ini.v1/ini.go index 23f07422ef..ac2a93a5b3 100644 --- a/vendor/gopkg.in/ini.v1/ini.go +++ b/vendor/gopkg.in/ini.v1/ini.go @@ -1,5 +1,3 @@ -// +build go1.6 - // Copyright 2014 Unknwon // // Licensed under the Apache License, Version 2.0 (the "License"): you may @@ -125,6 +123,8 @@ type LoadOptions struct { ReaderBufferSize int // AllowNonUniqueSections indicates whether to allow sections with the same name multiple times. AllowNonUniqueSections bool + // AllowDuplicateShadowValues indicates whether values for shadowed keys should be deduplicated. + AllowDuplicateShadowValues bool } // DebugFunc is the type of function called to log parse events. diff --git a/vendor/gopkg.in/ini.v1/key.go b/vendor/gopkg.in/ini.v1/key.go index 8baafd9ea6..0302c291bf 100644 --- a/vendor/gopkg.in/ini.v1/key.go +++ b/vendor/gopkg.in/ini.v1/key.go @@ -54,14 +54,16 @@ func (k *Key) addShadow(val string) error { return errors.New("cannot add shadow to auto-increment or boolean key") } - // Deduplicate shadows based on their values. - if k.value == val { - return nil - } - for i := range k.shadows { - if k.shadows[i].value == val { + if !k.s.f.options.AllowDuplicateShadowValues { + // Deduplicate shadows based on their values. + if k.value == val { return nil } + for i := range k.shadows { + if k.shadows[i].value == val { + return nil + } + } } shadow := newKey(k.s, k.name, val) @@ -781,10 +783,8 @@ func (k *Key) parseUint64s(strs []string, addInvalid, returnOnInvalid bool) ([]u return vals, err } - type Parser func(str string) (interface{}, error) - // parseTimesFormat transforms strings to times in given format. func (k *Key) parseTimesFormat(format string, strs []string, addInvalid, returnOnInvalid bool) ([]time.Time, error) { vals := make([]time.Time, 0, len(strs)) @@ -801,7 +801,6 @@ func (k *Key) parseTimesFormat(format string, strs []string, addInvalid, returnO return vals, err } - // doParse transforms strings to different types func (k *Key) doParse(strs []string, addInvalid, returnOnInvalid bool, parser Parser) ([]interface{}, error) { vals := make([]interface{}, 0, len(strs)) diff --git a/vendor/gopkg.in/ini.v1/parser.go b/vendor/gopkg.in/ini.v1/parser.go index 65147166f9..b8b5aa86a3 100644 --- a/vendor/gopkg.in/ini.v1/parser.go +++ b/vendor/gopkg.in/ini.v1/parser.go @@ -131,7 +131,7 @@ func readKeyName(delimiters string, in []byte) (string, int, error) { // Check if key name surrounded by quotes. var keyQuote string if line[0] == '"' { - if len(line) > 6 && string(line[0:3]) == `"""` { + if len(line) > 6 && line[0:3] == `"""` { keyQuote = `"""` } else { keyQuote = `"` @@ -232,7 +232,7 @@ func (p *parser) readValue(in []byte, bufferSize int) (string, error) { } var valQuote string - if len(line) > 3 && string(line[0:3]) == `"""` { + if len(line) > 3 && line[0:3] == `"""` { valQuote = `"""` } else if line[0] == '`' { valQuote = "`" @@ -289,12 +289,8 @@ func (p *parser) readValue(in []byte, bufferSize int) (string, error) { hasSurroundedQuote(line, '"')) && !p.options.PreserveSurroundedQuote { line = line[1 : len(line)-1] } else if len(valQuote) == 0 && p.options.UnescapeValueCommentSymbols { - if strings.Contains(line, `\;`) { - line = strings.Replace(line, `\;`, ";", -1) - } - if strings.Contains(line, `\#`) { - line = strings.Replace(line, `\#`, "#", -1) - } + line = strings.ReplaceAll(line, `\;`, ";") + line = strings.ReplaceAll(line, `\#`, "#") } else if p.options.AllowPythonMultilineValues && lastChar == '\n' { return p.readPythonMultilines(line, bufferSize) } diff --git a/vendor/gopkg.in/ini.v1/section.go b/vendor/gopkg.in/ini.v1/section.go index afaa97c97e..a3615d820b 100644 --- a/vendor/gopkg.in/ini.v1/section.go +++ b/vendor/gopkg.in/ini.v1/section.go @@ -217,7 +217,7 @@ func (s *Section) KeysHash() map[string]string { defer s.f.lock.RUnlock() } - hash := map[string]string{} + hash := make(map[string]string, len(s.keysHash)) for key, value := range s.keysHash { hash[key] = value } diff --git a/vendor/k8s.io/apimachinery/pkg/util/httpstream/doc.go b/vendor/k8s.io/apimachinery/pkg/util/httpstream/doc.go new file mode 100644 index 0000000000..5893df5bd2 --- /dev/null +++ b/vendor/k8s.io/apimachinery/pkg/util/httpstream/doc.go @@ -0,0 +1,19 @@ +/* +Copyright 2015 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Package httpstream adds multiplexed streaming support to HTTP requests and +// responses via connection upgrades. +package httpstream // import "k8s.io/apimachinery/pkg/util/httpstream" diff --git a/vendor/k8s.io/apimachinery/pkg/util/httpstream/httpstream.go b/vendor/k8s.io/apimachinery/pkg/util/httpstream/httpstream.go new file mode 100644 index 0000000000..00ce5f785c --- /dev/null +++ b/vendor/k8s.io/apimachinery/pkg/util/httpstream/httpstream.go @@ -0,0 +1,157 @@ +/* +Copyright 2015 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package httpstream + +import ( + "fmt" + "io" + "net/http" + "strings" + "time" +) + +const ( + HeaderConnection = "Connection" + HeaderUpgrade = "Upgrade" + HeaderProtocolVersion = "X-Stream-Protocol-Version" + HeaderAcceptedProtocolVersions = "X-Accepted-Stream-Protocol-Versions" +) + +// NewStreamHandler defines a function that is called when a new Stream is +// received. If no error is returned, the Stream is accepted; otherwise, +// the stream is rejected. After the reply frame has been sent, replySent is closed. +type NewStreamHandler func(stream Stream, replySent <-chan struct{}) error + +// NoOpNewStreamHandler is a stream handler that accepts a new stream and +// performs no other logic. +func NoOpNewStreamHandler(stream Stream, replySent <-chan struct{}) error { return nil } + +// Dialer knows how to open a streaming connection to a server. +type Dialer interface { + + // Dial opens a streaming connection to a server using one of the protocols + // specified (in order of most preferred to least preferred). + Dial(protocols ...string) (Connection, string, error) +} + +// UpgradeRoundTripper is a type of http.RoundTripper that is able to upgrade +// HTTP requests to support multiplexed bidirectional streams. After RoundTrip() +// is invoked, if the upgrade is successful, clients may retrieve the upgraded +// connection by calling UpgradeRoundTripper.Connection(). +type UpgradeRoundTripper interface { + http.RoundTripper + // NewConnection validates the response and creates a new Connection. + NewConnection(resp *http.Response) (Connection, error) +} + +// ResponseUpgrader knows how to upgrade HTTP requests and responses to +// add streaming support to them. +type ResponseUpgrader interface { + // UpgradeResponse upgrades an HTTP response to one that supports multiplexed + // streams. newStreamHandler will be called asynchronously whenever the + // other end of the upgraded connection creates a new stream. + UpgradeResponse(w http.ResponseWriter, req *http.Request, newStreamHandler NewStreamHandler) Connection +} + +// Connection represents an upgraded HTTP connection. +type Connection interface { + // CreateStream creates a new Stream with the supplied headers. + CreateStream(headers http.Header) (Stream, error) + // Close resets all streams and closes the connection. + Close() error + // CloseChan returns a channel that is closed when the underlying connection is closed. + CloseChan() <-chan bool + // SetIdleTimeout sets the amount of time the connection may remain idle before + // it is automatically closed. + SetIdleTimeout(timeout time.Duration) +} + +// Stream represents a bidirectional communications channel that is part of an +// upgraded connection. +type Stream interface { + io.ReadWriteCloser + // Reset closes both directions of the stream, indicating that neither client + // or server can use it any more. + Reset() error + // Headers returns the headers used to create the stream. + Headers() http.Header + // Identifier returns the stream's ID. + Identifier() uint32 +} + +// IsUpgradeRequest returns true if the given request is a connection upgrade request +func IsUpgradeRequest(req *http.Request) bool { + for _, h := range req.Header[http.CanonicalHeaderKey(HeaderConnection)] { + if strings.Contains(strings.ToLower(h), strings.ToLower(HeaderUpgrade)) { + return true + } + } + return false +} + +func negotiateProtocol(clientProtocols, serverProtocols []string) string { + for i := range clientProtocols { + for j := range serverProtocols { + if clientProtocols[i] == serverProtocols[j] { + return clientProtocols[i] + } + } + } + return "" +} + +func commaSeparatedHeaderValues(header []string) []string { + var parsedClientProtocols []string + for i := range header { + for _, clientProtocol := range strings.Split(header[i], ",") { + if proto := strings.Trim(clientProtocol, " "); len(proto) > 0 { + parsedClientProtocols = append(parsedClientProtocols, proto) + } + } + } + return parsedClientProtocols +} + +// Handshake performs a subprotocol negotiation. If the client did request a +// subprotocol, Handshake will select the first common value found in +// serverProtocols. If a match is found, Handshake adds a response header +// indicating the chosen subprotocol. If no match is found, HTTP forbidden is +// returned, along with a response header containing the list of protocols the +// server can accept. +func Handshake(req *http.Request, w http.ResponseWriter, serverProtocols []string) (string, error) { + clientProtocols := commaSeparatedHeaderValues(req.Header[http.CanonicalHeaderKey(HeaderProtocolVersion)]) + if len(clientProtocols) == 0 { + return "", fmt.Errorf("unable to upgrade: %s is required", HeaderProtocolVersion) + } + + if len(serverProtocols) == 0 { + panic(fmt.Errorf("unable to upgrade: serverProtocols is required")) + } + + negotiatedProtocol := negotiateProtocol(clientProtocols, serverProtocols) + if len(negotiatedProtocol) == 0 { + for i := range serverProtocols { + w.Header().Add(HeaderAcceptedProtocolVersions, serverProtocols[i]) + } + err := fmt.Errorf("unable to upgrade: unable to negotiate protocol: client supports %v, server accepts %v", clientProtocols, serverProtocols) + http.Error(w, err.Error(), http.StatusForbidden) + return "", err + } + + w.Header().Add(HeaderProtocolVersion, negotiatedProtocol) + return negotiatedProtocol, nil +} diff --git a/vendor/k8s.io/apimachinery/pkg/util/httpstream/spdy/connection.go b/vendor/k8s.io/apimachinery/pkg/util/httpstream/spdy/connection.go new file mode 100644 index 0000000000..21b2568d90 --- /dev/null +++ b/vendor/k8s.io/apimachinery/pkg/util/httpstream/spdy/connection.go @@ -0,0 +1,187 @@ +/* +Copyright 2015 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package spdy + +import ( + "net" + "net/http" + "sync" + "time" + + "github.com/moby/spdystream" + "k8s.io/apimachinery/pkg/util/httpstream" + "k8s.io/klog/v2" +) + +// connection maintains state about a spdystream.Connection and its associated +// streams. +type connection struct { + conn *spdystream.Connection + streams []httpstream.Stream + streamLock sync.Mutex + newStreamHandler httpstream.NewStreamHandler + ping func() (time.Duration, error) +} + +// NewClientConnection creates a new SPDY client connection. +func NewClientConnection(conn net.Conn) (httpstream.Connection, error) { + return NewClientConnectionWithPings(conn, 0) +} + +// NewClientConnectionWithPings creates a new SPDY client connection. +// +// If pingPeriod is non-zero, a background goroutine will send periodic Ping +// frames to the server. Use this to keep idle connections through certain load +// balancers alive longer. +func NewClientConnectionWithPings(conn net.Conn, pingPeriod time.Duration) (httpstream.Connection, error) { + spdyConn, err := spdystream.NewConnection(conn, false) + if err != nil { + defer conn.Close() + return nil, err + } + + return newConnection(spdyConn, httpstream.NoOpNewStreamHandler, pingPeriod, spdyConn.Ping), nil +} + +// NewServerConnection creates a new SPDY server connection. newStreamHandler +// will be invoked when the server receives a newly created stream from the +// client. +func NewServerConnection(conn net.Conn, newStreamHandler httpstream.NewStreamHandler) (httpstream.Connection, error) { + return NewServerConnectionWithPings(conn, newStreamHandler, 0) +} + +// NewServerConnectionWithPings creates a new SPDY server connection. +// newStreamHandler will be invoked when the server receives a newly created +// stream from the client. +// +// If pingPeriod is non-zero, a background goroutine will send periodic Ping +// frames to the server. Use this to keep idle connections through certain load +// balancers alive longer. +func NewServerConnectionWithPings(conn net.Conn, newStreamHandler httpstream.NewStreamHandler, pingPeriod time.Duration) (httpstream.Connection, error) { + spdyConn, err := spdystream.NewConnection(conn, true) + if err != nil { + defer conn.Close() + return nil, err + } + + return newConnection(spdyConn, newStreamHandler, pingPeriod, spdyConn.Ping), nil +} + +// newConnection returns a new connection wrapping conn. newStreamHandler +// will be invoked when the server receives a newly created stream from the +// client. +func newConnection(conn *spdystream.Connection, newStreamHandler httpstream.NewStreamHandler, pingPeriod time.Duration, pingFn func() (time.Duration, error)) httpstream.Connection { + c := &connection{conn: conn, newStreamHandler: newStreamHandler, ping: pingFn} + go conn.Serve(c.newSpdyStream) + if pingPeriod > 0 && pingFn != nil { + go c.sendPings(pingPeriod) + } + return c +} + +// createStreamResponseTimeout indicates how long to wait for the other side to +// acknowledge the new stream before timing out. +const createStreamResponseTimeout = 30 * time.Second + +// Close first sends a reset for all of the connection's streams, and then +// closes the underlying spdystream.Connection. +func (c *connection) Close() error { + c.streamLock.Lock() + for _, s := range c.streams { + // calling Reset instead of Close ensures that all streams are fully torn down + s.Reset() + } + c.streams = make([]httpstream.Stream, 0) + c.streamLock.Unlock() + + // now that all streams are fully torn down, it's safe to call close on the underlying connection, + // which should be able to terminate immediately at this point, instead of waiting for any + // remaining graceful stream termination. + return c.conn.Close() +} + +// CreateStream creates a new stream with the specified headers and registers +// it with the connection. +func (c *connection) CreateStream(headers http.Header) (httpstream.Stream, error) { + stream, err := c.conn.CreateStream(headers, nil, false) + if err != nil { + return nil, err + } + if err = stream.WaitTimeout(createStreamResponseTimeout); err != nil { + return nil, err + } + + c.registerStream(stream) + return stream, nil +} + +// registerStream adds the stream s to the connection's list of streams that +// it owns. +func (c *connection) registerStream(s httpstream.Stream) { + c.streamLock.Lock() + c.streams = append(c.streams, s) + c.streamLock.Unlock() +} + +// CloseChan returns a channel that, when closed, indicates that the underlying +// spdystream.Connection has been closed. +func (c *connection) CloseChan() <-chan bool { + return c.conn.CloseChan() +} + +// newSpdyStream is the internal new stream handler used by spdystream.Connection.Serve. +// It calls connection's newStreamHandler, giving it the opportunity to accept or reject +// the stream. If newStreamHandler returns an error, the stream is rejected. If not, the +// stream is accepted and registered with the connection. +func (c *connection) newSpdyStream(stream *spdystream.Stream) { + replySent := make(chan struct{}) + err := c.newStreamHandler(stream, replySent) + rejectStream := (err != nil) + if rejectStream { + klog.Warningf("Stream rejected: %v", err) + stream.Reset() + return + } + + c.registerStream(stream) + stream.SendReply(http.Header{}, rejectStream) + close(replySent) +} + +// SetIdleTimeout sets the amount of time the connection may remain idle before +// it is automatically closed. +func (c *connection) SetIdleTimeout(timeout time.Duration) { + c.conn.SetIdleTimeout(timeout) +} + +func (c *connection) sendPings(period time.Duration) { + t := time.NewTicker(period) + defer t.Stop() + for { + select { + case <-c.conn.CloseChan(): + return + case <-t.C: + } + if _, err := c.ping(); err != nil { + klog.V(3).Infof("SPDY Ping failed: %v", err) + // Continue, in case this is a transient failure. + // c.conn.CloseChan above will tell us when the connection is + // actually closed. + } + } +} diff --git a/vendor/k8s.io/apimachinery/pkg/util/httpstream/spdy/roundtripper.go b/vendor/k8s.io/apimachinery/pkg/util/httpstream/spdy/roundtripper.go new file mode 100644 index 0000000000..4cb1cfadcb --- /dev/null +++ b/vendor/k8s.io/apimachinery/pkg/util/httpstream/spdy/roundtripper.go @@ -0,0 +1,369 @@ +/* +Copyright 2015 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package spdy + +import ( + "bufio" + "bytes" + "context" + "crypto/tls" + "encoding/base64" + "fmt" + "io" + "io/ioutil" + "net" + "net/http" + "net/http/httputil" + "net/url" + "strings" + "time" + + apierrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/serializer" + "k8s.io/apimachinery/pkg/util/httpstream" + utilnet "k8s.io/apimachinery/pkg/util/net" + "k8s.io/apimachinery/third_party/forked/golang/netutil" +) + +// SpdyRoundTripper knows how to upgrade an HTTP request to one that supports +// multiplexed streams. After RoundTrip() is invoked, Conn will be set +// and usable. SpdyRoundTripper implements the UpgradeRoundTripper interface. +type SpdyRoundTripper struct { + //tlsConfig holds the TLS configuration settings to use when connecting + //to the remote server. + tlsConfig *tls.Config + + /* TODO according to http://golang.org/pkg/net/http/#RoundTripper, a RoundTripper + must be safe for use by multiple concurrent goroutines. If this is absolutely + necessary, we could keep a map from http.Request to net.Conn. In practice, + a client will create an http.Client, set the transport to a new insteace of + SpdyRoundTripper, and use it a single time, so this hopefully won't be an issue. + */ + // conn is the underlying network connection to the remote server. + conn net.Conn + + // Dialer is the dialer used to connect. Used if non-nil. + Dialer *net.Dialer + + // proxier knows which proxy to use given a request, defaults to http.ProxyFromEnvironment + // Used primarily for mocking the proxy discovery in tests. + proxier func(req *http.Request) (*url.URL, error) + + // followRedirects indicates if the round tripper should examine responses for redirects and + // follow them. + followRedirects bool + // requireSameHostRedirects restricts redirect following to only follow redirects to the same host + // as the original request. + requireSameHostRedirects bool + // pingPeriod is a period for sending Ping frames over established + // connections. + pingPeriod time.Duration +} + +var _ utilnet.TLSClientConfigHolder = &SpdyRoundTripper{} +var _ httpstream.UpgradeRoundTripper = &SpdyRoundTripper{} +var _ utilnet.Dialer = &SpdyRoundTripper{} + +// NewRoundTripper creates a new SpdyRoundTripper that will use the specified +// tlsConfig. +func NewRoundTripper(tlsConfig *tls.Config, followRedirects, requireSameHostRedirects bool) *SpdyRoundTripper { + return NewRoundTripperWithConfig(RoundTripperConfig{ + TLS: tlsConfig, + FollowRedirects: followRedirects, + RequireSameHostRedirects: requireSameHostRedirects, + }) +} + +// NewRoundTripperWithProxy creates a new SpdyRoundTripper that will use the +// specified tlsConfig and proxy func. +func NewRoundTripperWithProxy(tlsConfig *tls.Config, followRedirects, requireSameHostRedirects bool, proxier func(*http.Request) (*url.URL, error)) *SpdyRoundTripper { + return NewRoundTripperWithConfig(RoundTripperConfig{ + TLS: tlsConfig, + FollowRedirects: followRedirects, + RequireSameHostRedirects: requireSameHostRedirects, + Proxier: proxier, + }) +} + +// NewRoundTripperWithProxy creates a new SpdyRoundTripper with the specified +// configuration. +func NewRoundTripperWithConfig(cfg RoundTripperConfig) *SpdyRoundTripper { + if cfg.Proxier == nil { + cfg.Proxier = utilnet.NewProxierWithNoProxyCIDR(http.ProxyFromEnvironment) + } + return &SpdyRoundTripper{ + tlsConfig: cfg.TLS, + followRedirects: cfg.FollowRedirects, + requireSameHostRedirects: cfg.RequireSameHostRedirects, + proxier: cfg.Proxier, + pingPeriod: cfg.PingPeriod, + } +} + +// RoundTripperConfig is a set of options for an SpdyRoundTripper. +type RoundTripperConfig struct { + // TLS configuration used by the round tripper. + TLS *tls.Config + // Proxier is a proxy function invoked on each request. Optional. + Proxier func(*http.Request) (*url.URL, error) + // PingPeriod is a period for sending SPDY Pings on the connection. + // Optional. + PingPeriod time.Duration + + FollowRedirects bool + RequireSameHostRedirects bool +} + +// TLSClientConfig implements pkg/util/net.TLSClientConfigHolder for proper TLS checking during +// proxying with a spdy roundtripper. +func (s *SpdyRoundTripper) TLSClientConfig() *tls.Config { + return s.tlsConfig +} + +// Dial implements k8s.io/apimachinery/pkg/util/net.Dialer. +func (s *SpdyRoundTripper) Dial(req *http.Request) (net.Conn, error) { + conn, err := s.dial(req) + if err != nil { + return nil, err + } + + if err := req.Write(conn); err != nil { + conn.Close() + return nil, err + } + + return conn, nil +} + +// dial dials the host specified by req, using TLS if appropriate, optionally +// using a proxy server if one is configured via environment variables. +func (s *SpdyRoundTripper) dial(req *http.Request) (net.Conn, error) { + proxyURL, err := s.proxier(req) + if err != nil { + return nil, err + } + + if proxyURL == nil { + return s.dialWithoutProxy(req.Context(), req.URL) + } + + // ensure we use a canonical host with proxyReq + targetHost := netutil.CanonicalAddr(req.URL) + + // proxying logic adapted from http://blog.h6t.eu/post/74098062923/golang-websocket-with-http-proxy-support + proxyReq := http.Request{ + Method: "CONNECT", + URL: &url.URL{}, + Host: targetHost, + } + + if pa := s.proxyAuth(proxyURL); pa != "" { + proxyReq.Header = http.Header{} + proxyReq.Header.Set("Proxy-Authorization", pa) + } + + proxyDialConn, err := s.dialWithoutProxy(req.Context(), proxyURL) + if err != nil { + return nil, err + } + + proxyClientConn := httputil.NewProxyClientConn(proxyDialConn, nil) + _, err = proxyClientConn.Do(&proxyReq) + if err != nil && err != httputil.ErrPersistEOF { + return nil, err + } + + rwc, _ := proxyClientConn.Hijack() + + if req.URL.Scheme != "https" { + return rwc, nil + } + + host, _, err := net.SplitHostPort(targetHost) + if err != nil { + return nil, err + } + + tlsConfig := s.tlsConfig + switch { + case tlsConfig == nil: + tlsConfig = &tls.Config{ServerName: host} + case len(tlsConfig.ServerName) == 0: + tlsConfig = tlsConfig.Clone() + tlsConfig.ServerName = host + } + + tlsConn := tls.Client(rwc, tlsConfig) + + // need to manually call Handshake() so we can call VerifyHostname() below + if err := tlsConn.Handshake(); err != nil { + return nil, err + } + + // Return if we were configured to skip validation + if tlsConfig.InsecureSkipVerify { + return tlsConn, nil + } + + if err := tlsConn.VerifyHostname(tlsConfig.ServerName); err != nil { + return nil, err + } + + return tlsConn, nil +} + +// dialWithoutProxy dials the host specified by url, using TLS if appropriate. +func (s *SpdyRoundTripper) dialWithoutProxy(ctx context.Context, url *url.URL) (net.Conn, error) { + dialAddr := netutil.CanonicalAddr(url) + + if url.Scheme == "http" { + if s.Dialer == nil { + var d net.Dialer + return d.DialContext(ctx, "tcp", dialAddr) + } else { + return s.Dialer.DialContext(ctx, "tcp", dialAddr) + } + } + + // TODO validate the TLSClientConfig is set up? + var conn *tls.Conn + var err error + if s.Dialer == nil { + conn, err = tls.Dial("tcp", dialAddr, s.tlsConfig) + } else { + conn, err = tls.DialWithDialer(s.Dialer, "tcp", dialAddr, s.tlsConfig) + } + if err != nil { + return nil, err + } + + // Return if we were configured to skip validation + if s.tlsConfig != nil && s.tlsConfig.InsecureSkipVerify { + return conn, nil + } + + host, _, err := net.SplitHostPort(dialAddr) + if err != nil { + return nil, err + } + if s.tlsConfig != nil && len(s.tlsConfig.ServerName) > 0 { + host = s.tlsConfig.ServerName + } + err = conn.VerifyHostname(host) + if err != nil { + return nil, err + } + + return conn, nil +} + +// proxyAuth returns, for a given proxy URL, the value to be used for the Proxy-Authorization header +func (s *SpdyRoundTripper) proxyAuth(proxyURL *url.URL) string { + if proxyURL == nil || proxyURL.User == nil { + return "" + } + credentials := proxyURL.User.String() + encodedAuth := base64.StdEncoding.EncodeToString([]byte(credentials)) + return fmt.Sprintf("Basic %s", encodedAuth) +} + +// RoundTrip executes the Request and upgrades it. After a successful upgrade, +// clients may call SpdyRoundTripper.Connection() to retrieve the upgraded +// connection. +func (s *SpdyRoundTripper) RoundTrip(req *http.Request) (*http.Response, error) { + header := utilnet.CloneHeader(req.Header) + header.Add(httpstream.HeaderConnection, httpstream.HeaderUpgrade) + header.Add(httpstream.HeaderUpgrade, HeaderSpdy31) + + var ( + conn net.Conn + rawResponse []byte + err error + ) + + if s.followRedirects { + conn, rawResponse, err = utilnet.ConnectWithRedirects(req.Method, req.URL, header, req.Body, s, s.requireSameHostRedirects) + } else { + clone := utilnet.CloneRequest(req) + clone.Header = header + conn, err = s.Dial(clone) + } + if err != nil { + return nil, err + } + + responseReader := bufio.NewReader( + io.MultiReader( + bytes.NewBuffer(rawResponse), + conn, + ), + ) + + resp, err := http.ReadResponse(responseReader, nil) + if err != nil { + if conn != nil { + conn.Close() + } + return nil, err + } + + s.conn = conn + + return resp, nil +} + +// NewConnection validates the upgrade response, creating and returning a new +// httpstream.Connection if there were no errors. +func (s *SpdyRoundTripper) NewConnection(resp *http.Response) (httpstream.Connection, error) { + connectionHeader := strings.ToLower(resp.Header.Get(httpstream.HeaderConnection)) + upgradeHeader := strings.ToLower(resp.Header.Get(httpstream.HeaderUpgrade)) + if (resp.StatusCode != http.StatusSwitchingProtocols) || !strings.Contains(connectionHeader, strings.ToLower(httpstream.HeaderUpgrade)) || !strings.Contains(upgradeHeader, strings.ToLower(HeaderSpdy31)) { + defer resp.Body.Close() + responseError := "" + responseErrorBytes, err := ioutil.ReadAll(resp.Body) + if err != nil { + responseError = "unable to read error from server response" + } else { + // TODO: I don't belong here, I should be abstracted from this class + if obj, _, err := statusCodecs.UniversalDecoder().Decode(responseErrorBytes, nil, &metav1.Status{}); err == nil { + if status, ok := obj.(*metav1.Status); ok { + return nil, &apierrors.StatusError{ErrStatus: *status} + } + } + responseError = string(responseErrorBytes) + responseError = strings.TrimSpace(responseError) + } + + return nil, fmt.Errorf("unable to upgrade connection: %s", responseError) + } + + return NewClientConnectionWithPings(s.conn, s.pingPeriod) +} + +// statusScheme is private scheme for the decoding here until someone fixes the TODO in NewConnection +var statusScheme = runtime.NewScheme() + +// ParameterCodec knows about query parameters used with the meta v1 API spec. +var statusCodecs = serializer.NewCodecFactory(statusScheme) + +func init() { + statusScheme.AddUnversionedTypes(metav1.SchemeGroupVersion, + &metav1.Status{}, + ) +} diff --git a/vendor/k8s.io/apimachinery/pkg/util/httpstream/spdy/upgrade.go b/vendor/k8s.io/apimachinery/pkg/util/httpstream/spdy/upgrade.go new file mode 100644 index 0000000000..f17eb09e96 --- /dev/null +++ b/vendor/k8s.io/apimachinery/pkg/util/httpstream/spdy/upgrade.go @@ -0,0 +1,120 @@ +/* +Copyright 2015 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package spdy + +import ( + "bufio" + "fmt" + "io" + "net" + "net/http" + "strings" + "sync/atomic" + "time" + + "k8s.io/apimachinery/pkg/util/httpstream" + "k8s.io/apimachinery/pkg/util/runtime" +) + +const HeaderSpdy31 = "SPDY/3.1" + +// responseUpgrader knows how to upgrade HTTP responses. It +// implements the httpstream.ResponseUpgrader interface. +type responseUpgrader struct { + pingPeriod time.Duration +} + +// connWrapper is used to wrap a hijacked connection and its bufio.Reader. All +// calls will be handled directly by the underlying net.Conn with the exception +// of Read and Close calls, which will consider data in the bufio.Reader. This +// ensures that data already inside the used bufio.Reader instance is also +// read. +type connWrapper struct { + net.Conn + closed int32 + bufReader *bufio.Reader +} + +func (w *connWrapper) Read(b []byte) (n int, err error) { + if atomic.LoadInt32(&w.closed) == 1 { + return 0, io.EOF + } + return w.bufReader.Read(b) +} + +func (w *connWrapper) Close() error { + err := w.Conn.Close() + atomic.StoreInt32(&w.closed, 1) + return err +} + +// NewResponseUpgrader returns a new httpstream.ResponseUpgrader that is +// capable of upgrading HTTP responses using SPDY/3.1 via the +// spdystream package. +func NewResponseUpgrader() httpstream.ResponseUpgrader { + return NewResponseUpgraderWithPings(0) +} + +// NewResponseUpgraderWithPings returns a new httpstream.ResponseUpgrader that +// is capable of upgrading HTTP responses using SPDY/3.1 via the spdystream +// package. +// +// If pingPeriod is non-zero, for each incoming connection a background +// goroutine will send periodic Ping frames to the server. Use this to keep +// idle connections through certain load balancers alive longer. +func NewResponseUpgraderWithPings(pingPeriod time.Duration) httpstream.ResponseUpgrader { + return responseUpgrader{pingPeriod: pingPeriod} +} + +// UpgradeResponse upgrades an HTTP response to one that supports multiplexed +// streams. newStreamHandler will be called synchronously whenever the +// other end of the upgraded connection creates a new stream. +func (u responseUpgrader) UpgradeResponse(w http.ResponseWriter, req *http.Request, newStreamHandler httpstream.NewStreamHandler) httpstream.Connection { + connectionHeader := strings.ToLower(req.Header.Get(httpstream.HeaderConnection)) + upgradeHeader := strings.ToLower(req.Header.Get(httpstream.HeaderUpgrade)) + if !strings.Contains(connectionHeader, strings.ToLower(httpstream.HeaderUpgrade)) || !strings.Contains(upgradeHeader, strings.ToLower(HeaderSpdy31)) { + errorMsg := fmt.Sprintf("unable to upgrade: missing upgrade headers in request: %#v", req.Header) + http.Error(w, errorMsg, http.StatusBadRequest) + return nil + } + + hijacker, ok := w.(http.Hijacker) + if !ok { + errorMsg := fmt.Sprintf("unable to upgrade: unable to hijack response") + http.Error(w, errorMsg, http.StatusInternalServerError) + return nil + } + + w.Header().Add(httpstream.HeaderConnection, httpstream.HeaderUpgrade) + w.Header().Add(httpstream.HeaderUpgrade, HeaderSpdy31) + w.WriteHeader(http.StatusSwitchingProtocols) + + conn, bufrw, err := hijacker.Hijack() + if err != nil { + runtime.HandleError(fmt.Errorf("unable to upgrade: error hijacking response: %v", err)) + return nil + } + + connWithBuf := &connWrapper{Conn: conn, bufReader: bufrw.Reader} + spdyConn, err := NewServerConnectionWithPings(connWithBuf, newStreamHandler, u.pingPeriod) + if err != nil { + runtime.HandleError(fmt.Errorf("unable to upgrade: error creating SPDY server connection: %v", err)) + return nil + } + + return spdyConn +} diff --git a/vendor/k8s.io/apimachinery/pkg/util/rand/rand.go b/vendor/k8s.io/apimachinery/pkg/util/rand/rand.go new file mode 100644 index 0000000000..82a473bb14 --- /dev/null +++ b/vendor/k8s.io/apimachinery/pkg/util/rand/rand.go @@ -0,0 +1,127 @@ +/* +Copyright 2015 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Package rand provides utilities related to randomization. +package rand + +import ( + "math/rand" + "sync" + "time" +) + +var rng = struct { + sync.Mutex + rand *rand.Rand +}{ + rand: rand.New(rand.NewSource(time.Now().UnixNano())), +} + +// Int returns a non-negative pseudo-random int. +func Int() int { + rng.Lock() + defer rng.Unlock() + return rng.rand.Int() +} + +// Intn generates an integer in range [0,max). +// By design this should panic if input is invalid, <= 0. +func Intn(max int) int { + rng.Lock() + defer rng.Unlock() + return rng.rand.Intn(max) +} + +// IntnRange generates an integer in range [min,max). +// By design this should panic if input is invalid, <= 0. +func IntnRange(min, max int) int { + rng.Lock() + defer rng.Unlock() + return rng.rand.Intn(max-min) + min +} + +// IntnRange generates an int64 integer in range [min,max). +// By design this should panic if input is invalid, <= 0. +func Int63nRange(min, max int64) int64 { + rng.Lock() + defer rng.Unlock() + return rng.rand.Int63n(max-min) + min +} + +// Seed seeds the rng with the provided seed. +func Seed(seed int64) { + rng.Lock() + defer rng.Unlock() + + rng.rand = rand.New(rand.NewSource(seed)) +} + +// Perm returns, as a slice of n ints, a pseudo-random permutation of the integers [0,n) +// from the default Source. +func Perm(n int) []int { + rng.Lock() + defer rng.Unlock() + return rng.rand.Perm(n) +} + +const ( + // We omit vowels from the set of available characters to reduce the chances + // of "bad words" being formed. + alphanums = "bcdfghjklmnpqrstvwxz2456789" + // No. of bits required to index into alphanums string. + alphanumsIdxBits = 5 + // Mask used to extract last alphanumsIdxBits of an int. + alphanumsIdxMask = 1<>= alphanumsIdxBits + remaining-- + } + return string(b) +} + +// SafeEncodeString encodes s using the same characters as rand.String. This reduces the chances of bad words and +// ensures that strings generated from hash functions appear consistent throughout the API. +func SafeEncodeString(s string) string { + r := make([]byte, len(s)) + for i, b := range []rune(s) { + r[i] = alphanums[(int(b) % len(alphanums))] + } + return string(r) +} diff --git a/vendor/k8s.io/apimachinery/pkg/util/remotecommand/constants.go b/vendor/k8s.io/apimachinery/pkg/util/remotecommand/constants.go new file mode 100644 index 0000000000..acfeb827c9 --- /dev/null +++ b/vendor/k8s.io/apimachinery/pkg/util/remotecommand/constants.go @@ -0,0 +1,53 @@ +/* +Copyright 2016 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package remotecommand + +import ( + "time" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +const ( + DefaultStreamCreationTimeout = 30 * time.Second + + // The SPDY subprotocol "channel.k8s.io" is used for remote command + // attachment/execution. This represents the initial unversioned subprotocol, + // which has the known bugs http://issues.k8s.io/13394 and + // http://issues.k8s.io/13395. + StreamProtocolV1Name = "channel.k8s.io" + + // The SPDY subprotocol "v2.channel.k8s.io" is used for remote command + // attachment/execution. It is the second version of the subprotocol and + // resolves the issues present in the first version. + StreamProtocolV2Name = "v2.channel.k8s.io" + + // The SPDY subprotocol "v3.channel.k8s.io" is used for remote command + // attachment/execution. It is the third version of the subprotocol and + // adds support for resizing container terminals. + StreamProtocolV3Name = "v3.channel.k8s.io" + + // The SPDY subprotocol "v4.channel.k8s.io" is used for remote command + // attachment/execution. It is the 4th version of the subprotocol and + // adds support for exit codes. + StreamProtocolV4Name = "v4.channel.k8s.io" + + NonZeroExitCodeReason = metav1.StatusReason("NonZeroExitCode") + ExitCodeCauseType = metav1.CauseType("ExitCode") +) + +var SupportedStreamingProtocols = []string{StreamProtocolV4Name, StreamProtocolV3Name, StreamProtocolV2Name, StreamProtocolV1Name} diff --git a/vendor/k8s.io/apimachinery/third_party/forked/golang/netutil/addr.go b/vendor/k8s.io/apimachinery/third_party/forked/golang/netutil/addr.go new file mode 100644 index 0000000000..c70f431c27 --- /dev/null +++ b/vendor/k8s.io/apimachinery/third_party/forked/golang/netutil/addr.go @@ -0,0 +1,27 @@ +package netutil + +import ( + "net/url" + "strings" +) + +// FROM: http://golang.org/src/net/http/client.go +// Given a string of the form "host", "host:port", or "[ipv6::address]:port", +// return true if the string includes a port. +func hasPort(s string) bool { return strings.LastIndex(s, ":") > strings.LastIndex(s, "]") } + +// FROM: http://golang.org/src/net/http/transport.go +var portMap = map[string]string{ + "http": "80", + "https": "443", +} + +// FROM: http://golang.org/src/net/http/transport.go +// canonicalAddr returns url.Host but always with a ":port" suffix +func CanonicalAddr(url *url.URL) string { + addr := url.Host + if !hasPort(addr) { + return addr + ":" + portMap[url.Scheme] + } + return addr +} diff --git a/vendor/k8s.io/client-go/tools/remotecommand/doc.go b/vendor/k8s.io/client-go/tools/remotecommand/doc.go new file mode 100644 index 0000000000..ac06a9cd37 --- /dev/null +++ b/vendor/k8s.io/client-go/tools/remotecommand/doc.go @@ -0,0 +1,20 @@ +/* +Copyright 2015 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Package remotecommand adds support for executing commands in containers, +// with support for separate stdin, stdout, and stderr streams, as well as +// TTY. +package remotecommand // import "k8s.io/client-go/tools/remotecommand" diff --git a/vendor/k8s.io/client-go/tools/remotecommand/errorstream.go b/vendor/k8s.io/client-go/tools/remotecommand/errorstream.go new file mode 100644 index 0000000000..360276b652 --- /dev/null +++ b/vendor/k8s.io/client-go/tools/remotecommand/errorstream.go @@ -0,0 +1,55 @@ +/* +Copyright 2016 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package remotecommand + +import ( + "fmt" + "io" + "io/ioutil" + + "k8s.io/apimachinery/pkg/util/runtime" +) + +// errorStreamDecoder interprets the data on the error channel and creates a go error object from it. +type errorStreamDecoder interface { + decode(message []byte) error +} + +// watchErrorStream watches the errorStream for remote command error data, +// decodes it with the given errorStreamDecoder, sends the decoded error (or nil if the remote +// command exited successfully) to the returned error channel, and closes it. +// This function returns immediately. +func watchErrorStream(errorStream io.Reader, d errorStreamDecoder) chan error { + errorChan := make(chan error) + + go func() { + defer runtime.HandleCrash() + + message, err := ioutil.ReadAll(errorStream) + switch { + case err != nil && err != io.EOF: + errorChan <- fmt.Errorf("error reading from error stream: %s", err) + case len(message) > 0: + errorChan <- d.decode(message) + default: + errorChan <- nil + } + close(errorChan) + }() + + return errorChan +} diff --git a/vendor/k8s.io/client-go/tools/remotecommand/reader.go b/vendor/k8s.io/client-go/tools/remotecommand/reader.go new file mode 100644 index 0000000000..d1f1be34c9 --- /dev/null +++ b/vendor/k8s.io/client-go/tools/remotecommand/reader.go @@ -0,0 +1,41 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package remotecommand + +import ( + "io" +) + +// readerWrapper delegates to an io.Reader so that only the io.Reader interface is implemented, +// to keep io.Copy from doing things we don't want when copying from the reader to the data stream. +// +// If the Stdin io.Reader provided to remotecommand implements a WriteTo function (like bytes.Buffer does[1]), +// io.Copy calls that method[2] to attempt to write the entire buffer to the stream in one call. +// That results in an oversized call to spdystream.Stream#Write [3], +// which results in a single oversized data frame[4] that is too large. +// +// [1] https://golang.org/pkg/bytes/#Buffer.WriteTo +// [2] https://golang.org/pkg/io/#Copy +// [3] https://github.com/kubernetes/kubernetes/blob/90295640ef87db9daa0144c5617afe889e7992b2/vendor/github.com/docker/spdystream/stream.go#L66-L73 +// [4] https://github.com/kubernetes/kubernetes/blob/90295640ef87db9daa0144c5617afe889e7992b2/vendor/github.com/docker/spdystream/spdy/write.go#L302-L304 +type readerWrapper struct { + reader io.Reader +} + +func (r readerWrapper) Read(p []byte) (int, error) { + return r.reader.Read(p) +} diff --git a/vendor/k8s.io/client-go/tools/remotecommand/remotecommand.go b/vendor/k8s.io/client-go/tools/remotecommand/remotecommand.go new file mode 100644 index 0000000000..cb39faf7f1 --- /dev/null +++ b/vendor/k8s.io/client-go/tools/remotecommand/remotecommand.go @@ -0,0 +1,142 @@ +/* +Copyright 2015 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package remotecommand + +import ( + "fmt" + "io" + "net/http" + "net/url" + + "k8s.io/klog/v2" + + "k8s.io/apimachinery/pkg/util/httpstream" + "k8s.io/apimachinery/pkg/util/remotecommand" + restclient "k8s.io/client-go/rest" + spdy "k8s.io/client-go/transport/spdy" +) + +// StreamOptions holds information pertaining to the current streaming session: +// input/output streams, if the client is requesting a TTY, and a terminal size queue to +// support terminal resizing. +type StreamOptions struct { + Stdin io.Reader + Stdout io.Writer + Stderr io.Writer + Tty bool + TerminalSizeQueue TerminalSizeQueue +} + +// Executor is an interface for transporting shell-style streams. +type Executor interface { + // Stream initiates the transport of the standard shell streams. It will transport any + // non-nil stream to a remote system, and return an error if a problem occurs. If tty + // is set, the stderr stream is not used (raw TTY manages stdout and stderr over the + // stdout stream). + Stream(options StreamOptions) error +} + +type streamCreator interface { + CreateStream(headers http.Header) (httpstream.Stream, error) +} + +type streamProtocolHandler interface { + stream(conn streamCreator) error +} + +// streamExecutor handles transporting standard shell streams over an httpstream connection. +type streamExecutor struct { + upgrader spdy.Upgrader + transport http.RoundTripper + + method string + url *url.URL + protocols []string +} + +// NewSPDYExecutor connects to the provided server and upgrades the connection to +// multiplexed bidirectional streams. +func NewSPDYExecutor(config *restclient.Config, method string, url *url.URL) (Executor, error) { + wrapper, upgradeRoundTripper, err := spdy.RoundTripperFor(config) + if err != nil { + return nil, err + } + return NewSPDYExecutorForTransports(wrapper, upgradeRoundTripper, method, url) +} + +// NewSPDYExecutorForTransports connects to the provided server using the given transport, +// upgrades the response using the given upgrader to multiplexed bidirectional streams. +func NewSPDYExecutorForTransports(transport http.RoundTripper, upgrader spdy.Upgrader, method string, url *url.URL) (Executor, error) { + return NewSPDYExecutorForProtocols( + transport, upgrader, method, url, + remotecommand.StreamProtocolV4Name, + remotecommand.StreamProtocolV3Name, + remotecommand.StreamProtocolV2Name, + remotecommand.StreamProtocolV1Name, + ) +} + +// NewSPDYExecutorForProtocols connects to the provided server and upgrades the connection to +// multiplexed bidirectional streams using only the provided protocols. Exposed for testing, most +// callers should use NewSPDYExecutor or NewSPDYExecutorForTransports. +func NewSPDYExecutorForProtocols(transport http.RoundTripper, upgrader spdy.Upgrader, method string, url *url.URL, protocols ...string) (Executor, error) { + return &streamExecutor{ + upgrader: upgrader, + transport: transport, + method: method, + url: url, + protocols: protocols, + }, nil +} + +// Stream opens a protocol streamer to the server and streams until a client closes +// the connection or the server disconnects. +func (e *streamExecutor) Stream(options StreamOptions) error { + req, err := http.NewRequest(e.method, e.url.String(), nil) + if err != nil { + return fmt.Errorf("error creating request: %v", err) + } + + conn, protocol, err := spdy.Negotiate( + e.upgrader, + &http.Client{Transport: e.transport}, + req, + e.protocols..., + ) + if err != nil { + return err + } + defer conn.Close() + + var streamer streamProtocolHandler + + switch protocol { + case remotecommand.StreamProtocolV4Name: + streamer = newStreamProtocolV4(options) + case remotecommand.StreamProtocolV3Name: + streamer = newStreamProtocolV3(options) + case remotecommand.StreamProtocolV2Name: + streamer = newStreamProtocolV2(options) + case "": + klog.V(4).Infof("The server did not negotiate a streaming protocol version. Falling back to %s", remotecommand.StreamProtocolV1Name) + fallthrough + case remotecommand.StreamProtocolV1Name: + streamer = newStreamProtocolV1(options) + } + + return streamer.stream(conn) +} diff --git a/vendor/k8s.io/client-go/tools/remotecommand/resize.go b/vendor/k8s.io/client-go/tools/remotecommand/resize.go new file mode 100644 index 0000000000..c838f21ba6 --- /dev/null +++ b/vendor/k8s.io/client-go/tools/remotecommand/resize.go @@ -0,0 +1,33 @@ +/* +Copyright 2017 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package remotecommand + +// TerminalSize and TerminalSizeQueue was a part of k8s.io/kubernetes/pkg/util/term +// and were moved in order to decouple client from other term dependencies + +// TerminalSize represents the width and height of a terminal. +type TerminalSize struct { + Width uint16 + Height uint16 +} + +// TerminalSizeQueue is capable of returning terminal resize events as they occur. +type TerminalSizeQueue interface { + // Next returns the new terminal size after the terminal has been resized. It returns nil when + // monitoring has been stopped. + Next() *TerminalSize +} diff --git a/vendor/k8s.io/client-go/tools/remotecommand/v1.go b/vendor/k8s.io/client-go/tools/remotecommand/v1.go new file mode 100644 index 0000000000..ff0fbd2d7b --- /dev/null +++ b/vendor/k8s.io/client-go/tools/remotecommand/v1.go @@ -0,0 +1,160 @@ +/* +Copyright 2015 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package remotecommand + +import ( + "fmt" + "io" + "io/ioutil" + "net/http" + + "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/util/httpstream" + "k8s.io/klog/v2" +) + +// streamProtocolV1 implements the first version of the streaming exec & attach +// protocol. This version has some bugs, such as not being able to detect when +// non-interactive stdin data has ended. See http://issues.k8s.io/13394 and +// http://issues.k8s.io/13395 for more details. +type streamProtocolV1 struct { + StreamOptions + + errorStream httpstream.Stream + remoteStdin httpstream.Stream + remoteStdout httpstream.Stream + remoteStderr httpstream.Stream +} + +var _ streamProtocolHandler = &streamProtocolV1{} + +func newStreamProtocolV1(options StreamOptions) streamProtocolHandler { + return &streamProtocolV1{ + StreamOptions: options, + } +} + +func (p *streamProtocolV1) stream(conn streamCreator) error { + doneChan := make(chan struct{}, 2) + errorChan := make(chan error) + + cp := func(s string, dst io.Writer, src io.Reader) { + klog.V(6).Infof("Copying %s", s) + defer klog.V(6).Infof("Done copying %s", s) + if _, err := io.Copy(dst, src); err != nil && err != io.EOF { + klog.Errorf("Error copying %s: %v", s, err) + } + if s == v1.StreamTypeStdout || s == v1.StreamTypeStderr { + doneChan <- struct{}{} + } + } + + // set up all the streams first + var err error + headers := http.Header{} + headers.Set(v1.StreamType, v1.StreamTypeError) + p.errorStream, err = conn.CreateStream(headers) + if err != nil { + return err + } + defer p.errorStream.Reset() + + // Create all the streams first, then start the copy goroutines. The server doesn't start its copy + // goroutines until it's received all of the streams. If the client creates the stdin stream and + // immediately begins copying stdin data to the server, it's possible to overwhelm and wedge the + // spdy frame handler in the server so that it is full of unprocessed frames. The frames aren't + // getting processed because the server hasn't started its copying, and it won't do that until it + // gets all the streams. By creating all the streams first, we ensure that the server is ready to + // process data before the client starts sending any. See https://issues.k8s.io/16373 for more info. + if p.Stdin != nil { + headers.Set(v1.StreamType, v1.StreamTypeStdin) + p.remoteStdin, err = conn.CreateStream(headers) + if err != nil { + return err + } + defer p.remoteStdin.Reset() + } + + if p.Stdout != nil { + headers.Set(v1.StreamType, v1.StreamTypeStdout) + p.remoteStdout, err = conn.CreateStream(headers) + if err != nil { + return err + } + defer p.remoteStdout.Reset() + } + + if p.Stderr != nil && !p.Tty { + headers.Set(v1.StreamType, v1.StreamTypeStderr) + p.remoteStderr, err = conn.CreateStream(headers) + if err != nil { + return err + } + defer p.remoteStderr.Reset() + } + + // now that all the streams have been created, proceed with reading & copying + + // always read from errorStream + go func() { + message, err := ioutil.ReadAll(p.errorStream) + if err != nil && err != io.EOF { + errorChan <- fmt.Errorf("Error reading from error stream: %s", err) + return + } + if len(message) > 0 { + errorChan <- fmt.Errorf("Error executing remote command: %s", message) + return + } + }() + + if p.Stdin != nil { + // TODO this goroutine will never exit cleanly (the io.Copy never unblocks) + // because stdin is not closed until the process exits. If we try to call + // stdin.Close(), it returns no error but doesn't unblock the copy. It will + // exit when the process exits, instead. + go cp(v1.StreamTypeStdin, p.remoteStdin, readerWrapper{p.Stdin}) + } + + waitCount := 0 + completedStreams := 0 + + if p.Stdout != nil { + waitCount++ + go cp(v1.StreamTypeStdout, p.Stdout, p.remoteStdout) + } + + if p.Stderr != nil && !p.Tty { + waitCount++ + go cp(v1.StreamTypeStderr, p.Stderr, p.remoteStderr) + } + +Loop: + for { + select { + case <-doneChan: + completedStreams++ + if completedStreams == waitCount { + break Loop + } + case err := <-errorChan: + return err + } + } + + return nil +} diff --git a/vendor/k8s.io/client-go/tools/remotecommand/v2.go b/vendor/k8s.io/client-go/tools/remotecommand/v2.go new file mode 100644 index 0000000000..2f5561c942 --- /dev/null +++ b/vendor/k8s.io/client-go/tools/remotecommand/v2.go @@ -0,0 +1,200 @@ +/* +Copyright 2015 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package remotecommand + +import ( + "fmt" + "io" + "io/ioutil" + "net/http" + "sync" + + "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/util/runtime" +) + +// streamProtocolV2 implements version 2 of the streaming protocol for attach +// and exec. The original streaming protocol was metav1. As a result, this +// version is referred to as version 2, even though it is the first actual +// numbered version. +type streamProtocolV2 struct { + StreamOptions + + errorStream io.Reader + remoteStdin io.ReadWriteCloser + remoteStdout io.Reader + remoteStderr io.Reader +} + +var _ streamProtocolHandler = &streamProtocolV2{} + +func newStreamProtocolV2(options StreamOptions) streamProtocolHandler { + return &streamProtocolV2{ + StreamOptions: options, + } +} + +func (p *streamProtocolV2) createStreams(conn streamCreator) error { + var err error + headers := http.Header{} + + // set up error stream + headers.Set(v1.StreamType, v1.StreamTypeError) + p.errorStream, err = conn.CreateStream(headers) + if err != nil { + return err + } + + // set up stdin stream + if p.Stdin != nil { + headers.Set(v1.StreamType, v1.StreamTypeStdin) + p.remoteStdin, err = conn.CreateStream(headers) + if err != nil { + return err + } + } + + // set up stdout stream + if p.Stdout != nil { + headers.Set(v1.StreamType, v1.StreamTypeStdout) + p.remoteStdout, err = conn.CreateStream(headers) + if err != nil { + return err + } + } + + // set up stderr stream + if p.Stderr != nil && !p.Tty { + headers.Set(v1.StreamType, v1.StreamTypeStderr) + p.remoteStderr, err = conn.CreateStream(headers) + if err != nil { + return err + } + } + return nil +} + +func (p *streamProtocolV2) copyStdin() { + if p.Stdin != nil { + var once sync.Once + + // copy from client's stdin to container's stdin + go func() { + defer runtime.HandleCrash() + + // if p.stdin is noninteractive, p.g. `echo abc | kubectl exec -i -- cat`, make sure + // we close remoteStdin as soon as the copy from p.stdin to remoteStdin finishes. Otherwise + // the executed command will remain running. + defer once.Do(func() { p.remoteStdin.Close() }) + + if _, err := io.Copy(p.remoteStdin, readerWrapper{p.Stdin}); err != nil { + runtime.HandleError(err) + } + }() + + // read from remoteStdin until the stream is closed. this is essential to + // be able to exit interactive sessions cleanly and not leak goroutines or + // hang the client's terminal. + // + // TODO we aren't using go-dockerclient any more; revisit this to determine if it's still + // required by engine-api. + // + // go-dockerclient's current hijack implementation + // (https://github.com/fsouza/go-dockerclient/blob/89f3d56d93788dfe85f864a44f85d9738fca0670/client.go#L564) + // waits for all three streams (stdin/stdout/stderr) to finish copying + // before returning. When hijack finishes copying stdout/stderr, it calls + // Close() on its side of remoteStdin, which allows this copy to complete. + // When that happens, we must Close() on our side of remoteStdin, to + // allow the copy in hijack to complete, and hijack to return. + go func() { + defer runtime.HandleCrash() + defer once.Do(func() { p.remoteStdin.Close() }) + + // this "copy" doesn't actually read anything - it's just here to wait for + // the server to close remoteStdin. + if _, err := io.Copy(ioutil.Discard, p.remoteStdin); err != nil { + runtime.HandleError(err) + } + }() + } +} + +func (p *streamProtocolV2) copyStdout(wg *sync.WaitGroup) { + if p.Stdout == nil { + return + } + + wg.Add(1) + go func() { + defer runtime.HandleCrash() + defer wg.Done() + // make sure, packet in queue can be consumed. + // block in queue may lead to deadlock in conn.server + // issue: https://github.com/kubernetes/kubernetes/issues/96339 + defer io.Copy(ioutil.Discard, p.remoteStdout) + + if _, err := io.Copy(p.Stdout, p.remoteStdout); err != nil { + runtime.HandleError(err) + } + }() +} + +func (p *streamProtocolV2) copyStderr(wg *sync.WaitGroup) { + if p.Stderr == nil || p.Tty { + return + } + + wg.Add(1) + go func() { + defer runtime.HandleCrash() + defer wg.Done() + defer io.Copy(ioutil.Discard, p.remoteStderr) + + if _, err := io.Copy(p.Stderr, p.remoteStderr); err != nil { + runtime.HandleError(err) + } + }() +} + +func (p *streamProtocolV2) stream(conn streamCreator) error { + if err := p.createStreams(conn); err != nil { + return err + } + + // now that all the streams have been created, proceed with reading & copying + + errorChan := watchErrorStream(p.errorStream, &errorDecoderV2{}) + + p.copyStdin() + + var wg sync.WaitGroup + p.copyStdout(&wg) + p.copyStderr(&wg) + + // we're waiting for stdout/stderr to finish copying + wg.Wait() + + // waits for errorStream to finish reading with an error or nil + return <-errorChan +} + +// errorDecoderV2 interprets the error channel data as plain text. +type errorDecoderV2 struct{} + +func (d *errorDecoderV2) decode(message []byte) error { + return fmt.Errorf("error executing remote command: %s", message) +} diff --git a/vendor/k8s.io/client-go/tools/remotecommand/v3.go b/vendor/k8s.io/client-go/tools/remotecommand/v3.go new file mode 100644 index 0000000000..846dd24a5e --- /dev/null +++ b/vendor/k8s.io/client-go/tools/remotecommand/v3.go @@ -0,0 +1,111 @@ +/* +Copyright 2016 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package remotecommand + +import ( + "encoding/json" + "io" + "net/http" + "sync" + + "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/util/runtime" +) + +// streamProtocolV3 implements version 3 of the streaming protocol for attach +// and exec. This version adds support for resizing the container's terminal. +type streamProtocolV3 struct { + *streamProtocolV2 + + resizeStream io.Writer +} + +var _ streamProtocolHandler = &streamProtocolV3{} + +func newStreamProtocolV3(options StreamOptions) streamProtocolHandler { + return &streamProtocolV3{ + streamProtocolV2: newStreamProtocolV2(options).(*streamProtocolV2), + } +} + +func (p *streamProtocolV3) createStreams(conn streamCreator) error { + // set up the streams from v2 + if err := p.streamProtocolV2.createStreams(conn); err != nil { + return err + } + + // set up resize stream + if p.Tty { + headers := http.Header{} + headers.Set(v1.StreamType, v1.StreamTypeResize) + var err error + p.resizeStream, err = conn.CreateStream(headers) + if err != nil { + return err + } + } + + return nil +} + +func (p *streamProtocolV3) handleResizes() { + if p.resizeStream == nil || p.TerminalSizeQueue == nil { + return + } + go func() { + defer runtime.HandleCrash() + + encoder := json.NewEncoder(p.resizeStream) + for { + size := p.TerminalSizeQueue.Next() + if size == nil { + return + } + if err := encoder.Encode(&size); err != nil { + runtime.HandleError(err) + } + } + }() +} + +func (p *streamProtocolV3) stream(conn streamCreator) error { + if err := p.createStreams(conn); err != nil { + return err + } + + // now that all the streams have been created, proceed with reading & copying + + errorChan := watchErrorStream(p.errorStream, &errorDecoderV3{}) + + p.handleResizes() + + p.copyStdin() + + var wg sync.WaitGroup + p.copyStdout(&wg) + p.copyStderr(&wg) + + // we're waiting for stdout/stderr to finish copying + wg.Wait() + + // waits for errorStream to finish reading with an error or nil + return <-errorChan +} + +type errorDecoderV3 struct { + errorDecoderV2 +} diff --git a/vendor/k8s.io/client-go/tools/remotecommand/v4.go b/vendor/k8s.io/client-go/tools/remotecommand/v4.go new file mode 100644 index 0000000000..69ca934a0d --- /dev/null +++ b/vendor/k8s.io/client-go/tools/remotecommand/v4.go @@ -0,0 +1,119 @@ +/* +Copyright 2016 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package remotecommand + +import ( + "encoding/json" + "errors" + "fmt" + "strconv" + "sync" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/util/remotecommand" + "k8s.io/client-go/util/exec" +) + +// streamProtocolV4 implements version 4 of the streaming protocol for attach +// and exec. This version adds support for exit codes on the error stream through +// the use of metav1.Status instead of plain text messages. +type streamProtocolV4 struct { + *streamProtocolV3 +} + +var _ streamProtocolHandler = &streamProtocolV4{} + +func newStreamProtocolV4(options StreamOptions) streamProtocolHandler { + return &streamProtocolV4{ + streamProtocolV3: newStreamProtocolV3(options).(*streamProtocolV3), + } +} + +func (p *streamProtocolV4) createStreams(conn streamCreator) error { + return p.streamProtocolV3.createStreams(conn) +} + +func (p *streamProtocolV4) handleResizes() { + p.streamProtocolV3.handleResizes() +} + +func (p *streamProtocolV4) stream(conn streamCreator) error { + if err := p.createStreams(conn); err != nil { + return err + } + + // now that all the streams have been created, proceed with reading & copying + + errorChan := watchErrorStream(p.errorStream, &errorDecoderV4{}) + + p.handleResizes() + + p.copyStdin() + + var wg sync.WaitGroup + p.copyStdout(&wg) + p.copyStderr(&wg) + + // we're waiting for stdout/stderr to finish copying + wg.Wait() + + // waits for errorStream to finish reading with an error or nil + return <-errorChan +} + +// errorDecoderV4 interprets the json-marshaled metav1.Status on the error channel +// and creates an exec.ExitError from it. +type errorDecoderV4 struct{} + +func (d *errorDecoderV4) decode(message []byte) error { + status := metav1.Status{} + err := json.Unmarshal(message, &status) + if err != nil { + return fmt.Errorf("error stream protocol error: %v in %q", err, string(message)) + } + switch status.Status { + case metav1.StatusSuccess: + return nil + case metav1.StatusFailure: + if status.Reason == remotecommand.NonZeroExitCodeReason { + if status.Details == nil { + return errors.New("error stream protocol error: details must be set") + } + for i := range status.Details.Causes { + c := &status.Details.Causes[i] + if c.Type != remotecommand.ExitCodeCauseType { + continue + } + + rc, err := strconv.ParseUint(c.Message, 10, 8) + if err != nil { + return fmt.Errorf("error stream protocol error: invalid exit code value %q", c.Message) + } + return exec.CodeExitError{ + Err: fmt.Errorf("command terminated with exit code %d", rc), + Code: int(rc), + } + } + + return fmt.Errorf("error stream protocol error: no %s cause given", remotecommand.ExitCodeCauseType) + } + default: + return errors.New("error stream protocol error: unknown error") + } + + return fmt.Errorf(status.Message) +} diff --git a/vendor/k8s.io/client-go/transport/spdy/spdy.go b/vendor/k8s.io/client-go/transport/spdy/spdy.go new file mode 100644 index 0000000000..406d3cc19c --- /dev/null +++ b/vendor/k8s.io/client-go/transport/spdy/spdy.go @@ -0,0 +1,105 @@ +/* +Copyright 2017 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package spdy + +import ( + "fmt" + "net/http" + "net/url" + "time" + + "k8s.io/apimachinery/pkg/util/httpstream" + "k8s.io/apimachinery/pkg/util/httpstream/spdy" + restclient "k8s.io/client-go/rest" +) + +// Upgrader validates a response from the server after a SPDY upgrade. +type Upgrader interface { + // NewConnection validates the response and creates a new Connection. + NewConnection(resp *http.Response) (httpstream.Connection, error) +} + +// RoundTripperFor returns a round tripper and upgrader to use with SPDY. +func RoundTripperFor(config *restclient.Config) (http.RoundTripper, Upgrader, error) { + tlsConfig, err := restclient.TLSConfigFor(config) + if err != nil { + return nil, nil, err + } + proxy := http.ProxyFromEnvironment + if config.Proxy != nil { + proxy = config.Proxy + } + upgradeRoundTripper := spdy.NewRoundTripperWithConfig(spdy.RoundTripperConfig{ + TLS: tlsConfig, + FollowRedirects: true, + RequireSameHostRedirects: false, + Proxier: proxy, + PingPeriod: time.Second * 5, + }) + wrapper, err := restclient.HTTPWrappersForConfig(config, upgradeRoundTripper) + if err != nil { + return nil, nil, err + } + return wrapper, upgradeRoundTripper, nil +} + +// dialer implements the httpstream.Dialer interface. +type dialer struct { + client *http.Client + upgrader Upgrader + method string + url *url.URL +} + +var _ httpstream.Dialer = &dialer{} + +// NewDialer will create a dialer that connects to the provided URL and upgrades the connection to SPDY. +func NewDialer(upgrader Upgrader, client *http.Client, method string, url *url.URL) httpstream.Dialer { + return &dialer{ + client: client, + upgrader: upgrader, + method: method, + url: url, + } +} + +func (d *dialer) Dial(protocols ...string) (httpstream.Connection, string, error) { + req, err := http.NewRequest(d.method, d.url.String(), nil) + if err != nil { + return nil, "", fmt.Errorf("error creating request: %v", err) + } + return Negotiate(d.upgrader, d.client, req, protocols...) +} + +// Negotiate opens a connection to a remote server and attempts to negotiate +// a SPDY connection. Upon success, it returns the connection and the protocol selected by +// the server. The client transport must use the upgradeRoundTripper - see RoundTripperFor. +func Negotiate(upgrader Upgrader, client *http.Client, req *http.Request, protocols ...string) (httpstream.Connection, string, error) { + for i := range protocols { + req.Header.Add(httpstream.HeaderProtocolVersion, protocols[i]) + } + resp, err := client.Do(req) + if err != nil { + return nil, "", fmt.Errorf("error sending request: %v", err) + } + defer resp.Body.Close() + conn, err := upgrader.NewConnection(resp) + if err != nil { + return nil, "", err + } + return conn, resp.Header.Get(httpstream.HeaderProtocolVersion), nil +} diff --git a/vendor/k8s.io/client-go/util/exec/exec.go b/vendor/k8s.io/client-go/util/exec/exec.go new file mode 100644 index 0000000000..d170badb60 --- /dev/null +++ b/vendor/k8s.io/client-go/util/exec/exec.go @@ -0,0 +1,52 @@ +/* +Copyright 2014 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package exec + +// ExitError is an interface that presents an API similar to os.ProcessState, which is +// what ExitError from os/exec is. This is designed to make testing a bit easier and +// probably loses some of the cross-platform properties of the underlying library. +type ExitError interface { + String() string + Error() string + Exited() bool + ExitStatus() int +} + +// CodeExitError is an implementation of ExitError consisting of an error object +// and an exit code (the upper bits of os.exec.ExitStatus). +type CodeExitError struct { + Err error + Code int +} + +var _ ExitError = CodeExitError{} + +func (e CodeExitError) Error() string { + return e.Err.Error() +} + +func (e CodeExitError) String() string { + return e.Err.Error() +} + +func (e CodeExitError) Exited() bool { + return true +} + +func (e CodeExitError) ExitStatus() int { + return e.Code +} diff --git a/vendor/k8s.io/klog/v2/go.mod b/vendor/k8s.io/klog/v2/go.mod index eb297b6a1e..31aefba74a 100644 --- a/vendor/k8s.io/klog/v2/go.mod +++ b/vendor/k8s.io/klog/v2/go.mod @@ -2,4 +2,4 @@ module k8s.io/klog/v2 go 1.13 -require github.com/go-logr/logr v0.4.0 +require github.com/go-logr/logr v1.2.0 diff --git a/vendor/k8s.io/klog/v2/go.sum b/vendor/k8s.io/klog/v2/go.sum index 5778f81742..919fbadbc0 100644 --- a/vendor/k8s.io/klog/v2/go.sum +++ b/vendor/k8s.io/klog/v2/go.sum @@ -1,2 +1,2 @@ -github.com/go-logr/logr v0.4.0 h1:K7/B1jt6fIBQVd4Owv2MqGQClcgf0R266+7C/QjRcLc= -github.com/go-logr/logr v0.4.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU= +github.com/go-logr/logr v1.2.0 h1:QK40JKJyMdUDz+h+xvCsru/bJhvG0UxvePV0ufL/AcE= +github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= diff --git a/vendor/k8s.io/klog/v2/klog.go b/vendor/k8s.io/klog/v2/klog.go index 25483fad13..45efbb0755 100644 --- a/vendor/k8s.io/klog/v2/klog.go +++ b/vendor/k8s.io/klog/v2/klog.go @@ -284,6 +284,7 @@ func (m *moduleSpec) Get() interface{} { var errVmoduleSyntax = errors.New("syntax error: expect comma-separated list of filename=N") +// Set will sets module value // Syntax: -vmodule=recordio=2,file=1,gfs*=3 func (m *moduleSpec) Set(value string) error { var filter []modulePat @@ -362,6 +363,7 @@ func (t *traceLocation) Get() interface{} { var errTraceSyntax = errors.New("syntax error: expect file.go:234") +// Set will sets backtrace value // Syntax: -log_backtrace_at=gopherflakes.go:234 // Note that unlike vmodule the file extension is included here. func (t *traceLocation) Set(value string) error { @@ -507,7 +509,7 @@ type loggingT struct { addDirHeader bool // If set, all output will be redirected unconditionally to the provided logr.Logger - logr logr.Logger + logr *logr.Logger // If true, messages will not be propagated to lower severity log levels oneOutput bool @@ -696,11 +698,11 @@ func (buf *buffer) someDigits(i, d int) int { return copy(buf.tmp[i:], buf.tmp[j:]) } -func (l *loggingT) println(s severity, logr logr.Logger, filter LogFilter, args ...interface{}) { +func (l *loggingT) println(s severity, logger *logr.Logger, filter LogFilter, args ...interface{}) { buf, file, line := l.header(s, 0) - // if logr is set, we clear the generated header as we rely on the backing - // logr implementation to print headers - if logr != nil { + // if logger is set, we clear the generated header as we rely on the backing + // logger implementation to print headers + if logger != nil { l.putBuffer(buf) buf = l.getBuffer() } @@ -708,18 +710,18 @@ func (l *loggingT) println(s severity, logr logr.Logger, filter LogFilter, args args = filter.Filter(args) } fmt.Fprintln(buf, args...) - l.output(s, logr, buf, file, line, false) + l.output(s, logger, buf, 0 /* depth */, file, line, false) } -func (l *loggingT) print(s severity, logr logr.Logger, filter LogFilter, args ...interface{}) { - l.printDepth(s, logr, filter, 1, args...) +func (l *loggingT) print(s severity, logger *logr.Logger, filter LogFilter, args ...interface{}) { + l.printDepth(s, logger, filter, 1, args...) } -func (l *loggingT) printDepth(s severity, logr logr.Logger, filter LogFilter, depth int, args ...interface{}) { +func (l *loggingT) printDepth(s severity, logger *logr.Logger, filter LogFilter, depth int, args ...interface{}) { buf, file, line := l.header(s, depth) // if logr is set, we clear the generated header as we rely on the backing // logr implementation to print headers - if logr != nil { + if logger != nil { l.putBuffer(buf) buf = l.getBuffer() } @@ -730,14 +732,14 @@ func (l *loggingT) printDepth(s severity, logr logr.Logger, filter LogFilter, de if buf.Bytes()[buf.Len()-1] != '\n' { buf.WriteByte('\n') } - l.output(s, logr, buf, file, line, false) + l.output(s, logger, buf, depth, file, line, false) } -func (l *loggingT) printf(s severity, logr logr.Logger, filter LogFilter, format string, args ...interface{}) { +func (l *loggingT) printf(s severity, logger *logr.Logger, filter LogFilter, format string, args ...interface{}) { buf, file, line := l.header(s, 0) // if logr is set, we clear the generated header as we rely on the backing // logr implementation to print headers - if logr != nil { + if logger != nil { l.putBuffer(buf) buf = l.getBuffer() } @@ -748,17 +750,17 @@ func (l *loggingT) printf(s severity, logr logr.Logger, filter LogFilter, format if buf.Bytes()[buf.Len()-1] != '\n' { buf.WriteByte('\n') } - l.output(s, logr, buf, file, line, false) + l.output(s, logger, buf, 0 /* depth */, file, line, false) } // printWithFileLine behaves like print but uses the provided file and line number. If // alsoLogToStderr is true, the log message always appears on standard error; it // will also appear in the log file unless --logtostderr is set. -func (l *loggingT) printWithFileLine(s severity, logr logr.Logger, filter LogFilter, file string, line int, alsoToStderr bool, args ...interface{}) { +func (l *loggingT) printWithFileLine(s severity, logger *logr.Logger, filter LogFilter, file string, line int, alsoToStderr bool, args ...interface{}) { buf := l.formatHeader(s, file, line) // if logr is set, we clear the generated header as we rely on the backing // logr implementation to print headers - if logr != nil { + if logger != nil { l.putBuffer(buf) buf = l.getBuffer() } @@ -769,28 +771,28 @@ func (l *loggingT) printWithFileLine(s severity, logr logr.Logger, filter LogFil if buf.Bytes()[buf.Len()-1] != '\n' { buf.WriteByte('\n') } - l.output(s, logr, buf, file, line, alsoToStderr) + l.output(s, logger, buf, 2 /* depth */, file, line, alsoToStderr) } // if loggr is specified, will call loggr.Error, otherwise output with logging module. -func (l *loggingT) errorS(err error, loggr logr.Logger, filter LogFilter, depth int, msg string, keysAndValues ...interface{}) { +func (l *loggingT) errorS(err error, logger *logr.Logger, filter LogFilter, depth int, msg string, keysAndValues ...interface{}) { if filter != nil { msg, keysAndValues = filter.FilterS(msg, keysAndValues) } - if loggr != nil { - loggr.Error(err, msg, keysAndValues...) + if logger != nil { + logger.WithCallDepth(depth+2).Error(err, msg, keysAndValues...) return } l.printS(err, errorLog, depth+1, msg, keysAndValues...) } // if loggr is specified, will call loggr.Info, otherwise output with logging module. -func (l *loggingT) infoS(loggr logr.Logger, filter LogFilter, depth int, msg string, keysAndValues ...interface{}) { +func (l *loggingT) infoS(logger *logr.Logger, filter LogFilter, depth int, msg string, keysAndValues ...interface{}) { if filter != nil { msg, keysAndValues = filter.FilterS(msg, keysAndValues) } - if loggr != nil { - loggr.Info(msg, keysAndValues...) + if logger != nil { + logger.WithCallDepth(depth+2).Info(msg, keysAndValues...) return } l.printS(nil, infoLog, depth+1, msg, keysAndValues...) @@ -825,6 +827,8 @@ func kvListFormat(b *bytes.Buffer, keysAndValues ...interface{}) { switch v.(type) { case string, error: b.WriteString(fmt.Sprintf("%s=%q", k, v)) + case []byte: + b.WriteString(fmt.Sprintf("%s=%+q", k, v)) default: if _, ok := v.(fmt.Stringer); ok { b.WriteString(fmt.Sprintf("%s=%q", k, v)) @@ -855,13 +859,26 @@ func (rb *redirectBuffer) Write(bytes []byte) (n int, err error) { // SetLogger will set the backing logr implementation for klog. // If set, all log lines will be suppressed from the regular Output, and // redirected to the logr implementation. -// All log lines include the 'severity', 'file' and 'line' values attached as -// structured logging values. // Use as: // ... // klog.SetLogger(zapr.NewLogger(zapLog)) +// +// To remove a backing logr implemention, use ClearLogger. Setting an +// empty logger with SetLogger(logr.Logger{}) does not work. func SetLogger(logr logr.Logger) { - logging.logr = logr + logging.mu.Lock() + defer logging.mu.Unlock() + + logging.logr = &logr +} + +// ClearLogger removes a backing logr implementation if one was set earlier +// with SetLogger. +func ClearLogger() { + logging.mu.Lock() + defer logging.mu.Unlock() + + logging.logr = nil } // SetOutput sets the output destination for all severities @@ -899,7 +916,7 @@ func LogToStderr(stderr bool) { } // output writes the data to the log files and releases the buffer. -func (l *loggingT) output(s severity, log logr.Logger, buf *buffer, file string, line int, alsoToStderr bool) { +func (l *loggingT) output(s severity, log *logr.Logger, buf *buffer, depth int, file string, line int, alsoToStderr bool) { l.mu.Lock() if l.traceLocation.isSet() { if l.traceLocation.match(file, line) { @@ -911,9 +928,9 @@ func (l *loggingT) output(s severity, log logr.Logger, buf *buffer, file string, // TODO: set 'severity' and caller information as structured log info // keysAndValues := []interface{}{"severity", severityName[s], "file", file, "line", line} if s == errorLog { - l.logr.Error(nil, string(data)) + l.logr.WithCallDepth(depth+3).Error(nil, string(data)) } else { - log.Info(string(data)) + log.WithCallDepth(depth + 3).Info(string(data)) } } else if l.toStderr { os.Stderr.Write(data) @@ -1264,7 +1281,7 @@ func (l *loggingT) setV(pc uintptr) Level { // See the documentation of V for more information. type Verbose struct { enabled bool - logr logr.Logger + logr *logr.Logger filter LogFilter } @@ -1272,7 +1289,8 @@ func newVerbose(level Level, b bool) Verbose { if logging.logr == nil { return Verbose{b, nil, logging.filter} } - return Verbose{b, logging.logr.V(int(level)), logging.filter} + v := logging.logr.V(int(level)) + return Verbose{b, &v, logging.filter} } // V reports whether verbosity at the call site is at least the requested level. @@ -1310,9 +1328,14 @@ func V(level Level) Verbose { if runtime.Callers(2, logging.pcs[:]) == 0 { return newVerbose(level, false) } - v, ok := logging.vmap[logging.pcs[0]] + // runtime.Callers returns "return PCs", but we want + // to look up the symbolic information for the call, + // so subtract 1 from the PC. runtime.CallersFrames + // would be cleaner, but allocates. + pc := logging.pcs[0] - 1 + v, ok := logging.vmap[pc] if !ok { - v = logging.setV(logging.pcs[0]) + v = logging.setV(pc) } return newVerbose(level, v >= level) } @@ -1568,6 +1591,15 @@ func (ref ObjectRef) String() string { return ref.Name } +// MarshalLog ensures that loggers with support for structured output will log +// as a struct by removing the String method via a custom type. +func (ref ObjectRef) MarshalLog() interface{} { + type or ObjectRef + return or(ref) +} + +var _ logr.Marshaler = ObjectRef{} + // KMetadata is a subset of the kubernetes k8s.io/apimachinery/pkg/apis/meta/v1.Object interface // this interface may expand in the future, but will always be a subset of the // kubernetes k8s.io/apimachinery/pkg/apis/meta/v1.Object interface @@ -1598,3 +1630,20 @@ func KRef(namespace, name string) ObjectRef { Namespace: namespace, } } + +// KObjs returns slice of ObjectRef from an slice of ObjectMeta +func KObjs(arg interface{}) []ObjectRef { + s := reflect.ValueOf(arg) + if s.Kind() != reflect.Slice { + return nil + } + objectRefs := make([]ObjectRef, 0, s.Len()) + for i := 0; i < s.Len(); i++ { + if v, ok := s.Index(i).Interface().(KMetadata); ok { + objectRefs = append(objectRefs, KObj(v)) + } else { + return nil + } + } + return objectRefs +} diff --git a/vendor/knative.dev/kn-plugin-event/LICENSE b/vendor/knative.dev/kn-plugin-event/LICENSE new file mode 100644 index 0000000000..059b110a18 --- /dev/null +++ b/vendor/knative.dev/kn-plugin-event/LICENSE @@ -0,0 +1,202 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2020 Knative CLI Event Contributors + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + diff --git a/vendor/knative.dev/kn-plugin-event/internal/cli/cmd/build.go b/vendor/knative.dev/kn-plugin-event/internal/cli/cmd/build.go new file mode 100644 index 0000000000..4857e40bc7 --- /dev/null +++ b/vendor/knative.dev/kn-plugin-event/internal/cli/cmd/build.go @@ -0,0 +1,51 @@ +package cmd + +import ( + "errors" + "fmt" + + "github.com/spf13/cobra" + "knative.dev/kn-plugin-event/pkg/cli" + "knative.dev/kn-plugin-event/pkg/configuration" +) + +// ErrCantBePresented is returned if data can't be presented. +var ErrCantBePresented = errors.New("can't be presented") + +type buildCommand struct { + *Cmd + event *cli.EventArgs +} + +func (b *buildCommand) command() *cobra.Command { + c := &cobra.Command{ + Use: "build", + Short: "Builds a CloudEvent and print it to stdout", + RunE: b.run, + } + addBuilderFlags(b.event, c) + return c +} + +func (b *buildCommand) run(cmd *cobra.Command, _ []string) error { + b.options.OutWriter = cmd.OutOrStdout() + b.options.ErrWriter = cmd.ErrOrStderr() + c := configuration.CreateCli() + ce, err := c.CreateWithArgs(b.event) + if err != nil { + return cantBuildEventError(err) + } + out, err := c.PresentWith(ce, b.options.Output) + if err != nil { + return fmt.Errorf("event %w: %v", ErrCantBePresented, err) + } + cmd.Println(out) + return nil +} + +func cantBuildEventError(err error) error { + if errors.Is(err, cli.ErrCantBuildEvent) { + return err + } + return fmt.Errorf("%w: %v", cli.ErrCantBuildEvent, err) +} diff --git a/vendor/knative.dev/kn-plugin-event/internal/cli/cmd/builder.go b/vendor/knative.dev/kn-plugin-event/internal/cli/cmd/builder.go new file mode 100644 index 0000000000..5fd51630f5 --- /dev/null +++ b/vendor/knative.dev/kn-plugin-event/internal/cli/cmd/builder.go @@ -0,0 +1,36 @@ +package cmd + +import ( + "github.com/spf13/cobra" + "knative.dev/kn-plugin-event/pkg/cli" + "knative.dev/kn-plugin-event/pkg/event" +) + +func addBuilderFlags(eventArgs *cli.EventArgs, c *cobra.Command) { + fs := c.Flags() + fs.StringVarP( + &eventArgs.Type, "type", "t", event.DefaultType, + "Specify a type of a CloudEvent", + ) + fs.StringVarP( + &eventArgs.ID, "id", "i", event.NewID(), + "Specify a CloudEvent ID", + ) + fs.StringVarP( + &eventArgs.Source, "source", "s", event.DefaultSource(), + "Specify a source of an CloudEvent", + ) + fs.StringArrayVarP( + &eventArgs.Fields, "field", "f", make([]string, 0), + `Specify a field for data of an CloudEvent. Field should be specified as +jsonpath expression followed by equal sign and then a value. Value will be +resolved to be used in exact type. Example: +"person.age=18".`, + ) + fs.StringArrayVar( + &eventArgs.RawFields, "raw-field", make([]string, 0), + `Specify a raw field for data of an CloudEvent. Raw field should be +specified as jsonpath expression followed by equal sign and then a value. The +value will be used as string. Example: "person.name=John".`, + ) +} diff --git a/vendor/knative.dev/kn-plugin-event/internal/cli/cmd/root.go b/vendor/knative.dev/kn-plugin-event/internal/cli/cmd/root.go new file mode 100644 index 0000000000..947f31920e --- /dev/null +++ b/vendor/knative.dev/kn-plugin-event/internal/cli/cmd/root.go @@ -0,0 +1,124 @@ +package cmd + +import ( + "fmt" + "io" + "os" + + "github.com/spf13/cobra" + "github.com/thediveo/enumflag" + + // for kubeconfig auth plugins to work correctly see issue #24 . + _ "k8s.io/client-go/plugin/pkg/client/auth" + "knative.dev/kn-plugin-event/pkg/cli" + "knative.dev/kn-plugin-event/pkg/cli/retcode" + "knative.dev/kn-plugin-event/pkg/metadata" +) + +// Cmd represents a command line application entrypoint. +type Cmd struct { + options *cli.Options + root *cobra.Command + exit func(code int) +} + +// Execute will execute the application. +func (c *Cmd) Execute() { + if err := c.execute(); err != nil { + c.exit(retcode.Calc(err)) + } +} + +// ExecuteWithOptions will execute the application with the provided options. +func (c *Cmd) ExecuteWithOptions(options ...CommandOption) error { + return c.execute(options...) +} + +// WithArgs creates an option which sets args. +func WithArgs(args ...string) CommandOption { + return func(command *cobra.Command) { + command.SetArgs(args) + } +} + +// WithOutput creates an option witch sets os.Stdout and os.Stderr. +func WithOutput(out io.Writer) CommandOption { + return func(command *cobra.Command) { + command.SetOut(out) + command.SetErr(out) + } +} + +// CommandOption is used to configure a command in Cmd.ExecuteWithOptions. +type CommandOption func(*cobra.Command) + +func (c *Cmd) execute(configs ...CommandOption) error { + c.init() + for _, config := range configs { + config(c.root) + } + // cobra.Command should pass our own errors, no need to wrap them. + return c.root.Execute() //nolint:wrapcheck +} + +func (c *Cmd) init() { + if c.root != nil { + return + } + c.exit = os.Exit + c.options = &cli.Options{} + c.root = &cobra.Command{ + Use: metadata.PluginUse, + Aliases: []string{fmt.Sprintf("kn %s", metadata.PluginUse)}, + Short: metadata.PluginDescription, + Long: metadata.PluginLongDescription, + } + c.root.SetOut(os.Stdout) + c.root.SetErr(os.Stderr) + c.root.PersistentFlags().BoolVarP( + &c.options.Verbose, "verbose", "v", + false, "verbose output", + ) + c.root.PersistentFlags().VarP( + enumflag.New(&c.options.Output, "output", outputModeIds(), enumflag.EnumCaseInsensitive), + "output", "o", + "Output format. One of: human|json|yaml.", + ) + + eventArgs := &cli.EventArgs{} + targetArgs := &cli.TargetArgs{} + commands := []subcommand{ + &buildCommand{Cmd: c, event: eventArgs}, + &sendCommand{Cmd: c, event: eventArgs, target: targetArgs}, + &versionCommand{Cmd: c}, + } + for _, each := range commands { + c.root.AddCommand(each.command()) + } + + c.root.PersistentFlags().StringVar( + &c.options.KubeconfigOptions.Path, "kubeconfig", "", + "kubectl configuration file (default: ~/.kube/config)", + ) + c.root.PersistentFlags().StringVar( + &c.options.KubeconfigOptions.Context, "context", "", + "name of the kubeconfig context to use", + ) + c.root.PersistentFlags().StringVar( + &c.options.KubeconfigOptions.Cluster, "cluster", "", + "name of the kubeconfig cluster to use", + ) + + c.root.PersistentPreRun = func(cmd *cobra.Command, args []string) { + c.options.OutWriter = cmd.OutOrStdout() + c.options.ErrWriter = cmd.ErrOrStderr() + } +} + +func outputModeIds() map[cli.OutputMode][]string { + return map[cli.OutputMode][]string{ + cli.HumanReadable: {"human"}, + cli.JSON: {"json"}, + cli.YAML: {"yaml"}, + } +} diff --git a/vendor/knative.dev/kn-plugin-event/internal/cli/cmd/send.go b/vendor/knative.dev/kn-plugin-event/internal/cli/cmd/send.go new file mode 100644 index 0000000000..acaf762836 --- /dev/null +++ b/vendor/knative.dev/kn-plugin-event/internal/cli/cmd/send.go @@ -0,0 +1,95 @@ +package cmd + +import ( + "errors" + "fmt" + + "github.com/spf13/cobra" + "knative.dev/kn-plugin-event/pkg/cli" + "knative.dev/kn-plugin-event/pkg/configuration" + "knative.dev/kn-plugin-event/pkg/event" +) + +var ( + // ErrSendTargetValidationFailed is returned if a send target can't pass a + // validation. + ErrSendTargetValidationFailed = errors.New("send target validation failed") + + // ErrCantSendEvent is returned if event can't be sent. + ErrCantSendEvent = errors.New("can't send event") +) + +type sendCommand struct { + target *cli.TargetArgs + event *cli.EventArgs + *Cmd +} + +func (s *sendCommand) command() *cobra.Command { + c := &cobra.Command{ + Use: "send", + Short: "Builds and sends a CloudEvent to recipient", + RunE: s.run, + } + addBuilderFlags(s.event, c) + c.Flags().StringVarP( + &s.target.URL, "to-url", "u", "", + `Specify an URL to send event to. This option can't be used with +--to option.`, + ) + c.Flags().StringVarP( + &s.target.Addressable, "to", "r", "", + `Specify an addressable resource to send event to. This argument +takes format kind:apiVersion:name for named resources or +kind:apiVersion:labelKey1=value1,labelKey2=value2 for matching via a +label selector. This option can't be used with --to-url option.`, + ) + c.Flags().StringVarP( + &s.target.Namespace, "namespace", "n", "", + `Specify a namespace of addressable resource defined with --to +option. If this option isn't specified a current context namespace will be used +to find addressable resource. This option can't be used with --to-url option.`, + ) + c.Flags().StringVar( + &s.target.SenderNamespace, "sender-namespace", "", + `Specify a namespace of sender job to be created. While using --to +option, event is send within a cluster. To do that kn-event uses a special Job +that is deployed to cluster in namespace dictated by --sender-namespace. If +this option isn't specified a current context namespace will be used. This +option can't be used with --to-url option.`, + ) + c.Flags().StringVar( + &s.target.AddressableURI, "addressable-uri", "", + `Specify an URI of a target addressable resource. If this option +isn't specified target URL will not be changed. This option can't be used with +--to-url option.`, + ) + c.PreRunE = func(cmd *cobra.Command, args []string) error { + err := cli.ValidateTarget(s.target) + if err != nil { + return fmt.Errorf("%w: %v", ErrSendTargetValidationFailed, err) + } + return nil + } + return c +} + +func (s *sendCommand) run(_ *cobra.Command, _ []string) error { + c := configuration.CreateCli() + ce, err := c.CreateWithArgs(s.event) + if err != nil { + return cantBuildEventError(err) + } + err = c.Send(*ce, *s.target, s.options) + if err != nil { + return cantSentEvent(err) + } + return nil +} + +func cantSentEvent(err error) error { + if errors.Is(err, event.ErrCantSentEvent) { + return err + } + return fmt.Errorf("%w: %v", event.ErrCantSentEvent, err) +} diff --git a/vendor/knative.dev/kn-plugin-event/internal/cli/cmd/testing.go b/vendor/knative.dev/kn-plugin-event/internal/cli/cmd/testing.go new file mode 100644 index 0000000000..cc64400988 --- /dev/null +++ b/vendor/knative.dev/kn-plugin-event/internal/cli/cmd/testing.go @@ -0,0 +1,46 @@ +package cmd + +import "io" + +// TestingCmd a wrapper for Cmd to ease of testing. +type TestingCmd struct { + *Cmd +} + +// ExecuteOrFail the command or fail on error. +func (c *TestingCmd) ExecuteOrFail() { + c.init() + c.Cmd.Execute() +} + +// Execute the command and return error if any. +func (c *TestingCmd) Execute() error { + c.init() + return c.execute() +} + +// Exit sets the exit command that accepts retcode. +func (c *TestingCmd) Exit(fn func(code int)) { + c.init() + c.exit = fn +} + +// Out sets output stream to cmd. +func (c *TestingCmd) Out(newOut io.Writer) { + c.init() + c.root.SetOut(newOut) + c.root.SetErr(newOut) +} + +// Args set to main command to be executed. +func (c *TestingCmd) Args(args ...string) { + c.init() + c.root.SetArgs(args) +} + +func (c *TestingCmd) init() { + if c.Cmd == nil { + c.Cmd = &Cmd{} + } + c.Cmd.init() +} diff --git a/vendor/knative.dev/kn-plugin-event/internal/cli/cmd/types.go b/vendor/knative.dev/kn-plugin-event/internal/cli/cmd/types.go new file mode 100644 index 0000000000..01048b77e1 --- /dev/null +++ b/vendor/knative.dev/kn-plugin-event/internal/cli/cmd/types.go @@ -0,0 +1,7 @@ +package cmd + +import "github.com/spf13/cobra" + +type subcommand interface { + command() *cobra.Command +} diff --git a/vendor/knative.dev/kn-plugin-event/internal/cli/cmd/version.go b/vendor/knative.dev/kn-plugin-event/internal/cli/cmd/version.go new file mode 100644 index 0000000000..224ee9a18f --- /dev/null +++ b/vendor/knative.dev/kn-plugin-event/internal/cli/cmd/version.go @@ -0,0 +1,64 @@ +package cmd + +import ( + "encoding/json" + "errors" + "fmt" + + "github.com/spf13/cobra" + "gopkg.in/yaml.v2" + "knative.dev/kn-plugin-event/pkg/cli" + "knative.dev/kn-plugin-event/pkg/metadata" +) + +// ErrUnsupportedOutputMode is returned if user passed a unsupported +// output mode. +var ErrUnsupportedOutputMode = errors.New("unsupported mode") + +type versionCommand struct { + *Cmd +} + +func (v *versionCommand) command() *cobra.Command { + return &cobra.Command{ + Use: "version", + Short: "Prints the kn event plugin version", + RunE: v.run, + } +} + +func (v *versionCommand) run(cmd *cobra.Command, _ []string) error { + output, err := presentAs(cli.PluginVersionOutput{ + Name: metadata.PluginName, + Version: metadata.Version, + Image: metadata.ResolveImage(), + }, v.options.Output) + if err != nil { + return err + } + cmd.Println(output) + return nil +} + +func presentAs(pv cli.PluginVersionOutput, mode cli.OutputMode) (string, error) { + switch mode { + case cli.JSON: + return marshalWith(pv, json.Marshal) + case cli.YAML: + return marshalWith(pv, yaml.Marshal) + case cli.HumanReadable: + return fmt.Sprintf("%s version: %s\nsender image: %s", + pv.Name, pv.Version, pv.Image), nil + } + return "", fmt.Errorf("%w: %v", ErrUnsupportedOutputMode, mode) +} + +type marshalFunc func(in interface{}) (out []byte, err error) + +func marshalWith(pv cli.PluginVersionOutput, marchaller marshalFunc) (string, error) { + bytes, err := marchaller(pv) + if err != nil { + return "", fmt.Errorf("version %w: %v", ErrCantBePresented, err) + } + return string(bytes), err +} diff --git a/vendor/knative.dev/kn-plugin-event/pkg/cli/create.go b/vendor/knative.dev/kn-plugin-event/pkg/cli/create.go new file mode 100644 index 0000000000..bc5d1d72fe --- /dev/null +++ b/vendor/knative.dev/kn-plugin-event/pkg/cli/create.go @@ -0,0 +1,169 @@ +package cli + +import ( + "encoding/json" + "errors" + "fmt" + "strconv" + "strings" + "time" + + cloudevents "github.com/cloudevents/sdk-go/v2" + "github.com/ghodss/yaml" + "knative.dev/kn-plugin-event/pkg/event" +) + +const ( + fieldAssigmentSize = 2 + decimalBase = 10 + precision64BitSize = 64 +) + +var ( + // ErrUnsupportedOutputMode if user passed unsupported output mode. + ErrUnsupportedOutputMode = errors.New("unsupported output mode") + + // ErrInvalidFormat if user pass an un-parsable format. + ErrInvalidFormat = errors.New("invalid format") + + // ErrCantBuildEvent if event can't be built. + ErrCantBuildEvent = errors.New("can't build event") + + // ErrCantMarshalEvent if event can't be marshalled to text. + ErrCantMarshalEvent = errors.New("can't marshal event") +) + +// CreateWithArgs will create an event by parsing given args. +func (c *App) CreateWithArgs(args *EventArgs) (*cloudevents.Event, error) { + spec := &event.Spec{ + Type: args.Type, + ID: args.ID, + Source: args.Source, + Fields: make([]event.FieldSpec, 0, len(args.Fields)+len(args.RawFields)), + } + for _, fieldAssigment := range args.Fields { + split := strings.SplitN(fieldAssigment, "=", fieldAssigmentSize) + path, value := split[0], split[1] + var floatVal float64 + if boolVal, err := readAsBoolean(value); err == nil { + spec.AddField(path, boolVal) + } else if floatVal, err = readAsFloat64(value); err == nil { + spec.AddField(path, floatVal) + } else { + spec.AddField(path, value) + } + } + for _, fieldAssigment := range args.RawFields { + split := strings.SplitN(fieldAssigment, "=", fieldAssigmentSize) + path, value := split[0], split[1] + spec.AddField(path, value) + } + ce, err := event.CreateFromSpec(spec) + if err != nil { + return nil, fmt.Errorf("%w: %v", ErrCantBuildEvent, err) + } + return ce, nil +} + +// PresentWith will present an event with specified output. +func (c *App) PresentWith(e *cloudevents.Event, output OutputMode) (string, error) { + switch output { + case HumanReadable: + return presentEventAsHumanReadable(e) + case JSON: + return presentEventAsJSON(e) + case YAML: + return presentEventAsYaml(e) + } + return "", fmt.Errorf("%w: %v", ErrUnsupportedOutputMode, output) +} + +func presentEventAsYaml(in *cloudevents.Event) (string, error) { + bytes, err := yaml.Marshal(in) + if err != nil { + return "", fmt.Errorf("%w: %v", ErrCantMarshalEvent, err) + } + return string(bytes), nil +} + +func presentEventAsJSON(event *cloudevents.Event) (string, error) { + bytes, err := json.MarshalIndent(event, "", " ") + if err != nil { + return "", fmt.Errorf("%w: %v", ErrCantMarshalEvent, err) + } + return string(bytes), nil +} + +func presentEventAsHumanReadable(e *cloudevents.Event) (string, error) { + formattedTime := e.Time(). + In(time.UTC). + Format(time.RFC3339Nano) + m := map[string]interface{}{} + err := json.Unmarshal(e.Data(), &m) + if err != nil { + return "", fmt.Errorf("%w: %v", ErrCantMarshalEvent, err) + } + data, err := json.MarshalIndent(m, " ", " ") + if err != nil { + return "", fmt.Errorf("%w: %v", ErrCantMarshalEvent, err) + } + return fmt.Sprintf( + `☁️ cloudevents.Event +Validation: valid +Context Attributes, + specversion: %s + type: %s + source: %s + id: %s + time: %s + datacontenttype: %s +Data, + %s`, + e.SpecVersion(), + e.Type(), + e.Source(), + e.ID(), + formattedTime, + e.DataContentType(), + string(data), + ), nil +} + +func readAsBoolean(in string) (bool, error) { + val, err := strconv.ParseBool(in) + // TODO(cardil): log error as it may be beneficial for debugging + if err != nil { + return false, fmt.Errorf("%w: %v", ErrInvalidFormat, err) + } + if text := fmt.Sprintf("%t", val); in == text { + return val, nil + } + return false, fmt.Errorf("%w: not a bool: %v", ErrInvalidFormat, in) +} + +func readAsFloat64(in string) (float64, error) { + if intVal, err := readAsInt64(in); err == nil { + return float64(intVal), nil + } + val, err := strconv.ParseFloat(in, precision64BitSize) + // TODO(cardil): log error as it may be beneficial for debugging + if err != nil { + return -0, fmt.Errorf("%w: %v", ErrInvalidFormat, err) + } + if text := fmt.Sprintf("%f", val); in == text { + return val, nil + } + return -0, fmt.Errorf("%w: not a float: %v", ErrInvalidFormat, in) +} + +func readAsInt64(in string) (int64, error) { + val, err := strconv.ParseInt(in, decimalBase, precision64BitSize) + // TODO(cardil): log error as it may be beneficial for debugging + if err != nil { + return -0, fmt.Errorf("%w: %v", ErrInvalidFormat, err) + } + if text := fmt.Sprintf("%d", val); in == text { + return val, nil + } + return -0, fmt.Errorf("%w: not an int: %v", ErrInvalidFormat, in) +} diff --git a/vendor/knative.dev/kn-plugin-event/pkg/cli/ics/constants.go b/vendor/knative.dev/kn-plugin-event/pkg/cli/ics/constants.go new file mode 100644 index 0000000000..2daec77e7e --- /dev/null +++ b/vendor/knative.dev/kn-plugin-event/pkg/cli/ics/constants.go @@ -0,0 +1,5 @@ +package ics + +// ContainerBasename holds a OCI container base name. +// TODO: set value from .env file during the build. +var ContainerBasename = "quay.io/cardil" //nolint:gochecknoglobals diff --git a/vendor/knative.dev/kn-plugin-event/pkg/cli/ics/encoding.go b/vendor/knative.dev/kn-plugin-event/pkg/cli/ics/encoding.go new file mode 100644 index 0000000000..9cc72ded51 --- /dev/null +++ b/vendor/knative.dev/kn-plugin-event/pkg/cli/ics/encoding.go @@ -0,0 +1,58 @@ +package ics + +import ( + "bytes" + "compress/zlib" + "encoding/base64" + "encoding/json" + "fmt" + "io/ioutil" + "strings" + + cloudevents "github.com/cloudevents/sdk-go/v2" +) + +// Encode will encode a cloud event to ICS encoding form: +// Base64(zlib(minimal JSON)). +func Encode(ce cloudevents.Event) (string, error) { + bb, err := json.Marshal(ce) + if err != nil { + return "", fmt.Errorf("%w: %v", ErrCouldntEncode, err) + } + var b bytes.Buffer + encoder := base64.NewEncoder(base64.RawURLEncoding, &b) + w := zlib.NewWriter(encoder) + _, err = w.Write(bb) + if err != nil { + return "", fmt.Errorf("%w: %v", ErrCouldntEncode, err) + } + err = w.Close() + if err != nil { + return "", fmt.Errorf("%w: %v", ErrCouldntEncode, err) + } + err = encoder.Close() + if err != nil { + return "", fmt.Errorf("%w: %v", ErrCouldntEncode, err) + } + return b.String(), nil +} + +// Decode will decode an event from ICS encoding. +func Decode(encoded string) (*cloudevents.Event, error) { + r := strings.NewReader(encoded) + decoder := base64.NewDecoder(base64.RawURLEncoding, r) + reader, err := zlib.NewReader(decoder) + if err != nil { + return nil, fmt.Errorf("%w: %v", ErrCouldntDecode, err) + } + bb, err := ioutil.ReadAll(reader) + if err != nil { + return nil, fmt.Errorf("%w: %v", ErrCouldntDecode, err) + } + ce := &cloudevents.Event{} + err = json.Unmarshal(bb, ce) + if err != nil { + return nil, fmt.Errorf("%w: %v", ErrCouldntDecode, err) + } + return ce, nil +} diff --git a/vendor/knative.dev/kn-plugin-event/pkg/cli/ics/send.go b/vendor/knative.dev/kn-plugin-event/pkg/cli/ics/send.go new file mode 100644 index 0000000000..e7a6969b7b --- /dev/null +++ b/vendor/knative.dev/kn-plugin-event/pkg/cli/ics/send.go @@ -0,0 +1,59 @@ +package ics + +import ( + "fmt" + "net/url" + + cloudevents "github.com/cloudevents/sdk-go/v2" + "github.com/kelseyhightower/envconfig" + "knative.dev/kn-plugin-event/pkg/event" +) + +// SendFromEnv will send an event based on a values stored in environmental +// variables. +func (app *App) SendFromEnv() error { + c, err := app.configure() + if err != nil { + return err + } + err = c.sender.Send(*c.ce) + if err != nil { + return fmt.Errorf("%w: %v", ErrCantSendWithICS, err) + } + return nil +} + +func (app *App) configure() (config, error) { + args := &Args{ + Sink: "localhost", + } + err := envconfig.Process("K", args) + if err != nil { + return config{}, fmt.Errorf("%w: %v", ErrCantConfigureICS, err) + } + u, err := url.Parse(args.Sink) + if err != nil { + return config{}, fmt.Errorf("%w: %v", ErrCantConfigureICS, err) + } + target := &event.Target{ + Type: event.TargetTypeReachable, + URLVal: u, + } + s, err := app.Binding.CreateSender(target) + if err != nil { + return config{}, fmt.Errorf("%w: %v", ErrCantConfigureICS, err) + } + ce, err := Decode(args.Event) + if err != nil { + return config{}, err + } + return config{ + sender: s, + ce: ce, + }, nil +} + +type config struct { + sender event.Sender + ce *cloudevents.Event +} diff --git a/vendor/knative.dev/kn-plugin-event/pkg/cli/ics/types.go b/vendor/knative.dev/kn-plugin-event/pkg/cli/ics/types.go new file mode 100644 index 0000000000..c2c0a7cc5d --- /dev/null +++ b/vendor/knative.dev/kn-plugin-event/pkg/cli/ics/types.go @@ -0,0 +1,33 @@ +package ics + +import ( + "errors" + + "knative.dev/kn-plugin-event/pkg/event" +) + +var ( + // ErrCouldntEncode is returned when problem occur while trying to encode an + // event. + ErrCouldntEncode = errors.New("couldn't encode an event") + // ErrCouldntDecode is returned when problem occur while trying to decode an + // event. + ErrCouldntDecode = errors.New("couldn't decode an event") + // ErrCantConfigureICS is returned when problem occur while trying to + // configure ICS sender. + ErrCantConfigureICS = errors.New("can't configure ICS sender") + // ErrCantSendWithICS if can't send with ICS sender. + ErrCantSendWithICS = errors.New("can't send with ICS sender") +) + +// Args holds a list of args for in-cluster-sender. +type Args struct { + Sink string + CeOverrides string + Event string +} + +// App holds an ICS app binding. +type App struct { + event.Binding +} diff --git a/vendor/knative.dev/kn-plugin-event/pkg/cli/options.go b/vendor/knative.dev/kn-plugin-event/pkg/cli/options.go new file mode 100644 index 0000000000..513ce7238a --- /dev/null +++ b/vendor/knative.dev/kn-plugin-event/pkg/cli/options.go @@ -0,0 +1,114 @@ +package cli + +import ( + "encoding/json" + "errors" + "fmt" + "strings" + "time" + + "github.com/ghodss/yaml" + "go.uber.org/zap" + "go.uber.org/zap/buffer" + "go.uber.org/zap/zapcore" + "knative.dev/kn-plugin-event/pkg/event" +) + +// WithLogger will create an event suitable Options from CLI ones. +func (opts *Options) WithLogger() (*event.Properties, error) { + zc := zap.NewProductionConfig() + cfg := zap.NewProductionEncoderConfig() + if opts.Verbose { + cfg = zap.NewDevelopmentEncoderConfig() + } + cfg.EncodeTime = zapcore.RFC3339NanoTimeEncoder + var encoder zapcore.Encoder + switch opts.Output { + case HumanReadable: + if !opts.Verbose { + cfg.CallerKey = "" + } + cfg.ConsoleSeparator = " " + cfg.EncodeLevel = alignCapitalColorLevelEncoder + cfg.EncodeTime = zapcore.TimeEncoderOfLayout(time.StampMilli) + encoder = zapcore.NewConsoleEncoder(cfg) + case YAML: + encoder = &yamlEncoder{zapcore.NewJSONEncoder(cfg)} + case JSON: + encoder = zapcore.NewJSONEncoder(cfg) + } + sink := zapcore.AddSync(opts.OutWriter) + errSink := zapcore.AddSync(opts.ErrWriter) + zcore := zapcore.NewCore(encoder, sink, zc.Level) + log := zap.New( + zcore, buildOptions(zc, errSink)..., + ) + + return &event.Properties{ + KnPluginOptions: opts.KnPluginOptions, + Log: log.Sugar(), + }, nil +} + +func alignCapitalColorLevelEncoder(l zapcore.Level, enc zapcore.PrimitiveArrayEncoder) { + spaces := len(zapcore.FatalLevel.CapitalString()) - len(l.CapitalString()) + if spaces > 0 { + enc.AppendString(strings.Repeat(" ", spaces)) + } + zapcore.CapitalColorLevelEncoder(l, enc) +} + +func buildOptions(cfg zap.Config, errSink zapcore.WriteSyncer) []zap.Option { + opts := []zap.Option{zap.ErrorOutput(errSink)} + + if cfg.Development { + opts = append(opts, zap.Development()) + } + + if !cfg.DisableCaller { + opts = append(opts, zap.AddCaller()) + } + + stackLevel := zap.ErrorLevel + if cfg.Development { + stackLevel = zap.WarnLevel + } + if !cfg.DisableStacktrace { + opts = append(opts, zap.AddStacktrace(stackLevel)) + } + + return opts +} + +type yamlEncoder struct { + zapcore.Encoder +} + +func (y *yamlEncoder) EncodeEntry(entry zapcore.Entry, fields []zapcore.Field) (*buffer.Buffer, error) { + buf, err := y.Encoder.EncodeEntry(entry, fields) + if err != nil { + return nil, unexpected(err) + } + var v interface{} + err = json.Unmarshal(buf.Bytes(), &v) + if err != nil { + return nil, unexpected(err) + } + bytes, err := yaml.Marshal(v) + if err != nil { + return nil, unexpected(err) + } + buf = buffer.NewPool().Get() + _, _ = buf.Write([]byte("---\n")) + if _, err = buf.Write(bytes); err != nil { + return nil, unexpected(err) + } + return buf, nil +} + +func unexpected(err error) error { + if errors.Is(err, event.ErrUnexpected) { + return err + } + return fmt.Errorf("%w: %v", event.ErrUnexpected, err) +} diff --git a/vendor/knative.dev/kn-plugin-event/pkg/cli/retcode/retcode.go b/vendor/knative.dev/kn-plugin-event/pkg/cli/retcode/retcode.go new file mode 100644 index 0000000000..c3507cbe3a --- /dev/null +++ b/vendor/knative.dev/kn-plugin-event/pkg/cli/retcode/retcode.go @@ -0,0 +1,11 @@ +package retcode + +import "hash/crc32" + +// Calc will calculate an POSIX retcode from an error. +func Calc(err error) int { + if err == nil { + return 0 + } + return int(crc32.ChecksumIEEE([]byte(err.Error())))%254 + 1 +} diff --git a/vendor/knative.dev/kn-plugin-event/pkg/cli/send.go b/vendor/knative.dev/kn-plugin-event/pkg/cli/send.go new file mode 100644 index 0000000000..fa48253b5f --- /dev/null +++ b/vendor/knative.dev/kn-plugin-event/pkg/cli/send.go @@ -0,0 +1,37 @@ +package cli + +import ( + "errors" + "fmt" + + cloudevents "github.com/cloudevents/sdk-go/v2" + "knative.dev/kn-plugin-event/pkg/event" +) + +// Send will send CloudEvent to target. +func (c *App) Send(ce cloudevents.Event, target TargetArgs, options *Options) error { + props, err := options.WithLogger() + if err != nil { + return err + } + t, err := c.createTarget(target, props) + if err != nil { + return err + } + s, err := c.Binding.NewSender(t) + if err != nil { + return cantSentEvent(err) + } + err = s.Send(ce) + if err == nil { + return nil + } + return cantSentEvent(err) +} + +func cantSentEvent(err error) error { + if errors.Is(err, event.ErrCantSentEvent) { + return err + } + return fmt.Errorf("%w: %v", event.ErrCantSentEvent, err) +} diff --git a/vendor/knative.dev/kn-plugin-event/pkg/cli/target.go b/vendor/knative.dev/kn-plugin-event/pkg/cli/target.go new file mode 100644 index 0000000000..b9f96f57b9 --- /dev/null +++ b/vendor/knative.dev/kn-plugin-event/pkg/cli/target.go @@ -0,0 +1,114 @@ +package cli + +import ( + "errors" + "fmt" + "net/url" + "regexp" + + clientutil "knative.dev/client/pkg/util" + "knative.dev/kn-plugin-event/pkg/event" + "knative.dev/pkg/apis" +) + +var ( + // ErrCantUseBothToURLAndToFlags will be raised if user use both --to and + // --to-url flags. + ErrCantUseBothToURLAndToFlags = errors.New("can't use both --to and --to-url flags") + // ErrUseToURLOrToFlagIsRequired will be raised if user didn't used --to or + // --to-url flags. + ErrUseToURLOrToFlagIsRequired = errors.New("use --to or --to-url flag is required") + // ErrInvalidURLFormat will be raised if given URL is invalid. + ErrInvalidURLFormat = errors.New("invalid URL format") + // ErrInvalidToFormat will be raised if given addressable doesn't have valid + // expected format. + ErrInvalidToFormat = errors.New("--to flag needs to be in format " + + "kind:apiVersion:name for named resources or " + + "kind:apiVersion:labelKey1=value1,labelKey2=value2 for matching via " + + "a label selector") +) + +// ValidateTarget will perform validation on App element of target. +func ValidateTarget(args *TargetArgs) error { + if args.URL == "" && args.Addressable == "" { + return ErrUseToURLOrToFlagIsRequired + } + if args.URL != "" && args.Addressable != "" { + return ErrCantUseBothToURLAndToFlags + } + if args.URL != "" { + _, err := url.ParseRequestURI(args.URL) + if err != nil { + return fmt.Errorf("--to-url %w: %s", ErrInvalidURLFormat, err.Error()) + } + } + if args.Addressable != "" { + // ref: https://regex101.com/r/TcxsLO/3 + r := regexp.MustCompile("([a-zA-Z0-9]+):([a-zA-Z0-9/.]+):([a-zA-Z0-9=,_-]+)") + if !r.MatchString(args.Addressable) { + return ErrInvalidToFormat + } + } + return validateAddressableURI(args.AddressableURI) +} + +func validateAddressableURI(uri string) error { + if len(uri) > 0 { + _, err := url.ParseRequestURI(uri) + if err != nil { + return fmt.Errorf("--addressable-uri %w: %s", ErrInvalidURLFormat, err.Error()) + } + } + return nil +} + +func (c *App) createTarget(args TargetArgs, props *event.Properties) (*event.Target, error) { + if args.Addressable != "" { + args, err := c.fillInDefaultNamespace(args, props) + if err != nil { + return nil, err + } + ref, err := clientutil.ToTrackerReference(args.Addressable, args.Namespace) + if err != nil { + return nil, fmt.Errorf("%w: %s", ErrInvalidToFormat, err.Error()) + } + uri := &apis.URL{Path: args.AddressableURI} + return &event.Target{ + Type: event.TargetTypeAddressable, + AddressableVal: &event.AddressableSpec{ + Reference: ref, + URI: uri, + SenderNamespace: args.SenderNamespace, + }, + Properties: props, + }, nil + } + if args.URL != "" { + u, err := url.Parse(args.URL) + if err != nil { + return nil, fmt.Errorf("--to-url %w: %s", ErrInvalidURLFormat, err.Error()) + } + return &event.Target{ + Type: event.TargetTypeReachable, + URLVal: u, + Properties: props, + }, nil + } + return nil, ErrUseToURLOrToFlagIsRequired +} + +func (c *App) fillInDefaultNamespace(args TargetArgs, props *event.Properties) (TargetArgs, error) { + if len(args.Namespace) == 0 || len(args.SenderNamespace) == 0 { + defaultNs, err := c.DefaultNamespace(props) + if err != nil { + return TargetArgs{}, cantSentEvent(err) + } + if len(args.Namespace) == 0 { + args.Namespace = defaultNs + } + if len(args.SenderNamespace) == 0 { + args.SenderNamespace = defaultNs + } + } + return args, nil +} diff --git a/vendor/knative.dev/kn-plugin-event/pkg/cli/types.go b/vendor/knative.dev/kn-plugin-event/pkg/cli/types.go new file mode 100644 index 0000000000..e313a1b855 --- /dev/null +++ b/vendor/knative.dev/kn-plugin-event/pkg/cli/types.go @@ -0,0 +1,56 @@ +package cli + +import ( + "io" + + "github.com/thediveo/enumflag" + "knative.dev/kn-plugin-event/pkg/event" +) + +// Options holds a general args for all commands. +type Options struct { + event.KnPluginOptions + + // Output define type of output commands should be producing. + Output OutputMode + + // Verbose tells does commands should display additional information about + // what's happening? Verbose information is printed on stderr. + Verbose bool + + OutWriter io.Writer + ErrWriter io.Writer +} + +// EventArgs holds args of event to be created with. +type EventArgs struct { + Type string + ID string + Source string + Fields []string + RawFields []string +} + +// TargetArgs holds args specific for even sending. +type TargetArgs struct { + URL string + Addressable string + Namespace string + SenderNamespace string + AddressableURI string +} + +// OutputMode is type of output to produce. +type OutputMode enumflag.Flag + +// OutputMode enumeration values. +const ( + HumanReadable OutputMode = iota + JSON + YAML +) + +// App object. +type App struct { + event.Binding +} diff --git a/vendor/knative.dev/kn-plugin-event/pkg/cli/version.go b/vendor/knative.dev/kn-plugin-event/pkg/cli/version.go new file mode 100644 index 0000000000..7e9e114e99 --- /dev/null +++ b/vendor/knative.dev/kn-plugin-event/pkg/cli/version.go @@ -0,0 +1,9 @@ +package cli + +// PluginVersionOutput is a struct that is used to output project version in +// machine readable format. +type PluginVersionOutput struct { + Name string `json:"name" yaml:"name"` + Version string `json:"version" yaml:"version"` + Image string `json:"image" yaml:"image"` +} diff --git a/vendor/knative.dev/kn-plugin-event/pkg/configuration/cli.go b/vendor/knative.dev/kn-plugin-event/pkg/configuration/cli.go new file mode 100644 index 0000000000..a097374dfb --- /dev/null +++ b/vendor/knative.dev/kn-plugin-event/pkg/configuration/cli.go @@ -0,0 +1,11 @@ +package configuration + +import ( + "knative.dev/kn-plugin-event/pkg/cli" +) + +// CreateCli creates the configured cli.App to work with. +func CreateCli() *cli.App { + binding := senderBinding() + return &cli.App{Binding: eventsBinding(binding)} +} diff --git a/vendor/knative.dev/kn-plugin-event/pkg/configuration/defaults.go b/vendor/knative.dev/kn-plugin-event/pkg/configuration/defaults.go new file mode 100644 index 0000000000..9d947ae583 --- /dev/null +++ b/vendor/knative.dev/kn-plugin-event/pkg/configuration/defaults.go @@ -0,0 +1,22 @@ +package configuration + +import ( + "knative.dev/kn-plugin-event/pkg/event" + "knative.dev/kn-plugin-event/pkg/k8s" + "knative.dev/kn-plugin-event/pkg/sender" +) + +func senderBinding() sender.Binding { + return sender.Binding{ + CreateKubeClients: memoizeKubeClients(k8s.CreateKubeClient), + CreateJobRunner: k8s.CreateJobRunner, + CreateAddressResolver: k8s.CreateAddressResolver, + } +} + +func eventsBinding(binding sender.Binding) event.Binding { + return event.Binding{ + CreateSender: binding.New, + DefaultNamespace: binding.DefaultNamespace, + } +} diff --git a/vendor/knative.dev/kn-plugin-event/pkg/configuration/ics.go b/vendor/knative.dev/kn-plugin-event/pkg/configuration/ics.go new file mode 100644 index 0000000000..f1b6aa02c7 --- /dev/null +++ b/vendor/knative.dev/kn-plugin-event/pkg/configuration/ics.go @@ -0,0 +1,11 @@ +package configuration + +import ( + "knative.dev/kn-plugin-event/pkg/cli/ics" +) + +// CreateIcs creates the configured ics.App to work with. +func CreateIcs() *ics.App { + binding := senderBinding() + return &ics.App{Binding: eventsBinding(binding)} +} diff --git a/vendor/knative.dev/kn-plugin-event/pkg/configuration/memoized.go b/vendor/knative.dev/kn-plugin-event/pkg/configuration/memoized.go new file mode 100644 index 0000000000..4aa24dd8fb --- /dev/null +++ b/vendor/knative.dev/kn-plugin-event/pkg/configuration/memoized.go @@ -0,0 +1,29 @@ +package configuration + +import ( + "knative.dev/kn-plugin-event/pkg/event" + "knative.dev/kn-plugin-event/pkg/k8s" + "knative.dev/kn-plugin-event/pkg/sender" +) + +func memoizeKubeClients(delegate sender.CreateKubeClients) sender.CreateKubeClients { + mem := kubeClientsMemoizer{delegate: delegate} + return mem.computeClients +} + +type kubeClientsMemoizer struct { + delegate sender.CreateKubeClients + result k8s.Clients +} + +func (m *kubeClientsMemoizer) computeClients(props *event.Properties) (k8s.Clients, error) { + if m.result != nil { + return m.result, nil + } + cl, err := m.delegate(props) + if err != nil { + return nil, err + } + m.result = cl + return m.result, nil +} diff --git a/vendor/knative.dev/kn-plugin-event/pkg/event/constants.go b/vendor/knative.dev/kn-plugin-event/pkg/event/constants.go new file mode 100644 index 0000000000..48b76fd32c --- /dev/null +++ b/vendor/knative.dev/kn-plugin-event/pkg/event/constants.go @@ -0,0 +1,27 @@ +package event + +import ( + "errors" + "fmt" + + "github.com/google/uuid" + "knative.dev/kn-plugin-event/pkg/metadata" +) + +const ( + // DefaultType holds a default type for a event. + DefaultType = "dev.knative.cli.plugin.event.generic" +) + +// ErrUnexpected if unexpected error found. +var ErrUnexpected = errors.New("unexpected") + +// DefaultSource holds a default source of an event. +func DefaultSource() string { + return fmt.Sprintf("%s/%s", metadata.PluginName, metadata.Version) +} + +// NewID creates a new ID for an event. +func NewID() string { + return uuid.New().String() +} diff --git a/vendor/knative.dev/kn-plugin-event/pkg/event/create.go b/vendor/knative.dev/kn-plugin-event/pkg/event/create.go new file mode 100644 index 0000000000..c7d8766a9f --- /dev/null +++ b/vendor/knative.dev/kn-plugin-event/pkg/event/create.go @@ -0,0 +1,81 @@ +package event + +import ( + "errors" + "fmt" + "strings" + "time" + + cloudevents "github.com/cloudevents/sdk-go/v2" + "github.com/wavesoftware/go-ensure" +) + +var ( + // ErrCantMarshalAsJSON is returned if given CE data can't be marshalled + // as JSON. + ErrCantMarshalAsJSON = errors.New("can't marshal as JSON") + + // ErrCantSetField is returned if given field can't be applied. + ErrCantSetField = errors.New("can't set field") +) + +// NewDefault creates a default CloudEvent. +func NewDefault() *cloudevents.Event { + e := cloudevents.NewEvent() + e.SetType(DefaultType) + e.SetID(NewID()) + ensure.NoError(e.SetData(cloudevents.ApplicationJSON, map[string]string{})) + e.SetSource(DefaultSource()) + e.SetTime(time.Now()) + ensure.NoError(e.Validate()) + return &e +} + +// CreateFromSpec will create an event by parsing given args. +func CreateFromSpec(spec *Spec) (*cloudevents.Event, error) { + e := NewDefault() + e.SetID(spec.ID) + e.SetSource(spec.Source) + e.SetType(spec.Type) + m := map[string]interface{}{} + for _, fieldSpec := range spec.Fields { + if err := updateMapWithSpec(m, fieldSpec); err != nil { + return nil, err + } + } + err := e.SetData(cloudevents.ApplicationJSON, m) + if err != nil { + return nil, fmt.Errorf("%w: %v", ErrCantMarshalAsJSON, err) + } + return e, nil +} + +func updateMapWithSpec(m map[string]interface{}, spec FieldSpec) error { + sep := "." + paths := strings.Split(spec.Path, sep) + curr := m + for i, p := range paths { + if i < len(paths)-1 { + if _, ok := curr[p]; !ok { + curr[p] = map[string]interface{}{} + } + candidate := curr[p] + var ok bool + curr, ok = candidate.(map[string]interface{}) + if !ok { + return fmt.Errorf("%w: %#v path in conflict with value %#v", + ErrCantSetField, spec.Path, candidate) + } + } else { + curr[p] = spec.Value + } + } + return nil +} + +// AddField will add a field to the spec. +func (s *Spec) AddField(path string, val interface{}) { + s.Fields = append(s.Fields, FieldSpec{ + Path: path, Value: val, + }) +} diff --git a/vendor/knative.dev/kn-plugin-event/pkg/event/sender.go b/vendor/knative.dev/kn-plugin-event/pkg/event/sender.go new file mode 100644 index 0000000000..087b8f5524 --- /dev/null +++ b/vendor/knative.dev/kn-plugin-event/pkg/event/sender.go @@ -0,0 +1,41 @@ +package event + +import ( + "errors" + "fmt" + + cloudevents "github.com/cloudevents/sdk-go/v2" +) + +// ErrCantSentEvent if event can't be sent. +var ErrCantSentEvent = errors.New("can't sent event") + +// NewSender will create a sender that can send event to cluster. +func (b Binding) NewSender(target *Target) (Sender, error) { + sender, err := b.CreateSender(target) + if err != nil { + return nil, err + } + return &sendLogic{Sender: sender, Properties: target.Properties}, nil +} + +type sendLogic struct { + Sender + *Properties +} + +func (l *sendLogic) Send(ce cloudevents.Event) error { + err := l.Sender.Send(ce) + if err == nil { + l.Log.Infof("Event (ID: %s) have been sent.", ce.ID()) + return nil + } + return cantSentEvent(err) +} + +func cantSentEvent(err error) error { + if errors.Is(err, ErrCantSentEvent) { + return err + } + return fmt.Errorf("%w: %v", ErrCantSentEvent, err) +} diff --git a/vendor/knative.dev/kn-plugin-event/pkg/event/types.go b/vendor/knative.dev/kn-plugin-event/pkg/event/types.go new file mode 100644 index 0000000000..052d402aed --- /dev/null +++ b/vendor/knative.dev/kn-plugin-event/pkg/event/types.go @@ -0,0 +1,92 @@ +package event + +import ( + "net/url" + + cloudevents "github.com/cloudevents/sdk-go/v2" + "go.uber.org/zap" + "knative.dev/pkg/apis" + "knative.dev/pkg/tracker" +) + +// Spec holds specification of event to be created. +type Spec struct { + Type string + ID string + Source string + Fields []FieldSpec +} + +// FieldSpec holds a specification of a event's data field. +type FieldSpec struct { + Path string + Value interface{} +} + +// TargetType specify a type of a event target. +type TargetType int + +const ( + // TargetTypeReachable specify a type of event target that is network + // reachable, and direct HTTP communication can be performed. + TargetTypeReachable TargetType = iota + + // TargetTypeAddressable represent a type of event target that is cluster + // private, and direct communication can't be performed. In this case in + // cluster sender Job will be created to send the event. + TargetTypeAddressable +) + +// AddressableSpec specify destination of a event to be sent, as well as sender +// namespace that should be used to create a sender Job in. +type AddressableSpec struct { + *tracker.Reference + URI *apis.URL + SenderNamespace string +} + +// Target is a target to send event to. +type Target struct { + Type TargetType + URLVal *url.URL + AddressableVal *AddressableSpec + *Properties +} + +// KubeconfigOptions holds options for Kubernetes Client. +type KubeconfigOptions struct { + Path string + Context string + Cluster string +} + +// KnPluginOptions holds options inherited to every Kn plugin. +type KnPluginOptions struct { + KubeconfigOptions +} + +// Properties holds a general properties. +type Properties struct { + KnPluginOptions + Log *zap.SugaredLogger +} + +// Sender will send event to specified target. +type Sender interface { + // Send will send cloudevents.Event to configured target, or return an error + // if one occur. + Send(ce cloudevents.Event) error +} + +// CreateSender creates a Sender. +type CreateSender func(target *Target) (Sender, error) + +// DefaultNamespace returns a default namespace for connected K8s cluster or +// error is namespace can't be determined. +type DefaultNamespace func(props *Properties) (string, error) + +// Binding holds injectable dependencies. +type Binding struct { + CreateSender + DefaultNamespace +} diff --git a/vendor/knative.dev/kn-plugin-event/pkg/k8s/addressresolver.go b/vendor/knative.dev/kn-plugin-event/pkg/k8s/addressresolver.go new file mode 100644 index 0000000000..5adf2bee03 --- /dev/null +++ b/vendor/knative.dev/kn-plugin-event/pkg/k8s/addressresolver.go @@ -0,0 +1,141 @@ +package k8s + +import ( + "context" + "fmt" + "net/url" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/types" + "knative.dev/pkg/apis" + duckv1 "knative.dev/pkg/apis/duck/v1" + "knative.dev/pkg/client/injection/ducks/duck/v1/addressable" + "knative.dev/pkg/controller" + "knative.dev/pkg/injection/clients/dynamicclient" + "knative.dev/pkg/kmeta" + "knative.dev/pkg/resolver" + "knative.dev/pkg/tracker" + servingv1 "knative.dev/serving/pkg/apis/serving/v1" +) + +// ReferenceAddressResolver will resolve the tracker.Reference to an url.URL, or +// return an error. +type ReferenceAddressResolver interface { + ResolveAddress(ref *tracker.Reference, uri *apis.URL) (*url.URL, error) +} + +// CreateAddressResolver will create ReferenceAddressResolver, or return an +// error. +func CreateAddressResolver(kube Clients) ReferenceAddressResolver { + ctx := ctxWithDynamic(kube) + return &addressResolver{ + kube: kube, ctx: addressable.WithDuck(ctx), + } +} + +type addressResolver struct { + kube Clients + ctx context.Context +} + +// ResolveAddress of a tracker.Reference with given uri (as apis.URL). +func (a *addressResolver) ResolveAddress( + ref *tracker.Reference, + uri *apis.URL, +) (*url.URL, error) { + if isKsvc(ref) { + // knative.dev/pkg/resolver doesn't resolve proper URL for knative service + return a.resolveKsvcAddress(ref, uri) + } + gvr := a.toGVR(ref) + dest, err := a.toDestination(gvr, ref, uri) + if err != nil { + return nil, err + } + parent := toAccessor(ref) + tr := tracker.New(noopCallback, controller.GetTrackerLease(a.ctx)) + r := resolver.NewURIResolverFromTracker(a.ctx, tr) + u, err := r.URIFromDestinationV1(a.ctx, *dest, parent) + if err != nil { + return nil, fmt.Errorf("%w: %v", ErrNotAddressable, err) + } + resolved := u.URL() + return resolved, nil +} + +func (a *addressResolver) resolveKsvcAddress( + ref *tracker.Reference, + uri *apis.URL, +) (*url.URL, error) { + ksvc, err := a.kube.Serving().Services(ref.Namespace). + Get(a.ctx, ref.Name, metav1.GetOptions{}) + if err != nil { + return nil, fmt.Errorf("%w: %v", ErrNotFound, err) + } + return ksvc.Status.URL.ResolveReference(uri).URL(), nil +} + +func (a *addressResolver) toDestination( + gvr schema.GroupVersionResource, + ref *tracker.Reference, + uri *apis.URL, +) (*duckv1.Destination, error) { + dest := &duckv1.Destination{ + Ref: &duckv1.KReference{ + Kind: ref.Kind, + Namespace: ref.Namespace, + Name: ref.Name, + APIVersion: ref.APIVersion, + }, + URI: uri, + } + if ref.Selector != nil { + list, err := a.kube.Dynamic().Resource(gvr). + Namespace(ref.Namespace).List(a.ctx, metav1.ListOptions{ + LabelSelector: ref.Selector.String(), + }) + if err != nil { + return nil, fmt.Errorf("%w: %v", ErrNotFound, err) + } + count := len(list.Items) + if count == 0 { + return nil, ErrNotFound + } + if count > 1 { + return nil, fmt.Errorf("%w: %d", ErrMoreThenOneFound, count) + } + dest.Ref.Name = list.Items[0].GetName() + } + return dest, nil +} + +func (a *addressResolver) toGVR(ref *tracker.Reference) schema.GroupVersionResource { + gvk := ref.GroupVersionKind() + gvr := apis.KindToResource(gvk) + return gvr +} + +func isKsvc(ref *tracker.Reference) bool { + return ref.Kind == "Service" && + ref.APIVersion == servingv1.SchemeGroupVersion.String() +} + +func toAccessor(ref *tracker.Reference) kmeta.Accessor { + return &unstructured.Unstructured{Object: map[string]interface{}{ + "apiVersion": ref.APIVersion, + "kind": ref.Kind, + "metadata": map[string]interface{}{ + "name": ref.Name, + "namespace": ref.Namespace, + }, + }} +} + +func ctxWithDynamic(kube Clients) context.Context { + return context.WithValue(kube.Context(), dynamicclient.Key{}, kube.Dynamic()) +} + +func noopCallback(_ types.NamespacedName) { +} diff --git a/vendor/knative.dev/kn-plugin-event/pkg/k8s/errors.go b/vendor/knative.dev/kn-plugin-event/pkg/k8s/errors.go new file mode 100644 index 0000000000..1ca84639cf --- /dev/null +++ b/vendor/knative.dev/kn-plugin-event/pkg/k8s/errors.go @@ -0,0 +1,23 @@ +package k8s + +import "errors" + +var ( + // ErrInvalidReference if given reference is invalid. + ErrInvalidReference = errors.New("reference is invalid") + + // ErrNotFound if given reference do not point to any resource. + ErrNotFound = errors.New("resource not found") + + // ErrNotAddressable if found resource isn't addressable. + ErrNotAddressable = errors.New("resource isn't addressable") + + // ErrMoreThenOneFound if more then one resource has been found. + ErrMoreThenOneFound = errors.New("more then one resource has been found") + + // ErrUnexcpected if something unexpected actually has happened. + ErrUnexcpected = errors.New("something unexpected actually has happened") + + // ErrICSenderJobFailed if the ICS job runner has failed. + ErrICSenderJobFailed = errors.New("the ICS job runner has failed") +) diff --git a/vendor/knative.dev/kn-plugin-event/pkg/k8s/jobrunner.go b/vendor/knative.dev/kn-plugin-event/pkg/k8s/jobrunner.go new file mode 100644 index 0000000000..668b9155d7 --- /dev/null +++ b/vendor/knative.dev/kn-plugin-event/pkg/k8s/jobrunner.go @@ -0,0 +1,143 @@ +package k8s + +import ( + "fmt" + "sync" + + batchv1 "k8s.io/api/batch/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/watch" +) + +// JobRunner will launch a Job and monitor it for completion. +type JobRunner interface { + Run(*batchv1.Job) error +} + +// CreateJobRunner will create a JobRunner, or return an error. +func CreateJobRunner(kube Clients) JobRunner { + return &jobRunner{ + kube: kube, + } +} + +type jobRunner struct { + kube Clients +} + +type task struct { + errs chan<- error + ready chan<- bool + wg *sync.WaitGroup +} + +func (j *jobRunner) Run(job *batchv1.Job) error { + ready := make(chan bool) + errs := make(chan error) + tsk := task{ + errs, ready, &sync.WaitGroup{}, + } + tasks := []func(*batchv1.Job, task){ + // wait is started first, making sure to capture success, even the ultra-fast one. + j.waitForSuccess, + j.createJob, + } + tsk.wg.Add(len(tasks)) + // run all tasks in parallel + for _, fn := range tasks { + go fn(job, tsk) + <-ready + } + go waitAndClose(tsk) + // return the first error + for err := range errs { + if err != nil { + return err + } + } + + return j.deleteJob(job) +} + +func (j *jobRunner) createJob(job *batchv1.Job, tsk task) { + defer tsk.wg.Done() + tsk.ready <- true + ctx := j.kube.Context() + jobs := j.kube.Typed().BatchV1().Jobs(job.Namespace) + _, err := jobs.Create(ctx, job, metav1.CreateOptions{}) + if err != nil { + tsk.errs <- fmt.Errorf("%w: %v", ErrICSenderJobFailed, err) + } +} + +func (j *jobRunner) waitForSuccess(job *batchv1.Job, tsk task) { + defer tsk.wg.Done() + err := j.watchJob(job, tsk, func(job *batchv1.Job) (bool, error) { + if job.Status.CompletionTime == nil && job.Status.Failed == 0 { + return false, nil + } + // We should be done if we reach here. + if job.Status.Succeeded < 1 { + return false, fmt.Errorf("%w: %s", ErrICSenderJobFailed, + "expected to have successful job") + } + return true, nil + }) + if err != nil { + tsk.errs <- fmt.Errorf("%w: %v", ErrICSenderJobFailed, err) + } +} + +func waitAndClose(tsk task) { + tsk.wg.Wait() + close(tsk.errs) +} + +func (j *jobRunner) deleteJob(job *batchv1.Job) error { + ctx := j.kube.Context() + jobs := j.kube.Typed().BatchV1().Jobs(job.GetNamespace()) + err := jobs.Delete(ctx, job.GetName(), metav1.DeleteOptions{}) + if err != nil { + return fmt.Errorf("%w: %v", ErrICSenderJobFailed, err) + } + pods := j.kube.Typed().CoreV1().Pods(job.GetNamespace()) + err = pods.DeleteCollection(ctx, metav1.DeleteOptions{}, metav1.ListOptions{ + LabelSelector: fmt.Sprintf("job-name=%s", job.GetName()), + }) + if err != nil { + return fmt.Errorf("%w: %v", ErrICSenderJobFailed, err) + } + return nil +} + +func (j *jobRunner) watchJob(obj metav1.Object, tsk task, changeFn func(job *batchv1.Job) (bool, error)) error { + ctx := j.kube.Context() + jobs := j.kube.Typed().BatchV1().Jobs(obj.GetNamespace()) + watcher, err := jobs.Watch(ctx, metav1.ListOptions{ + FieldSelector: fmt.Sprintf("metadata.name=%s", obj.GetName()), + }) + if err != nil { + return fmt.Errorf("%w: %v", ErrICSenderJobFailed, err) + } + defer watcher.Stop() + resultCh := watcher.ResultChan() + tsk.ready <- true + for result := range resultCh { + if result.Type == watch.Added || result.Type == watch.Modified { + job, ok := result.Object.(*batchv1.Job) + if !ok { + return fmt.Errorf("%w: %s: %T", ErrICSenderJobFailed, + "expected to watch batchv1.Job, got", result.Object) + } + var brk bool + brk, err = changeFn(job) + if err != nil { + return fmt.Errorf("%w: %v", ErrICSenderJobFailed, err) + } + if brk { + return nil + } + } + } + return nil +} diff --git a/vendor/knative.dev/kn-plugin-event/pkg/k8s/kubeclient.go b/vendor/knative.dev/kn-plugin-event/pkg/k8s/kubeclient.go new file mode 100644 index 0000000000..69de830665 --- /dev/null +++ b/vendor/knative.dev/kn-plugin-event/pkg/k8s/kubeclient.go @@ -0,0 +1,141 @@ +package k8s + +import ( + "context" + "errors" + "fmt" + + "k8s.io/client-go/dynamic" + "k8s.io/client-go/kubernetes" + + // see: https://github.com/kubernetes/client-go/issues/242 + _ "k8s.io/client-go/plugin/pkg/client/auth" + "k8s.io/client-go/rest" + "k8s.io/client-go/tools/clientcmd" + eventingv1 "knative.dev/eventing/pkg/client/clientset/versioned/typed/eventing/v1" + messagingv1 "knative.dev/eventing/pkg/client/clientset/versioned/typed/messaging/v1" + "knative.dev/kn-plugin-event/pkg/event" + servingv1 "knative.dev/serving/pkg/client/clientset/versioned/typed/serving/v1" +) + +// ErrNoKubernetesConnection if can't connect to Kube API server. +var ErrNoKubernetesConnection = errors.New("no Kubernetes connection") + +// CreateKubeClient creates kubernetes.Interface. +func CreateKubeClient(props *event.Properties) (Clients, error) { + cc, err := loadClientConfig(props) + if err != nil { + return nil, err + } + restcfg := cc.Config + typed, err := kubernetes.NewForConfig(restcfg) + if err != nil { + return nil, fmt.Errorf("%w: %v", ErrUnexcpected, err) + } + dyn, err := dynamic.NewForConfig(restcfg) + if err != nil { + return nil, fmt.Errorf("%w: %v", ErrUnexcpected, err) + } + servingclient, err := servingv1.NewForConfig(restcfg) + if err != nil { + return nil, fmt.Errorf("%w: %v", ErrUnexcpected, err) + } + eventingclient, err := eventingv1.NewForConfig(restcfg) + if err != nil { + return nil, fmt.Errorf("%w: %v", ErrUnexcpected, err) + } + messagingclient, err := messagingv1.NewForConfig(restcfg) + if err != nil { + return nil, fmt.Errorf("%w: %v", ErrUnexcpected, err) + } + return &clients{ + ctx: context.Background(), + namespace: cc.namespace, + typed: typed, + dynamic: dyn, + serving: servingclient, + eventing: eventingclient, + messaging: messagingclient, + }, nil +} + +// Clients holds available Kubernetes clients. +type Clients interface { + Namespace() string + Typed() kubernetes.Interface + Dynamic() dynamic.Interface + Context() context.Context + Serving() servingv1.ServingV1Interface + Eventing() eventingv1.EventingV1Interface + Messaging() messagingv1.MessagingV1Interface +} + +func loadClientConfig(props *event.Properties) (clientConfig, error) { + loadingRules := clientcmd.NewDefaultClientConfigLoadingRules() + var configOverrides *clientcmd.ConfigOverrides + if props.Context != "" && props.Cluster != "" { + configOverrides = &clientcmd.ConfigOverrides{} + if props.Context != "" { + configOverrides.CurrentContext = props.Context + } + if props.Cluster != "" { + configOverrides.Context.Cluster = props.Cluster + } + } + if len(props.Path) > 0 { + loadingRules.ExplicitPath = props.Path + } + cc := clientcmd.NewNonInteractiveDeferredLoadingClientConfig(loadingRules, configOverrides) + cfg, err := cc.ClientConfig() + if err != nil { + return clientConfig{}, fmt.Errorf("%w: %v", ErrNoKubernetesConnection, err) + } + ns, _, err := cc.Namespace() + if err != nil { + return clientConfig{}, fmt.Errorf("%w: %v", ErrNoKubernetesConnection, err) + } + return clientConfig{Config: cfg, namespace: ns}, nil +} + +type clientConfig struct { + *rest.Config + namespace string +} + +type clients struct { + namespace string + ctx context.Context + typed kubernetes.Interface + dynamic dynamic.Interface + serving servingv1.ServingV1Interface + eventing eventingv1.EventingV1Interface + messaging messagingv1.MessagingV1Interface +} + +func (c *clients) Typed() kubernetes.Interface { + return c.typed +} + +func (c *clients) Dynamic() dynamic.Interface { + return c.dynamic +} + +func (c *clients) Context() context.Context { + return c.ctx +} + +func (c *clients) Serving() servingv1.ServingV1Interface { + return c.serving +} + +func (c *clients) Eventing() eventingv1.EventingV1Interface { + return c.eventing +} + +func (c *clients) Messaging() messagingv1.MessagingV1Interface { + return c.messaging +} + +func (c *clients) Namespace() string { + return c.namespace +} diff --git a/vendor/knative.dev/kn-plugin-event/pkg/metadata/image.go b/vendor/knative.dev/kn-plugin-event/pkg/metadata/image.go new file mode 100644 index 0000000000..e1e74b0566 --- /dev/null +++ b/vendor/knative.dev/kn-plugin-event/pkg/metadata/image.go @@ -0,0 +1,32 @@ +package metadata + +import "fmt" + +var ( + // Image holds information about companion image reference. + Image = "" //nolint:gochecknoglobals + // ImageBasename holds a basename of a image, so the development reference + // could be built from it. + ImageBasename = "" //nolint:gochecknoglobals +) + +// ResolveImage will try to resolve the image reference from set values. If +// Image is given it will be used, otherwise the ImageBasename and Version will +// be used. +func ResolveImage() string { + //goland:noinspection GoBoolExpressions + if Image == "" { + return fmt.Sprintf("%s/kn-event-sender:%s", ImageBasename, Version) + } + return Image +} + +// ImagePath return a path to the image variable. +func ImagePath() string { + return importPath("Image") +} + +// ImageBasenamePath return a path to the image basename variable. +func ImageBasenamePath() string { + return importPath("ImageBasename") +} diff --git a/vendor/knative.dev/kn-plugin-event/pkg/metadata/names.go b/vendor/knative.dev/kn-plugin-event/pkg/metadata/names.go new file mode 100644 index 0000000000..242647f8b0 --- /dev/null +++ b/vendor/knative.dev/kn-plugin-event/pkg/metadata/names.go @@ -0,0 +1,13 @@ +package metadata + +const ( + // PluginName hold a name of the plugin. + PluginName = "kn-event" + // PluginUse hold a the plugin short name, intended to use as "kn ". + PluginUse = "event" + // PluginDescription holds a short description of the plugin. + PluginDescription = "Manage CloudEvents from command line" + // PluginLongDescription holds a long description of the plugin. + PluginLongDescription = `Manage CloudEvents from command line. Perform, easily, tasks like sending, +building, and parsing, all from command line.` +) diff --git a/vendor/knative.dev/kn-plugin-event/pkg/metadata/reflect.go b/vendor/knative.dev/kn-plugin-event/pkg/metadata/reflect.go new file mode 100644 index 0000000000..f54bb1d4f1 --- /dev/null +++ b/vendor/knative.dev/kn-plugin-event/pkg/metadata/reflect.go @@ -0,0 +1,18 @@ +package metadata + +import ( + "fmt" + "reflect" +) + +type marker struct{} + +func importPath(variable string) string { + m := marker{} + p := findPackageForType(m) + return fmt.Sprintf("%s.%s", p, variable) +} + +func findPackageForType(any interface{}) string { + return reflect.TypeOf(any).PkgPath() +} diff --git a/vendor/knative.dev/kn-plugin-event/pkg/metadata/version.go b/vendor/knative.dev/kn-plugin-event/pkg/metadata/version.go new file mode 100644 index 0000000000..e5550a83cb --- /dev/null +++ b/vendor/knative.dev/kn-plugin-event/pkg/metadata/version.go @@ -0,0 +1,9 @@ +package metadata + +// Version holds application version information. +var Version = "0.0.0" //nolint:gochecknoglobals + +// VersionPath return a path to the version variable. +func VersionPath() string { + return importPath("Version") +} diff --git a/vendor/knative.dev/kn-plugin-event/pkg/plugin/plugin.go b/vendor/knative.dev/kn-plugin-event/pkg/plugin/plugin.go new file mode 100644 index 0000000000..819ea9e458 --- /dev/null +++ b/vendor/knative.dev/kn-plugin-event/pkg/plugin/plugin.go @@ -0,0 +1,46 @@ +package plugin + +import ( + "io" + + knplugin "knative.dev/client/pkg/kn/plugin" + "knative.dev/kn-plugin-event/internal/cli/cmd" + "knative.dev/kn-plugin-event/pkg/metadata" +) + +// init makes sure to register plugin as internal one, after import of +// pkg/plugin, as knative cli plugins are expected to do. +// nolint:gochecknoinits +func init() { + knplugin.InternalPlugins = append(knplugin.InternalPlugins, &plugin{}) +} + +type plugin struct { + io.Writer +} + +func (p plugin) Name() string { + return metadata.PluginName +} + +func (p plugin) Execute(args []string) error { + opts := []cmd.CommandOption{ + cmd.WithArgs(args...), + } + if p.Writer != nil { + opts = append(opts, cmd.WithOutput(p.Writer)) + } + return new(cmd.Cmd).ExecuteWithOptions(opts...) //nolint:wrapcheck +} + +func (p plugin) Description() (string, error) { + return metadata.PluginDescription, nil +} + +func (p plugin) CommandParts() []string { + return []string{metadata.PluginUse} +} + +func (p plugin) Path() string { + return "" +} diff --git a/vendor/knative.dev/kn-plugin-event/pkg/plugin/testing.go b/vendor/knative.dev/kn-plugin-event/pkg/plugin/testing.go new file mode 100644 index 0000000000..102c1dfda6 --- /dev/null +++ b/vendor/knative.dev/kn-plugin-event/pkg/plugin/testing.go @@ -0,0 +1,35 @@ +package plugin + +import ( + "bytes" + "io" + + knplugin "knative.dev/client/pkg/kn/plugin" +) + +// WithCapture captures the output from of a running plugin. +func WithCapture(fn func()) []byte { + var buf bytes.Buffer + WithOutput(&buf, fn) + return buf.Bytes() +} + +// WithOutput executes provided function after configuring the stdout and stderr. +func WithOutput(output io.Writer, fn func()) { + pl := findPlugin() + save := pl.Writer + pl.Writer = output + defer func() { + pl.Writer = save + }() + fn() +} + +func findPlugin() *plugin { + for _, ip := range knplugin.InternalPlugins { + if pl, ok := ip.(*plugin); ok { + return pl + } + } + panic("this should never happen") +} diff --git a/vendor/knative.dev/kn-plugin-event/pkg/sender/create.go b/vendor/knative.dev/kn-plugin-event/pkg/sender/create.go new file mode 100644 index 0000000000..fd2e6186ae --- /dev/null +++ b/vendor/knative.dev/kn-plugin-event/pkg/sender/create.go @@ -0,0 +1,38 @@ +package sender + +import ( + "errors" + "fmt" + + "knative.dev/kn-plugin-event/pkg/event" +) + +// New creates a new Sender. +func (b *Binding) New(target *event.Target) (event.Sender, error) { + switch target.Type { + case event.TargetTypeReachable: + return &directSender{ + url: *target.URLVal, + }, nil + case event.TargetTypeAddressable: + kube, err := b.CreateKubeClients(target.Properties) + if err != nil { + return nil, err + } + jr := b.CreateJobRunner(kube) + ar := b.CreateAddressResolver(kube) + return &inClusterSender{ + addressable: target.AddressableVal, + jobRunner: jr, + addressResolver: ar, + }, nil + } + return nil, fmt.Errorf("%w: %v", ErrUnsupportedTargetType, target.Type) +} + +func cantSentEvent(err error) error { + if errors.Is(err, event.ErrCantSentEvent) { + return err + } + return fmt.Errorf("%w: %v", event.ErrCantSentEvent, err) +} diff --git a/vendor/knative.dev/kn-plugin-event/pkg/sender/direct.go b/vendor/knative.dev/kn-plugin-event/pkg/sender/direct.go new file mode 100644 index 0000000000..b591c9b807 --- /dev/null +++ b/vendor/knative.dev/kn-plugin-event/pkg/sender/direct.go @@ -0,0 +1,30 @@ +package sender + +import ( + "context" + "net/url" + + cloudevents "github.com/cloudevents/sdk-go/v2" +) + +type directSender struct { + url url.URL +} + +func (d *directSender) Send(ce cloudevents.Event) error { + c, err := cloudevents.NewClientHTTP() + if err != nil { + return cantSentEvent(err) + } + + // Set a target. + ctx := cloudevents.ContextWithTarget(context.TODO(), d.url.String()) + + // Send that Event. + err = c.Send(ctx, ce) + if !cloudevents.IsACK(err) { + return cantSentEvent(err) + } + + return nil +} diff --git a/vendor/knative.dev/kn-plugin-event/pkg/sender/in_cluster.go b/vendor/knative.dev/kn-plugin-event/pkg/sender/in_cluster.go new file mode 100644 index 0000000000..811dff44f8 --- /dev/null +++ b/vendor/knative.dev/kn-plugin-event/pkg/sender/in_cluster.go @@ -0,0 +1,74 @@ +package sender + +import ( + "fmt" + "regexp" + + cloudevents "github.com/cloudevents/sdk-go/v2" + batchv1 "k8s.io/api/batch/v1" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "knative.dev/kn-plugin-event/pkg/cli/ics" + "knative.dev/kn-plugin-event/pkg/event" + "knative.dev/kn-plugin-event/pkg/k8s" +) + +type inClusterSender struct { + addressable *event.AddressableSpec + jobRunner k8s.JobRunner + addressResolver k8s.ReferenceAddressResolver +} + +func (i *inClusterSender) Send(ce cloudevents.Event) error { + url, err := i.addressResolver.ResolveAddress( + i.addressable.Reference, i.addressable.URI, + ) + if err != nil { + return fmt.Errorf("%w: %v", k8s.ErrInvalidReference, err) + } + kevent, err := ics.Encode(ce) + if err != nil { + return fmt.Errorf("%w: %v", ics.ErrCouldntEncode, err) + } + job := &batchv1.Job{ + ObjectMeta: metav1.ObjectMeta{ + Name: fmt.Sprintf("kn-event-sender-%s", ce.ID()), + Namespace: i.addressable.SenderNamespace, + Labels: map[string]string{ + "event-id": ce.ID(), + }, + }, + Spec: batchv1.JobSpec{ + Template: corev1.PodTemplateSpec{ + Spec: corev1.PodSpec{ + RestartPolicy: corev1.RestartPolicyNever, + Containers: []corev1.Container{{ + Name: "kn-event-sender", + Image: imageFor("kn-event-sender"), + Env: []corev1.EnvVar{{ + Name: "K_SINK", + Value: url.String(), + }, { + Name: "K_EVENT", + Value: kevent, + }}, + }}, + }, + }, + }, + } + err = i.jobRunner.Run(job) + if err != nil { + return fmt.Errorf("%w: %v", ics.ErrCantSendWithICS, err) + } + return nil +} + +func imageFor(artifact string) string { + basename := ics.ContainerBasename + r := regexp.MustCompile(".+[A-Za-z0-9]$") + if r.MatchString(basename) { + basename += "/" + } + return basename + artifact +} diff --git a/vendor/knative.dev/kn-plugin-event/pkg/sender/namespace.go b/vendor/knative.dev/kn-plugin-event/pkg/sender/namespace.go new file mode 100644 index 0000000000..364bcf24cf --- /dev/null +++ b/vendor/knative.dev/kn-plugin-event/pkg/sender/namespace.go @@ -0,0 +1,13 @@ +package sender + +import "knative.dev/kn-plugin-event/pkg/event" + +// DefaultNamespace returns a default namespace of connected K8s cluster or +// error if such namespace can't be determined. +func (b *Binding) DefaultNamespace(props *event.Properties) (string, error) { + clients, err := b.CreateKubeClients(props) + if err != nil { + return "", err + } + return clients.Namespace(), nil +} diff --git a/vendor/knative.dev/kn-plugin-event/pkg/sender/types.go b/vendor/knative.dev/kn-plugin-event/pkg/sender/types.go new file mode 100644 index 0000000000..e87a5fe50a --- /dev/null +++ b/vendor/knative.dev/kn-plugin-event/pkg/sender/types.go @@ -0,0 +1,28 @@ +package sender + +import ( + "errors" + + "knative.dev/kn-plugin-event/pkg/event" + "knative.dev/kn-plugin-event/pkg/k8s" +) + +// ErrUnsupportedTargetType is an error if user pass unsupported event target +// type. Only supporting: reachable or addressable. +var ErrUnsupportedTargetType = errors.New("unsupported target type") + +// CreateKubeClients creates k8s.Clients. +type CreateKubeClients func(props *event.Properties) (k8s.Clients, error) + +// CreateJobRunner creates a k8s.JobRunner. +type CreateJobRunner func(kube k8s.Clients) k8s.JobRunner + +// CreateAddressResolver creates a k8s.ReferenceAddressResolver. +type CreateAddressResolver func(kube k8s.Clients) k8s.ReferenceAddressResolver + +// Binding holds injectable dependencies. +type Binding struct { + CreateJobRunner + CreateAddressResolver + CreateKubeClients +} diff --git a/vendor/knative.dev/kn-plugin-func/.codecov.yaml b/vendor/knative.dev/kn-plugin-func/.codecov.yaml index 16733ebf01..f6fd0b2e74 100644 --- a/vendor/knative.dev/kn-plugin-func/.codecov.yaml +++ b/vendor/knative.dev/kn-plugin-func/.codecov.yaml @@ -2,3 +2,4 @@ ignore: - third_party - vendor - testdata + - docker/docker_client_generated.go diff --git a/vendor/knative.dev/kn-plugin-func/Makefile b/vendor/knative.dev/kn-plugin-func/Makefile index 86b8fa0c06..1c0e3eb67d 100644 --- a/vendor/knative.dev/kn-plugin-func/Makefile +++ b/vendor/knative.dev/kn-plugin-func/Makefile @@ -60,7 +60,7 @@ check: bin/golangci-lint ## Check code quality (lint) cd test/_e2e && ../../bin/golangci-lint run --timeout 300s bin/golangci-lint: - curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b ./bin v1.40.1 + curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b ./bin v1.43.0 pkged.go: $(TEMPLATES) @rm -rf templates/node/cloudevents/node_modules @@ -152,7 +152,7 @@ $(BIN_WINDOWS): pkged.go ##@ Schemas ###################### schema-generate: schema/func_yaml-schema.json ## Generate func.yaml schema -schema/func_yaml-schema.json: config.go +schema/func_yaml-schema.json: function.go go run schema/generator/main.go schema-check: ## Check that func.yaml schema is up-to-date diff --git a/vendor/knative.dev/kn-plugin-func/buildpacks/builder.go b/vendor/knative.dev/kn-plugin-func/buildpacks/builder.go index ea8a74fcb1..939694c617 100644 --- a/vendor/knative.dev/kn-plugin-func/buildpacks/builder.go +++ b/vendor/knative.dev/kn-plugin-func/buildpacks/builder.go @@ -11,6 +11,8 @@ import ( "runtime" "strings" + "github.com/docker/docker/client" + fn "knative.dev/kn-plugin-func" "knative.dev/kn-plugin-func/docker" @@ -30,25 +32,12 @@ func NewBuilder() *Builder { return &Builder{} } -//RuntimeToBuildpack holds the mapping between the Runtime and its corresponding -//Buildpack builder to use -var RuntimeToBuildpack = map[string]string{ - "quarkus": "quay.io/boson/faas-jvm-builder", - "node": "quay.io/boson/faas-nodejs-builder", - "go": "quay.io/boson/faas-go-builder", - "springboot": "quay.io/boson/faas-jvm-builder", - "python": "quay.io/boson/faas-python-builder", - "typescript": "quay.io/boson/faas-nodejs-builder", - "rust": "quay.io/boson/faas-rust-builder", -} - var v330 = semver.MustParse("v3.3.0") // Build the Function at path. func (builder *Builder) Build(ctx context.Context, f fn.Function) (err error) { // Use the builder found in the Function configuration file - // If one isn't found, use the defaults var packBuilder string if f.Builder != "" { packBuilder = f.Builder @@ -57,10 +46,7 @@ func (builder *Builder) Build(ctx context.Context, f fn.Function) (err error) { packBuilder = pb } } else { - packBuilder = RuntimeToBuildpack[f.Runtime] - if packBuilder == "" { - return errors.New(fmt.Sprint("unsupported runtime: ", f.Runtime)) - } + return errors.New("no buildpack configured for function") } // Build options for the pack client. @@ -79,10 +65,11 @@ func (builder *Builder) Build(ctx context.Context, f fn.Function) (err error) { logWriter = &bytes.Buffer{} } - cli, dockerHost, err := docker.NewDockerClient() + cli, dockerHost, err := docker.NewClient(client.DefaultDockerHost) if err != nil { return err } + defer cli.Close() version, err := cli.ServerVersion(ctx) if err != nil { diff --git a/vendor/knative.dev/kn-plugin-func/buildpacks/utils.go b/vendor/knative.dev/kn-plugin-func/buildpacks/utils.go deleted file mode 100644 index ca7be411e3..0000000000 --- a/vendor/knative.dev/kn-plugin-func/buildpacks/utils.go +++ /dev/null @@ -1,31 +0,0 @@ -package buildpacks - -import ( - "sort" - "strings" -) - -//Runtimes returns the list of supported runtimes -//as comma seperated strings, sorted alphabetically -func Runtimes() string { - runtimes := RuntimesList() - - //make it more grammatical :) - s := runtimes[:len(runtimes)-1] - str := strings.Join(s, ", ") - str = str + " and " + runtimes[len(runtimes)-1] - return str -} - -// RuntimesList returns the list of supported runtimes -//as an array of strings, sorted alphabetically -func RuntimesList() []string { - rb := RuntimeToBuildpack - runtimes := make([]string, 0, len(rb)) - for k := range rb { - runtimes = append(runtimes, k) - } - sort.Strings(runtimes) - - return runtimes -} diff --git a/vendor/knative.dev/kn-plugin-func/ci b/vendor/knative.dev/kn-plugin-func/ci new file mode 100644 index 0000000000..d829c3fc1a --- /dev/null +++ b/vendor/knative.dev/kn-plugin-func/ci @@ -0,0 +1 @@ +Wed Dec 8 19:36:30 EST 2021 diff --git a/vendor/knative.dev/kn-plugin-func/client.go b/vendor/knative.dev/kn-plugin-func/client.go index d1c92d47c7..10188eec25 100644 --- a/vendor/knative.dev/kn-plugin-func/client.go +++ b/vendor/knative.dev/kn-plugin-func/client.go @@ -8,6 +8,7 @@ import ( "os" "path/filepath" "runtime" + "runtime/debug" "time" "github.com/mitchellh/go-homedir" @@ -17,54 +18,26 @@ const ( // DefaultRegistry through which containers of Functions will be shuttled. DefaultRegistry = "docker.io" - // DefaultRuntime is the language runtime for a new Function, including - // the template written and builder invoked on deploy. - DefaultRuntime = "node" - // DefaultTemplate is the default Function signature / environmental context // of the resultant function. All runtimes are expected to have at least // one implementation of each supported function signature. Currently that // includes an HTTP Handler ("http") and Cloud Events handler ("events") DefaultTemplate = "http" - // The name of the config directory within ~/.config (or configured location) - configDirName = "func" -) - -// ConfigPath is the effective path to the optional global config directory used for -// function defaults and extensible templates. -func ConfigPath() string { - path := configPath() - _ = os.MkdirAll(path, 0700) - return path -} - -func configPath() string { - // Use XDG_CONFIG_HOME/func if defined - if xdg := os.Getenv("XDG_CONFIG_HOME"); xdg != "" { - return filepath.Join(xdg, configDirName) - } - - // Expand and use ~/.config/func - home, err := homedir.Expand("~") - if err == nil { - return filepath.Join(home, ".config", configDirName) - } + // DefaultVersion is the initial value for string members whose implicit type + // is a semver. + DefaultVersion = "0.0.0" - // default is .config in current working directory, used when there is no - // available home in which to find a .`.config/func` directory. - // A case could be made that a panic is in order in this scenario, but - // currently this seems like a nonfatal situation, as in the scenario - // "there is no home directory", the fallback of using `.config` if extant - // may very well be the optimal choice. - fmt.Fprintf(os.Stderr, "Error locating ~/.config: %v", err) - return filepath.Join(".config", configDirName) -} + // DefaultConfigPath is used in the unlikely event that + // the user has no home directory (no ~), there is no + // XDG_CONFIG_HOME set, and no WithConfigPath was used. + DefaultConfigPath = ".config/func" +) // Client for managing Function instances. type Client struct { - repositories *Repositories // Repositories management - templates *Templates // Templates management + repositoriesPath string // path to repositories + repositoriesURI string // repo URI (overrides repositories path) verbose bool // print verbose logs builder Builder // Builds a runnable image source pusher Pusher // Pushes Funcation image to a remote @@ -77,6 +50,8 @@ type Client struct { registry string // default registry for OCI image tags progressListener ProgressListener // progress listener emitter Emitter // Emits CloudEvents to functions + repositories *Repositories // Repositories management + templates *Templates // Templates management } // ErrNotBuilt indicates the Function has not yet been built. @@ -196,8 +171,6 @@ type Emitter interface { func New(options ...Option) *Client { // Instantiate client with static defaults. c := &Client{ - repositories: &Repositories{}, - templates: &Templates{}, builder: &noopBuilder{output: os.Stdout}, pusher: &noopPusher{output: os.Stdout}, deployer: &noopDeployer{output: os.Stdout}, @@ -207,15 +180,63 @@ func New(options ...Option) *Client { dnsProvider: &noopDNSProvider{output: os.Stdout}, progressListener: &NoopProgressListener{}, emitter: &noopEmitter{}, + repositoriesPath: filepath.Join(ConfigPath(), "repositories"), } - c.repositories = newRepositories(c) - c.templates = newTemplates(c) for _, o := range options { o(c) } + // Initialize sub-managers using now-fully-initialized client. + c.repositories = newRepositories(c) + c.templates = newTemplates(c) + + // Trigger the creation of the config and repository paths + _ = ConfigPath() // Config is package-global scoped + _ = c.RepositoriesPath() // Repositories is Client-specific + return c } +// The default config path is evaluated in the following order, from lowest +// to highest precedence. +// 1. The static default is DefaultConfigPath (./.config/func) +// 2. ~/.config/func if it exists (can be expanded: user has a home dir) +// 3. The value of $XDG_CONFIG_PATH/func if the environment variable exists. +// The path will be created if it does not already exist. +func ConfigPath() (path string) { + path = DefaultConfigPath + + // ~/.config/func is the default if ~ can be expanded + if home, err := homedir.Expand("~"); err == nil { + path = filepath.Join(home, ".config", "func") + } + + // 'XDG_CONFIG_HOME/func' takes precidence if defined + if xdg := os.Getenv("XDG_CONFIG_HOME"); xdg != "" { + path = filepath.Join(xdg, "func") + } + + mkdir(path) // make sure it exists + return +} + +// RepositoriesPath accesses the currently effective repositories path, +// which defaults to [ConfigPath]/repositories but can be set explicitly using +// the WithRepositories option when creating the client.. +// The path will be created if it does not already exist. +func (c *Client) RepositoriesPath() (path string) { + path = c.repositories.Path() + mkdir(path) // make sure it exists + return +} + +// RepositoriesPath is a convenience method for accessing the default path to +// repositories that will be used by new instances of a Client unless options +// such as WithRepositories are used to override. +// The path will be created if it does not already exist. +func RepositoriesPath() string { + return New().RepositoriesPath() +} + // OPTIONS // --------- @@ -296,21 +317,21 @@ func WithDNSProvider(provider DNSProvider) Option { } } -// WithRepositories sets the location to use for extensible template repositories. -// Extensible template repositories are additional templates that exist on disk and are -// not built into the binary. +// WithRepositories sets the location to use for extensible template +// repositories. Extensible template repositories are additional templates +// that exist on disk and are not built into the binary. func WithRepositories(path string) Option { return func(c *Client) { - c.Repositories().SetPath(path) + c.repositoriesPath = path } } -// WithRepository sets a specific URL to a Git repository from which to pull templates. -// This setting's existence precldes the use of either the inbuilt templates or any -// repositories from the extensible repositories path. +// WithRepository sets a specific URL to a Git repository from which to pull +// templates. This setting's existence precldes the use of either the inbuilt +// templates or any repositories from the extensible repositories path. func WithRepository(uri string) Option { return func(c *Client) { - c.Repositories().SetRemote(uri) + c.repositoriesURI = uri } } @@ -386,9 +407,8 @@ func (c *Client) New(ctx context.Context, cfg Function) (err error) { c.progressListener.Stopping() }() - // Create local template - err = c.Create(cfg) - if err != nil { + // Create Function at path indidcated by Config + if err = c.Create(cfg); err != nil { return } @@ -428,61 +448,65 @@ func (c *Client) New(ctx context.Context, cfg Function) (err error) { return } -// Create a new Function project locally using the settings provided on a -// Function object. -func (c *Client) Create(f Function) (err error) { +// Create a new Function from the given defaults. +// will default to the absolute path of the current working directory. +// will default to the current working directory. +// When is provided but is not, a directory is created +// in the current working directory and used for . +func (c *Client) Create(cfg Function) (err error) { + // convert Root path to absolute + cfg.Root, err = filepath.Abs(cfg.Root) + if err != nil { + return + } + // Create project root directory, if it doesn't already exist - if err = os.MkdirAll(f.Root, 0755); err != nil { + if err = os.MkdirAll(cfg.Root, 0755); err != nil { return } - // Root must not already be a Function - // - // Instantiate a Function struct about the given root path, but - // immediately exit with error (prior to actual creation) if this is - // a Function already initialized at that path (Create should never - // clobber a pre-existing Function) - defaults, err := NewFunction(f.Root) + // Create should never clobber a pre-existing Function + hasFunc, err := hasInitializedFunction(cfg.Root) if err != nil { - return + return err } - if defaults.Initialized() { - err = fmt.Errorf("Function at '%v' already initialized", f.Root) - return + if hasFunc { + return fmt.Errorf("Function at '%v' already initialized", cfg.Root) } - // Root must not contain any visible files - // - // We know from above that the target directory does not contain a Function, - // but also immediately exit if the target directoy contains any visible files - // at all, or any of the known hidden files that will be written. - // This is to ensure that if a user inadvertently chooses an incorrect directory - // for their new Function, the template and config file writing steps do not - // cause data loss. - if err = assertEmptyRoot(f.Root); err != nil { - return + // The path for the new Function should not have any contentious files + // (hidden files OK, unless it's one used by Func) + if err := assertEmptyRoot(cfg.Root); err != nil { + return err } - // Assert runtime was provided, or default. - if f.Runtime == "" { - f.Runtime = DefaultRuntime + // Path is defaulted to the current working directory + if cfg.Root == "" { + if cfg.Root, err = os.Getwd(); err != nil { + return + } } - // Assert template name was provided, or default. - if f.Template == "" { - f.Template = DefaultTemplate + // Name is defaulted to the directory of the given path. + if cfg.Name == "" { + cfg.Name = nameFromPath(cfg.Root) } - // Write out the template for a Function - // returns a Function which may be mutated based on the content of - // the template (default Function, builders, buildpacks, etc). + // Create a new Function + f := NewFunctionWith(cfg) + + // Write out the new Function's Template files. + // Templates contain values which may result in the Function being mutated + // (default builders, etc), so a new (potentially mutated) Function is + // returned from Templates.Write f, err = c.Templates().Write(f) if err != nil { return } - // Write the Function metadata (func.yaml) - if err = writeConfig(f); err != nil { + // Mark the Function as having been created + f.Created = time.Now() + if err = f.Write(); err != nil { return } @@ -511,7 +535,7 @@ func (c *Client) Build(ctx context.Context, path string) (err error) { "Don't give up on me", "This is taking a while", "Still building"} - ticker := time.NewTicker(5 * time.Second) + ticker := time.NewTicker(10 * time.Second) defer ticker.Stop() go func() { for { @@ -543,9 +567,9 @@ func (c *Client) Build(ctx context.Context, path string) (err error) { return } - // Write out config, which will now contain a populated image tag - // if it had not already - if err = writeConfig(f); err != nil { + // Write (save) - Serialize the Function to disk + // Will now contain populated image tag. + if err = f.Write(); err != nil { return } @@ -578,15 +602,7 @@ func (c *Client) Deploy(ctx context.Context, path string) (err error) { return ErrNotBuilt } - // Push the image for the named service to the configured registry - imageDigest, err := c.pusher.Push(ctx, f) - if err != nil { - return - } - - // Store the produced image Digest in the config - f.ImageDigest = imageDigest - if err = writeConfig(f); err != nil { + if err = c.Push(ctx, &f); err != nil { return } @@ -700,6 +716,18 @@ func (c *Client) Emit(ctx context.Context, endpoint string) error { return c.emitter.Emit(ctx, endpoint) } +// Push the image for the named service to the configured registry +func (c *Client) Push(ctx context.Context, f *Function) (err error) { + imageDigest, err := c.pusher.Push(ctx, *f) + if err != nil { + return + } + + // Record the Image Digest pushed. + f.ImageDigest = imageDigest + return f.Write() +} + // DEFAULTS // --------- @@ -765,3 +793,14 @@ func (p *NoopProgressListener) Increment(m string) {} func (p *NoopProgressListener) Complete(m string) {} func (p *NoopProgressListener) Stopping() {} func (p *NoopProgressListener) Done() {} + +// mkdir attempts to mkdir, writing any errors to stderr. +func mkdir(path string) { + // Since it is expected that the code elsewhere never assume directories + // exist (doing so is a racing condition), it is valid to simply + // handle errors at this level. + if err := os.MkdirAll(path, 0700); err != nil { + fmt.Fprintf(os.Stderr, "Error creating '%v': %v", path, err) + debug.PrintStack() + } +} diff --git a/vendor/knative.dev/kn-plugin-func/cmd/build.go b/vendor/knative.dev/kn-plugin-func/cmd/build.go index 58542bce7b..8ba3c46b3e 100644 --- a/vendor/knative.dev/kn-plugin-func/cmd/build.go +++ b/vendor/knative.dev/kn-plugin-func/cmd/build.go @@ -11,6 +11,7 @@ import ( fn "knative.dev/kn-plugin-func" "knative.dev/kn-plugin-func/buildpacks" + "knative.dev/kn-plugin-func/docker" "knative.dev/kn-plugin-func/progress" ) @@ -24,11 +25,31 @@ func newBuildClient(cfg buildConfig) (*fn.Client, error) { builder := buildpacks.NewBuilder() listener := progress.New() + pusherOption := fn.WithPusher(nil) + if cfg.Push { + credentialsProvider := docker.NewCredentialsProvider( + newCredentialsCallback(), + docker.CheckAuth, + newChooseHelperCallback(), + ) + pusher, err := docker.NewPusher( + docker.WithCredentialsProvider(credentialsProvider), + docker.WithProgressListener(listener), + ) + + if err != nil { + return nil, err + } + pusher.Verbose = cfg.Verbose + pusherOption = fn.WithPusher(pusher) + } builder.Verbose = cfg.Verbose listener.Verbose = cfg.Verbose return fn.New( fn.WithBuilder(builder), + // fn.WithPusher(pusher), + pusherOption, fn.WithProgressListener(listener), fn.WithRegistry(cfg.Registry), // for image name when --image not provided fn.WithVerbose(cfg.Verbose)), nil @@ -64,14 +85,15 @@ kn func build kn func build --builder cnbs/sample-builder:bionic `, SuggestFor: []string{"biuld", "buidl", "built"}, - PreRunE: bindEnv("image", "path", "builder", "registry", "confirm"), + PreRunE: bindEnv("image", "path", "builder", "registry", "confirm", "push"), } cmd.Flags().StringP("builder", "b", "", "Buildpack builder, either an as a an image name or a mapping name.\nSpecified value is stored in func.yaml for subsequent builds.") cmd.Flags().BoolP("confirm", "c", false, "Prompt to confirm all configuration options (Env: $FUNC_CONFIRM)") cmd.Flags().StringP("image", "i", "", "Full image name in the form [registry]/[namespace]/[name]:[tag] (optional). This option takes precedence over --registry (Env: $FUNC_IMAGE)") - cmd.Flags().StringP("path", "p", cwd(), "Path to the project directory (Env: $FUNC_PATH)") cmd.Flags().StringP("registry", "r", "", "Registry + namespace part of the image to build, ex 'quay.io/myuser'. The full image name is automatically determined based on the local directory name. If not provided the registry will be taken from func.yaml (Env: $FUNC_REGISTRY)") + cmd.Flags().BoolP("push", "u", false, "Attempt to push the function image after being successfully built") + setPathFlag(cmd) if err := cmd.RegisterFlagCompletionFunc("builder", CompleteBuilderList); err != nil { fmt.Println("internal: error while calling RegisterFlagCompletionFunc: ", err) @@ -84,7 +106,7 @@ kn func build --builder cnbs/sample-builder:bionic return cmd } -func ValidNamespaceAndRegistry() survey.Validator { +func ValidNamespaceAndRegistry(path string) survey.Validator { return func(val interface{}) error { // if the value passed in is the zero value of the appropriate type @@ -92,10 +114,10 @@ func ValidNamespaceAndRegistry() survey.Validator { return errors.New("Value is required") } - _, err := fn.DerivedImage("", val.(string)) //image can be derived without any error + _, err := fn.DerivedImage(path, val.(string)) //image can be derived without any error if err != nil { - return errors.New(val.(string) + " Registry and Namespace are required (ie. docker.io/tigerteam). The image name will be derived from the function name.") + return fmt.Errorf("Invalid registry [%s] %v", val.(string), err) } return nil } @@ -120,6 +142,14 @@ func runBuild(cmd *cobra.Command, _ []string, clientFn buildClientFn) (err error return fmt.Errorf("the given path '%v' does not contain an initialized function. Please create one at this path before deploying", config.Path) } + // If a registry name was provided as a command line flag, it should be validated + if config.Registry != "" { + err = ValidNamespaceAndRegistry(config.Path)(config.Registry) + if err != nil { + return + } + } + // If the Function does not yet have an image name and one was not provided on the command line if function.Image == "" { // AND a --registry was not provided, then we need to @@ -129,7 +159,7 @@ func runBuild(cmd *cobra.Command, _ []string, clientFn buildClientFn) (err error err = survey.AskOne( &survey.Input{Message: "Registry for Function images:"}, - &config.Registry, survey.WithValidator(ValidNamespaceAndRegistry())) + &config.Registry, survey.WithValidator(ValidNamespaceAndRegistry(config.Path))) if err != nil { if err == terminal.InterruptErr { return nil @@ -145,7 +175,7 @@ func runBuild(cmd *cobra.Command, _ []string, clientFn buildClientFn) (err error } // All set, let's write changes in the config to the disk - err = function.WriteConfig() + err = function.Write() if err != nil { return } @@ -162,7 +192,11 @@ func runBuild(cmd *cobra.Command, _ []string, clientFn buildClientFn) (err error return err } - return client.Build(cmd.Context(), config.Path) + err = client.Build(cmd.Context(), config.Path) + if err == nil && config.Push { + err = client.Push(cmd.Context(), &function) + } + return } type buildConfig struct { @@ -198,6 +232,7 @@ func newBuildConfig() buildConfig { Verbose: viper.GetBool("verbose"), // defined on root Confirm: viper.GetBool("confirm"), Builder: viper.GetString("builder"), + Push: viper.GetBool("push"), } } diff --git a/vendor/knative.dev/kn-plugin-func/cmd/config.go b/vendor/knative.dev/kn-plugin-func/cmd/config.go index 40a78d27fd..b27429fb7d 100644 --- a/vendor/knative.dev/kn-plugin-func/cmd/config.go +++ b/vendor/knative.dev/kn-plugin-func/cmd/config.go @@ -38,14 +38,14 @@ func (s standardLoaderSaver) Load(path string) (fn.Function, error) { } func (s standardLoaderSaver) Save(f fn.Function) error { - return f.WriteConfig() + return f.Write() } var defaultLoaderSaver standardLoaderSaver func init() { root.AddCommand(configCmd) - configCmd.Flags().StringP("path", "p", cwd(), "Path to the project directory (Env: $FUNC_PATH)") + setPathFlag(configCmd) configCmd.AddCommand(NewConfigLabelsCmd(defaultLoaderSaver)) } diff --git a/vendor/knative.dev/kn-plugin-func/cmd/config_envs.go b/vendor/knative.dev/kn-plugin-func/cmd/config_envs.go index fbf20fde18..8d4684d9d8 100644 --- a/vendor/knative.dev/kn-plugin-func/cmd/config_envs.go +++ b/vendor/knative.dev/kn-plugin-func/cmd/config_envs.go @@ -15,12 +15,12 @@ import ( ) func init() { + setPathFlag(configEnvsCmd) + setPathFlag(configEnvsAddCmd) + setPathFlag(configEnvsRemoveCmd) configCmd.AddCommand(configEnvsCmd) - configEnvsCmd.Flags().StringP("path", "p", cwd(), "Path to the project directory (Env: $FUNC_PATH)") configEnvsCmd.AddCommand(configEnvsAddCmd) - configEnvsAddCmd.Flags().StringP("path", "p", cwd(), "Path to the project directory (Env: $FUNC_PATH)") configEnvsCmd.AddCommand(configEnvsRemoveCmd) - configEnvsRemoveCmd.Flags().StringP("path", "p", cwd(), "Path to the project directory (Env: $FUNC_PATH)") } var configEnvsCmd = &cobra.Command{ @@ -375,7 +375,7 @@ func runAddEnvsPrompt(ctx context.Context, f fn.Function) (err error) { f.Envs[insertToIndex] = newEnv } - err = f.WriteConfig() + err = f.Write() if err == nil { fmt.Println("Environment variable entry was added to the function configuration") } @@ -407,7 +407,7 @@ func runRemoveEnvsPrompt(f fn.Function) (err error) { return } - var newEnvs fn.Envs + var newEnvs []fn.Env removed := false for i, e := range f.Envs { if e.String() == selectedEnv { @@ -419,7 +419,7 @@ func runRemoveEnvsPrompt(f fn.Function) (err error) { if removed { f.Envs = newEnvs - err = f.WriteConfig() + err = f.Write() if err == nil { fmt.Println("Environment variable entry was removed from the function configuration") } diff --git a/vendor/knative.dev/kn-plugin-func/cmd/config_labels.go b/vendor/knative.dev/kn-plugin-func/cmd/config_labels.go index 46f60b2496..e10b92c9be 100644 --- a/vendor/knative.dev/kn-plugin-func/cmd/config_labels.go +++ b/vendor/knative.dev/kn-plugin-func/cmd/config_labels.go @@ -79,11 +79,11 @@ directory or from the directory specified with --path. }, } - configLabelsCmd.Flags().StringP("path", "p", cwd(), "Path to the project directory (Env: $FUNC_PATH)") + setPathFlag(configLabelsCmd) + setPathFlag(configLabelsAddCmd) + setPathFlag(configLabelsRemoveCmd) configLabelsCmd.AddCommand(configLabelsAddCmd) - configLabelsAddCmd.Flags().StringP("path", "p", cwd(), "Path to the project directory (Env: $FUNC_PATH)") configLabelsCmd.AddCommand(configLabelsRemoveCmd) - configLabelsRemoveCmd.Flags().StringP("path", "p", cwd(), "Path to the project directory (Env: $FUNC_PATH)") return configLabelsCmd } @@ -269,7 +269,7 @@ func runRemoveLabelsPrompt(f fn.Function, saver functionSaver) (err error) { return } - var newLabels fn.Labels + var newLabels []fn.Label removed := false for i, e := range f.Labels { if e.String() == selectedLabel { diff --git a/vendor/knative.dev/kn-plugin-func/cmd/config_volumes.go b/vendor/knative.dev/kn-plugin-func/cmd/config_volumes.go index d1d2ddba67..4d2f8c6011 100644 --- a/vendor/knative.dev/kn-plugin-func/cmd/config_volumes.go +++ b/vendor/knative.dev/kn-plugin-func/cmd/config_volumes.go @@ -14,12 +14,12 @@ import ( ) func init() { + setPathFlag(configVolumesCmd) + setPathFlag(configVolumesAddCmd) + setPathFlag(configVolumesRemoveCmd) configCmd.AddCommand(configVolumesCmd) - configVolumesCmd.Flags().StringP("path", "p", cwd(), "Path to the project directory (Env: $FUNC_PATH)") configVolumesCmd.AddCommand(configVolumesAddCmd) - configVolumesAddCmd.Flags().StringP("path", "p", cwd(), "Path to the project directory (Env: $FUNC_PATH)") configVolumesCmd.AddCommand(configVolumesRemoveCmd) - configVolumesRemoveCmd.Flags().StringP("path", "p", cwd(), "Path to the project directory (Env: $FUNC_PATH)") } var configVolumesCmd = &cobra.Command{ @@ -192,7 +192,7 @@ func runAddVolumesPrompt(ctx context.Context, f fn.Function) (err error) { f.Volumes = append(f.Volumes, newVolume) - err = f.WriteConfig() + err = f.Write() if err == nil { fmt.Println("Volume entry was added to the function configuration") } @@ -224,7 +224,7 @@ func runRemoveVolumesPrompt(f fn.Function) (err error) { return } - var newVolumes fn.Volumes + var newVolumes []fn.Volume removed := false for i, v := range f.Volumes { if v.String() == selectedVolume { @@ -236,7 +236,7 @@ func runRemoveVolumesPrompt(f fn.Function) (err error) { if removed { f.Volumes = newVolumes - err = f.WriteConfig() + err = f.Write() if err == nil { fmt.Println("Volume entry was removed from the function configuration") } diff --git a/vendor/knative.dev/kn-plugin-func/cmd/create.go b/vendor/knative.dev/kn-plugin-func/cmd/create.go index 9e6ea70bd3..2920fd9e97 100644 --- a/vendor/knative.dev/kn-plugin-func/cmd/create.go +++ b/vendor/knative.dev/kn-plugin-func/cmd/create.go @@ -16,6 +16,15 @@ import ( "knative.dev/kn-plugin-func/utils" ) +// ErrNoRuntime indicates that the language runtime flag was not passed. +type ErrNoRuntime error + +// ErrInvalidRuntime indicates that the passed language runtime was invalid. +type ErrInvalidRuntime error + +// ErrInvalidTemplate indicates that the passed template was invalid. +type ErrInvalidTemplate error + func init() { // Add to the root a new "Create" command which obtains an appropriate // instance of fn.Client from the given client creator function. @@ -86,7 +95,7 @@ EXAMPLES } // Flags - cmd.Flags().StringP("language", "l", fn.DefaultRuntime, "Language Runtime (see help text for list) (Env: $FUNC_LANGUAGE)") + cmd.Flags().StringP("language", "l", "", "Language Runtime (see help text for list) (Env: $FUNC_LANGUAGE)") cmd.Flags().StringP("template", "t", fn.DefaultTemplate, "Function template. (see help text for list) (Env: $FUNC_TEMPLATE)") cmd.Flags().StringP("repository", "r", "", "URI to a Git repository containing the specified template (Env: $FUNC_REPOSITORY)") cmd.Flags().BoolP("confirm", "c", false, "Prompt to confirm all options interactively (Env: $FUNC_CONFIRM)") @@ -237,7 +246,7 @@ func newCreateConfig(args []string, clientFn createClientFn) (cfg createConfig, // it is still available as an environment variable. repositories = os.Getenv("FUNC_REPOSITORIES") if repositories == "" { // if no env var provided - repositories = repositoriesPath() // use ~/.config/func/repositories + repositories = fn.New().RepositoriesPath() // use ~/.config/func/repositories } // Config is the final default values based off the execution context. @@ -315,6 +324,22 @@ func isValidTemplate(client *fn.Client, runtime, template string) bool { return false } +// noRuntimeError creates an error stating that the language flag +// is required, and a verbose list of valid options. +func noRuntimeError(client *fn.Client) error { + b := strings.Builder{} + fmt.Fprintf(&b, "Required flag \"language\" not set.\n") + fmt.Fprintln(&b, "Available language runtimes are:") + runtimes, err := client.Runtimes() + if err != nil { + return err + } + for _, v := range runtimes { + fmt.Fprintf(&b, " %v\n", v) + } + return ErrNoRuntime(errors.New(b.String())) +} + // newInvalidRuntimeError creates an error stating that the given language // is not valid, and a verbose list of valid options. func newInvalidRuntimeError(client *fn.Client, runtime string) error { @@ -328,7 +353,7 @@ func newInvalidRuntimeError(client *fn.Client, runtime string) error { for _, v := range runtimes { fmt.Fprintf(&b, " %v\n", v) } - return errors.New(b.String()) + return ErrInvalidRuntime(errors.New(b.String())) } // newInvalidTemplateError creates an error stating that the given template @@ -345,7 +370,7 @@ func newInvalidTemplateError(client *fn.Client, runtime, template string) error for _, v := range templates { fmt.Fprintf(&b, " %v\n", v) } - return errors.New(b.String()) + return ErrInvalidTemplate(errors.New(b.String())) } // Validate the current state of the config, returning any errors. @@ -355,6 +380,7 @@ func newInvalidTemplateError(client *fn.Client, runtime, template string) error // pre-client validation should not be required, as the Client does its own // validation. func (c createConfig) Validate(client *fn.Client) (err error) { + // Confirm Name is valid // Note that this is highly constricted, as it must currently adhere to the // naming of a Knative Service, which itself is constrained to a Kubernetes @@ -371,13 +397,16 @@ func (c createConfig) Validate(client *fn.Client) (err error) { // Perhaps additional validation would be of use here in the CLI, but // the client libray itself is ultimately responsible for validating all input // prior to exeuting any requests. - // Client validates both language runtime and template exist, defaulting - // them if not (to 'node' and 'http', respectively). However, if either of - // them are invalid, or the chosen combination does not exist, the error - // message is a rather terse one-liner. This is suitable for libraries, but + // Client validates both language runtime and template exist, with language runtime + // being a mandatory flag while defaulting template if not present to 'http'. + // However, if either of them are invalid, or the chosen combination does not exist, + // the error message is a rather terse one-liner. This is suitable for libraries, but // for a CLI it behooves us to be more verbose, including valid options for // each. So here, we check that the values entered (if any) are both valid // and valid together. + if c.Runtime == "" { + return noRuntimeError(client) + } if c.Runtime != "" && c.Repository == "" && !isValidRuntime(client, c.Runtime) { return newInvalidRuntimeError(client, c.Runtime) diff --git a/vendor/knative.dev/kn-plugin-func/cmd/delete.go b/vendor/knative.dev/kn-plugin-func/cmd/delete.go index df0bd818f4..7de33a55df 100644 --- a/vendor/knative.dev/kn-plugin-func/cmd/delete.go +++ b/vendor/knative.dev/kn-plugin-func/cmd/delete.go @@ -63,8 +63,8 @@ kn func delete -n apps myfunc } cmd.Flags().BoolP("confirm", "c", false, "Prompt to confirm all configuration options (Env: $FUNC_CONFIRM)") - cmd.Flags().StringP("path", "p", cwd(), "Path to the function project that should be undeployed (Env: $FUNC_PATH)") - cmd.Flags().StringP("namespace", "n", "", "Namespace of the function to undeploy. By default, the namespace in func.yaml is used or the actual active namespace if not set in the configuration. (Env: $FUNC_NAMESPACE)") + setNamespaceFlag(cmd) + setPathFlag(cmd) cmd.RunE = func(cmd *cobra.Command, args []string) error { return runDelete(cmd, args, clientFn) diff --git a/vendor/knative.dev/kn-plugin-func/cmd/deploy.go b/vendor/knative.dev/kn-plugin-func/cmd/deploy.go index f272d4f5c3..8ff33687ef 100644 --- a/vendor/knative.dev/kn-plugin-func/cmd/deploy.go +++ b/vendor/knative.dev/kn-plugin-func/cmd/deploy.go @@ -93,10 +93,10 @@ kn func deploy --image quay.io/myuser/myfunc -n myns "You may provide this flag multiple times for setting multiple environment variables. "+ "To unset, specify the environment variable name followed by a \"-\" (e.g., NAME-).") cmd.Flags().StringP("image", "i", "", "Full image name in the form [registry]/[namespace]/[name]:[tag] (optional). This option takes precedence over --registry (Env: $FUNC_IMAGE)") - cmd.Flags().StringP("namespace", "n", "", "Namespace of the function to undeploy. By default, the namespace in func.yaml is used or the actual active namespace if not set in the configuration. (Env: $FUNC_NAMESPACE)") - cmd.Flags().StringP("path", "p", cwd(), "Path to the project directory (Env: $FUNC_PATH)") cmd.Flags().StringP("registry", "r", "", "Registry + namespace part of the image to build, ex 'quay.io/myuser'. The full image name is automatically determined based on the local directory name. If not provided the registry will be taken from func.yaml (Env: $FUNC_REGISTRY)") cmd.Flags().BoolP("build", "b", true, "Build the image before deploying (Env: $FUNC_BUILD)") + setPathFlag(cmd) + setNamespaceFlag(cmd) cmd.RunE = func(cmd *cobra.Command, args []string) error { return runDeploy(cmd, args, clientFn) @@ -158,7 +158,7 @@ func runDeploy(cmd *cobra.Command, _ []string, clientFn deployClientFn) (err err } // All set, let's write changes in the config to the disk - err = function.WriteConfig() + err = function.Write() if err != nil { return } diff --git a/vendor/knative.dev/kn-plugin-func/cmd/emit.go b/vendor/knative.dev/kn-plugin-func/cmd/emit.go index aa88cf29bd..d695ec3600 100644 --- a/vendor/knative.dev/kn-plugin-func/cmd/emit.go +++ b/vendor/knative.dev/kn-plugin-func/cmd/emit.go @@ -80,7 +80,7 @@ kn func emit --sink "http://my.event.broker.com" cmd.Flags().StringP("data", "d", "", "Any arbitrary string to be sent as the CloudEvent data. Ignored if --file is provided (Env: $FUNC_DATA)") cmd.Flags().StringP("file", "f", "", "Path to a local file containing CloudEvent data to be sent (Env: $FUNC_FILE)") cmd.Flags().StringP("content-type", "c", "application/json", "The MIME Content-Type for the CloudEvent data (Env: $FUNC_CONTENT_TYPE)") - cmd.Flags().StringP("path", "p", cwd(), "Path to the project directory. Ignored when --sink is provided (Env: $FUNC_PATH)") + setPathFlag(cmd) cmd.RunE = func(cmd *cobra.Command, args []string) error { return runEmit(cmd, args, clientFn) diff --git a/vendor/knative.dev/kn-plugin-func/cmd/info.go b/vendor/knative.dev/kn-plugin-func/cmd/info.go index 9a0e633bed..781cc36486 100644 --- a/vendor/knative.dev/kn-plugin-func/cmd/info.go +++ b/vendor/knative.dev/kn-plugin-func/cmd/info.go @@ -56,9 +56,9 @@ kn func info --output yaml --path myotherfunc PreRunE: bindEnv("namespace", "output", "path"), } - cmd.Flags().StringP("namespace", "n", "", "Namespace of the function. By default, the namespace in func.yaml is used or the actual active namespace if not set in the configuration. (Env: $FUNC_NAMESPACE)") + setNamespaceFlag(cmd) cmd.Flags().StringP("output", "o", "human", "Output format (human|plain|json|xml|yaml|url) (Env: $FUNC_OUTPUT)") - cmd.Flags().StringP("path", "p", cwd(), "Path to the project directory (Env: $FUNC_PATH)") + setPathFlag(cmd) if err := cmd.RegisterFlagCompletionFunc("output", CompleteOutputFormatList); err != nil { fmt.Println("internal: error while calling RegisterFlagCompletionFunc: ", err) diff --git a/vendor/knative.dev/kn-plugin-func/cmd/list.go b/vendor/knative.dev/kn-plugin-func/cmd/list.go index 57ecf99b8c..e01692137a 100644 --- a/vendor/knative.dev/kn-plugin-func/cmd/list.go +++ b/vendor/knative.dev/kn-plugin-func/cmd/list.go @@ -62,8 +62,8 @@ kn func list --all-namespaces --output json } cmd.Flags().BoolP("all-namespaces", "A", false, "List functions in all namespaces. If set, the --namespace flag is ignored.") - cmd.Flags().StringP("namespace", "n", "", "Namespace to search for functions. By default, the functions of the actual active namespace are listed. (Env: $FUNC_NAMESPACE)") cmd.Flags().StringP("output", "o", "human", "Output format (human|plain|json|xml|yaml) (Env: $FUNC_OUTPUT)") + setNamespaceFlag(cmd) if err := cmd.RegisterFlagCompletionFunc("output", CompleteOutputFormatList); err != nil { fmt.Println("internal: error while calling RegisterFlagCompletionFunc: ", err) diff --git a/vendor/knative.dev/kn-plugin-func/cmd/repository.go b/vendor/knative.dev/kn-plugin-func/cmd/repository.go index 33ce4624d9..6c3da17cf5 100644 --- a/vendor/knative.dev/kn-plugin-func/cmd/repository.go +++ b/vendor/knative.dev/kn-plugin-func/cmd/repository.go @@ -169,7 +169,7 @@ EXAMPLES } cmd.Flags().BoolP("confirm", "c", false, "Prompt to confirm all options interactively (Env: $FUNC_CONFIRM)") - cmd.Flags().StringP("repositories", "r", repositoriesPath(), "Path to language pack repositories (Env: $FUNC_REPOSITORIES)") + cmd.Flags().StringP("repositories", "r", fn.RepositoriesPath(), "Path to language pack repositories (Env: $FUNC_REPOSITORIES)") cmd.RunE = func(cmd *cobra.Command, args []string) error { return runRepository(cmd, args, clientFn) @@ -184,7 +184,7 @@ func NewRepositoryListCmd(clientFn repositoryClientFn) *cobra.Command { PreRunE: bindEnv("repositories"), } - cmd.Flags().StringP("repositories", "r", repositoriesPath(), "Path to language pack repositories (Env: $FUNC_REPOSITORIES)") + cmd.Flags().StringP("repositories", "r", fn.RepositoriesPath(), "Path to language pack repositories (Env: $FUNC_REPOSITORIES)") cmd.RunE = func(_ *cobra.Command, args []string) error { return runRepositoryList(args, clientFn) @@ -201,7 +201,7 @@ func NewRepositoryAddCmd(clientFn repositoryClientFn) *cobra.Command { } cmd.Flags().BoolP("confirm", "c", false, "Prompt to confirm all options interactively (Env: $FUNC_CONFIRM)") - cmd.Flags().StringP("repositories", "r", repositoriesPath(), "Path to language pack repositories (Env: $FUNC_REPOSITORIES)") + cmd.Flags().StringP("repositories", "r", fn.RepositoriesPath(), "Path to language pack repositories (Env: $FUNC_REPOSITORIES)") cmd.RunE = func(_ *cobra.Command, args []string) error { return runRepositoryAdd(args, clientFn) @@ -217,7 +217,7 @@ func NewRepositoryRenameCmd(clientFn repositoryClientFn) *cobra.Command { } cmd.Flags().BoolP("confirm", "c", false, "Prompt to confirm all options interactively (Env: $FUNC_CONFIRM)") - cmd.Flags().StringP("repositories", "r", repositoriesPath(), "Path to language pack repositories (Env: $FUNC_REPOSITORIES)") + cmd.Flags().StringP("repositories", "r", fn.RepositoriesPath(), "Path to language pack repositories (Env: $FUNC_REPOSITORIES)") cmd.RunE = func(_ *cobra.Command, args []string) error { return runRepositoryRename(args, clientFn) @@ -235,7 +235,7 @@ func NewRepositoryRemoveCmd(clientFn repositoryClientFn) *cobra.Command { } cmd.Flags().BoolP("confirm", "c", false, "Prompt to confirm all options interactively (Env: $FUNC_CONFIRM)") - cmd.Flags().StringP("repositories", "r", repositoriesPath(), "Path to language pack repositories (Env: $FUNC_REPOSITORIES)") + cmd.Flags().StringP("repositories", "r", fn.RepositoriesPath(), "Path to language pack repositories (Env: $FUNC_REPOSITORIES)") cmd.RunE = func(_ *cobra.Command, args []string) error { return runRepositoryRemove(args, clientFn) diff --git a/vendor/knative.dev/kn-plugin-func/cmd/root.go b/vendor/knative.dev/kn-plugin-func/cmd/root.go index 639bce16c3..0fe0f969ec 100644 --- a/vendor/knative.dev/kn-plugin-func/cmd/root.go +++ b/vendor/knative.dev/kn-plugin-func/cmd/root.go @@ -153,19 +153,10 @@ func cwd() (cwd string) { return cwd } -// The anme of the repositories directory within config dir (usually ~/.config) -const repositoriesDirName = "repositories" - -// repositoriesPath is the effective path to the optional repositories directory -// used for extensible language packs. -func repositoriesPath() string { - return filepath.Join(fn.ConfigPath(), repositoriesDirName) -} - // bindFunc which conforms to the cobra PreRunE method signature type bindFunc func(*cobra.Command, []string) error -// bindEnv returns a bindFunc that binds env vars to the namd flags. +// bindEnv returns a bindFunc that binds env vars to the named flags. func bindEnv(flags ...string) bindFunc { return func(cmd *cobra.Command, args []string) (err error) { for _, flag := range flags { @@ -299,7 +290,7 @@ func envFromCmd(cmd *cobra.Command) (*util.OrderedMap, []string, error) { return util.NewOrderedMap(), []string{}, nil } -func mergeEnvs(envs fn.Envs, envToUpdate *util.OrderedMap, envToRemove []string) (fn.Envs, error) { +func mergeEnvs(envs []fn.Env, envToUpdate *util.OrderedMap, envToRemove []string) ([]fn.Env, error) { updated := sets.NewString() for i := range envs { @@ -332,8 +323,18 @@ func mergeEnvs(envs fn.Envs, envToUpdate *util.OrderedMap, envToRemove []string) errMsg := fn.ValidateEnvs(envs) if len(errMsg) > 0 { - return fn.Envs{}, fmt.Errorf(strings.Join(errMsg, "\n")) + return []fn.Env{}, fmt.Errorf(strings.Join(errMsg, "\n")) } return envs, nil } + +// setPathFlag ensures common text/wording when the --path flag is used +func setPathFlag(cmd *cobra.Command) { + cmd.Flags().StringP("path", "p", cwd(), "Path to the project directory (Env: $FUNC_PATH)") +} + +// setNamespaceFlag ensures common text/wording when the --namespace flag is used +func setNamespaceFlag(cmd *cobra.Command) { + cmd.Flags().StringP("namespace", "n", "", "The namespace on the cluster. By default, the namespace in func.yaml is used or the currently active namespace if not set in the configuration. (Env: $FUNC_NAMESPACE)") +} diff --git a/vendor/knative.dev/kn-plugin-func/cmd/run.go b/vendor/knative.dev/kn-plugin-func/cmd/run.go index 44839a4289..5455c85bd1 100644 --- a/vendor/knative.dev/kn-plugin-func/cmd/run.go +++ b/vendor/knative.dev/kn-plugin-func/cmd/run.go @@ -50,7 +50,7 @@ kn func run "Environment variable to set in the form NAME=VALUE. "+ "You may provide this flag multiple times for setting multiple environment variables. "+ "To unset, specify the environment variable name followed by a \"-\" (e.g., NAME-).") - cmd.Flags().StringP("path", "p", cwd(), "Path to the project directory (Env: $FUNC_PATH)") + setPathFlag(cmd) cmd.RunE = func(cmd *cobra.Command, args []string) error { return runRun(cmd, args, clientFn) @@ -75,7 +75,7 @@ func runRun(cmd *cobra.Command, args []string, clientFn runClientFn) (err error) return } - err = function.WriteConfig() + err = function.Write() if err != nil { return } diff --git a/vendor/knative.dev/kn-plugin-func/config.go b/vendor/knative.dev/kn-plugin-func/config.go index 11624cfae0..ef56798be9 100644 --- a/vendor/knative.dev/kn-plugin-func/config.go +++ b/vendor/knative.dev/kn-plugin-func/config.go @@ -1,566 +1,5 @@ package function -import ( - "errors" - "fmt" - "io/ioutil" - "os" - "path/filepath" - "regexp" - "strings" - - "gopkg.in/yaml.v2" - "k8s.io/apimachinery/pkg/api/resource" - "knative.dev/kn-plugin-func/utils" -) - -// ConfigFile is the name of the config's serialized form. -const ConfigFile = "func.yaml" - -var ( - regWholeSecret = regexp.MustCompile(`^{{\s*secret:((?:\w|['-]\w)+)\s*}}$`) - regKeyFromSecret = regexp.MustCompile(`^{{\s*secret:((?:\w|['-]\w)+):([-._a-zA-Z0-9]+)\s*}}$`) - regWholeConfigMap = regexp.MustCompile(`^{{\s*configMap:((?:\w|['-]\w)+)\s*}}$`) - regKeyFromConfigMap = regexp.MustCompile(`^{{\s*configMap:((?:\w|['-]\w)+):([-._a-zA-Z0-9]+)\s*}}$`) - regLocalEnv = regexp.MustCompile(`^{{\s*env:(\w+)\s*}}$`) -) - -type Volumes []Volume -type Volume struct { - Secret *string `yaml:"secret,omitempty" jsonschema:"oneof_required=secret"` - ConfigMap *string `yaml:"configMap,omitempty" jsonschema:"oneof_required=configmap"` - Path *string `yaml:"path"` -} - -func (v Volume) String() string { - if v.ConfigMap != nil { - return fmt.Sprintf("ConfigMap \"%s\" mounted at path: \"%s\"", *v.ConfigMap, *v.Path) - } else if v.Secret != nil { - return fmt.Sprintf("Secret \"%s\" mounted at path: \"%s\"", *v.Secret, *v.Path) - } - - return "" -} - -type Envs []Env -type Env struct { - Name *string `yaml:"name,omitempty" jsonschema:"pattern=^[-._a-zA-Z][-._a-zA-Z0-9]*$"` - Value *string `yaml:"value"` -} - -func (e Env) String() string { - if e.Name == nil && e.Value != nil { - match := regWholeSecret.FindStringSubmatch(*e.Value) - if len(match) == 2 { - return fmt.Sprintf("All key=value pairs from Secret \"%s\"", match[1]) - } - match = regWholeConfigMap.FindStringSubmatch(*e.Value) - if len(match) == 2 { - return fmt.Sprintf("All key=value pairs from ConfigMap \"%s\"", match[1]) - } - } else if e.Name != nil && e.Value != nil { - match := regKeyFromSecret.FindStringSubmatch(*e.Value) - if len(match) == 3 { - return fmt.Sprintf("Env \"%s\" with value set from key \"%s\" from Secret \"%s\"", *e.Name, match[2], match[1]) - } - match = regKeyFromConfigMap.FindStringSubmatch(*e.Value) - if len(match) == 3 { - return fmt.Sprintf("Env \"%s\" with value set from key \"%s\" from ConfigMap \"%s\"", *e.Name, match[2], match[1]) - } - match = regLocalEnv.FindStringSubmatch(*e.Value) - if len(match) == 2 { - return fmt.Sprintf("Env \"%s\" with value set from local env variable \"%s\"", *e.Name, match[1]) - } - - return fmt.Sprintf("Env \"%s\" with value \"%s\"", *e.Name, *e.Value) - } - return "" -} - -type Labels []Label -type Label struct { - // Key consist of optional prefix part (ended by '/') and name part - // Prefix part validation pattern: [a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)* - // Name part validation pattern: ([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9] - Key *string `yaml:"key" jsonschema:"pattern=^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\\/)?([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9]$"` - Value *string `yaml:"value,omitempty" jsonschema:"pattern=^(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])?$"` -} - -func (l Label) String() string { - if l.Key != nil && l.Value == nil { - return fmt.Sprintf("Label with key \"%s\"", *l.Key) - } else if l.Key != nil && l.Value != nil { - match := regLocalEnv.FindStringSubmatch(*l.Value) - if len(match) == 2 { - return fmt.Sprintf("Label with key \"%s\" and value set from local env variable \"%s\"", *l.Key, match[1]) - } - return fmt.Sprintf("Label with key \"%s\" and value \"%s\"", *l.Key, *l.Value) - } - return "" -} - -type Options struct { - Scale *ScaleOptions `yaml:"scale,omitempty"` - Resources *ResourcesOptions `yaml:"resources,omitempty"` -} - -type ScaleOptions struct { - Min *int64 `yaml:"min,omitempty" jsonschema_extras:"minimum=0"` - Max *int64 `yaml:"max,omitempty" jsonschema_extras:"minimum=0"` - Metric *string `yaml:"metric,omitempty" jsonschema:"enum=concurrency,enum=rps"` - Target *float64 `yaml:"target,omitempty" jsonschema_extras:"minimum=0.01"` - Utilization *float64 `yaml:"utilization,omitempty" jsonschema:"minimum=1,maximum=100"` -} - -type ResourcesOptions struct { - Requests *ResourcesRequestsOptions `yaml:"requests,omitempty"` - Limits *ResourcesLimitsOptions `yaml:"limits,omitempty"` -} - -type ResourcesLimitsOptions struct { - CPU *string `yaml:"cpu,omitempty" jsonschema:"pattern=^([+-]?[0-9.]+)([eEinumkKMGTP]*[-+]?[0-9]*)$"` - Memory *string `yaml:"memory,omitempty" jsonschema:"pattern=^([+-]?[0-9.]+)([eEinumkKMGTP]*[-+]?[0-9]*)$"` - Concurrency *int64 `yaml:"concurrency,omitempty" jsonschema_extras:"minimum=0"` -} - -type ResourcesRequestsOptions struct { - CPU *string `yaml:"cpu,omitempty" jsonschema:"pattern=^([+-]?[0-9.]+)([eEinumkKMGTP]*[-+]?[0-9]*)$"` - Memory *string `yaml:"memory,omitempty" jsonschema:"pattern=^([+-]?[0-9.]+)([eEinumkKMGTP]*[-+]?[0-9]*)$"` -} - -// Config represents the serialized state of a Function's metadata. -// See the Function struct for attribute documentation. -type Config struct { - Name string `yaml:"name" jsonschema:"pattern=^[a-z0-9]([-a-z0-9]*[a-z0-9])?$"` - Namespace string `yaml:"namespace"` - Runtime string `yaml:"runtime"` - Image string `yaml:"image"` - ImageDigest string `yaml:"imageDigest"` - Builder string `yaml:"builder"` - Builders map[string]string `yaml:"builders"` - Buildpacks []string `yaml:"buildpacks"` - HealthEndpoints HealthEndpoints `yaml:"healthEndpoints"` - Volumes Volumes `yaml:"volumes"` - BuildEnvs Envs `yaml:"buildEnvs"` - Envs Envs `yaml:"envs"` - Annotations map[string]string `yaml:"annotations"` - Options Options `yaml:"options"` - Labels Labels `yaml:"labels"` - // Add new values to the toConfig/fromConfig functions. -} - -// newConfig returns a Config populated from data serialized to disk if it is -// available. Errors are returned if the path is not valid, if there are -// errors accessing an extant config file, or the contents of the file do not -// unmarshall. A missing file at a valid path does not error but returns the -// empty value of Config. -func newConfig(root string) (c Config, err error) { - filename := filepath.Join(root, ConfigFile) - if _, err = os.Stat(filename); err != nil { - // do not consider a missing config file an error. Just return. - if os.IsNotExist(err) { - err = nil - } - return - } - bb, err := ioutil.ReadFile(filename) - if err != nil { - return - } - - errMsg := "" - errMsgHeader := "'func.yaml' config file is not valid:\n" - errMsgReg := regexp.MustCompile("not found in type .*") - - // Let's try to unmarshal the config file, any fields that are found - // in the data that do not have corresponding struct members, or mapping - // keys that are duplicates, will result in an error. - err = yaml.UnmarshalStrict(bb, &c) - if err != nil { - errMsg = err.Error() - - if strings.HasPrefix(errMsg, "yaml: unmarshal errors:") { - errMsg = errMsgReg.ReplaceAllString(errMsg, "is not valid") - errMsg = strings.Replace(errMsg, "yaml: unmarshal errors:\n", errMsgHeader, 1) - } else if strings.HasPrefix(errMsg, "yaml:") { - errMsg = errMsgReg.ReplaceAllString(errMsg, "is not valid") - errMsg = strings.Replace(errMsg, "yaml: ", errMsgHeader+" ", 1) - } - } - - // Let's check that all entries in `volumes`, `buildEnvs`, `envs` and `options` contain all required fields - volumesErrors := validateVolumes(c.Volumes) - buildEnvsErrors := ValidateBuildEnvs((c.BuildEnvs)) - envsErrors := ValidateEnvs(c.Envs) - optionsErrors := validateOptions(c.Options) - labelsErrors := ValidateLabels(c.Labels) - if len(volumesErrors) > 0 || len(buildEnvsErrors) > 0 || len(envsErrors) > 0 || len(optionsErrors) > 0 || len(labelsErrors) > 0 { - // if there aren't any previously reported errors, we need to set the error message header first - if errMsg == "" { - errMsg = errMsgHeader - } else { - // if there are some previously reporeted errors, we need to indent them - errMsg = errMsg + "\n" - } - - // lets make the error message a little bit nice -> indent each error message - for i := range volumesErrors { - volumesErrors[i] = " " + volumesErrors[i] - } - for i := range buildEnvsErrors { - buildEnvsErrors[i] = " " + buildEnvsErrors[i] - } - for i := range envsErrors { - envsErrors[i] = " " + envsErrors[i] - } - for i := range optionsErrors { - optionsErrors[i] = " " + optionsErrors[i] - } - for i := range labelsErrors { - labelsErrors[i] = " " + labelsErrors[i] - } - errMsg = errMsg + strings.Join(volumesErrors, "\n") - // we have errors from both volumes and buildEnvs sections -> let's make sure they are both indented - if len(buildEnvsErrors) > 0 && len(volumesErrors) > 0 { - errMsg = errMsg + "\n" - } - errMsg = errMsg + strings.Join(buildEnvsErrors, "\n") - // we have errors from volumes, buildEnvs and envs sections -> let's make sure they are indented - if len(envsErrors) > 0 && (len(volumesErrors) > 0 || len(buildEnvsErrors) > 0) { - errMsg = errMsg + "\n" - } - errMsg = errMsg + strings.Join(envsErrors, "\n") - // lets indent options related errors if there are already some set - if len(optionsErrors) > 0 && (len(volumesErrors) > 0 || len(buildEnvsErrors) > 0 || len(envsErrors) > 0) { - errMsg = errMsg + "\n" - } - errMsg = errMsg + strings.Join(optionsErrors, "\n") - // now also handle labels related errors - if len(labelsErrors) > 0 && (len(optionsErrors) > 0 || len(volumesErrors) > 0 || len(buildEnvsErrors) > 0 || len(envsErrors) > 0) { - errMsg = errMsg + "\n" - } - errMsg = errMsg + strings.Join(labelsErrors, "\n") - } - - if errMsg != "" { - err = errors.New(errMsg) - } - - return -} - -// fromConfig returns a Function populated from config. -// Note that config does not include ancillary fields not serialized, such as Root. -func fromConfig(c Config) (f Function) { - return Function{ - Name: c.Name, - Namespace: c.Namespace, - Runtime: c.Runtime, - Image: c.Image, - ImageDigest: c.ImageDigest, - Builder: c.Builder, - Builders: c.Builders, - Buildpacks: c.Buildpacks, - HealthEndpoints: c.HealthEndpoints, - Volumes: c.Volumes, - BuildEnvs: c.BuildEnvs, - Envs: c.Envs, - Annotations: c.Annotations, - Options: c.Options, - Labels: c.Labels, - } -} - -// toConfig serializes a Function to a config object. -func toConfig(f Function) Config { - return Config{ - Name: f.Name, - Namespace: f.Namespace, - Runtime: f.Runtime, - Image: f.Image, - ImageDigest: f.ImageDigest, - Builder: f.Builder, - Builders: f.Builders, - Buildpacks: f.Buildpacks, - HealthEndpoints: f.HealthEndpoints, - Volumes: f.Volumes, - BuildEnvs: f.BuildEnvs, - Envs: f.Envs, - Annotations: f.Annotations, - Options: f.Options, - Labels: f.Labels, - } -} - -// writeConfig for the given Function out to disk at root. -func writeConfig(f Function) (err error) { - path := filepath.Join(f.Root, ConfigFile) - c := toConfig(f) - var bb []byte - if bb, err = yaml.Marshal(&c); err != nil { - return - } - return ioutil.WriteFile(path, bb, 0644) -} - -// validateVolumes checks that input Volumes are correct and contain all necessary fields. -// Returns array of error messages, empty if no errors are found -// -// Allowed settings: -// - secret: example-secret # mount Secret as Volume -// path: /etc/secret-volume -// - configMap: example-configMap # mount ConfigMap as Volume -// path: /etc/configMap-volume -func validateVolumes(volumes Volumes) (errors []string) { - - for i, vol := range volumes { - if vol.Secret != nil && vol.ConfigMap != nil { - errors = append(errors, fmt.Sprintf("volume entry #%d is not properly set, both secret '%s' and configMap '%s' can not be set at the same time", - i, *vol.Secret, *vol.ConfigMap)) - } else if vol.Path == nil && vol.Secret == nil && vol.ConfigMap == nil { - errors = append(errors, fmt.Sprintf("volume entry #%d is not properly set", i)) - } else if vol.Path == nil { - if vol.Secret != nil { - errors = append(errors, fmt.Sprintf("volume entry #%d is missing path field, only secret '%s' is set", i, *vol.Secret)) - } else if vol.ConfigMap != nil { - errors = append(errors, fmt.Sprintf("volume entry #%d is missing path field, only configMap '%s' is set", i, *vol.ConfigMap)) - } - } else if vol.Path != nil && vol.Secret == nil && vol.ConfigMap == nil { - errors = append(errors, fmt.Sprintf("volume entry #%d is missing secret or configMap field, only path '%s' is set", i, *vol.Path)) - } - } - - return -} - -// ValidateBuildEnvs checks that input BuildEnvs are correct and contain all necessary fields. -// Returns array of error messages, empty if no errors are found -// -// Allowed settings: -// - name: EXAMPLE1 # ENV directly from a value -// value: value1 -// - name: EXAMPLE2 # ENV from the local ENV var -// value: {{ env:MY_ENV }} -func ValidateBuildEnvs(envs Envs) (errors []string) { - for i, env := range envs { - if env.Name == nil && env.Value == nil { - errors = append(errors, fmt.Sprintf("env entry #%d is not properly set", i)) - } else if env.Value == nil { - errors = append(errors, fmt.Sprintf("env entry #%d is missing value field, only name '%s' is set", i, *env.Name)) - } else { - - if err := utils.ValidateEnvVarName(*env.Name); err != nil { - errors = append(errors, fmt.Sprintf("env entry #%d has invalid name set: %q; %s", i, *env.Name, err.Error())) - } - - if strings.HasPrefix(*env.Value, "{{") { - // ENV from the local ENV var; {{ env:MY_ENV }} - if !regLocalEnv.MatchString(*env.Value) { - errors = append(errors, - fmt.Sprintf( - "env entry #%d with name '%s' has invalid value field set, it has '%s', but allowed is only '{{ env:MY_ENV }}'", - i, *env.Name, *env.Value)) - } - } - } - } - - return -} - -// ValidateEnvs checks that input Envs are correct and contain all necessary fields. -// Returns array of error messages, empty if no errors are found -// -// Allowed settings: -// - name: EXAMPLE1 # ENV directly from a value -// value: value1 -// - name: EXAMPLE2 # ENV from the local ENV var -// value: {{ env:MY_ENV }} -// - name: EXAMPLE3 -// value: {{ secret:secretName:key }} # ENV from a key in secret -// - value: {{ secret:secretName }} # all key-pair values from secret are set as ENV -// - name: EXAMPLE4 -// value: {{ configMap:configMapName:key }} # ENV from a key in configMap -// - value: {{ configMap:configMapName }} # all key-pair values from configMap are set as ENV -func ValidateEnvs(envs Envs) (errors []string) { - for i, env := range envs { - if env.Name == nil && env.Value == nil { - errors = append(errors, fmt.Sprintf("env entry #%d is not properly set", i)) - } else if env.Value == nil { - errors = append(errors, fmt.Sprintf("env entry #%d is missing value field, only name '%s' is set", i, *env.Name)) - } else if env.Name == nil { - // all key-pair values from secret are set as ENV; {{ secret:secretName }} or {{ configMap:configMapName }} - if !regWholeSecret.MatchString(*env.Value) && !regWholeConfigMap.MatchString(*env.Value) { - errors = append(errors, fmt.Sprintf("env entry #%d has invalid value field set, it has '%s', but allowed is only '{{ secret:secretName }}' or '{{ configMap:configMapName }}'", - i, *env.Value)) - } - } else { - - if err := utils.ValidateEnvVarName(*env.Name); err != nil { - errors = append(errors, fmt.Sprintf("env entry #%d has invalid name set: %q; %s", i, *env.Name, err.Error())) - } - - if strings.HasPrefix(*env.Value, "{{") { - // ENV from the local ENV var; {{ env:MY_ENV }} - // or - // ENV from a key in secret/configMap; {{ secret:secretName:key }} or {{ configMap:configMapName:key }} - if !regLocalEnv.MatchString(*env.Value) && !regKeyFromSecret.MatchString(*env.Value) && !regKeyFromConfigMap.MatchString(*env.Value) { - errors = append(errors, - fmt.Sprintf( - "env entry #%d with name '%s' has invalid value field set, it has '%s', but allowed is only '{{ env:MY_ENV }}', '{{ secret:secretName:key }}' or '{{ configMap:configMapName:key }}'", - i, *env.Name, *env.Value)) - } - } - } - } - - return -} - -// ValidateLabels checks that input labels are correct and contain all necessary fields. -// Returns array of error messages, empty if no errors are found -// -// Allowed settings: -// - key: EXAMPLE1 # label directly from a value -// value: value1 -// - key: EXAMPLE2 # label from the local ENV var -// value: {{ env:MY_ENV }} -func ValidateLabels(labels Labels) (errors []string) { - for i, label := range labels { - if label.Key == nil && label.Value == nil { - errors = append(errors, fmt.Sprintf("label entry #%d is not properly set", i)) - } else if label.Key == nil && label.Value != nil { - errors = append(errors, fmt.Sprintf("label entry #%d is missing key field, only value '%s' is set", i, *label.Value)) - } else { - if err := utils.ValidateLabelKey(*label.Key); err != nil { - errors = append(errors, fmt.Sprintf("label entry #%d has invalid key set: %q; %s", i, *label.Key, err.Error())) - } - if label.Value != nil { - if err := utils.ValidateLabelValue(*label.Value); err != nil { - errors = append(errors, fmt.Sprintf("label entry #%d has invalid value set: %q; %s", i, *label.Value, err.Error())) - } - - if strings.HasPrefix(*label.Value, "{{") { - // ENV from the local ENV var; {{ env:MY_ENV }} - if !regLocalEnv.MatchString(*label.Value) { - errors = append(errors, - fmt.Sprintf( - "label entry #%d with key '%s' has invalid value field set, it has '%s', but allowed is only '{{ env:MY_ENV }}'", - i, *label.Key, *label.Value)) - } else { - match := regLocalEnv.FindStringSubmatch(*label.Value) - value := os.Getenv(match[1]) - if err := utils.ValidateLabelValue(value); err != nil { - errors = append(errors, fmt.Sprintf("label entry #%d with key '%s' has invalid value when the environment is evaluated: '%s': %s", i, *label.Key, value, err.Error())) - } - } - } - } - } - } - - return -} - -// validateOptions checks that input Options are correctly set. -// Returns array of error messages, empty if no errors are found -func validateOptions(options Options) (errors []string) { - - // options.scale - if options.Scale != nil { - if options.Scale.Min != nil { - if *options.Scale.Min < 0 { - errors = append(errors, fmt.Sprintf("options field \"scale.min\" has invalid value set: %d, the value must be greater than \"0\"", - *options.Scale.Min)) - } - } - - if options.Scale.Max != nil { - if *options.Scale.Max < 0 { - errors = append(errors, fmt.Sprintf("options field \"scale.max\" has invalid value set: %d, the value must be greater than \"0\"", - *options.Scale.Max)) - } - } - - if options.Scale.Min != nil && options.Scale.Max != nil { - if *options.Scale.Max < *options.Scale.Min { - errors = append(errors, "options field \"scale.max\" value must be greater or equal to \"scale.min\"") - } - } - - if options.Scale.Metric != nil { - if *options.Scale.Metric != "concurrency" && *options.Scale.Metric != "rps" { - errors = append(errors, fmt.Sprintf("options field \"scale.metric\" has invalid value set: %s, allowed is only \"concurrency\" or \"rps\"", - *options.Scale.Metric)) - } - } - - if options.Scale.Target != nil { - if *options.Scale.Target < 0.01 { - errors = append(errors, fmt.Sprintf("options field \"scale.target\" has value set to \"%f\", but it must not be less than 0.01", - *options.Scale.Target)) - } - } - - if options.Scale.Utilization != nil { - if *options.Scale.Utilization < 1 || *options.Scale.Utilization > 100 { - errors = append(errors, - fmt.Sprintf("options field \"scale.utilization\" has value set to \"%f\", but it must not be less than 1 or greater than 100", - *options.Scale.Utilization)) - } - } - } - - // options.resource - if options.Resources != nil { - - // options.resource.requests - if options.Resources.Requests != nil { - - if options.Resources.Requests.CPU != nil { - _, err := resource.ParseQuantity(*options.Resources.Requests.CPU) - if err != nil { - errors = append(errors, fmt.Sprintf("options field \"resources.requests.cpu\" has invalid value set: \"%s\"; \"%s\"", - *options.Resources.Requests.CPU, err.Error())) - } - } - - if options.Resources.Requests.Memory != nil { - _, err := resource.ParseQuantity(*options.Resources.Requests.Memory) - if err != nil { - errors = append(errors, fmt.Sprintf("options field \"resources.requests.memory\" has invalid value set: \"%s\"; \"%s\"", - *options.Resources.Requests.Memory, err.Error())) - } - } - } - - // options.resource.limits - if options.Resources.Limits != nil { - - if options.Resources.Limits.CPU != nil { - _, err := resource.ParseQuantity(*options.Resources.Limits.CPU) - if err != nil { - errors = append(errors, fmt.Sprintf("options field \"resources.limits.cpu\" has invalid value set: \"%s\"; \"%s\"", - *options.Resources.Limits.CPU, err.Error())) - } - } - - if options.Resources.Limits.Memory != nil { - _, err := resource.ParseQuantity(*options.Resources.Limits.Memory) - if err != nil { - errors = append(errors, fmt.Sprintf("options field \"resources.limits.memory\" has invalid value set: \"%s\"; \"%s\"", - *options.Resources.Limits.Memory, err.Error())) - } - } - - if options.Resources.Limits.Concurrency != nil { - if *options.Resources.Limits.Concurrency < 0 { - errors = append(errors, fmt.Sprintf("options field \"resources.limits.concurrency\" has value set to \"%d\", but it must not be less than 0", - *options.Resources.Limits.Concurrency)) - } - } - } - } - - return -} +// Config is local and global configuration which is not "part of the Function" +// and is thus not likely to be tracked in source control. +type Config struct{} diff --git a/vendor/knative.dev/kn-plugin-func/docker/docker_client.go b/vendor/knative.dev/kn-plugin-func/docker/docker_client.go index 4f3e88d558..78fe46b57b 100644 --- a/vendor/knative.dev/kn-plugin-func/docker/docker_client.go +++ b/vendor/knative.dev/kn-plugin-func/docker/docker_client.go @@ -1,19 +1,54 @@ package docker import ( + "context" + "errors" + "fmt" + "io" "net/http" "net/url" "os" + "os/exec" + "path/filepath" + "runtime" + "syscall" + "time" "knative.dev/kn-plugin-func/ssh" "github.com/docker/docker/client" ) -func NewDockerClient() (dockerClient client.CommonAPIClient, dockerHost string, err error) { +func NewClient(defaultHost string) (dockerClient client.CommonAPIClient, dockerHost string, err error) { + var _url *url.URL + dockerHost = os.Getenv("DOCKER_HOST") - _url, err := url.Parse(dockerHost) + + if dockerHost == "" && runtime.GOOS == "linux" && podmanPresent() { + _url, err = url.Parse(defaultHost) + if err != nil { + return + } + _, err = os.Stat(_url.Path) + switch { + case err != nil && !os.IsNotExist(err): + return + case os.IsNotExist(err): + dockerClient, dockerHost, err = newClientWithPodmanService() + return + } + } + + _url, err = url.Parse(dockerHost) isSSH := err == nil && _url.Scheme == "ssh" + isTCP := err == nil && _url.Scheme == "tcp" + + if isTCP { + // With TCP, it's difficult to determine how to expose the daemon socket to lifecycle containers, + // so we are defaulting to standard docker location by returning empty string. + // This should work well most of the time. + dockerHost = "" + } if !isSSH { dockerClient, err = client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation()) @@ -27,7 +62,7 @@ func NewDockerClient() (dockerClient client.CommonAPIClient, dockerHost string, PassPhraseCallback: ssh.NewPassPhraseCbk(), HostKeyCallback: ssh.NewHostKeyCbk(), } - dialContext, dockerHost, err := ssh.NewDialContext(_url, credentialsConfig) + contextDialer, dockerHost, err := ssh.NewDialContext(_url, credentialsConfig) if err != nil { return } @@ -36,7 +71,7 @@ func NewDockerClient() (dockerClient client.CommonAPIClient, dockerHost string, // No tls // No proxy Transport: &http.Transport{ - DialContext: dialContext, + DialContext: contextDialer.DialContext, }, } @@ -45,5 +80,75 @@ func NewDockerClient() (dockerClient client.CommonAPIClient, dockerHost string, client.WithHTTPClient(httpClient), client.WithHost("http://placeholder/")) + if closer, ok := contextDialer.(io.Closer); ok { + dockerClient = clientWithAdditionalCleanup{ + pimpl: dockerClient, + cleanUp: func() { + closer.Close() + }, + } + } + return dockerClient, dockerHost, err } + +func podmanPresent() bool { + _, err := exec.LookPath("podman") + return err == nil +} + +// creates a docker client that has its own podman service associated with it +// the service is shutdown when Close() is called on the client +func newClientWithPodmanService() (dockerClient client.CommonAPIClient, dockerHost string, err error) { + tmpDir, err := os.MkdirTemp("", "func-podman-") + if err != nil { + return + } + + podmanSocket := filepath.Join(tmpDir, "podman.sock") + dockerHost = fmt.Sprintf("unix://%s", podmanSocket) + + cmd := exec.Command("podman", "system", "service", dockerHost, "--time=0") + err = cmd.Start() + if err != nil { + return + } + + dockerClient, err = client.NewClientWithOpts(client.FromEnv, client.WithHost(dockerHost), client.WithAPIVersionNegotiation()) + stopPodmanService := func() { + _ = cmd.Process.Signal(syscall.SIGTERM) + _ = os.RemoveAll(tmpDir) + } + dockerClient = clientWithAdditionalCleanup{ + pimpl: dockerClient, + cleanUp: stopPodmanService, + } + + podmanServiceRunning := false + // give a time to podman to start + for i := 0; i < 40; i++ { + if _, e := dockerClient.Ping(context.Background()); e == nil { + podmanServiceRunning = true + break + } + time.Sleep(time.Millisecond * 250) + } + + if !podmanServiceRunning { + stopPodmanService() + err = errors.New("failed to start podman service") + } + + return +} + +type clientWithAdditionalCleanup struct { + cleanUp func() + pimpl client.CommonAPIClient +} + +// Close function need to stop associated podman service +func (w clientWithAdditionalCleanup) Close() error { + defer w.cleanUp() + return w.pimpl.Close() +} diff --git a/vendor/knative.dev/kn-plugin-func/docker/docker_client_generated.go b/vendor/knative.dev/kn-plugin-func/docker/docker_client_generated.go new file mode 100644 index 0000000000..eedd3904dc --- /dev/null +++ b/vendor/knative.dev/kn-plugin-func/docker/docker_client_generated.go @@ -0,0 +1,488 @@ +package docker + +import ( + "context" + "io" + "net" + "net/http" + "time" + + "github.com/docker/docker/api/types" + "github.com/docker/docker/api/types/container" + "github.com/docker/docker/api/types/events" + "github.com/docker/docker/api/types/filters" + "github.com/docker/docker/api/types/image" + "github.com/docker/docker/api/types/network" + "github.com/docker/docker/api/types/registry" + "github.com/docker/docker/api/types/swarm" + "github.com/docker/docker/api/types/volume" + v1 "github.com/opencontainers/image-spec/specs-go/v1" +) + +// + +func (w clientWithAdditionalCleanup) BuildCachePrune(arg0 context.Context, arg1 types.BuildCachePruneOptions) (*types.BuildCachePruneReport, error) { + return w.pimpl.BuildCachePrune(arg0, arg1) +} + +func (w clientWithAdditionalCleanup) BuildCancel(arg0 context.Context, arg1 string) error { + return w.pimpl.BuildCancel(arg0, arg1) +} + +func (w clientWithAdditionalCleanup) ClientVersion() string { + return w.pimpl.ClientVersion() +} + +func (w clientWithAdditionalCleanup) ConfigCreate(arg0 context.Context, arg1 swarm.ConfigSpec) (types.ConfigCreateResponse, error) { + return w.pimpl.ConfigCreate(arg0, arg1) +} + +func (w clientWithAdditionalCleanup) ConfigInspectWithRaw(arg0 context.Context, arg1 string) (swarm.Config, []uint8, error) { + return w.pimpl.ConfigInspectWithRaw(arg0, arg1) +} + +func (w clientWithAdditionalCleanup) ConfigList(arg0 context.Context, arg1 types.ConfigListOptions) ([]swarm.Config, error) { + return w.pimpl.ConfigList(arg0, arg1) +} + +func (w clientWithAdditionalCleanup) ConfigRemove(arg0 context.Context, arg1 string) error { + return w.pimpl.ConfigRemove(arg0, arg1) +} + +func (w clientWithAdditionalCleanup) ConfigUpdate(arg0 context.Context, arg1 string, arg2 swarm.Version, arg3 swarm.ConfigSpec) error { + return w.pimpl.ConfigUpdate(arg0, arg1, arg2, arg3) +} + +func (w clientWithAdditionalCleanup) ContainerAttach(arg0 context.Context, arg1 string, arg2 types.ContainerAttachOptions) (types.HijackedResponse, error) { + return w.pimpl.ContainerAttach(arg0, arg1, arg2) +} + +func (w clientWithAdditionalCleanup) ContainerCommit(arg0 context.Context, arg1 string, arg2 types.ContainerCommitOptions) (types.IDResponse, error) { + return w.pimpl.ContainerCommit(arg0, arg1, arg2) +} + +func (w clientWithAdditionalCleanup) ContainerCreate(arg0 context.Context, arg1 *container.Config, arg2 *container.HostConfig, arg3 *network.NetworkingConfig, arg4 *v1.Platform, arg5 string) (container.ContainerCreateCreatedBody, error) { + return w.pimpl.ContainerCreate(arg0, arg1, arg2, arg3, arg4, arg5) +} + +func (w clientWithAdditionalCleanup) ContainerDiff(arg0 context.Context, arg1 string) ([]container.ContainerChangeResponseItem, error) { + return w.pimpl.ContainerDiff(arg0, arg1) +} + +func (w clientWithAdditionalCleanup) ContainerExecAttach(arg0 context.Context, arg1 string, arg2 types.ExecStartCheck) (types.HijackedResponse, error) { + return w.pimpl.ContainerExecAttach(arg0, arg1, arg2) +} + +func (w clientWithAdditionalCleanup) ContainerExecCreate(arg0 context.Context, arg1 string, arg2 types.ExecConfig) (types.IDResponse, error) { + return w.pimpl.ContainerExecCreate(arg0, arg1, arg2) +} + +func (w clientWithAdditionalCleanup) ContainerExecInspect(arg0 context.Context, arg1 string) (types.ContainerExecInspect, error) { + return w.pimpl.ContainerExecInspect(arg0, arg1) +} + +func (w clientWithAdditionalCleanup) ContainerExecResize(arg0 context.Context, arg1 string, arg2 types.ResizeOptions) error { + return w.pimpl.ContainerExecResize(arg0, arg1, arg2) +} + +func (w clientWithAdditionalCleanup) ContainerExecStart(arg0 context.Context, arg1 string, arg2 types.ExecStartCheck) error { + return w.pimpl.ContainerExecStart(arg0, arg1, arg2) +} + +func (w clientWithAdditionalCleanup) ContainerExport(arg0 context.Context, arg1 string) (io.ReadCloser, error) { + return w.pimpl.ContainerExport(arg0, arg1) +} + +func (w clientWithAdditionalCleanup) ContainerInspect(arg0 context.Context, arg1 string) (types.ContainerJSON, error) { + return w.pimpl.ContainerInspect(arg0, arg1) +} + +func (w clientWithAdditionalCleanup) ContainerInspectWithRaw(arg0 context.Context, arg1 string, arg2 bool) (types.ContainerJSON, []uint8, error) { + return w.pimpl.ContainerInspectWithRaw(arg0, arg1, arg2) +} + +func (w clientWithAdditionalCleanup) ContainerKill(arg0 context.Context, arg1 string, arg2 string) error { + return w.pimpl.ContainerKill(arg0, arg1, arg2) +} + +func (w clientWithAdditionalCleanup) ContainerList(arg0 context.Context, arg1 types.ContainerListOptions) ([]types.Container, error) { + return w.pimpl.ContainerList(arg0, arg1) +} + +func (w clientWithAdditionalCleanup) ContainerLogs(arg0 context.Context, arg1 string, arg2 types.ContainerLogsOptions) (io.ReadCloser, error) { + return w.pimpl.ContainerLogs(arg0, arg1, arg2) +} + +func (w clientWithAdditionalCleanup) ContainerPause(arg0 context.Context, arg1 string) error { + return w.pimpl.ContainerPause(arg0, arg1) +} + +func (w clientWithAdditionalCleanup) ContainerRemove(arg0 context.Context, arg1 string, arg2 types.ContainerRemoveOptions) error { + return w.pimpl.ContainerRemove(arg0, arg1, arg2) +} + +func (w clientWithAdditionalCleanup) ContainerRename(arg0 context.Context, arg1 string, arg2 string) error { + return w.pimpl.ContainerRename(arg0, arg1, arg2) +} + +func (w clientWithAdditionalCleanup) ContainerResize(arg0 context.Context, arg1 string, arg2 types.ResizeOptions) error { + return w.pimpl.ContainerResize(arg0, arg1, arg2) +} + +func (w clientWithAdditionalCleanup) ContainerRestart(arg0 context.Context, arg1 string, arg2 *time.Duration) error { + return w.pimpl.ContainerRestart(arg0, arg1, arg2) +} + +func (w clientWithAdditionalCleanup) ContainerStart(arg0 context.Context, arg1 string, arg2 types.ContainerStartOptions) error { + return w.pimpl.ContainerStart(arg0, arg1, arg2) +} + +func (w clientWithAdditionalCleanup) ContainerStatPath(arg0 context.Context, arg1 string, arg2 string) (types.ContainerPathStat, error) { + return w.pimpl.ContainerStatPath(arg0, arg1, arg2) +} + +func (w clientWithAdditionalCleanup) ContainerStats(arg0 context.Context, arg1 string, arg2 bool) (types.ContainerStats, error) { + return w.pimpl.ContainerStats(arg0, arg1, arg2) +} + +func (w clientWithAdditionalCleanup) ContainerStatsOneShot(arg0 context.Context, arg1 string) (types.ContainerStats, error) { + return w.pimpl.ContainerStatsOneShot(arg0, arg1) +} + +func (w clientWithAdditionalCleanup) ContainerStop(arg0 context.Context, arg1 string, arg2 *time.Duration) error { + return w.pimpl.ContainerStop(arg0, arg1, arg2) +} + +func (w clientWithAdditionalCleanup) ContainerTop(arg0 context.Context, arg1 string, arg2 []string) (container.ContainerTopOKBody, error) { + return w.pimpl.ContainerTop(arg0, arg1, arg2) +} + +func (w clientWithAdditionalCleanup) ContainerUnpause(arg0 context.Context, arg1 string) error { + return w.pimpl.ContainerUnpause(arg0, arg1) +} + +func (w clientWithAdditionalCleanup) ContainerUpdate(arg0 context.Context, arg1 string, arg2 container.UpdateConfig) (container.ContainerUpdateOKBody, error) { + return w.pimpl.ContainerUpdate(arg0, arg1, arg2) +} + +func (w clientWithAdditionalCleanup) ContainerWait(arg0 context.Context, arg1 string, arg2 container.WaitCondition) (<-chan container.ContainerWaitOKBody, <-chan error) { + return w.pimpl.ContainerWait(arg0, arg1, arg2) +} + +func (w clientWithAdditionalCleanup) ContainersPrune(arg0 context.Context, arg1 filters.Args) (types.ContainersPruneReport, error) { + return w.pimpl.ContainersPrune(arg0, arg1) +} + +func (w clientWithAdditionalCleanup) CopyFromContainer(arg0 context.Context, arg1 string, arg2 string) (io.ReadCloser, types.ContainerPathStat, error) { + return w.pimpl.CopyFromContainer(arg0, arg1, arg2) +} + +func (w clientWithAdditionalCleanup) CopyToContainer(arg0 context.Context, arg1 string, arg2 string, arg3 io.Reader, arg4 types.CopyToContainerOptions) error { + return w.pimpl.CopyToContainer(arg0, arg1, arg2, arg3, arg4) +} + +func (w clientWithAdditionalCleanup) DaemonHost() string { + return w.pimpl.DaemonHost() +} + +func (w clientWithAdditionalCleanup) DialHijack(arg0 context.Context, arg1 string, arg2 string, arg3 map[string][]string) (net.Conn, error) { + return w.pimpl.DialHijack(arg0, arg1, arg2, arg3) +} + +func (w clientWithAdditionalCleanup) Dialer() func(context.Context) (net.Conn, error) { + return w.pimpl.Dialer() +} + +func (w clientWithAdditionalCleanup) DiskUsage(arg0 context.Context) (types.DiskUsage, error) { + return w.pimpl.DiskUsage(arg0) +} + +func (w clientWithAdditionalCleanup) DistributionInspect(arg0 context.Context, arg1 string, arg2 string) (registry.DistributionInspect, error) { + return w.pimpl.DistributionInspect(arg0, arg1, arg2) +} + +func (w clientWithAdditionalCleanup) Events(arg0 context.Context, arg1 types.EventsOptions) (<-chan events.Message, <-chan error) { + return w.pimpl.Events(arg0, arg1) +} + +func (w clientWithAdditionalCleanup) HTTPClient() *http.Client { + return w.pimpl.HTTPClient() +} + +func (w clientWithAdditionalCleanup) ImageBuild(arg0 context.Context, arg1 io.Reader, arg2 types.ImageBuildOptions) (types.ImageBuildResponse, error) { + return w.pimpl.ImageBuild(arg0, arg1, arg2) +} + +func (w clientWithAdditionalCleanup) ImageCreate(arg0 context.Context, arg1 string, arg2 types.ImageCreateOptions) (io.ReadCloser, error) { + return w.pimpl.ImageCreate(arg0, arg1, arg2) +} + +func (w clientWithAdditionalCleanup) ImageHistory(arg0 context.Context, arg1 string) ([]image.HistoryResponseItem, error) { + return w.pimpl.ImageHistory(arg0, arg1) +} + +func (w clientWithAdditionalCleanup) ImageImport(arg0 context.Context, arg1 types.ImageImportSource, arg2 string, arg3 types.ImageImportOptions) (io.ReadCloser, error) { + return w.pimpl.ImageImport(arg0, arg1, arg2, arg3) +} + +func (w clientWithAdditionalCleanup) ImageInspectWithRaw(arg0 context.Context, arg1 string) (types.ImageInspect, []uint8, error) { + return w.pimpl.ImageInspectWithRaw(arg0, arg1) +} + +func (w clientWithAdditionalCleanup) ImageList(arg0 context.Context, arg1 types.ImageListOptions) ([]types.ImageSummary, error) { + return w.pimpl.ImageList(arg0, arg1) +} + +func (w clientWithAdditionalCleanup) ImageLoad(arg0 context.Context, arg1 io.Reader, arg2 bool) (types.ImageLoadResponse, error) { + return w.pimpl.ImageLoad(arg0, arg1, arg2) +} + +func (w clientWithAdditionalCleanup) ImagePull(arg0 context.Context, arg1 string, arg2 types.ImagePullOptions) (io.ReadCloser, error) { + return w.pimpl.ImagePull(arg0, arg1, arg2) +} + +func (w clientWithAdditionalCleanup) ImagePush(arg0 context.Context, arg1 string, arg2 types.ImagePushOptions) (io.ReadCloser, error) { + return w.pimpl.ImagePush(arg0, arg1, arg2) +} + +func (w clientWithAdditionalCleanup) ImageRemove(arg0 context.Context, arg1 string, arg2 types.ImageRemoveOptions) ([]types.ImageDeleteResponseItem, error) { + return w.pimpl.ImageRemove(arg0, arg1, arg2) +} + +func (w clientWithAdditionalCleanup) ImageSave(arg0 context.Context, arg1 []string) (io.ReadCloser, error) { + return w.pimpl.ImageSave(arg0, arg1) +} + +func (w clientWithAdditionalCleanup) ImageSearch(arg0 context.Context, arg1 string, arg2 types.ImageSearchOptions) ([]registry.SearchResult, error) { + return w.pimpl.ImageSearch(arg0, arg1, arg2) +} + +func (w clientWithAdditionalCleanup) ImageTag(arg0 context.Context, arg1 string, arg2 string) error { + return w.pimpl.ImageTag(arg0, arg1, arg2) +} + +func (w clientWithAdditionalCleanup) ImagesPrune(arg0 context.Context, arg1 filters.Args) (types.ImagesPruneReport, error) { + return w.pimpl.ImagesPrune(arg0, arg1) +} + +func (w clientWithAdditionalCleanup) Info(arg0 context.Context) (types.Info, error) { + return w.pimpl.Info(arg0) +} + +func (w clientWithAdditionalCleanup) NegotiateAPIVersion(arg0 context.Context) { + w.pimpl.NegotiateAPIVersion(arg0) +} + +func (w clientWithAdditionalCleanup) NegotiateAPIVersionPing(arg0 types.Ping) { + w.pimpl.NegotiateAPIVersionPing(arg0) +} + +func (w clientWithAdditionalCleanup) NetworkConnect(arg0 context.Context, arg1 string, arg2 string, arg3 *network.EndpointSettings) error { + return w.pimpl.NetworkConnect(arg0, arg1, arg2, arg3) +} + +func (w clientWithAdditionalCleanup) NetworkCreate(arg0 context.Context, arg1 string, arg2 types.NetworkCreate) (types.NetworkCreateResponse, error) { + return w.pimpl.NetworkCreate(arg0, arg1, arg2) +} + +func (w clientWithAdditionalCleanup) NetworkDisconnect(arg0 context.Context, arg1 string, arg2 string, arg3 bool) error { + return w.pimpl.NetworkDisconnect(arg0, arg1, arg2, arg3) +} + +func (w clientWithAdditionalCleanup) NetworkInspect(arg0 context.Context, arg1 string, arg2 types.NetworkInspectOptions) (types.NetworkResource, error) { + return w.pimpl.NetworkInspect(arg0, arg1, arg2) +} + +func (w clientWithAdditionalCleanup) NetworkInspectWithRaw(arg0 context.Context, arg1 string, arg2 types.NetworkInspectOptions) (types.NetworkResource, []uint8, error) { + return w.pimpl.NetworkInspectWithRaw(arg0, arg1, arg2) +} + +func (w clientWithAdditionalCleanup) NetworkList(arg0 context.Context, arg1 types.NetworkListOptions) ([]types.NetworkResource, error) { + return w.pimpl.NetworkList(arg0, arg1) +} + +func (w clientWithAdditionalCleanup) NetworkRemove(arg0 context.Context, arg1 string) error { + return w.pimpl.NetworkRemove(arg0, arg1) +} + +func (w clientWithAdditionalCleanup) NetworksPrune(arg0 context.Context, arg1 filters.Args) (types.NetworksPruneReport, error) { + return w.pimpl.NetworksPrune(arg0, arg1) +} + +func (w clientWithAdditionalCleanup) NodeInspectWithRaw(arg0 context.Context, arg1 string) (swarm.Node, []uint8, error) { + return w.pimpl.NodeInspectWithRaw(arg0, arg1) +} + +func (w clientWithAdditionalCleanup) NodeList(arg0 context.Context, arg1 types.NodeListOptions) ([]swarm.Node, error) { + return w.pimpl.NodeList(arg0, arg1) +} + +func (w clientWithAdditionalCleanup) NodeRemove(arg0 context.Context, arg1 string, arg2 types.NodeRemoveOptions) error { + return w.pimpl.NodeRemove(arg0, arg1, arg2) +} + +func (w clientWithAdditionalCleanup) NodeUpdate(arg0 context.Context, arg1 string, arg2 swarm.Version, arg3 swarm.NodeSpec) error { + return w.pimpl.NodeUpdate(arg0, arg1, arg2, arg3) +} + +func (w clientWithAdditionalCleanup) Ping(arg0 context.Context) (types.Ping, error) { + return w.pimpl.Ping(arg0) +} + +func (w clientWithAdditionalCleanup) PluginCreate(arg0 context.Context, arg1 io.Reader, arg2 types.PluginCreateOptions) error { + return w.pimpl.PluginCreate(arg0, arg1, arg2) +} + +func (w clientWithAdditionalCleanup) PluginDisable(arg0 context.Context, arg1 string, arg2 types.PluginDisableOptions) error { + return w.pimpl.PluginDisable(arg0, arg1, arg2) +} + +func (w clientWithAdditionalCleanup) PluginEnable(arg0 context.Context, arg1 string, arg2 types.PluginEnableOptions) error { + return w.pimpl.PluginEnable(arg0, arg1, arg2) +} + +func (w clientWithAdditionalCleanup) PluginInspectWithRaw(arg0 context.Context, arg1 string) (*types.Plugin, []uint8, error) { + return w.pimpl.PluginInspectWithRaw(arg0, arg1) +} + +func (w clientWithAdditionalCleanup) PluginInstall(arg0 context.Context, arg1 string, arg2 types.PluginInstallOptions) (io.ReadCloser, error) { + return w.pimpl.PluginInstall(arg0, arg1, arg2) +} + +func (w clientWithAdditionalCleanup) PluginList(arg0 context.Context, arg1 filters.Args) (types.PluginsListResponse, error) { + return w.pimpl.PluginList(arg0, arg1) +} + +func (w clientWithAdditionalCleanup) PluginPush(arg0 context.Context, arg1 string, arg2 string) (io.ReadCloser, error) { + return w.pimpl.PluginPush(arg0, arg1, arg2) +} + +func (w clientWithAdditionalCleanup) PluginRemove(arg0 context.Context, arg1 string, arg2 types.PluginRemoveOptions) error { + return w.pimpl.PluginRemove(arg0, arg1, arg2) +} + +func (w clientWithAdditionalCleanup) PluginSet(arg0 context.Context, arg1 string, arg2 []string) error { + return w.pimpl.PluginSet(arg0, arg1, arg2) +} + +func (w clientWithAdditionalCleanup) PluginUpgrade(arg0 context.Context, arg1 string, arg2 types.PluginInstallOptions) (io.ReadCloser, error) { + return w.pimpl.PluginUpgrade(arg0, arg1, arg2) +} + +func (w clientWithAdditionalCleanup) RegistryLogin(arg0 context.Context, arg1 types.AuthConfig) (registry.AuthenticateOKBody, error) { + return w.pimpl.RegistryLogin(arg0, arg1) +} + +func (w clientWithAdditionalCleanup) SecretCreate(arg0 context.Context, arg1 swarm.SecretSpec) (types.SecretCreateResponse, error) { + return w.pimpl.SecretCreate(arg0, arg1) +} + +func (w clientWithAdditionalCleanup) SecretInspectWithRaw(arg0 context.Context, arg1 string) (swarm.Secret, []uint8, error) { + return w.pimpl.SecretInspectWithRaw(arg0, arg1) +} + +func (w clientWithAdditionalCleanup) SecretList(arg0 context.Context, arg1 types.SecretListOptions) ([]swarm.Secret, error) { + return w.pimpl.SecretList(arg0, arg1) +} + +func (w clientWithAdditionalCleanup) SecretRemove(arg0 context.Context, arg1 string) error { + return w.pimpl.SecretRemove(arg0, arg1) +} + +func (w clientWithAdditionalCleanup) SecretUpdate(arg0 context.Context, arg1 string, arg2 swarm.Version, arg3 swarm.SecretSpec) error { + return w.pimpl.SecretUpdate(arg0, arg1, arg2, arg3) +} + +func (w clientWithAdditionalCleanup) ServerVersion(arg0 context.Context) (types.Version, error) { + return w.pimpl.ServerVersion(arg0) +} + +func (w clientWithAdditionalCleanup) ServiceCreate(arg0 context.Context, arg1 swarm.ServiceSpec, arg2 types.ServiceCreateOptions) (types.ServiceCreateResponse, error) { + return w.pimpl.ServiceCreate(arg0, arg1, arg2) +} + +func (w clientWithAdditionalCleanup) ServiceInspectWithRaw(arg0 context.Context, arg1 string, arg2 types.ServiceInspectOptions) (swarm.Service, []uint8, error) { + return w.pimpl.ServiceInspectWithRaw(arg0, arg1, arg2) +} + +func (w clientWithAdditionalCleanup) ServiceList(arg0 context.Context, arg1 types.ServiceListOptions) ([]swarm.Service, error) { + return w.pimpl.ServiceList(arg0, arg1) +} + +func (w clientWithAdditionalCleanup) ServiceLogs(arg0 context.Context, arg1 string, arg2 types.ContainerLogsOptions) (io.ReadCloser, error) { + return w.pimpl.ServiceLogs(arg0, arg1, arg2) +} + +func (w clientWithAdditionalCleanup) ServiceRemove(arg0 context.Context, arg1 string) error { + return w.pimpl.ServiceRemove(arg0, arg1) +} + +func (w clientWithAdditionalCleanup) ServiceUpdate(arg0 context.Context, arg1 string, arg2 swarm.Version, arg3 swarm.ServiceSpec, arg4 types.ServiceUpdateOptions) (types.ServiceUpdateResponse, error) { + return w.pimpl.ServiceUpdate(arg0, arg1, arg2, arg3, arg4) +} + +func (w clientWithAdditionalCleanup) SwarmGetUnlockKey(arg0 context.Context) (types.SwarmUnlockKeyResponse, error) { + return w.pimpl.SwarmGetUnlockKey(arg0) +} + +func (w clientWithAdditionalCleanup) SwarmInit(arg0 context.Context, arg1 swarm.InitRequest) (string, error) { + return w.pimpl.SwarmInit(arg0, arg1) +} + +func (w clientWithAdditionalCleanup) SwarmInspect(arg0 context.Context) (swarm.Swarm, error) { + return w.pimpl.SwarmInspect(arg0) +} + +func (w clientWithAdditionalCleanup) SwarmJoin(arg0 context.Context, arg1 swarm.JoinRequest) error { + return w.pimpl.SwarmJoin(arg0, arg1) +} + +func (w clientWithAdditionalCleanup) SwarmLeave(arg0 context.Context, arg1 bool) error { + return w.pimpl.SwarmLeave(arg0, arg1) +} + +func (w clientWithAdditionalCleanup) SwarmUnlock(arg0 context.Context, arg1 swarm.UnlockRequest) error { + return w.pimpl.SwarmUnlock(arg0, arg1) +} + +func (w clientWithAdditionalCleanup) SwarmUpdate(arg0 context.Context, arg1 swarm.Version, arg2 swarm.Spec, arg3 swarm.UpdateFlags) error { + return w.pimpl.SwarmUpdate(arg0, arg1, arg2, arg3) +} + +func (w clientWithAdditionalCleanup) TaskInspectWithRaw(arg0 context.Context, arg1 string) (swarm.Task, []uint8, error) { + return w.pimpl.TaskInspectWithRaw(arg0, arg1) +} + +func (w clientWithAdditionalCleanup) TaskList(arg0 context.Context, arg1 types.TaskListOptions) ([]swarm.Task, error) { + return w.pimpl.TaskList(arg0, arg1) +} + +func (w clientWithAdditionalCleanup) TaskLogs(arg0 context.Context, arg1 string, arg2 types.ContainerLogsOptions) (io.ReadCloser, error) { + return w.pimpl.TaskLogs(arg0, arg1, arg2) +} + +func (w clientWithAdditionalCleanup) VolumeCreate(arg0 context.Context, arg1 volume.VolumeCreateBody) (types.Volume, error) { + return w.pimpl.VolumeCreate(arg0, arg1) +} + +func (w clientWithAdditionalCleanup) VolumeInspect(arg0 context.Context, arg1 string) (types.Volume, error) { + return w.pimpl.VolumeInspect(arg0, arg1) +} + +func (w clientWithAdditionalCleanup) VolumeInspectWithRaw(arg0 context.Context, arg1 string) (types.Volume, []uint8, error) { + return w.pimpl.VolumeInspectWithRaw(arg0, arg1) +} + +func (w clientWithAdditionalCleanup) VolumeList(arg0 context.Context, arg1 filters.Args) (volume.VolumeListOKBody, error) { + return w.pimpl.VolumeList(arg0, arg1) +} + +func (w clientWithAdditionalCleanup) VolumeRemove(arg0 context.Context, arg1 string, arg2 bool) error { + return w.pimpl.VolumeRemove(arg0, arg1, arg2) +} + +func (w clientWithAdditionalCleanup) VolumesPrune(arg0 context.Context, arg1 filters.Args) (types.VolumesPruneReport, error) { + return w.pimpl.VolumesPrune(arg0, arg1) +} + +// diff --git a/vendor/knative.dev/kn-plugin-func/docker/pusher.go b/vendor/knative.dev/kn-plugin-func/docker/pusher.go index df1aaf7a7f..b892d2f1f9 100644 --- a/vendor/knative.dev/kn-plugin-func/docker/pusher.go +++ b/vendor/knative.dev/kn-plugin-func/docker/pusher.go @@ -8,17 +8,23 @@ import ( "errors" "fmt" "io" + "net/http" "os" "path/filepath" "regexp" "strings" + "github.com/google/go-containerregistry/pkg/authn" + "github.com/google/go-containerregistry/pkg/name" + "github.com/google/go-containerregistry/pkg/v1/remote/transport" + + "github.com/docker/docker/client" + fn "knative.dev/kn-plugin-func" "github.com/containers/image/v5/pkg/docker/config" containersTypes "github.com/containers/image/v5/types" "github.com/docker/docker/api/types" - "github.com/docker/docker/errdefs" ) type Opt func(*Pusher) error @@ -39,23 +45,49 @@ var ErrUnauthorized = errors.New("bad credentials") type VerifyCredentialsCallback func(ctx context.Context, username, password, registry string) error func CheckAuth(ctx context.Context, username, password, registry string) error { - cli, _, err := NewDockerClient() + serverAddress := registry + if !strings.HasPrefix(serverAddress, "https://") && !strings.HasPrefix(serverAddress, "http://") { + serverAddress = "https://" + serverAddress + } + + url := fmt.Sprintf("%s/v2", serverAddress) + + authenticator := &authn.Basic{ + Username: username, + Password: password, + } + + reg, err := name.NewRegistry(registry) if err != nil { return err } - _, err = cli.RegistryLogin(ctx, types.AuthConfig{Username: username, Password: password, ServerAddress: registry}) - if err != nil && strings.Contains(err.Error(), "401 Unauthorized") { - return ErrUnauthorized + tr, err := transport.NewWithContext(ctx, reg, authenticator, http.DefaultTransport, nil) + if err != nil { + return err } - // podman hack until https://github.com/containers/podman/pull/11595 is merged - // podman returns 400 (instead of 500) and body in unexpected shape - if errdefs.IsInvalidParameter(err) { - return ErrUnauthorized + cli := http.Client{Transport: tr} + + req, err := http.NewRequestWithContext(ctx, "GET", url, nil) + if err != nil { + return err + } + + resp, err := cli.Do(req) + if err != nil { + return fmt.Errorf("failed to verify credentials: %w", err) } + defer resp.Body.Close() - return err + switch { + case resp.StatusCode == http.StatusUnauthorized: + return ErrUnauthorized + case resp.StatusCode != http.StatusOK: + return fmt.Errorf("failed to verify credentials: status code: %d", resp.StatusCode) + default: + return nil + } } type ChooseCredentialHelperCallback func(available []string) (string, error) @@ -242,10 +274,11 @@ func (n *Pusher) Push(ctx context.Context, f fn.Function) (digest string, err er return "", err } - cli, _, err := NewDockerClient() + cli, _, err := NewClient(client.DefaultDockerHost) if err != nil { return "", fmt.Errorf("failed to create docker api client: %w", err) } + defer cli.Close() n.progressListener.Stopping() credentials, err := n.credentialsProvider(ctx, registry) diff --git a/vendor/knative.dev/kn-plugin-func/docker/runner.go b/vendor/knative.dev/kn-plugin-func/docker/runner.go index ff67103fe3..a96fa47ccf 100644 --- a/vendor/knative.dev/kn-plugin-func/docker/runner.go +++ b/vendor/knative.dev/kn-plugin-func/docker/runner.go @@ -8,6 +8,8 @@ import ( "strings" "time" + "github.com/docker/docker/client" + "github.com/docker/docker/api/types" "github.com/docker/docker/api/types/container" "github.com/docker/docker/pkg/stdcopy" @@ -33,10 +35,11 @@ func (n *Runner) Run(ctx context.Context, f fn.Function) error { ctx, cancel := context.WithCancel(ctx) defer cancel() - cli, _, err := NewDockerClient() + cli, _, err := NewClient(client.DefaultDockerHost) if err != nil { return errors.Wrap(err, "failed to create docker api client") } + defer cli.Close() if f.Image == "" { return errors.New("Function has no associated Image. Has it been built?") diff --git a/vendor/knative.dev/kn-plugin-func/function.go b/vendor/knative.dev/kn-plugin-func/function.go index a0114c7766..fdd7217951 100644 --- a/vendor/knative.dev/kn-plugin-func/function.go +++ b/vendor/knative.dev/kn-plugin-func/function.go @@ -6,25 +6,37 @@ import ( "io/ioutil" "os" "path/filepath" + "regexp" "strings" + "time" + + "gopkg.in/yaml.v2" ) +// FunctionFile is the file used for the serialized form of a Function. +const FunctionFile = "func.yaml" + type Function struct { + // Version at which this function is known to be compatible. + // More specifically, it is the highest migration which has been applied. + // For details see the .Migrated() and .Migrate() methods. + Version string // semver format + // Root on disk at which to find/create source and config files. - Root string + Root string `yaml:"-"` // Name of the Function. If not provided, path derivation is attempted when // requried (such as for initialization). - Name string + Name string `yaml:"name" jsonschema:"pattern=^[a-z0-9]([-a-z0-9]*[a-z0-9])?$"` // Namespace into which the Function is deployed on supported platforms. - Namespace string + Namespace string `yaml:"namespace"` // Runtime is the language plus context. nodejs|go|quarkus|rust etc. - Runtime string + Runtime string `yaml:"runtime"` // Template for the Function. - Template string + Template string `yaml:"-"` // Registry at which to store interstitial containers, in the form // [registry]/[user]. @@ -39,104 +51,181 @@ type Function struct { // alice/my.function.name // If Image is provided, it overrides the default of concatenating // "Registry+Name:latest" to derive the Image. - Image string + Image string `yaml:"image"` // SHA256 hash of the latest image that has been built - ImageDigest string + ImageDigest string `yaml:"imageDigest"` // Builder represents the CNCF Buildpack builder image for a function - Builder string + Builder string `yaml:"builder"` // Map containing known builders. // e.g. { "jvm": "docker.io/example/quarkus-jvm-builder" } - Builders map[string]string + Builders map[string]string `yaml:"builders"` // Optional list of buildpacks to use when building the function - Buildpacks []string + Buildpacks []string `yaml:"buildpacks"` // List of volumes to be mounted to the function - Volumes Volumes + Volumes []Volume `yaml:"volumes"` // Build Env variables to be set - BuildEnvs Envs + BuildEnvs []Env `yaml:"buildEnvs"` // Env variables to be set - Envs Envs + Envs []Env `yaml:"envs"` // Map containing user-supplied annotations // Example: { "division": "finance" } - Annotations map[string]string + Annotations map[string]string `yaml:"annotations"` // Options to be set on deployed function (scaling, etc.) - Options Options + Options Options `yaml:"options"` // Map of user-supplied labels - Labels Labels + Labels []Label `yaml:"labels"` // Health endpoints specified by the language pack - HealthEndpoints HealthEndpoints + HealthEndpoints HealthEndpoints `yaml:"healthEndpoints"` + + // Created time is the moment that creation was successfully completed + // according to the client which is in charge of what constitutes being + // fully "Created" (aka initialized) + Created time.Time } -// NewFunction loads a Function from a path on disk. use .Initialized() to determine if -// the path contained an initialized Function. -// NewFunction creates a Function struct whose attributes are loaded from the -// configuraiton located at path. -func NewFunction(root string) (f Function, err error) { +// NewFunctionWith defaults as provided. +func NewFunctionWith(defaults Function) Function { + if defaults.Version == "" { + defaults.Version = DefaultVersion + } + if defaults.Template == "" { + defaults.Template = DefaultTemplate + } + return defaults +} - // Expand the passed root to its absolute path (default current dir) - if root, err = filepath.Abs(root); err != nil { +// NewFunction from a given path. +// Invalid paths, or no Function at path are errors. +// Syntactic errors are returned immediately (yaml unmarshal errors). +// Functions which are syntactically valid are also then logically validated. +// Functions from earlier versions are brought up to current using migrations. +// Migrations are run prior to validators such that validation can omit +// concerning itself with backwards compatibility. Migrators must therefore +// selectively consider the minimal validation necesssary to ehable migration. +func NewFunction(path string) (f Function, err error) { + f.Root = path // path is not persisted, as this is the purvew of the FS itself + var filename = filepath.Join(path, FunctionFile) + if _, err = os.Stat(filename); err != nil { return } - - // Load a Config from the given absolute path - c, err := newConfig(root) + bb, err := ioutil.ReadFile(filename) if err != nil { return } + if err = yaml.UnmarshalStrict(bb, &f); err != nil { + err = formatUnmarshalError(err) // human-friendly unmarshalling errors + return + } + if f, err = f.Migrate(); err != nil { + return + } + return f, f.Validate() +} - // Let's set Function name, if it is not already set - if c.Name == "" { - pathParts := strings.Split(strings.TrimRight(root, string(os.PathSeparator)), string(os.PathSeparator)) - c.Name = pathParts[len(pathParts)-1] +// Validate Function is logically correct, returning a bundled, and quite +// verbose, formatted error detailing any issues. +func (f Function) Validate() error { + if f.Name == "" { + return errors.New("function name is required") + } + if f.Runtime == "" { + return errors.New("function language runtime is required") + } + if f.Root == "" { + return errors.New("function root path is required") + } + + var ctr int + errs := [][]string{ + validateVolumes(f.Volumes), + ValidateBuildEnvs(f.BuildEnvs), + ValidateEnvs(f.Envs), + validateOptions(f.Options), + ValidateLabels(f.Labels), } - // set Function to the value of the config loaded from disk. - f = fromConfig(c) + var b strings.Builder + b.WriteString(fmt.Sprintf("'%v' contains errors:", FunctionFile)) - // The only value not included in the config is the effective path on disk - f.Root = root - return + for _, ee := range errs { + if len(ee) > 0 { + b.WriteString("\n") // Precede each group of errors with a linebreak + } + for _, e := range ee { + ctr++ + b.WriteString("\t" + e) + } + } + + if ctr == 0 { + return nil // Return nil if there were no validation errors. + } + + return errors.New(b.String()) +} + +// nameFromPath returns the default name for a Function derived from a path. +// This consists of the last directory in the given path, if derivable (empty +// paths, paths consisting of all slashes, etc. return the zero value "") +func nameFromPath(path string) string { + pathParts := strings.Split(strings.TrimRight(path, string(os.PathSeparator)), string(os.PathSeparator)) + return pathParts[len(pathParts)-1] + /* the above may have edge conditions as it assumes the trailing value + * is a directory name. If errors are encountered, we _may_ need to use the + * inbuilt logic in the std lib and either check if the path indicated is a + * directory (appending slash) and then run: + base := filepath.Base(filepath.Dir(path)) + if base == string(os.PathSeparator) || base == "." { + return "" // Consider it underivable: string zero value + } + return base + */ } -// WriteConfig writes this Function's configuration to disk. -func (f Function) WriteConfig() (err error) { - return writeConfig(f) +// Write aka (save, serialize, marshal) the Function to disk at its path. +func (f Function) Write() (err error) { + path := filepath.Join(f.Root, FunctionFile) + var bb []byte + if bb, err = yaml.Marshal(&f); err != nil { + return + } + // TODO: open existing file for writing, such that existing permissions + // are preserved. + return ioutil.WriteFile(path, bb, 0644) } // Initialized returns if the Function has been initialized. // Any errors are considered failure (invalid or inaccessible root, config file, etc). func (f Function) Initialized() bool { - // Load the Function's configuration from disk and check if the (required) value Runtime is populated. - c, err := newConfig(f.Root) - if err != nil { - return false - } - - return c.Runtime != "" && c.Name != "" + return !f.Created.IsZero() } // Built indicates the Function has been built. Does not guarantee the // image indicated actually exists, just that it _should_ exist based off -// the current state of the Funciton object, in particular the value of +// the current state of the Function object, in particular the value of // the Image and ImageDiget fields. func (f Function) Built() bool { // If Image (the override) and ImageDigest (the most recent build stamp) are // both empty, the Function is considered unbuilt. + // TODO: upgrade to a "build complete" timestamp. return f.Image != "" || f.ImageDigest != "" } // ImageWithDigest returns the full reference to the image including SHA256 Digest. // If Digest is empty, image:tag is returned. +// TODO: Populate this only on a successful deploy, as this results on a dirty +// git tree on every build. func (f Function) ImageWithDigest() string { // Return image, if Digest is empty if f.ImageDigest == "" { @@ -164,6 +253,8 @@ func (f Function) ImageWithDigest() string { // example docker.io/alice/my.example.func:latest // Default if not provided is --registry (a required global setting) // followed by the provided (or derived) image name. +// TODO: this calculated field should probably be generated on instantiation +// to avoid confusion. func DerivedImage(root, registry string) (image string, err error) { f, err := NewFunction(root) if err != nil { @@ -243,10 +334,10 @@ func assertEmptyRoot(path string) (err error) { // contentiousFiles are files which, if extant, preclude the creation of a // Function rooted in the given directory. var contentiousFiles = []string{ - ConfigFile, + FunctionFile, } -// contentiousFilesIn the given directoy +// contentiousFilesIn the given directory func contentiousFilesIn(dir string) (contentious []string, err error) { files, err := ioutil.ReadDir(dir) for _, file := range files { @@ -273,3 +364,57 @@ func isEffectivelyEmpty(dir string) (bool, error) { } return true, nil } + +// returns true if the given path contains an initialized Function. +func hasInitializedFunction(path string) (bool, error) { + var err error + var filename = filepath.Join(path, FunctionFile) + + if _, err = os.Stat(filename); err != nil { + if os.IsNotExist(err) { + return false, nil + } + return false, err // invalid path or access error + } + bb, err := ioutil.ReadFile(filename) + if err != nil { + return false, err + } + f := Function{} + if err = yaml.UnmarshalStrict(bb, &f); err != nil { + return false, err + } + if f, err = f.Migrate(); err != nil { + return false, err + } + return f.Initialized(), nil +} + +// Format yaml unmarshall error to be more human friendly. +func formatUnmarshalError(err error) error { + var ( + e = err.Error() + rxp = regexp.MustCompile("not found in type .*") + header = fmt.Sprintf("'%v' is not valid:\n", FunctionFile) + ) + + if strings.HasPrefix(e, "yaml: unmarshal errors:") { + e = rxp.ReplaceAllString(e, "is not valid") + e = strings.Replace(e, "yaml: unmarshal errors:\n", header, 1) + } else if strings.HasPrefix(e, "yaml:") { + e = rxp.ReplaceAllString(e, "is not valid") + e = strings.Replace(e, "yaml: ", header+" ", 1) + } + + return errors.New(e) +} + +// Regex used during instantiation and validation of various Function fields +// by labels, envs, options, etc. +var ( + regWholeSecret = regexp.MustCompile(`^{{\s*secret:((?:\w|['-]\w)+)\s*}}$`) + regKeyFromSecret = regexp.MustCompile(`^{{\s*secret:((?:\w|['-]\w)+):([-._a-zA-Z0-9]+)\s*}}$`) + regWholeConfigMap = regexp.MustCompile(`^{{\s*configMap:((?:\w|['-]\w)+)\s*}}$`) + regKeyFromConfigMap = regexp.MustCompile(`^{{\s*configMap:((?:\w|['-]\w)+):([-._a-zA-Z0-9]+)\s*}}$`) + regLocalEnv = regexp.MustCompile(`^{{\s*env:(\w+)\s*}}$`) +) diff --git a/vendor/knative.dev/kn-plugin-func/function_envs.go b/vendor/knative.dev/kn-plugin-func/function_envs.go new file mode 100644 index 0000000000..ea244bc00a --- /dev/null +++ b/vendor/knative.dev/kn-plugin-func/function_envs.go @@ -0,0 +1,126 @@ +package function + +import ( + "fmt" + "strings" + + "knative.dev/kn-plugin-func/utils" +) + +type Env struct { + Name *string `yaml:"name,omitempty" jsonschema:"pattern=^[-._a-zA-Z][-._a-zA-Z0-9]*$"` + Value *string `yaml:"value"` +} + +func (e Env) String() string { + if e.Name == nil && e.Value != nil { + match := regWholeSecret.FindStringSubmatch(*e.Value) + if len(match) == 2 { + return fmt.Sprintf("All key=value pairs from Secret \"%s\"", match[1]) + } + match = regWholeConfigMap.FindStringSubmatch(*e.Value) + if len(match) == 2 { + return fmt.Sprintf("All key=value pairs from ConfigMap \"%s\"", match[1]) + } + } else if e.Name != nil && e.Value != nil { + match := regKeyFromSecret.FindStringSubmatch(*e.Value) + if len(match) == 3 { + return fmt.Sprintf("Env \"%s\" with value set from key \"%s\" from Secret \"%s\"", *e.Name, match[2], match[1]) + } + match = regKeyFromConfigMap.FindStringSubmatch(*e.Value) + if len(match) == 3 { + return fmt.Sprintf("Env \"%s\" with value set from key \"%s\" from ConfigMap \"%s\"", *e.Name, match[2], match[1]) + } + match = regLocalEnv.FindStringSubmatch(*e.Value) + if len(match) == 2 { + return fmt.Sprintf("Env \"%s\" with value set from local env variable \"%s\"", *e.Name, match[1]) + } + + return fmt.Sprintf("Env \"%s\" with value \"%s\"", *e.Name, *e.Value) + } + return "" +} + +// ValidateEnvs checks that input Envs are correct and contain all necessary fields. +// Returns array of error messages, empty if no errors are found +// +// Allowed settings: +// - name: EXAMPLE1 # ENV directly from a value +// value: value1 +// - name: EXAMPLE2 # ENV from the local ENV var +// value: {{ env:MY_ENV }} +// - name: EXAMPLE3 +// value: {{ secret:secretName:key }} # ENV from a key in secret +// - value: {{ secret:secretName }} # all key-pair values from secret are set as ENV +// - name: EXAMPLE4 +// value: {{ configMap:configMapName:key }} # ENV from a key in configMap +// - value: {{ configMap:configMapName }} # all key-pair values from configMap are set as ENV +func ValidateEnvs(envs []Env) (errors []string) { + for i, env := range envs { + if env.Name == nil && env.Value == nil { + errors = append(errors, fmt.Sprintf("env entry #%d is not properly set", i)) + } else if env.Value == nil { + errors = append(errors, fmt.Sprintf("env entry #%d is missing value field, only name '%s' is set", i, *env.Name)) + } else if env.Name == nil { + // all key-pair values from secret are set as ENV; {{ secret:secretName }} or {{ configMap:configMapName }} + if !regWholeSecret.MatchString(*env.Value) && !regWholeConfigMap.MatchString(*env.Value) { + errors = append(errors, fmt.Sprintf("env entry #%d has invalid value field set, it has '%s', but allowed is only '{{ secret:secretName }}' or '{{ configMap:configMapName }}'", + i, *env.Value)) + } + } else { + + if err := utils.ValidateEnvVarName(*env.Name); err != nil { + errors = append(errors, fmt.Sprintf("env entry #%d has invalid name set: %q; %s", i, *env.Name, err.Error())) + } + + if strings.HasPrefix(*env.Value, "{{") { + // ENV from the local ENV var; {{ env:MY_ENV }} + // or + // ENV from a key in secret/configMap; {{ secret:secretName:key }} or {{ configMap:configMapName:key }} + if !regLocalEnv.MatchString(*env.Value) && !regKeyFromSecret.MatchString(*env.Value) && !regKeyFromConfigMap.MatchString(*env.Value) { + errors = append(errors, + fmt.Sprintf( + "env entry #%d with name '%s' has invalid value field set, it has '%s', but allowed is only '{{ env:MY_ENV }}', '{{ secret:secretName:key }}' or '{{ configMap:configMapName:key }}'", + i, *env.Name, *env.Value)) + } + } + } + } + + return +} + +// ValidateBuildEnvs checks that input BuildEnvs are correct and contain all necessary fields. +// Returns array of error messages, empty if no errors are found +// +// Allowed settings: +// - name: EXAMPLE1 # ENV directly from a value +// value: value1 +// - name: EXAMPLE2 # ENV from the local ENV var +// value: {{ env:MY_ENV }} +func ValidateBuildEnvs(envs []Env) (errors []string) { + for i, env := range envs { + if env.Name == nil && env.Value == nil { + errors = append(errors, fmt.Sprintf("env entry #%d is not properly set", i)) + } else if env.Value == nil { + errors = append(errors, fmt.Sprintf("env entry #%d is missing value field, only name '%s' is set", i, *env.Name)) + } else { + + if err := utils.ValidateEnvVarName(*env.Name); err != nil { + errors = append(errors, fmt.Sprintf("env entry #%d has invalid name set: %q; %s", i, *env.Name, err.Error())) + } + + if strings.HasPrefix(*env.Value, "{{") { + // ENV from the local ENV var; {{ env:MY_ENV }} + if !regLocalEnv.MatchString(*env.Value) { + errors = append(errors, + fmt.Sprintf( + "env entry #%d with name '%s' has invalid value field set, it has '%s', but allowed is only '{{ env:MY_ENV }}'", + i, *env.Name, *env.Value)) + } + } + } + } + + return +} diff --git a/vendor/knative.dev/kn-plugin-func/function_labels.go b/vendor/knative.dev/kn-plugin-func/function_labels.go new file mode 100644 index 0000000000..87d55c3903 --- /dev/null +++ b/vendor/knative.dev/kn-plugin-func/function_labels.go @@ -0,0 +1,75 @@ +package function + +import ( + "fmt" + "os" + "strings" + + "knative.dev/kn-plugin-func/utils" +) + +type Label struct { + // Key consist of optional prefix part (ended by '/') and name part + // Prefix part validation pattern: [a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)* + // Name part validation pattern: ([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9] + Key *string `yaml:"key" jsonschema:"pattern=^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\\/)?([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9]$"` + Value *string `yaml:"value,omitempty" jsonschema:"pattern=^(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])?$"` +} + +func (l Label) String() string { + if l.Key != nil && l.Value == nil { + return fmt.Sprintf("Label with key \"%s\"", *l.Key) + } else if l.Key != nil && l.Value != nil { + match := regLocalEnv.FindStringSubmatch(*l.Value) + if len(match) == 2 { + return fmt.Sprintf("Label with key \"%s\" and value set from local env variable \"%s\"", *l.Key, match[1]) + } + return fmt.Sprintf("Label with key \"%s\" and value \"%s\"", *l.Key, *l.Value) + } + return "" +} + +// ValidateLabels checks that input labels are correct and contain all necessary fields. +// Returns array of error messages, empty if no errors are found +// +// Allowed settings: +// - key: EXAMPLE1 # label directly from a value +// value: value1 +// - key: EXAMPLE2 # label from the local ENV var +// value: {{ env:MY_ENV }} +func ValidateLabels(labels []Label) (errors []string) { + for i, label := range labels { + if label.Key == nil && label.Value == nil { + errors = append(errors, fmt.Sprintf("label entry #%d is not properly set", i)) + } else if label.Key == nil && label.Value != nil { + errors = append(errors, fmt.Sprintf("label entry #%d is missing key field, only value '%s' is set", i, *label.Value)) + } else { + if err := utils.ValidateLabelKey(*label.Key); err != nil { + errors = append(errors, fmt.Sprintf("label entry #%d has invalid key set: %q; %s", i, *label.Key, err.Error())) + } + if label.Value != nil { + if err := utils.ValidateLabelValue(*label.Value); err != nil { + errors = append(errors, fmt.Sprintf("label entry #%d has invalid value set: %q; %s", i, *label.Value, err.Error())) + } + + if strings.HasPrefix(*label.Value, "{{") { + // ENV from the local ENV var; {{ env:MY_ENV }} + if !regLocalEnv.MatchString(*label.Value) { + errors = append(errors, + fmt.Sprintf( + "label entry #%d with key '%s' has invalid value field set, it has '%s', but allowed is only '{{ env:MY_ENV }}'", + i, *label.Key, *label.Value)) + } else { + match := regLocalEnv.FindStringSubmatch(*label.Value) + value := os.Getenv(match[1]) + if err := utils.ValidateLabelValue(value); err != nil { + errors = append(errors, fmt.Sprintf("label entry #%d with key '%s' has invalid value when the environment is evaluated: '%s': %s", i, *label.Key, value, err.Error())) + } + } + } + } + } + } + + return +} diff --git a/vendor/knative.dev/kn-plugin-func/function_migrations.go b/vendor/knative.dev/kn-plugin-func/function_migrations.go new file mode 100644 index 0000000000..4863a58877 --- /dev/null +++ b/vendor/knative.dev/kn-plugin-func/function_migrations.go @@ -0,0 +1,114 @@ +package function + +import ( + "time" + + "github.com/coreos/go-semver/semver" +) + +// Migrate applies any necessary migrations, returning a new migrated +// version of the Function. It is the caller's responsibility to +// .Write() the Function to persist to disk. +func (f Function) Migrate() (migrated Function, err error) { + // Return immediately if the Function indicates it has already been + // migrated. + if f.Migrated() { + return f, nil + } + + // If the version is empty, treat it as 0.0.0 + if f.Version == "" { + f.Version = DefaultVersion + } + + migrated = f // initially equivalent + for _, m := range migrations { + // Skip this migration if the current function's version is not less than + // the migration's applicable verion. + if !semver.New(migrated.Version).LessThan(*semver.New(m.version)) { + continue + } + // Apply this migration when the Function's version is less than that which + // the migration will impart. + migrated, err = m.migrate(migrated, m) + if err != nil { + return // fail fast on any migration errors + } + } + return +} + +// migration is a migration which should be applied to Functions whose version +// is below that indicated. +type migration struct { + version string // version before which this migration may be needed. + migrate migrator // Migrator migrates. +} + +// migrator is a function which returns a migrated copy of an inbound function. +type migrator func(Function, migration) (Function, error) + +// Migrated returns whether or not the Function has been migrated to the highest +// level the currently executing system is aware of (or beyond). +// returns true. +func (f Function) Migrated() bool { + // If the function has no Version, it is pre-migrations and is implicitly + // not migrated. + if f.Version == "" { + return false + } + + // lastMigration is the last registered migration. + lastMigration := semver.New(migrations[len(migrations)-1].version) + + // Fail the migration test if the Function's version is less than + // the latest available. + return !semver.New(f.Version).LessThan(*lastMigration) +} + +// Migrations registry +// ------------------- + +// migrations are all migrators in ascending order. +// No two migrations may have the exact version number (introduce a patch +// version for the migration if necessary) +var migrations = []migration{ + {"0.19.0", migrateToCreationStamp}, + // New Migrations Here. +} + +// Individual Migration implementations +// ------------------------------------ + +// migrateToCreationStamp is the initial migration which brings a Function from +// some unknown point in the past to the point at which it is versioned, +// migrated and includes a creation timestamp. Without this migration, +// instantiation of old functions will fail with a "Function at path X not +// initialized" in Func versions above v0.19.0 +// +// This migration must be aware of the difference between a Function which +// was previously created (but with no create stamp), and a Function which +// exists only in memory and should legitimately fail the .Initialized() check. +// The only way to know is to check a side-effect of earlier versions: +// are the .Name and .Runtime fields populated. This was the way the +// .Initialized check was implemented prior to versioning being introduced, so +// it is equivalent logically to use this here as well. + +// In summary: if the creation stamp is zero, but name and runtime fields are +// populated, then this is an old Function and should be migrated to having a +// create stamp. Otherwise, this is an in-memory (new) Function that is +// currently in the process of being created and as such need not be mutated +// to consider this migration having been evaluated. +func migrateToCreationStamp(f Function, m migration) (Function, error) { + // For functions with no creation timestamp, but appear to have been pre- + // existing, populate their create stamp and version. + // Yes, it's a little gnarly, but bootstrapping into the lovelieness of a + // versioned/migrated system takes cleaning up the trash. + if f.Created.IsZero() { // If there is no create stamp + if f.Name != "" && f.Runtime != "" { // and it appears to be an old Function + f.Created = time.Now() // Migrate it to having a timestamp. + } + } + f.Version = m.version // Record this migration was evaluated. + return f, nil +} diff --git a/vendor/knative.dev/kn-plugin-func/function_options.go b/vendor/knative.dev/kn-plugin-func/function_options.go new file mode 100644 index 0000000000..19d750a338 --- /dev/null +++ b/vendor/knative.dev/kn-plugin-func/function_options.go @@ -0,0 +1,139 @@ +package function + +import ( + "fmt" + + "k8s.io/apimachinery/pkg/api/resource" +) + +type Options struct { + Scale *ScaleOptions `yaml:"scale,omitempty"` + Resources *ResourcesOptions `yaml:"resources,omitempty"` +} + +type ScaleOptions struct { + Min *int64 `yaml:"min,omitempty" jsonschema_extras:"minimum=0"` + Max *int64 `yaml:"max,omitempty" jsonschema_extras:"minimum=0"` + Metric *string `yaml:"metric,omitempty" jsonschema:"enum=concurrency,enum=rps"` + Target *float64 `yaml:"target,omitempty" jsonschema_extras:"minimum=0.01"` + Utilization *float64 `yaml:"utilization,omitempty" jsonschema:"minimum=1,maximum=100"` +} + +type ResourcesOptions struct { + Requests *ResourcesRequestsOptions `yaml:"requests,omitempty"` + Limits *ResourcesLimitsOptions `yaml:"limits,omitempty"` +} + +type ResourcesLimitsOptions struct { + CPU *string `yaml:"cpu,omitempty" jsonschema:"pattern=^([+-]?[0-9.]+)([eEinumkKMGTP]*[-+]?[0-9]*)$"` + Memory *string `yaml:"memory,omitempty" jsonschema:"pattern=^([+-]?[0-9.]+)([eEinumkKMGTP]*[-+]?[0-9]*)$"` + Concurrency *int64 `yaml:"concurrency,omitempty" jsonschema_extras:"minimum=0"` +} + +type ResourcesRequestsOptions struct { + CPU *string `yaml:"cpu,omitempty" jsonschema:"pattern=^([+-]?[0-9.]+)([eEinumkKMGTP]*[-+]?[0-9]*)$"` + Memory *string `yaml:"memory,omitempty" jsonschema:"pattern=^([+-]?[0-9.]+)([eEinumkKMGTP]*[-+]?[0-9]*)$"` +} + +// validateOptions checks that input Options are correctly set. +// Returns array of error messages, empty if no errors are found +func validateOptions(options Options) (errors []string) { + + // options.scale + if options.Scale != nil { + if options.Scale.Min != nil { + if *options.Scale.Min < 0 { + errors = append(errors, fmt.Sprintf("options field \"scale.min\" has invalid value set: %d, the value must be greater than \"0\"", + *options.Scale.Min)) + } + } + + if options.Scale.Max != nil { + if *options.Scale.Max < 0 { + errors = append(errors, fmt.Sprintf("options field \"scale.max\" has invalid value set: %d, the value must be greater than \"0\"", + *options.Scale.Max)) + } + } + + if options.Scale.Min != nil && options.Scale.Max != nil { + if *options.Scale.Max < *options.Scale.Min { + errors = append(errors, "options field \"scale.max\" value must be greater or equal to \"scale.min\"") + } + } + + if options.Scale.Metric != nil { + if *options.Scale.Metric != "concurrency" && *options.Scale.Metric != "rps" { + errors = append(errors, fmt.Sprintf("options field \"scale.metric\" has invalid value set: %s, allowed is only \"concurrency\" or \"rps\"", + *options.Scale.Metric)) + } + } + + if options.Scale.Target != nil { + if *options.Scale.Target < 0.01 { + errors = append(errors, fmt.Sprintf("options field \"scale.target\" has value set to \"%f\", but it must not be less than 0.01", + *options.Scale.Target)) + } + } + + if options.Scale.Utilization != nil { + if *options.Scale.Utilization < 1 || *options.Scale.Utilization > 100 { + errors = append(errors, + fmt.Sprintf("options field \"scale.utilization\" has value set to \"%f\", but it must not be less than 1 or greater than 100", + *options.Scale.Utilization)) + } + } + } + + // options.resource + if options.Resources != nil { + + // options.resource.requests + if options.Resources.Requests != nil { + + if options.Resources.Requests.CPU != nil { + _, err := resource.ParseQuantity(*options.Resources.Requests.CPU) + if err != nil { + errors = append(errors, fmt.Sprintf("options field \"resources.requests.cpu\" has invalid value set: \"%s\"; \"%s\"", + *options.Resources.Requests.CPU, err.Error())) + } + } + + if options.Resources.Requests.Memory != nil { + _, err := resource.ParseQuantity(*options.Resources.Requests.Memory) + if err != nil { + errors = append(errors, fmt.Sprintf("options field \"resources.requests.memory\" has invalid value set: \"%s\"; \"%s\"", + *options.Resources.Requests.Memory, err.Error())) + } + } + } + + // options.resource.limits + if options.Resources.Limits != nil { + + if options.Resources.Limits.CPU != nil { + _, err := resource.ParseQuantity(*options.Resources.Limits.CPU) + if err != nil { + errors = append(errors, fmt.Sprintf("options field \"resources.limits.cpu\" has invalid value set: \"%s\"; \"%s\"", + *options.Resources.Limits.CPU, err.Error())) + } + } + + if options.Resources.Limits.Memory != nil { + _, err := resource.ParseQuantity(*options.Resources.Limits.Memory) + if err != nil { + errors = append(errors, fmt.Sprintf("options field \"resources.limits.memory\" has invalid value set: \"%s\"; \"%s\"", + *options.Resources.Limits.Memory, err.Error())) + } + } + + if options.Resources.Limits.Concurrency != nil { + if *options.Resources.Limits.Concurrency < 0 { + errors = append(errors, fmt.Sprintf("options field \"resources.limits.concurrency\" has value set to \"%d\", but it must not be less than 0", + *options.Resources.Limits.Concurrency)) + } + } + } + } + + return +} diff --git a/vendor/knative.dev/kn-plugin-func/function_volumes.go b/vendor/knative.dev/kn-plugin-func/function_volumes.go new file mode 100644 index 0000000000..fd85dd07b6 --- /dev/null +++ b/vendor/knative.dev/kn-plugin-func/function_volumes.go @@ -0,0 +1,49 @@ +package function + +import "fmt" + +type Volume struct { + Secret *string `yaml:"secret,omitempty" jsonschema:"oneof_required=secret"` + ConfigMap *string `yaml:"configMap,omitempty" jsonschema:"oneof_required=configmap"` + Path *string `yaml:"path"` +} + +func (v Volume) String() string { + if v.ConfigMap != nil { + return fmt.Sprintf("ConfigMap \"%s\" mounted at path: \"%s\"", *v.ConfigMap, *v.Path) + } else if v.Secret != nil { + return fmt.Sprintf("Secret \"%s\" mounted at path: \"%s\"", *v.Secret, *v.Path) + } + + return "" +} + +// validateVolumes checks that input Volumes are correct and contain all necessary fields. +// Returns array of error messages, empty if no errors are found +// +// Allowed settings: +// - secret: example-secret # mount Secret as Volume +// path: /etc/secret-volume +// - configMap: example-configMap # mount ConfigMap as Volume +// path: /etc/configMap-volume +func validateVolumes(volumes []Volume) (errors []string) { + + for i, vol := range volumes { + if vol.Secret != nil && vol.ConfigMap != nil { + errors = append(errors, fmt.Sprintf("volume entry #%d is not properly set, both secret '%s' and configMap '%s' can not be set at the same time", + i, *vol.Secret, *vol.ConfigMap)) + } else if vol.Path == nil && vol.Secret == nil && vol.ConfigMap == nil { + errors = append(errors, fmt.Sprintf("volume entry #%d is not properly set", i)) + } else if vol.Path == nil { + if vol.Secret != nil { + errors = append(errors, fmt.Sprintf("volume entry #%d is missing path field, only secret '%s' is set", i, *vol.Secret)) + } else if vol.ConfigMap != nil { + errors = append(errors, fmt.Sprintf("volume entry #%d is missing path field, only configMap '%s' is set", i, *vol.ConfigMap)) + } + } else if vol.Path != nil && vol.Secret == nil && vol.ConfigMap == nil { + errors = append(errors, fmt.Sprintf("volume entry #%d is missing secret or configMap field, only path '%s' is set", i, *vol.Path)) + } + } + + return +} diff --git a/vendor/knative.dev/kn-plugin-func/go.mod b/vendor/knative.dev/kn-plugin-func/go.mod index d498bcb1fa..85b828b659 100644 --- a/vendor/knative.dev/kn-plugin-func/go.mod +++ b/vendor/knative.dev/kn-plugin-func/go.mod @@ -10,6 +10,7 @@ require ( github.com/buildpacks/pack v0.22.0 github.com/cloudevents/sdk-go/v2 v2.5.0 github.com/containers/image/v5 v5.10.6 + github.com/coreos/go-semver v0.3.0 github.com/docker/cli v20.10.10+incompatible github.com/docker/docker v20.10.10+incompatible github.com/docker/docker-credential-helpers v0.6.4 @@ -17,10 +18,12 @@ require ( github.com/go-git/go-billy/v5 v5.3.1 github.com/go-git/go-git/v5 v5.4.2 github.com/google/go-cmp v0.5.6 + github.com/google/go-containerregistry v0.6.0 github.com/google/uuid v1.3.0 github.com/hinshun/vt10x v0.0.0-20180809195222-d55458df857c github.com/markbates/pkger v0.17.1 github.com/mitchellh/go-homedir v1.1.0 + github.com/opencontainers/image-spec v1.0.2-0.20190823105129-775207bd45b6 github.com/ory/viper v1.7.5 github.com/pkg/errors v0.9.1 github.com/spf13/cobra v1.2.1 diff --git a/vendor/knative.dev/kn-plugin-func/go.sum b/vendor/knative.dev/kn-plugin-func/go.sum index cbe9be5888..6f8671fd3c 100644 --- a/vendor/knative.dev/kn-plugin-func/go.sum +++ b/vendor/knative.dev/kn-plugin-func/go.sum @@ -334,6 +334,7 @@ github.com/coreos/go-iptables v0.4.5/go.mod h1:/mVI274lEDI2ns62jHCDnCyBF9Iwsmeka github.com/coreos/go-iptables v0.5.0/go.mod h1:/mVI274lEDI2ns62jHCDnCyBF9Iwsmekav8Dbxlm1MU= github.com/coreos/go-oidc v2.1.0+incompatible/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHoZ1nMCKZlZ9V6mm3/LKc= github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/coreos/go-semver v0.3.0 h1:wkHLiw0WNATZnSG7epLsujiMCgPAc9xhjJ4tgnAxmfM= github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-systemd v0.0.0-20161114122254-48702e0da86b/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= @@ -404,6 +405,7 @@ github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25Kn github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= +github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153 h1:yUdfgN0XgIJw7foRItutHYUIhlcKzcSf5vDpdhQAKTc= github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc= github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= github.com/emicklei/go-restful v2.9.5+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= @@ -870,6 +872,7 @@ github.com/mitchellh/mapstructure v1.4.1 h1:CpVNEelQCZBooIPDn+AR3NpivK/TIKU8bDxd github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/osext v0.0.0-20151018003038-5e2d6d41470f/go.mod h1:OkQIRizQZAeMln+1tSwduZz7+Af5oFlKirV/MSYes2A= github.com/moby/locker v1.0.1/go.mod h1:S7SDdo5zpBK84bzzVlKr2V0hz+7x9hWbYC/kq7oQppc= +github.com/moby/spdystream v0.2.0 h1:cjW1zVyyoiM0T7b6UoySUFqzXMoqRckQtXwGPiBhOM8= github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c= github.com/moby/sys/mount v0.2.0 h1:WhCW5B355jtxndN5ovugJlMFJawbUODuW8fSnEH6SSM= github.com/moby/sys/mount v0.2.0/go.mod h1:aAivFE2LB3W4bACsUXChRHQ0qKWsetY4Y9V7sxOougM= diff --git a/vendor/knative.dev/kn-plugin-func/k8s/dialer.go b/vendor/knative.dev/kn-plugin-func/k8s/dialer.go new file mode 100644 index 0000000000..9af287bc64 --- /dev/null +++ b/vendor/knative.dev/kn-plugin-func/k8s/dialer.go @@ -0,0 +1,324 @@ +package k8s + +import ( + "bytes" + "context" + "errors" + "fmt" + "io" + "net" + "time" + + coreV1 "k8s.io/api/core/v1" + metaV1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/fields" + "k8s.io/apimachinery/pkg/util/rand" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/kubernetes" + "k8s.io/client-go/kubernetes/scheme" + v1 "k8s.io/client-go/kubernetes/typed/core/v1" + restclient "k8s.io/client-go/rest" + "k8s.io/client-go/tools/remotecommand" +) + +const ( + socatImage = "alpine/socat:1.7.4.2-r0" +) + +type ContextDialer interface { + DialContext(ctx context.Context, network string, addr string) (net.Conn, error) + Close() error +} + +// NewInClusterDialer creates context dialer that will dial TCP connections via POD running in k8s cluster. +// This is useful when accessing k8s services that are not exposed outside cluster (e.g. openshift image registry). +// +// Usage: +// +// dialer, err := k8s.NewInClusterDialer(ctx) +// if err != nil { +// return err +// } +// defer dialer.Close() +// +// transport := &http.Transport{ +// DialContext: dialer.DialContext, +// } +// +// var client = http.Client{ +// Transport: transport, +// } +func NewInClusterDialer(ctx context.Context) (ContextDialer, error) { + c := &contextDialer{} + err := c.startDialerPod(ctx) + if err != nil { + return nil, err + } + return c, nil +} + +type contextDialer struct { + coreV1 v1.CoreV1Interface + restConf *restclient.Config + podName string + namespace string +} + +func (c *contextDialer) DialContext(ctx context.Context, network string, addr string) (net.Conn, error) { + if !(network == "tcp" || network == "tcp4" || network == "tcp6") { + return nil, fmt.Errorf("unsupported network: %q", network) + } + + execDone := make(chan struct{}) + pr, pw, conn := newConn(execDone) + + go func() { + defer close(execDone) + errOut := bytes.NewBuffer(nil) + err := c.exec(addr, pr, pw, errOut) + if err != nil { + err = fmt.Errorf("failed to exec in pod: %w (stderr: %q)", err, errOut.String()) + _ = pr.CloseWithError(err) + _ = pw.CloseWithError(err) + } + }() + + return conn, nil +} + +func (c *contextDialer) Close() error { + ctx, cancel := context.WithTimeout(context.Background(), time.Minute*1) + defer cancel() + delOpts := metaV1.DeleteOptions{} + + return c.coreV1.Pods(c.namespace).Delete(ctx, c.podName, delOpts) +} + +func (c *contextDialer) startDialerPod(ctx context.Context) (err error) { + cliConf := GetClientConfig() + c.restConf, err = cliConf.ClientConfig() + if err != nil { + return + } + + err = setConfigDefaults(c.restConf) + if err != nil { + return + } + + client, err := kubernetes.NewForConfig(c.restConf) + if err != nil { + return + } + c.coreV1 = client.CoreV1() + + c.namespace, err = GetNamespace("") + if err != nil { + return + } + + pods := client.CoreV1().Pods(c.namespace) + + c.podName = "in-cluster-dialer-" + rand.String(5) + + defer func() { + if err != nil { + c.Close() + } + }() + + pod := &coreV1.Pod{ + ObjectMeta: metaV1.ObjectMeta{ + Name: c.podName, + Labels: nil, + Annotations: nil, + }, + Spec: coreV1.PodSpec{ + Containers: []coreV1.Container{ + { + Name: c.podName, + Image: socatImage, + Stdin: true, + Command: []string{"sleep", "infinity"}, + }, + }, + DNSPolicy: coreV1.DNSClusterFirst, + RestartPolicy: coreV1.RestartPolicyNever, + }, + } + creatOpts := metaV1.CreateOptions{} + + ready := c.podReady(ctx) + + _, err = pods.Create(ctx, pod, creatOpts) + if err != nil { + return + } + + select { + case err = <-ready: + case <-ctx.Done(): + err = ctx.Err() + case <-time.After(time.Minute * 1): + err = errors.New("timeout") + } + + if err != nil { + err = fmt.Errorf("failed to start dialer container: %w", err) + } + + return err +} + +func (c *contextDialer) exec(hostPort string, in io.Reader, out, errOut io.Writer) error { + + restClient := c.coreV1.RESTClient() + req := restClient.Post(). + Resource("pods"). + Name(c.podName). + Namespace(c.namespace). + SubResource("exec") + req.VersionedParams(&coreV1.PodExecOptions{ + Command: []string{"socat", "-", fmt.Sprintf("TCP:%s", hostPort)}, + Container: c.podName, + Stdin: true, + Stdout: true, + Stderr: true, + TTY: false, + }, scheme.ParameterCodec) + + executor, err := remotecommand.NewSPDYExecutor(c.restConf, "POST", req.URL()) + if err != nil { + return err + } + + return executor.Stream(remotecommand.StreamOptions{ + Stdin: in, + Stdout: out, + Stderr: errOut, + Tty: false, + }) +} + +func (c *contextDialer) podReady(ctx context.Context) (errChan <-chan error) { + d := make(chan error) + errChan = d + + pods := c.coreV1.Pods(c.namespace) + + nameSelector := fields.OneTermEqualSelector("metadata.name", c.podName).String() + listOpts := metaV1.ListOptions{ + Watch: true, + FieldSelector: nameSelector, + } + watcher, err := pods.Watch(ctx, listOpts) + if err != nil { + return + } + + go func() { + defer watcher.Stop() + ch := watcher.ResultChan() + for event := range ch { + pod := event.Object.(*coreV1.Pod) + + if event.Type == watch.Modified { + for _, status := range pod.Status.ContainerStatuses { + if status.Ready { + d <- nil + return + } + if status.State.Waiting != nil { + switch status.State.Waiting.Reason { + case "ErrImagePull", + "CreateContainerError", + "CreateContainerConfigError", + "InvalidImageName", + "CrashLoopBackOff", + "ImagePullBackOff": + d <- fmt.Errorf("reason: %v, message: %v", + status.State.Waiting.Reason, + status.State.Waiting.Message) + return + default: + continue + } + } + } + } + } + }() + + return +} + +func setConfigDefaults(config *restclient.Config) error { + gv := coreV1.SchemeGroupVersion + config.GroupVersion = &gv + config.APIPath = "/api" + config.NegotiatedSerializer = scheme.Codecs.WithoutConversion() + + if config.UserAgent == "" { + config.UserAgent = restclient.DefaultKubernetesUserAgent() + } + + return nil +} + +type addr struct{} + +func (a addr) Network() string { + return "pod-stdio" +} + +func (a addr) String() string { + return "pod-stdio" +} + +type conn struct { + pr *io.PipeReader + pw *io.PipeWriter + execDone <-chan struct{} +} + +func (c conn) Read(b []byte) (n int, err error) { + return c.pr.Read(b) +} + +func (c conn) Write(b []byte) (n int, err error) { + return c.pw.Write(b) +} + +func (c conn) Close() error { + err := c.pw.Close() + if err != nil { + return fmt.Errorf("failed to close writer: %w", err) + } + <-c.execDone + err = c.pr.Close() + if err != nil { + return fmt.Errorf("failed to close reader: %w", err) + } + return nil +} + +func (c conn) LocalAddr() net.Addr { + return addr{} +} + +func (c conn) RemoteAddr() net.Addr { + return addr{} +} + +func (c conn) SetDeadline(t time.Time) error { return nil } + +func (c conn) SetReadDeadline(t time.Time) error { return nil } + +func (c conn) SetWriteDeadline(t time.Time) error { return nil } + +func newConn(execDone <-chan struct{}) (*io.PipeReader, *io.PipeWriter, conn) { + pr0, pw0 := io.Pipe() + pr1, pw1 := io.Pipe() + rwc := conn{pr: pr0, pw: pw1, execDone: execDone} + return pr1, pw0, rwc +} diff --git a/vendor/knative.dev/kn-plugin-func/knative/deployer.go b/vendor/knative.dev/kn-plugin-func/knative/deployer.go index a6bf4c566f..6b0d71c654 100644 --- a/vendor/knative.dev/kn-plugin-func/knative/deployer.go +++ b/vendor/knative.dev/kn-plugin-func/knative/deployer.go @@ -390,7 +390,7 @@ func processLabels(f fn.Function) (map[string]string, error) { // - name: EXAMPLE4 // value: {{ configMap:configMapName:key }} # ENV from a key in ConfigMap // - value: {{ configMap:configMapName }} # all key-pair values from ConfigMap are set as ENV -func processEnvs(envs fn.Envs, referencedSecrets, referencedConfigMaps *sets.String) ([]corev1.EnvVar, []corev1.EnvFromSource, error) { +func processEnvs(envs []fn.Env, referencedSecrets, referencedConfigMaps *sets.String) ([]corev1.EnvVar, []corev1.EnvFromSource, error) { envVars := []corev1.EnvVar{{Name: "BUILT", Value: time.Now().Format("20060102T150405")}} envFrom := []corev1.EnvFromSource{} @@ -563,7 +563,7 @@ func processLocalEnvValue(val string) (string, error) { // path: /etc/secret-volume // - configMap: example-cm # mount ConfigMap as Volume // path: /etc/cm-volume -func processVolumes(volumes fn.Volumes, referencedSecrets, referencedConfigMaps *sets.String) ([]corev1.Volume, []corev1.VolumeMount, error) { +func processVolumes(volumes []fn.Volume, referencedSecrets, referencedConfigMaps *sets.String) ([]corev1.Volume, []corev1.VolumeMount, error) { createdVolumes := sets.NewString() usedPaths := sets.NewString() diff --git a/vendor/knative.dev/kn-plugin-func/pkged.go b/vendor/knative.dev/kn-plugin-func/pkged.go index 67dc7490ca..08141be5cf 100644 --- a/vendor/knative.dev/kn-plugin-func/pkged.go +++ b/vendor/knative.dev/kn-plugin-func/pkged.go @@ -9,4 +9,4 @@ import ( "github.com/markbates/pkger/pkging/mem" ) -var _ = pkger.Apply(mem.UnmarshalEmbed([]byte(`1f8b08000000000000ffecbd5b939bbab6e8ff554ef573e66c2ea6d3a46a3f186c30d8d0313602746ad72a840860c425e662e35debbbff0bb0ddb7a4d3c9cc9cb5f6ffe821690343f7a1a121f143fa9f9b24ff5254379ffee726cdfd3a69c33f71d8dea6f91f2569a224ffe34b9307fdd359b2bff974731b175978bb0bf334c9abdb43b14fabd20fc2db20b93d07ff234fa2b826dd1f41f2c7f3585e46fae146cbca625f7ff6ebf8e6d35bc97fb831fd2cbcf974d35fd54991df7cb89915c1cda79b9b0f375b7f1f85f5f8db2a8afab7e7d2f0eb20bef9f47f6ffebcf9ef0f379bda27e1cda77adf84e70b2bf4ab22bff97453f557ff07876598e3300fba4fff274aeab8417f0645761b157f4449ddff410921dd6d2bdc7cb8510b252161d5471e9024cceb3fa3e2e6c34d50e45f9268fcfda517e8aa3accced7e72a18afca340af1f8731f964595d4c53e09ab1777baf1ba2af67588abf09c4a1d6625f1ebf0f9d510f6bf2f6d3366adc8ebf058df7cb809f7fb625ff5b9c8facb1f15efcde7b759987da9be27d5fff97e1ce3d3dbaa2ef67e14f63115fbeeb970e6ef53d497e7b6afa3fd9b0ffbff933ceae3792197d4411c1212f789f64a859321a6a24ca33f93fcb6f333f267cbdd7cb8498ae1bfdba468ea84dc7cb849efab3f93e2d62f93cc0fe2240ff75d9f4c7fe3761f5645b30fc25eecbb5a7fdb47d4d74f1ed6b7cdbe8fb3e82f4bbf8e6f7bade87f0cad1c85c7b2ffd1e4759285e786eeffd4fb248ffa30553768f2f0f8bf3fdcccc2726858d47c19f28dba3aac06bdcbca7d5855b7e89494dcd31b5f7ad5787a233a25e5d3eb1349d0a8b9b5df17f69624557dbe31ea4eb0efcabab8feb8f5c724c78b2029e3a191ced7f8e9435cf98f1761f0fc127382c08aaf6edc26791dee739fdc86f8e0ef71f5528c90a4ac93e0f14e9cf94faeaec1f77e8ecf4dfaf251d5a09a848f0f322c3c5ef4e19e5c059327174f0b50c53efbec8a13ee9e5d0b2cf7e4fa45923579524f4781119f5fdd966972ecfb6d1e1438c9a3273f6ffd2a679f5e23bf0aef26cfee24b93f74abeb9da8404f2fe3f069e4b7bb6ab0ccd7eb72e84edfb7199ff7455de4869f90be7b9db38d923a68f66d58bd4776ef27795914e41db2a17f7c87d4b56dfb2e716ef61f852902f41ea932cccba87cbf64df416ed3b03becfd9f0ab5cf8afd4fc887018e7f469c447ee6bfab5a2e212eedffde00d736f04954ec933ace7e25701804bf14ecb1a7bc376ce90769f81ed5be04a8b8f4b9749825fbd2af92e0362a70757b35a2d59b62bd857d87c4adbfdffbddd91c7f5fb6de872ffbdcb724ce46210e5f2ae50be1cbe0f58de13bf8127df7c16d15f879fe72b87e2a50176998bff1b82b5f16e3175c93382465b8bf0de27def50be53ba2c48f72521e4af393e57a9a27a87d06b13f5932ed4e86afe40e871300cdba41afdef77c98f6ecb5ba2256932f4aabf7d57ec36f083387cb770415edac2ef0bf72e5556e07747fea5d8677efdbe0a7c1908275fbefc649028a993282ff63f9bbf041ffb92fd6ca81c87c79f0c53a0dd2fa4d45bcf5f0996d624c9df1daa40bb30f86e4f7e295df6d63b28c890b9f2d742dd067ee9a3842475f78b1154090ed1e845be2bf83e6c5f5bf9ef8bf793a7ef19dad7d2f5decfab729c57fc5c80db7166fbf3e17e462b1e4345c92f2415d7f5bb9bf931d4d5cc054596fdd0287e23822adcb7bfd004b75515bf6f66fccef9f3e31ac34f07b8c545fde32a7f6ba2fe4a78701d1e271f3f167d87351d05af93f31f8b66e13e2561bd4f7e54872fc5df5f99af42bec7e87e23d05909bfecfdeca7339b17f8b502a2e6cb179f14b771f87ab4898ad14ca1e6cbf8e3b94092617f9f147d12d18b473b14e6e19099f39ac06df242220ddb2447cd3e0d7b0dffd7b746d69f5ad5799dff9712d7cacbfcb27acf12d1bb9691c20c85f817179cbe2d57d5b87899bfef2c4d3d4a54e13e4afaa77dff183a49e6d7415c0ecb99cf248f7e7eeafa3affc38fcea6ba207e1efd59eca3dbe3ed65b64d8ac39764343ddf781cf8552d7cef59ec07b1cf31df7bdc4ff82f0b346f0b3cd1f72424f83bf28fab42df7afa7a01e75b52bd3bcff2ccf78a547db722aa2abe7dab1efbe78feb0cc3cd7f9528c55fde904ff3e290c7c579c2f754a8ef538f8b6caf1e3d96b508d26f062ef7c5b17bf9a0eaaadbf018063e7a15a67ff4e8e0e795ff258c43ff6c465e0a36f9b0fe745d304df22f7fb6ccd33b077f9f277954bdb8fdb8b21afb434df77f6e7d4cc23d7fb97b1bec83f1a2ce7aab9e64e39037fcbd3affe3d535c7c3e57918181fedcab0efd7cf967e7cf2ec5650364f2fbf64f57989f57a2b0feb7aef0f4bbad77b4535ac7d3cbd5516c3fcf0c9eae2f320fbf00b09839a24f5b3db55924724fc4292287e966ad555814fc8d05461de7eebd1b905aef7ebb0aa49f1ac742f1af1b2943d4c3f7f6549fb3b627d2c8fab416f4a5561fd4399d62709f6cf6f83de2979351aef58761f2b291b17d9fb3fb728891e7f0e191c7e9f577ab371edbdff739b35a44e4a7f5091e1c6d7a6a8435cee93bcf6d16072f261c9a8ef8067e7f3f273f8efa24bd79b97c63adfebbbfb65f87df17ea0187beef8aba986263dbf2a78fdea60d0b6672f11861fb75597d7c382e9e34b85f3afdb607cb774be7a5cacab8b6c584e7ff5e45c85afee575df5ec5d45500c1afceaad45ffe731fab35e5fde667cb869f22418a7ede75fb74dfd85bd7b7e7d3f5cf66a7ef3e1a60d735cec6f7f3050bd43eac910f196f4f0a7b72aef95bbaccdbf25fc74c87c432e1ec79537245e8f866f08ffa0c4bd2ae2bceaff6561558de6f87b8257658f9aa133fd50ee3252bd25c8ddc6fdecf90da904e7fe771ef723d668eabff574f059ab3068f6e12d4a70b26fbe5b5b83e8305ffb52ecb3b7842e3ada47f81eb9bc8fefbf3fdc6cc3aa7efaf678f095ffd51bf7f3fbdb5ee0c93bdca706af378c65bdbf188c3e50efdafef7871ba3c07da13efdcfcd7b5eca1b7e925fde84ff1d78805a1805febdb1de46c59f598187c841b81fd6323fddb07fb27737fffef7bfcf6fdbdf86213edd5e5f95f78249fea5e8ffe2b0f6fb81e3d3ffdce423acf028f6e1a64a4ee1cd2776c27fb819d6183f71ece4e3e47ec24ed8e1cebf0663f6e9866338f60f96fd8365b6acf8899f7c62277f721f45e6e3ddc77bf60f46f8c4f4a629a9fed57bfbe7aaefede8a7ffb99985edcda7bb89c00a1f6eb4bcb8f9c4321ccbdcdff3c2871b9324797af3491c5ab8cfc8ddfdc78f1f6eec04f7620cfbe1467dfce9feeb5fa58f999b4fcc871b0bf7b1321f6e368f0590483a1667c28877fde5e059f642d33ac9faac6cc2a04f83bf1344e6feeee3871bb3eaefdc4f588ebf63f9bb7f7fb831be252a4c2ea2d732fffbc38dfc7e51f75fff6af2a60af1cda7ffcb7c603e30ff3db46a1cee29c24211168ab0508485222c1461a1080b455828c24211168ab0508485222c1461a1080b4558de062e28c24211168ab0bc8b46a1080b455828c24211168ab0508485222c1461a1080b455828c24211168ab0fc1308cbd94ef6a54fa37712094f78967f7fb8c17eeddf7cca1b42fab8f6bd0f788ded31cc90d4bb18995b6b3e9d19f33f33fc362df32876a165ee27930b2d33e1987760323cf3f18ebbbb7f85c97cf149f5634e66c25c3919f6c2c9f03c7b7fff0b9ccc90f5ef7032f7dfe1641e891651e458fee3c7f77132e742bf87937914fd8739995b5c04d54b58e65199ce4fdfc2611e19965133cf08cbb9659f332c4fa19451fa6a44c6cb911d187f3f33428fb75e84a046e5d78dca130370352f375a27d9d0610f485518e81a4b3931769a22c51e57c790230d3c144bc0c50425121ba8568c5570d254a5831ba9f61c8b680babd51656015db3ff4d902b559e6b91a03b44588d49b8916aec9a8ca6ea445b5ce205a926c727e8eaa5e71ccb3003a9a62a27399b4716771f05bcd561d76283cc2e355517b485cea24c285116449ecac63e07a2952cc5285b471e17138fab8767be3319d2d4163a097850615569b02c45815ae7d059379013234d852552ed468e8a9dd6491ae283c877d711e6c4cee78da59cbf4e4b5349a32dfafc4c22df114e58552ab430c6b454e9e0739804d934f232d278ae2eac6489f755b2f36569e73993c8cbecc7702a48b5052cbd6db1f454dc6a2a26589672dfb50aec688dc789f58a63e320ab93b11ec531fe44dc2167dd0e6571f5484efbbcd9431e5022952887adcff56df3343f2043bcdee731479d94608754509d367254dabe6a4741064ed83932be23e49770501672c44d2398910a6ea4126566859d3e1f12d387f138b1c12a68f0c28810e79debfb69bb4ba9efeac4e3ad36c8d34ace405fa6143aebc8738dc8db480bd44927bcd0598f074c9f076d810bdf310b4d25a741979c49841c650ffbf45c18fbce31f6b22319da4135dbfe3e76cdb18d9c49b406922ee766891c5279ae1661f5fe9c2f93f11c21f55c3dd5d463e9e57a1ce4691e74528478337ad4c7ab3e6c3cd72a1127c448b59732010d5649a52d4cd6e3a208aba4861b290e3a8920472750b5863c047cdf2fc8aed7e180034cd049254aa4c4778438c8485f27e570ef5c97501e9ef7f5b9f432e504375204b9fbc8cb418954abd751166526e33b62d3f70fbc48a3e5c22470231578611d8253d1ae385c623566bd44d8218e692127569e23e42b0eb72b8e9c021e90a0bb3f99db9435e474e96dfaf4480765f6e0b93a136e2406716235d6b94e021794c1d80f1b289f7528910e412672fed8fe314a24c99ea711ce40176ea493efb02552954e93a7cb6b9dab521b70d32850959dcf2939dc4c9672f45fff75f39b9c98a878db7b19e1c461b417ee7f81f115ef7996bf13ef3efe34e32b0af7e2dd84bffa2e93bfcaf8f6f9ff75c4f79ee17871f291f9b1eb722df28f5d97a7a214f1a5882f457c29e24b115f8af852c49722be14f1a5882f457c29e24b115f8af852c49722be14f1a5882f457c29e24b115f8af852c49722be14f1a5882f457c29e24b115f8af852c49722beffafd37851f1b750be51711b90a2c1611be6f50f36c67b2a78a16644e69776c6fb1ef2fb036a86bb9bb08cf891bb5233dc5fa566fafcff323523b21fb90977c7f3ff7f017e293543a9194acd506a865233949ab9a5d40ca566283543a9194acd506a865233949aa1d40ca566283543a9194acd506a865233949aa1d40ca566283543a9194acd506a865233949aa1d40ca566fef3a8996778cbdf4fd0fcfab6792cc330ffccbe79678a86ff7dfbe68d79a71be7518e86723494a3a11c0de568284743391acad1508e86723494a3a11c0de568284743391acad1508e86723494a3a11c0de568284743391acad1508e86723494a3a11c0de568284743391acad1fc2fe168be7734dc0275d20ca9220b6549c1d978ec979583c6e3ad127193a54c3041aad922c71e8edd0a1d910d12a9816e301ce5f64436d614ab801b29411ca9a0ab8f47ce6da40c3bc20eaba44589b4439c4534d58c512225fd33c483e67c5c16f2d438469955c18d90234ec2cba7d75ddaf4f1fbeeb3fc45fd3572408cf2f590bf2003a74015fb3849a89a1576cd1267a01a8ec3ea24b4e68e2d76d691e5428272ebe46ee227476e9915e2410acfcf561969575d5a69aace625912106f471ea734da4227c81139b8b91c9916138fab2298899db618f3783daaeec9515fe7a3b74a2c4bbcef1cabf1183ba945d93af27370c2b294f98e703e724faa3c8734da02c628231552e791ef083bc4b1c391641bc5b26d59eaa0abb0d03599a09b44e723cee643fe55f1801cd0e069b1b454c041e7d806f2d86e3003315e800eba46e4e569e439563a1e11378fb03ae463a8ab6b7b0091e9d35865b8f514a6f0fb72a847e2f21609f87503b9fb5253611b2412f18663de20f1c6e3fdaa739977881332dfd56b4d258cb6c06d90d5276d814bac46d1704cdea28fcb8a5651b104ae947aee70f460af4f1d768466cc9fd278ceb1859dd4c2f178b5083ed185cb9171e763ca06bdf36469b69da711e2b5c8e38e257404e6c95171d59336797a941f87b89a405962038e34b093624d6563948318a94761e5981d7414063aeb68d4276bec3bb362296752e4f5fd25375ba4da4b8f071d92a7b5234beb2d6bda9acca69a8c3f6a594c907a6cb55d1169795f1fc754cb995c530e4b4d9ed61b19cf1027307d7e57ae2504aa7da7a9ca21e8f3ce29833eadb8f284b8c9b33070c396705644c62688dc69116932abe98c4956aed96257dfc16dd1d743df07ea51cffbbf718c5ca982afc25cd2b5084e843dca14c67721596560e20d474ada2fd33e052ad8e10c7401475ab4ebf33139e89d14c8c934f2171613ccfa7ec60a4ffa70f398fe78d4dd5087bddef6fd4965db418fc6e3f1d0d8b6663bc8f73aa25aadc783baafa7f3d17e7829e3ef1ea3e773428c55c2f5791d8e0eccc4c98aab9b952b55d8c1254ad8416f56bcd541c76e91a394281153c49927bd4b7ff35177cf4cf47930f8c1e977e70163c4f63efe43e7f69ef9c3c9efe30f3fd2637b297d48e9434a1f52fa90d287943ea4f421a50f297d48e9c35b4a1f7e4b8ad287df040a297d48e9434a1f7e2b38a50f297d48e9434a1f52fa90d287943ea4f421a50f297d48e9434a1f52fa90d287943ea4f421a50fff51faf09cd2237a881c31c5cef1191e2747658ebae971b59b3372540e689befea44539f233c23be649133aed8069cb55f39b85df15ea72dbc6eb5b31b635afc8d984ed5643fc4747a990ba633e127ffec4661c2ef0375c6bc7f07d561ef28ab43591dcaea505687b23a94d5a1ac0e657528ab43591dcaea505687b23a94d5a1ac0e657528ab43591dcaea505687b23a94d5a1ac0e657528ab43591dcaea505687b23a94d5a1ac0e657528abf31fc8ea544df684d5811c61fc05485699d9a28db81bb60b1bb6941298a0134f50ad6ac8ddb778a74578a735e66672d0d4e8f840ac939929c646d565609799c7083b6767b5d856b2cd6ebddfe653de66eca3e3781d3e599235af376b6ecd5bd9bd2867bfc0fcc8628e3aa146dc3af267f33b941d3d5fc5aacf79070cac3658c4b54de2182d888959a3dbce03de50cd8dc54a5db8286b3f2d739b090e60cb2c5f9639c840ec71551b2c2c415b78c7d56ede3c6c5ea4c7d4bee502626515bb666a0da7a4d8128ddd02b0f7b7d393333715b0a92d93c0b9a392c6c9c162b3334ed6ebf452cf85c4e370b1e270bb72cd03748308efe68db1991c867b19db42592a8c6db934d974e238a66ba442e92fcc1c01d8ae389633b8a384b9431b70f5e7edce2ab7f3f8abcd9bfa9233d8cdcc987c5e97b9ef5a0576b4c6e3c47ac55931cec00e72510bb9fb3ae025823b89333693bebc43197156087e22b286a31f510e679603975b1e037f61555b46d904ae715af2fa7ea310686ccdaf0ec036d8a6bc77faa9321effbe32e21671b88243dbb13be44e23bc9b3eea6c225a9ecd6aebccf28d1d94d73b736bf32663cc098f66f383e54abb251f1760a1b088635d6726b54e0a64330f5ee92ce4c41672473294c531eb409638439eb0abddb4afdf0639623aa4997b13a858e956d54deba4ef378ed1e2b4e4905c67e60e38c64e4fbdacf6bc4ce4ad2dfc0ad9750b19410ee7f69b69c21cdc85c9d07e87576966968c66921c28018789d72e3916da8acdd8eafd295059e0e7f1de4ca165abc7142f800ed543bbdd7aace5bc514e1eb0beb3beb6e1904e8af75e669e7c595c78b9e4853b5cd92a64b6f3f9c99e41dbb159de4f4dc3719889c195a54514df4aee4f904ddf9dce0b5db1372e593b99cd6c1d7cc419248e6dc95606d2ad232e2c5e5270271a812d12cf16ed252714a162ef433b6e5febcab0bd5aedbb1609328541bcd6d7e1355d634c6f15eee00c670287773a6f71566c75a2f3d0db980cee912d94ce622e38cebcdbb08033177a8bed7219ecbc6fe8e68fd27b6e6f369c6501dbe4cc13a95727bbdbf0307b982bae91c39501bc89e7d42676aaa3ed94ab150f3ec379ec79a9d29ab3577d711f24e2012fd2efd5e9c1220a443b8f034cdc6d7969edd842e5e7f8f3d6555a632bd93e4b0ac38182c199d077ee3b343393356f5aafcb58772bde22e1623df4bbd7f6ac603699ce2d196b094e2600b268f8b6c86f32d02bcb113af08815305971c4f155a55e9d2c0e669614a482fec3b492731fdf81877026416f2bf90148bbd0c18e71f238db2d19eceada663b3f6df2b960dacac16361bc49f522508cfd1abcd6499fd75aac82091efb76f7ba9f0103ba1a6fec741b3a7569f1c0f439926edd78b6e225d39859156040dfde1a00a05ee7c104cdf43c485ff7ed3e4ee8eacd30ee71668b32930d729d0c5b5ff6e5932787d5563b18dbe860ecb48931f38ee6cc16568e7df0b686e06dad9db75b77c66668533f7000dc6631301851dbcea313b2f16a33b7767e5a6eac146e82b48ccd0c48db2dd0968cc958aaf53960a5ddeb7a665ba8820e256c8e3a71873861875dbd1bb65a5c78bded690c99e98cd97c62ccb4ee6136e58ced9a7dd8b0c450e7a70767ce789cc618bbf9f3badbc174931a07642b6b53257bc72609cec9cee460e967a5bbc9acd476898176b10e4fe672bd03b3c011e507307fbbee789dc0ec483c7eddbdce5f7030b6d3ce38ad3b4366186f87636fbb3e79278f3767dad0ef2cd78c61b63e1ab33567cd8f737b2bb906205f1dd79441571f1e14bbc35bcc8519760d625a2063ab6da6dcc1d763608db8beaf4f06ff29c8408654b0c333ed557b9aa7e9d198692773a61d565b2b3139253667e6cedc058c913cb70b5e1e75682e343e8f9d350f8eeb944cacaccc90829780531a674e1283d52ba4b2c99a275568b31dce3067bcb60b8def801aba84f4f621c80033da882779db4d7b5de38dadc63cccd6ddca991f0dd5e63d4e21305b4fe0a86b9935b3790be81b735e3296ab9c00a767b61a73e6dc327d5b396c16a4f21db232dd7806e68263b352e9d9cae9b5ae09257458123aa05bf152075d8b093743dfebdbb13676d3ce984d3b63171c8ddd7a62ceb4dadbce0f708b779e0332388bc90bdb7667cd94da4e45636d0bbec747475b819b356b1c02a7b64d5ee2b76abd80395ea29375e767e6c38ab58480135e8f17bcb4879d48825c6f83dc18eae9e13a0e42659d1e27865b6e8ddd9c413c3ef879ca07ae2943874c3c02363e0f0adb56f820ad58e062c3622d1ecfd6af743950eb7cc5812ec8c42ee886b20bab977d27d379cfc51398c6b2950ace923974be020e86ab6b6bdb6221f14e1b9b65506a6da0ea1d831d78d8d8828266d36fa4c79230533a388c3f6cea3b30432a49463fb8d785d16e5b739db7e6f6619b62c1764479a3ea860dc81ab326b05571b6057863daba12a664bfe2bc2352ca640d14f31bf55843b78c836c3df8a1502519cc8ea5f75d5f86ac36b380f73951f5153201f3ea18a8e60665f5cae7950ca8621e707a6e72d8df1208cd85b9b114e2af4edfa85bdeea756ae72fb41671fad770b4ebc75769a6b1eab3a9606ca16e257587396b0e5356f2598fdff2168f5d450679d959db7861efe0c2caa33d66c0646bbfb6eb4fd31cb6df554936e8f466727a9d2ec30286080fb655183b45b76c92a114cf301b2fbc13489c0caeb669c9c034ae0d001ce0601f259560d9afc7ae37d2652ffe3e4ac50522ca7cbbc5aa638307cc81c2518ff98aab5590096d70323bcb85cc86b5beda39fc0c58f3cedb41ed1b3ec6092f748255b30892713b61df81e7b994dd182fe6522608ba70be3edab979b0ec358b4e310c586c390a9c6107a4c642e76c76be4760bddf6cc12e54cd7aeb4266fd7a2ec579ce51f09c63bce27401ab20c10ecc86eda939b17aaec3e522b0e72c981bed604340da7a3ba25a27ebb3bf2566b0338f261bc3700657483dde792e56374ebc838ac4bfd661d8cf3363a4ce5b2f270c747416669004b9d422ee30fa59f22bdf87f3527db7b5950ef36469da55bb76d899cf62ce704ac63ce13d2058583305b759489fb10d1a932f0e6bde1cc664d409ac97816e95891decc418ab62ed3bc69096299f7d9fcc9c84297110036ccf952ccb55e6bea2b006ab642887de1a78ccda39de793c046b3ede0302547c32f61618f4b65de52081aed6205ecf579cc2208e2dbd718ec8bcee97786ea431419ce9195d2d585d2d40e6e87bbc7e67db651c38acebef88b471181eeda693611e0782d69e7f2b2d96450bab84aede5de6dfe736d310036a3b8d2d5b81dbc0058999075db8d35323059f416e74302b058be88bd011337f5eb3a16d1d0d45d1bf516735768e8cef802e482ef3de977335bc319dba852a2b59647e007635b19d6382b9b2b219413094827b50f1d29f5b4b60076cc0959b87ad755c9da6afcbc497f130271c7cfb73fba4e2269c452cca74db77ca877017577e5e3638354d7ba7f8eb94ac370c6c0caeb4824cc98dade419a972c236f3c3f85f8c7b1ce6d2d6c994d9da5180c7e8fbd031b5803b4eac19918dbc2c4d05d88e1aabe64e3a99c4748305985b3b69f0e911778c51169cd389da80278dd73d1b878f0fdba9606ce7c787997d3466d3dae3d62c9ca5ece04f6de1cb717813ced91cba010bd27212e680981bf1eb86588ae902e2e7d257901d3fc38d5886b92e9b276989388f37b271fc78999f507d363e3ec9d3bc3366eb3e6fac71f2ea07474f61a62470eb4dccedfa34b681cdc3ae122c86d8c176cafb0b290b88ce9a3ba883d422e19c8d7d0e72e656275ba5e8d66c2c038eac82dd309eb448551ad8096d90056d288b935e6711af9f5ef89a82b1d50e66ff77669fcc8411bcccca3c4727e62e62cd99f1c2eea7ade916dcc3363ea11d5979dbd88676b97bb0d95590890038f0b84ef51803fcd5761563b3d33fdb2aac9deda87783cf909166c5990574ccfd2af78e2ff2c3f5f979e87de0add1991ba633d475673a76efaf33c6cc7e911fb335339280b494c24c903c9bec03773af117c0c6dc7169dba6dfc7e96762b6e2cc64bbb31c700230dcbd999fe3637eb4433f57304ff3cedc6aac29331398cd1973977626071353f58671629d1e3bcf861ecad80eba1e8b94f53e548f255a28bbcd2cf636a7b4f5b7928467fa64c395ae7fb20e665e9ec6353ef1e07341e33b93f6bc857f8377f347dbfcdcbf658d9dcdacb671e66dd7dcc356e361a631f085efbde6ee39dfd19d4daadca15489374e7d0c66718181c5a37969add9e2606ce157c479adc7e90fa6025d1390bbd1f77ecc4fe828359205cee8ed50d2cf2bb517b635d61fb6a6b7ced82350c9699d421300ab36546d6265ccdecfb593a506c76d2a4c02171f96272019002ef0e8073cd63f4f62e41c9acbdaadd15dc7892a0440b2edf8f3766b2e8c3973823bc0d94ec16f176019a4c0c659e9207e7d727680a0196960060156ec1fc6ffa2df179b6d7a72e67a1d00ab0c185ddd0260a3ad943ccc61bde4cace60acdcb0858770a1f0815cb1ebade2583cd03fafffb66f3c633fc764f8c0eccdcf3c1fc5ae1bb28bf7ffe8879e77bf7147f63eeb7f614b769ee53fde731cfdcc937ee6493ff3a49f79d2cf3ce9679ef4334ffa9927fdcc937ee6493ff3a49f79d2cf3ce9679ef4334ffa9927fdcc937ee6493ff3a49f79d2cf3ce9679ef4334ffa9927fdcc937ee6493ff3a49f79d2cf3ce9679ef4334ffa9927fdccf39ff9ccf3915d79fcd23350959dcf2939dc481976841d56498ba262e93bec01f13aa3c9d152dee83bc4090c7463468b0a5dcb608d65adbfdf069db69423327ea5294f939ff872349193742927f7ad368f63945915dc48b136372bc483d4722141f9ba199e2b261b2ca436c82d026549bde633914ebe831bcfb5d82003a787a86857ddf4ebb8c3bc512cd72fae37d248eabf90f338b119bfe811669772be0cfb4d99efc407cf793f97a11cca201711cc41e375f1b9ae0465fc9b46232da82d57dd7db44cc67658aa668bf2e14ba6667d4dfb10fd20ee6b3badd26bf84a3bd7ff2a1dffbe37df9a5c3ecfebf447f2d1d717f7fab4072af33df5b992a55775b3cc9ee7fdd7ca3b2d5ec6d3a735d441922ec7b824cd738414a976e1f1d6447bbbfe5fb5c3a59cdaa25aca0ec986eb647af779732d93e339c712aa0a033751f9d0f5e96b91b6652294916a08b7261972d78d954b9def080c4ce236e8842d56ad5eb6d264bd44398c914ad24b19b5854e3c0e943803e92a99129c68639df77d6b4d3a38f48dc9a063724444391ad3b0177d5c56b6943582c9b1d1926bd94a397a0cd7e74dce99e5df4add5d478977a07757d90b7f27321fff51feeee3efe3ef86ac53fe8ef27794bfa3fc1de5ef287f47f93bcadf51fe8ef27794bfa3fc1de5ef287f47f93bcadf51fe8ef27794bfa3fc1de5ef287f47f93bcadf51fe8ef27794bfa3fc1de5ef287f47f93bcadf51feee7f177f776d92bf08e1e5160978ab445990c80394f7fee31356dc191e8a8a521e2030c986aec96c54a581ea91682a68021e74d03522acc63196af7054e439e60eba12137452ac2dce30d273682fc21c617c5564f115b29a5c20ab67e92c17eb68f9588e06c869141e0a7dd5dd47eb8d54fb8e502247a956b29460771de14ca97ce709e01515fa05c87ad83157286b9b017e29a74bd939cb1193e039992f65ddb68069af6ce058b660afb6d3a396bc90532c2150ed421b00468184aa5207ea91ac2e00d990df75b25c5fd36e6c0e303627b2416692a5ac1778611d1e92fb16a9e2ce738e05e24de661171d1e66d376482f4afb3ad7510e5b9fb3fb3a269a6a119891063aebc83fd74f5f6f2f60b24748ed11a0933dc7dc435e6fb123a44b39bdd6cf725b0de09726cf454d154a244b1fe528d5b12ca89e6bc5488e49906be50086e5cc08632a437b9cd301fa13e0eca54ec428919e0069a4091680b982692a2628039de75aa4d715947c47171c811bc0b8f918fe7b3ae15fe5cef1cf0af111f41308eea25293ef5b4d65cb8037fbb0519081237648d7d729cc0841aa75eafbcaa05faec540873d60596250271517fd1edb8234675dbbe8547529bfef08b9b6b00aafd7c741f60cafbada593fad182f8c7338ebd4eba8ef78633bf479bec2ae4fe1453df6b83a0f329145d9ba586e0ed1cbf25edb72c67cbb2d55afd0b2c7bcc0a14d8416cb520e1d61385e005ec0cf446a9fb7ddb91e9369b475c829e04803bb69032ee551ed62b99176be0a76fee97ed0fd2feb5294a3fffa9ddbf10d6eefdb08e0e8189f37debbbb707f1c3bf938b99fb013f62fe07fe3a8f55dfa8f9fdcb1fc3d2f5ee93fee42ffb177f71f3ffecaee7b77df85ff98efc07f77f7174c4fb89b70e24771f291c27f14fea3f01f85ff28fc47e13f0aff51f88fc27f14fea3f01f85ff28fc47e13f0aff51f88fc27f14fea3f01f85ff28fc47e13f0aff51f88fc27f14fea3f01f85ff28fc47e13f0aff51f88fc27f7f1ffc3798f22be6973784fc5e58e6d69a4f67c6fccf0cbf8dcd3c8a5dd8993b4efc6736cd1ab19909f3fb36cd1ab24e37cda2dc0ce566283743b919cacd506e867233949ba1dc0ce566283743b919cacd506e867233949ba1dc0ce566283743b919cacd506e867233949ba1dc0ce566283743b919cacd506e867233949bf94fe7669eb02d8f1b65699db4409da401c55a6b73c8a2cc647c476ce4a874a173dc218e25dac26ab50569b1ab452803bc36c7ed53596d23d9be6a475e269648055da01e63acdae38982bc55226e12799c98c28db4f39c49e4657604c78d7922df992c1deeba59500339317237f193ebfb7295f4f193d3b334173a0978a94599751af2378f6da04ccf1b1481135e188d1c153bad93e6c3c641aa7840ce70e2e2d21a36e739b6812c35d00d229881182fc68d98bc3c8d3cc74a874d89d4798455703a6f6884bccbc6444064a06b32ab0cb79ec21497cda55c7ed8c86ac8b3a6c236884ae23966a1a9908c276ada95d6cbcad20e7142e6bb7aada984d116b80db2faa42d7089d528f254dc6a8b61c3a66815154be04aa9e75a7d3b14702375d8119a317f4ae339c71676520b1389f15fd43976c74d9bc64d95c68dd03c599a6de76984782df2b863399c00991d4b2fd7e3204f2ff92bb1fcd856be237088ab0994a52cc8c4faa20b5eaeb798374990486d905c9e0d79ecf5a6eedb50538f25caec3b392a234f1dca7d42dc91c899c906d921f2171613cc8a76c5b1c293bc37d08d63e44a15dc8c9bafc99914797ddb6562a7a96c3bd4e5c2247023a1b17c663bc8f7f5a45aadc783ba2f9be7f6f1097829e36113b1e0d4a7f57c63379f1362ac120e6ed8539f672f13272bae6e56ae54610797286187ba5bf156071dbb458e52a2444c11679ef42e5dca51f1bb376dba98833721b4abc918c12d4ef8470134f6f701687dce297f46f933ca9f51fe8cf267943fa3fc19e5cf287f46f933ca9f51fe8cf267943fa3fc19e5cf287f46f933ca9f51fe8cf267943fa3fc19e5cf287f46f933ca9f51fe8cf267943fa3fc19e5cf287ff61fcf9f9d937884cf9023a6d839124d7d069ee5a89b1e57bb39f3379c86763e32b2d785b7cf45bb8a5df01a7ec2fca37c0df7fbf89a21eb14b0a1800d056c286043011b0ad850c086023614b0a1800d056c286043011b0ad850c086023614b0a1800d056c286043011b0ad850c086023614b0a1800d056c286043011b0ad850c086023614b0f98f076c1ea19547c62650959dcf2939dc8c1b006195b4282a96bec31e10af339a1c2de58dbe439cc0403766b4a8d0b50cd658d6fafb0d74d7edb049cf78dd069db65cae8be5aabb8f36e78d8f3455692e1b30d9970d98e4c972d8d0a793b4f3664e85c75b9361a39edc22e162ddac39b1c12a9860f910051938696acce0c5b4b133700a54b10938e0061961a0ab55c3864f9be9d7312fc206ba0a0b5d93596ea48f72443ae81acd4605315441b794d366ed58e952d66743b91c8159014b08543b59c9d3644c533c20552951a2957254e86e7788a0ab77daac1035b52fbfa0060bbd44b9952dfbb4bb43a4a5e2ca5527c9725de8bee38df2f25cd454a144729f8f548719cbac52780832d260d52b106f34366fa5bd6c9f76ff17f1dab00153702da71d615e2fb16adf6932e0b464cc4b9fce977529fe7d1cd4b5dfbe0386baca5e88a8fb3bfe1f25a2f8df47440d59a7441425a228114589284a4451228a12519488a2441425a228114589284a4451228a12519488a2441425a228114589284a4451228a12519488a2441425a228114589284a4451228a12519488a244d4ff1222eada167f158b120896c5e11cb197d72b2e66f0421ace851b9ee5c3f96d25ca82444ed2a59cdcb79a32dcbbe050117484137675127412e3ab0aa3cdcfe7cb6d2412aa60875dab7fc6fbae55201e309a0aba2013bb952c7570384f4e386933ed60cca6d170d6dac22478610c68d693ebc81bce633b6350ee80413572065994191150c1095fd38d194d2e8732f88e90afc8bad416d55276611c24d3428e521d77d3489b31e3b96d8bf1bcbb6d06783b033bc4eb2974b562b92e74d91d702d7144bac67a59a502c1ac4e0217f4e10a2dc50a90b54a93f5a10e1f92fbf6e5b96fe3f97b5a352256e9525e0fa857b4cc5ea26276ff8c04b9169d11aba5bc49977294b6ab4ed2510e5b9fb3c7b3f02ee575b5086724d6d47914f0567f2f0eb2756471f7d119333bb715e8e4880c7ab25c04d12382661e10279c20c09ddfb75532606c474d2e479d20d7b28ef5b8268f28dc157d1364cf31f790d75bec08e9524e2b6d119c71b77429bb4c81bb31debe5e074c6ec644b81bd267d1623dd4375441d697a77fbe4af5162ed266cd1ddb80b3fbe74b7973df6a73e51470a0c3b27440bcc9f479802a19b6dd0a0edf47dab02ca89e6bc548f50a2d070d7425e2f11681b244825c6f83442a5172c5fcbe81b08d710f792326339c85c8982d54ed48db3291b19b1ecef5c3ac52186355a9601225d81148b8b8a6d55deb7bd0678b3c24538293331ad8095bac2a0c76cd59ffec55ba694c3ca76f236101dd5ef7460c11e5eb1a2cc8016eb4529b31a2266bc9cbbc2c65fdaa079a6a9550961ac4afa380ebfbe43c3ab765836589095d890c673f9ecf637c82f825e73c2dbfac7feb7981999f275f7a03d7cfd3de06f99e8b5e383e81fd198c4fbce759fe4ebcfbf8d3181f230af7e2dd64f2fb30be3ee73f49f1dddf5d783b9e13eed93beefe1d14dfb5cc3fa6f89e8a528a8f527c94e2a3141fa5f828c547293e4af1518a8f527c94e2a3141fa5f828c547293e4af1518a8f527c94e2a3141fa5f828c547293e4af1518a8f527c94e2a3141fa5f828c547293e4af1518aef05dcf2c8ef793928916a912037eee4641a4115649e0b2a3c2ba2c00571b8114ad48909e2cd162562e639ca69e5e076e5e8acef1c53e86acbdfc5e0fc650067c2fc1481f3eb1b69311ccbdcdf4fd8df47e00c59a71b69510487223814c1a1080e4570288243111c8ae0500487223814c1a1080e4570288243111c8ae0500487223814c1a1080e4570288243111c8ae0500487223814c1a1080e4570288243111c8ae0fcc72238dfe36f02ce2ca0c3c62e0f49909b25e22677da6cda18f2e4a8c94604d498688bebb3086662a7a96c8c32920d7b41e52446ce21bac42347c54e53ac026ea4c67358a22dc0093aeb31dcc22a7cd78890aa34900731e4ec68d8bfab933ae84a6dc01106f1baa02d70019d4914642083ae4e506612382d769a4a9a3e0eb89180231fc6bdb154c2049dc441573ff98ed8c8991023c7bed3548bc04c61d162bdc419e8028eb4685744863c39ac76f3a59c18d19697863d933ce7d068f39878ce91f16589a0cc3a208e3478619ccb6b91403db6a103524d852ccacc71afa56ed82f2946ea210a72d06095d4d0359a216e47113455279a2af679eb7cc74afb327979fa28bb1104cf61ab717f2fab44193e69aac29ccb58798e906367d8dbac822e24489e2c7d15c46861159623a4812a9628b74e0f511169eab1c41968a06b9e1e92697b915b718ff7e564dad7690c55f25a8ed789e7f47900a7e0f0fbf635ca072ae92d942a1fc7c7f31646f717808a63271f27f71376c2fe859d8cc6eeff5d8c8afd280a1f4541b86254930b46c5dedd7ffcf82b1b19dd7f97a262be4351dddd5f78a78f938f3ccb0b22ddc888525494a2a21415a5a8284545292a4a51518a8a525494a2a21415a5a8284545292a4a51518a8a525494a2a21415a5a8284545292a4a51518a8a525494a2a21415a5a8284545292a4a51518aeaefa2a80656e50a4fe50d21bf1193b90d48d1e0b00df3ba7a1b99792a782167c4bb5f2067b88f02f3f16ec28b3f49ce701fefd9c947e6cacdf07f959b1941995fe566ee273c7bf75110deb3fbd0b9c0efd97de851947233949ba1dc0ce566283743b919cacd506e867233949ba1dc0ce566283743b919cacd506e867233949ba1dc0ce566283743b919cacd506e867233949ba1dc0ce566283743b919cacd506e8672332ff0967f82a1b9b5e6d39931ff33c36fd3348f621796861538ee1f39c86be4687ee3315e63cee9395ed74b5c04d54b9ce651bbce4fdf02661e29975155cf90cbb9619f532e4fb19551fa6a66c6cb912e187f3f33538fb75e84a066e7379a9d2716e1710734ad931e10679155569eb4b959211ea4da1c70d01198a09354ec083bac921645c51270a0f238b1861b89419d24201e749a2a10fc348e273b84690ba9435c493c7e1d9f77454b10472ae8ea07a42a0cdc48d963fce5ae8f4353cd182552d23f433c68a03cec32863c95345005933e0d4f618a55229628b348280b5f832e6dfaf87dd788600e1a8fb786ddda86ddd61c10a37cbdc4ea7d1464e014a8621f679f7fb4e68e2d76d691e5428272ebe46ee2022fac43702ada1537d6053c3f5b65a45d756933ecf0d64906e2cc18c9120955b0c3ee90de524e950cab7d9d8009744c16f779eea408e552ada9a409782b46ea315ac97dddd991c7298db6d05994488caf92e775a71e5b8f532ab448875dd3a01b138f078cef08b99c494da032c34e6a17394f9e2c6532d471871d81f187dde77089d4431ff6807893680bab0832403415347021b5fed0c693a59c4ca36522452b6e3aee78f7e4b9a6c236482e6dfd98bf5554449a5c449e2c16d0512aac46edd3ddd53c59b27dd58ee075a7b6f32e78eafcd92e6c9a7add796ee7ab60e71f5ec78b54d2eb230978333aebd1e32e7572af275ae46da4caefdbaa6fe34eba848d3c2e261e575deae6c5fdfaf444df628f33fb34c859e7ce65d63bc4e31374b5c873d74b878b19bc98dead3ab11a74408ddb805fdf3dcca613e33b75e16ea2525395064e4be42f2c2698f5fa35b69baf8a273c2b26c62c3aacb84b5d888f65619962b999448e23b2e7bcb20167479e6ab241768cb485d56aaab4deb2a6edc952ff9ce00c34785af63ace0c6df0a44f3c698f3b392a234f957688134e883b1239ebe33c442b1045f65cdc02795a43799a879d3eee66b82b228d5825e440a7258748ebe579ab450ee836ce3a7948a689319b77c669cd9abb60f2b0d145bd93825ebf567694af39b1c12a68b0cc32a12b9187448a838554f98e190f362011bf069cd83c0f63d7beb3bed366f35c530e4b4d9ed61b19cfe0863df5ede371f69da68e7d75e58c766be58089e7b007a4da2fc35cd24da1eb353e27f4e9727023905055ea403d92976907bc44bc67bb43ce1b430e22775a449afa862e4cfbba9d5efb247494d41f74d838efdcf8b833e1f3fe38b4efd2e1869d132bc429e9ca953ac45b646c43012f8774a5d34372df621ef3ab4c3820a73cad32b3451bf1e039e6de7330597d378ec9451f79df3956da4227012fb5285b4798237d5f8c368a65dbf2943566466473a0c319d9c18d0450a6709e432acfd12be84c2ff2b1a64a33a41282f2756d67800972128d7ddb22412295302a5fd9106db07916e96d267248039d75d4db692fb323d4d779766cfbf0503e445ea60c3b69f63a8c071bc512e4885db8e9eb6bd8253246d97a39daeb758454b10d642985ce310e37bd8d33769a6291a02f7f160cedf272bc08167aeb676087fbfe9f9915eef3de49b1a6d42cca08a32d86f078294f5aac821396c5e17e3f262dc7f423cf992c9dde2ea9200f32e53c0ebe0a57a2dc2290d7cf7a7f1ec3e64a8564291ac63859ca7ce748cebb6c0efd780c2ba5beabf7edd80679baf45c9d8c63c8642967526f175a949b2d52ede530ee0c69af979e2a4572f45fbf7567cb67cec5f08eeacfdd0fd8fdabd475b2c14d987f70b2c1fdc6c9c690733ad9a0930d3ad978cb1e3c39ed9c139b805f4761d78f15220bcff38c952c6940b1d6da82893ef763a5abb0bd8d5bca7837c8a997f948503e1c8ae5aa2bbecac9f4aba69016bb5a34faf19632f83db254f4e32b1a7defc7f94572887c47e01057f7fe1defbb56a1a920f6b8a8f7478fd8e96deb64d9fb9e408dcba093ae3ec14bbf1cf246e4bbd669f0e917a0cfff60fbaff38b85f1382e9ee754e31c633dc48fb9b8ecd3858e59200e9cce3b1ef7634e3b8c83ddd98793a5d473adb82feb50de39619ef8ab25ca61eb7320edfdfcdea7d5b93e9f46041db6c472d0a735a4b75e48719029b5b6a867881318e8c6cc97cde0f70dbf7b9fdc1b7db30996a5d6cb86395b33a6291d3c578fd146fa8838fd2b74cc67615799dec2453a8ec9bd1fe1827ebc89bc4c4cc38d54c2448a519ebeccc7390d4bd486f1ca22e162dd0c61f34b5c0a0b5d5dd016261364439da4d035499091182dcabe0de37e6c46c935bf95a692acf76bc275d1cf67a681aa749ec344212726c3b8be609e9453a81017f47e420eb921fe4b3c97b6aba16b1588ebdbb99f034d73df1132d405952663de73f546ef0e91ce812ec8c4aeff0d5d6bd7cf8bde91763f4f48a1ab5fdafeacff8ff5e7abfdfc0174c1e1457cfcb93ef867f19df3ba1eeb6e1edb40993ed1eb4b59d62fdbe184177a8932fcac1d86398af2b8ebf9b338177a8b557187b84374dd597c2cf3160e3b8f3ffaa6b0afc70548ce7ee91ef5fe900bc9ca3563945909e2a3d6e7267d1f63fb36583983feb65eeff72562ed39a4597156ebf1460b795042159c569cd042157c0d3aa186b2d9fb45f5633db097367cadf74feccd97cdb57f0d7ed533fb31edcb72bf7cb68ed0fbcaea912c1feba8d2ce3669b9913ef6f385177ad58cba12258ff7b5de76454febb9d7bd55df96d97db121e6e76d225cdaa384795a3c863d44280715920f9191a4830dd4e4a77df0d8c24e285106dba5ac9fcbf6f3e99d7de74a530516a9874a9b69e5725b2dcf3ba733d8d59bb31e345e461acfd585e5b8fef3ac7e978baa9f7345dac26cb1abefe0b6e8fbc968ebb3b86ffb0aba5abeeae750f234c20b7238cbec7cf5fe7a1faa0ae36d8b085e6da7242e37e94739673eca515923ce62916a37e3fa86ce04dd54d416d5b5bdb4452ff737fabca51fa47e14fed13b7d7f0e1fb9bce9fcbe16bf7ac1e29df0f127fde0ef7dbbfa2e3f98ff8d7ef039efdff184f9fbc9eff585ff377cc24a7d61ea0bbf69271e9de27058f07cb2c0965d16b1ae8632190da27e3de66390db4d1b63333968c9b0c0952055dcf91c2c910a9ca772c6f9f9e80c900eba46f290484c9003728ef7ba601474da9d7631deb2d6cb0d83db78fd9e3c0eb2c9d53148b43b4dd60eabddbc3164ad7a1257e53b2641b939c6972a7d1e0ab861bad56efa2c2ea882037484143ac2ce77c0a9971febec1ad78b49429fa61e9ac35127c6d3b87ad9cc7394d3ca294f2b5767516e95c8b187854b77376dcc6e72d4a28bbc24bec80767fd382f0de22c822e6d44267d791af359d9a791969b6ca0826e5cd0799a5fed657e19cf95ce0baf1366b59b9ffafab9c6b560ce032d73893f41999842209e0747705a3152e6b9fde4050a2b4ef98a13768738f6302c2e254fdbbbcfd7d5e91b17733793e3cbf6e82739883b72f0bce03b388b0be36ed5891d747019f056176e842650d9de496b832c68d72a8c03deea9d8cd6734a6ee5982d72a55e57bb55c7bcbeb79d0fbabdcaad3c4c9ee9cd65e1acc48b74483fe0e2d8dccebb9583b93523826d2e79018bbb0d989fd65b2b76e6a6b171ac04cd0f073cb78ee64c97adeebe7316018ff838f19d83e0cfe647ec88bcb195eeb06274160f54cf2d1fd619fceae5fac9d98106c97563ab07d64fadad9f152c50ccfcf396f9595d8dfddc3beb9bd7185bad3113ed5aff5fd6a3ec97cd61f9549f5c8e6de10254d0359ed525ccc40e734a075590be48eb651fecdbf1651feca06bb66801091c75f0f1e517af13c891de39141e1797c50e76e21466ca09ab240b37628678bd9f08a5d059b7abe7d7f5d07ebb6983557c77b65163bad965719430e16648f7e4ab73d6d86a35c8c4cfcb1374ad9914db7931f1729c6f483109d47a1faae5d1e4ee5bf314751e3b3ffabb9431edd88527a9f548694286c45021aec14a049fa67bcf99ecfd93626d6758b79552db6ecdd4db01d7dac1cff60c4ecc05a9b7f65cfcbc795627a4778651f6fdbe3ddade89a8cde687a7b6628ce389cdc88689ca17e488291e16729fd5dd21c8c449b86163a85add0fdaeef437b4ddb3f4fb3ed84fecc2455a7b8e950609734e5360205f3cd371df1118e8e0ce772d61a88bdc2cbcad7d34129609b7984704a42b06139b5756606e749b4cbc0bb8031bce7182f218a014a8eb93f419edb4362412b73ac565b820bcef4a1602d0c73c70712a2c50aab7be6b2d8d1c97e1023b812366988d1fb0339ff83b08cd9d5ed95b467cae5b160954d04015341e475e8c6763fedfea3f1a997ca39f0c3a7b18eb45f87a195f8c64d0ef9fb5c527df11d2c186f27a815da3f5c7f1f8e938fb7a9cdfae7f4bfb071c69e04227012776fea29f4c9353dff6be6bd4863c390e63d0cfd8dc2d79b0c05a30b6d27c9b29baad0ab9e308c6569108eceacf902f8f01970ad8661804cc04b1361b6ee1e14131586b519a40814ac0947e9029bcbfa965c4580f0040d9dbea737f5e1e6d40809543d352610eb653ce488fd6376c2ed7d7135ee82cdc3cd505d00c0b3bafeaf7d237c771fff38ee17eb61f077c597baebe0b3365bf1a5f08d7e3f167af7ca6176d398c6bdd339dcd87f6a87076d6c1ec710125c840eebb2613e4698372a9f673a341bc9ef77a14666c1c64e69de754ed3006cbecf0d23f48eeeb1779aac7715cfb295beccc896c903809d3d8deee60096df215a6c4043b522005ee209180b1832723873124c4b51dd3df28d8dbccc589ef281b8710c59ad70ae6accad86a829393dcdc4ef7301321d8e95fd71c66825cd9aeb7f0b8cdc183cdbcb2c52974bd17beeabbc7d9143a900409cba0aef77784063a26f3ac8f6f9e8cbbff8cdec45ed6f75bef3d3a72fccb3ac2298997eb040ffa70f9cd1c075f7cf35376bd41992dac1852da1bb1085352385b788073abf1529d097778ee13c9def03a3466d27ac5979cad98b5e94a9fadacaecc3c662d5e5f2012372b1632602e3cc05460d60ef41f36f7473bb788afd6a790d842e098b6efa4876fd9753cf8aa56871dfbc776965392de0ff51c935939c71672fd981efca0deb5f1d8c7df50efdf48bbf78f622f379920537658662bc4e1dc77847cb51dd3fd39bbabcb3ed16d278f6d7b010b688b9cc5e972c01d559b259f8153774bd6fc6a2faccf28d70d7b669c60523b1b808d300377b62bf91eaf38f084bf7a5bd330554b7654f62ecc300fe43a36669ae0137d620269e66fcd257688d4dbddf7e8f8e8dfbe55cf57bff7af8e677d5a43bdfab9579bc9e4682413eee7e60cc5091268401edae8647726a7342120c226151740214b2f0df638131a1b10ceda4ab5e9b0b5cf194730aff6288fa56021edd7ccd1dcd88783070a06aa7a0552f3013178ebab71bde4ea3b6b6bf9c025fb75269af064fdca9c6198bfad1c8b40775a4357613de7709e4318af6d451f67efe7c9ec00d3ac5c9319608d0dfb74b1f71c7ed0bdc3cbf07e6eb628614f1e1713e4cc6bbcd0e3d1277d32577ed9577abfd5d5cb7e6efd385fd51a23f99e9d852ccaac6ff4cbbedf594270b6b3979708df48ab7ad9275fbc70185ec6f5be4ed0892450c504ba3a09b3ba443f39e7f21ce1e46fd818a924473f9a3377a35ff857e7cccfd31c6c781370bd7f7e2c2137a9cfe9fcdc989e4b33a4c05500e20783d517eb8c5df98e9e4282ef02db84a67a6cfc14b08811eec016d8862a2a562e655016ef4c57596e14180739d8071949ad99f515dbc7cf460abdad4378009449b0236e0014c603247e50e28de306bf734c3feb6f50638ea4588d1efb40afc33f3916a3dc2c578e52f90e6ece2f955e3f777bdb03263f989f31df58dffa257bf634cd715d64d0815e47482833e7747e66ec668e9e2b115b85de76ab802d6b1ef1496a1f6c525aa9d26202ef1e6c86b54fca1c76150316fa1c73d0842eb6cc7cda06196b620724266fb94e565a86ab4fccf9b10db78a14a47a0e39f168f15216b84abad95a1de284149ede1cbb7f69aefdb36b24cffb8ef8ea79dfdf86b1d7c5255c58c58fe7dfbfa57d5fea6f3f76bdbcd7f7ebe3cff66b9c2999c77bdc862b1d27adb7902f0e66269a2b26e22cc692835461c25dcc4135b63ca75ef829d4712a749bf99c0bb7a6b666bce39a21cd7691ee6dfb787c502d7b4324cb70b4fd86b140605baac75b7ba8e8ae39b388f17bfb35418ef8f551cfcfeba1837d9bbf5c0f2d838ecdb073ac2ef5e571620a37ec19067e3e377f1176a8eb4066877e761ea3d873dbfee373811fd89f57797d433fd9619cfd4dfa7949735813eafb893badc7fec49cd3f9a9b9c31c03fd643878e5a5fa3160d8d506945590c10c7347169e6273a3d63b944b5f8313706c95350c2049be5cd7ebad71005b690e549181a9e51beaba03009c9c85b44640aab736bb1c70ed93697af6fcb449eacacb88fbff91f76d5d8aea5cbb3fe8bbd804a4467bd928015162114802b903e25b0881a29452e0d7ef215a67bbaaac76adefdd635facb15a9b362187797ce633bdcf7d877767760092cba444f5f93d3eeadc83adcfc3277de31df32e7fca1330bd1a80be67624f839f32dcddd9ffdc06d165b123f5fd5c3eb3b1dd8f76ddcf7c99d7630eb6f61b1d151cc7f9aecdedfa8a46088884261d0cbc3e31c5da234d180545e7164e96f66ec7caf4ddfe7dfb0e2a3fba83215256c3e7cfed3a3419f557b4eb7a61cb4117bdace9d33c0e7adebdf49edd44c54c4f0b34f7a8d7a6a5f310536e46b9739f92c6f24d9d077656096b3b0a24f557f0bef769ade129b250a12b2bcb899884d3a4d48338806eacdd6d7c8277b185bdc4e47b379f7502702330e53da7f59c5004cfe9f9af62af913ade26daec08d82969f7565e9bafefc38fec84e51fe5f867be06ed92f7325215b5b03210adf53c51955da46659626ddfefddff1940f315daa5b9d25e7ef6641385388f275ffa13edbbbce04fcf9d9e30a844ead33d7e1a5f39da37eb8bce9b87a6e86057de7a4482d46a2a4132ba62a88b7adcfab9dcacf22c8e437a4b997c88082502dc69d4cc1417163bace80ba445fb8899a354162337e023aad631d29c39374dc02c8c22cd6058e245109a1b52f1f002bbf21b72fdb026837d7873b01da2f06803cee4e84caee5b027461da9e397fd7a3eb3de5f9fd9d9f4ee523dd0456aa6ff4bf9be2c2dd1fdca1ffccf61dc21377b99ccdf446a3d09725806242b78902d51e8cc7828477168e4be221e3031c74ff7e753bb3e447a52a24d1c7a5fe64cd075f45fbf3ad8adaa54067fec65fcc69d8c940becf47611de0104ead2edeff6abc01ba5e578bda2d926b06b93954d1140b78ffbefc5d884356e62e636a9da4a1efefe3a9e7c9db5501215d45107fac4a2329d0c67e2dd774afb83bce12628c60fd886463c15fbd5d488a8a23bf31ee3a8aa77319ded128937be09c3a0a2855b513529ea5610af5d6877200a0424b446bef4f61e433729d9ee091ba9481df305c08404d08d245d44ac8e53fb77ef0752f9185ffeb68d313addabcbfcd1902a438158a9efbe8a1fa1c948bd8a9df166cc61af80b0c679c4f4c7441d35a7712ef2335328669838f3782ad7318012c38cc7395c065367e2492919c45960356b524add55f418697c4972b84e03a1522d9b9169e6cf55394d08d6bd022982dd75c404f3988a2d56db3a0659e686bff701a494058870fb9c9ff9956c47f7116b379fcaf3126d631f1ce3a281fb12d33c134b8dd4769794e4255efa3e7ff7caae4935ba4fadf18b5d33e4dd3ef8b0795a8efbb403595a0af5f3bc33dfa5a5d20c4058ff59ef8033bf791f856e73944f6e135be35dac3dbdd799fb7fb88f16ee162c3b9c9d1dd79c2cf1c14b6e7b98b7f7610c6ecf9ad892bdb0c6555ac266111a322d911c705407ddc4c6eb78fda90f3ee89c456864698564ba7e35e6e4f05e1ff04ff7ab610c59bcc653b9ddfb75025952c2ea9d2eefceaf29a89352360719f7b2f6effde7c373e3c705d3a59880ede159ce462feb79e69ca4b623858df505737461d1fe25bee09eb327ba4415dd50fcf9d97b558e1ce466e8a82f317ff335eeefb58c38e57f3f5dffe333a7f8d7696cf5834c7b633b3bf507997538f3ef65dac4c9448877910a1f93c3da95757fa94dfce6df7f8c89e4b105b7f1177edad5e2ef279b7fe13f8dfb134c8ca2e0299a20294a34858b00481f97b85f95c04c099862cd0454463b4180e1e533cd556a27b0c0edbc470f1e6bef97f04e490956b88d2b0fcc7a5e654a54b43008eb60359d7584e1fba4c0b95f71e056a4e5926b3ff2cbdefa356fe31cefcfd9938cb3dde624f74ecfa7578a8b5c6c0faba294bb2fec61ed948bfa6b7b5854bc4eba419f0ee32e82f4d15d8fba8bf28e340bdd02214f05714450e329a8f7199c47a45dac4c78436c61b9bd289955b4be224641315639c3b7a945eb54698b24cce2a474b65875fbd8366614c8c704fedef8ca98ae60dd47617d8fa62864a63ee320db4715d47e82553cdafecf3ae19c3c293873007f83b9fdf0cc90bf4c5f7e473da3bf5ac128e03e686286ba44c359aa6e5fcbbbee625932ecd3c7d83fb7e85ab0afb000dee3c1effe7b9b19cba8a2d5c177388ddb1ce348e6457617b7c650a8584d02ec792a5d2073db130997aeaca76ee1704a9c6c650bd7a3ce34a57513b05ac1f9e1acc1b92b9db56b677b5ab63b2c9d474f199b42830fa92d1e3d36ce921eef396b974b6bdf93a22e448e2a22cf6171beb2bb40ff8ca378b75f3f8c8ffe59275586e4a163be9d13423cc4d9d9bc61689c0a84409ea8edee03eef9f8dc2eb50782856c8807bdc69abc397797c9a5337aacf92ad6e8aeaf13f3498ef1c526ed94ee07319e1eab8db79a342c2e809210530de85d87d4b1814c3ec1057571816296e300c1ace544dc3213a928cf143a691ea21ca97137f6570c2e28f8bd27102f5654280969832030d67315169462284aa777a9012372d78983eefa4e1ca084db88e939675e738a697dc707fe7bdc9dea6489051f2395160b063261a1fb212ef0713e27fcf365983b571d079cd25b176244f3488bcd51eb31b066365a205b6629259ab0eadab7daf50a3a262bc67b7f6a2c685f6c3c9546c8727c8fc1c835e1e3caf6f6c2beeb82d0d993ca08058019b185939832c0a4be67940072d6bf7ac9e37d43ceaea31049947b8735fa720f3ef8573fdc8354252a9a1ccef9410fbffeacb48b9c5c8a6f337ccdc8186b67499e2908221615e399a7159b28271b5f692a21678aa89c1e4f3335aa78179512fb95d123952f30c49bb86cccb42ad4b82cf6a9a4f3b870f7b156af83927a812d6e56b6398a43b94f7aaf4d193d93a37a139f4e5ecbd5b7b2ec5bd898c3da83b4dcbf9713551ce27bc1668f913a6e161ada0fc43f9ad32f542e8f3ee9ec8dbc7ba3a33fcacb814ce7b89646266c471ee4d75bbdfe87f8ba2634d1e9075fade3ece02b0c789d9287ce2ed5dcf5ebf77f23f727ef74cec1ceb3e5fea8339c81c848b07620c9fae69a3c8d793c5b1a02a96decd2ca7b3b07ef599789efdc8998e9595a150d0f33851f6c6b367efc86ccff50fbf423bfe55498bb6074242cfa38d8c0d5a007fe30af836eb838affb802da4f8ebb143255cb3723c5fb166c749b68e61b60fd476e955d00e4aa431b35ef8e5b842530722929904528d501c70ab9efa16ae63ab7e704dbc4dca4c9240ac13cb21a8c4b340856550c09af4d92e017071415ef767f9a2efc4f1caf1e81807f8c2765c5f23deeaec56167d3cea9761dc83edd85d1ab3e364a608eae9a41037bc7776dc3620c9a32e2a1c8d28ad4a19b5bdae0923e93cc495d47199d9a9d23c467da6a59371e34e9a7b122244434e798066ae8cf6784a55d11b8f5e896f5d964dfd721c273d6d7c95029f5e15c7fd0627f1454c2f4b18dd462aec4ff26085fcc1d6fe107f7b8e231cfc918ff182534d61d10cebfeec0fcf3eeeebe00f7fc4129d6af5cec47db04c4ba5495579c35fe279ef6bec9e65eb8271996ade737c72790e73a9ca820ff8d0b67e8953baff842ffe7a4f4bc1f4e22986f46ecf2ed33d1aaa93120fbe785a66e0b50ebae04eeefe0e2f41fe25bc04b9287776c4283b1c95fc0105fc9652731f43d2fa6a6d0505c682d4160febd65771e785d2e2a694a280661cc28e2a9946d4769d106719906c8f18dcb865a4b8d06896664d7025915b82766535362af52a56b25b3780e5426dcf6194ffb6c66674a1ffbe4eb44c9ec3ee9de272ff12fee5984b1864f071dc1fe16e91e9f55ece439e7badaf8c392978916a75836d883c45b48872b6d028f2c8ac433d9afba46d826edbc705dcc6d32c423634858515ae20df55f948588e8b09b821da5de74a58c4966e464aad8ac0012ee34ca857c5e77dc4c91c633de7e4d6795ffb88e76bdfd5cbfd9b3afb8c7ca04da2d6dfc5f88eae944f7f87753cf82f6fe7b108ee2e97110404b194371110cb4031f73c14866f1b37ae0946299496a844852af9b00ae012f7e86017eed2f05e4553cc3cf5d78e48a34aaa59bb50842d264d1df5a8f625be214106458008379516419409556794011b07dcf85446fcd5bec87e2002b25a2d665889276020065e842742da7fa756f60b9ce961df3e9fe7a5d8b8611fc35a4f9802e61ad9a40aea09103a9eca3628a18c65d46393abb1891691da2eb8256f1883731ad29917dcf5a4681fa25c3c128dda49890b4fc96c911bf771d72c5820260181db1408e9f7987296aa98462a83f0bf5ad65f88d356ae14e3ff164efb688b5f5a53e9cc23e9f5418ee731e420a119742dba0b20d1b1891e22155acbc05904a6de520b589eaadb6e68944b0b031a6616d68442a6dcc053fe18abb5b66466ef335c930abbae423ad1a339b6245c6859ed6afc967fac6fbf3a4e7b793ee6ff3d9cf679dbfb1c4efb8b1ce5ffd2d97cc6467f81e9f8988bfd916fff76cc5f073b5a494bb95fb0a3dd791ae7a233e98554f501eea8c57120e5d2674889e4acf5bb31c700fb6e900254083d0246cf7bb15e32a7a0b9344508419ae34ae43cf335386316bc47b98897a66c482f421cde0342791e6878cb65daa5b28682090555ff846df2a2c38f39f7ff9db3929630e73e902bdb18e675dcffaf6b7d5dffaf65d6b9b18798cf99ef4ff5e0e66535a74c4e053566d8e4555a641152ee3a515067d1d3516adfef915607be39dbbb10ef05136d6c012e206f02f24b4581394a0802a400bb00482bb130f4cafd9ef7e60869b44cb4ba88485651a5c919e16b94c316abf2731bc3bf30c77d3667f0677c4ca48e1f23152a0b06b274f2c463f4ae6efc3b764ee56491fae1ec9eb75bfe5e771df7fb98f779faf3c967b94c5745790612bf715deadc04010a314437a2cc1a540a6795439d4bbcf62a4f65146f23852ebc90f74908a74cd696e83d7595471d2a5b16e7f2c10d252430ed5de50ef89366eb49b86705f05cb61d2593adb634b3cc35afaaabca98b5db45e86449299ef893b42bd5fd5f2a17f281db8ac1756291e68594f34b9d7115eea54885796cd12c2a5b7990932782d101d7727e5e8a7a799d21b88d73947b44789e066f99bcd34875af22481f5781633302e3a06c6b4251cb4b4712dba93c6ab642698c98653c218826959379159e0bb3c93198292bfb5e134ab409acf1dceb9a3e55782caa0878a5b0964456d7c583a36da2eac7f53962fae51b5cdefa7dac51483119eaa965c494931c2167f132276e8ee35afba0e7ec60d7e03ad25ee16ccee1f354aa8bf5a776d236d1844c4b94a52a690ecfbfe7a679f7fc63a23943fdf0aa24cd73fdf41f63952f6b915872c3dfe04066ffbe1fff8773fcd17f7cbf375fc4fdae12ab7f33e6e16e553cf49ac37de40c3643dc6f7d69dc4f9fe07563b9a16330c9a7c21fef91e63cac4a61cc815c23ab2d19cdbad4da6b51c05942ea8e06998673e9b8042d84fcbd23a1f00259cf9262bc15aa436250a8dce60a2ee40d2e40b0a2308a8a764721f448655c55dfa6366dd27776fe7f6b7dcf731d4fe5eede73245d47d67ff41f126bacf1d0c9a310c9056be4ea4b1ea8335c0d3f3aabed4ea8b43be649c08687470ea833f369dc1ff813c2864b663b01eab35d40c610f5681984d90299140510f6848d35aa46a3b868768972a7f35e8c880555223dcd9d721f95ce86907b15c3a2a316d148483711ad7bc1da5114b87b014c2d2ab7fbd4521466c95972898ffb8f6110519658fb262ae523ffaa9ecbffc0f3f853bdbe4d26e0a0938b637cfad5e7638dce6598c440dcce15bef654799f16334015b1c652ca54458a5001f1552851e5dcc644de24e17d1b33d4712ae6f3dec8bc40b87ec941ca3298aabf3a3a958f9166e4b8c2370185ca4a66a52ba18d352aa952db14ca3e0d9d73f2e64bbbee85d0fff8ae2f7afae04b9dd5d38777eee221dffd0613ff678c5a75906df2919f392717f28e6ce332cbd27276f9797a9dcbfccc4efc98e3fce9796a386b8ff7ff789e5e3e1ff45777214711d9774b8888979b9a6be91a05aeea02fa20ac16060ae9b9d51684c07d44ea8895cdad1f4010105eaecaa84fa50388452bdf82331e229d33b2616186e7205589c67d0c21439276dc1c17a494be1b905e28f53f11cbbcb4aeff5b18f563eee41a7bf601a3aefc80dfab884976c34dbc585988ce55c748015d274ae612939a8449cdb521e481d1f2a90818a58fae925591c2b754156b6ca13230452f94f18c316aa745b65815a9beca39652cdabbccd369c11197f588984abb8275f0ff3e46ddfcf36ffc9dec38ede3e9fffd8b2cb90dcc4b65c87da23635b7e037f845c9e3156250796c8d3731c3d99183f065fc45e00ed8bfcbf451b149bbe6964f9ad0857cee57752614dc44feb81285b32421dc504bb68ce230b0699c68d24855a9a64aa1780c86d44437be99eed17a4c0256f73c87396344f7d4998e009d62963dac723113a5eec5bdb35f68f81c46fee7f1a6977aebe1bdfef307aeaed7f1a159353a13071af4d83651674d6ac18e9f7260b3ea99bbe43d5769bf604e9d94b05bbdae87aa46dd9f9f1f7eff344fef230fdef17c750983db38ace52234b227fea5ff9ccbb51fe559c62d5ca7d5efe7e7d035ee9eff7bb4c8cdcffc89171cb7f9f53ef10a1d1b66d8ee699eb323f6ff52b9ef83a101c71777ed4c4dda0fefda69bca3ae2e9a63c311a5fb418d1210e656c321ee586e2ce7cad8c50550621bb7817aaff0a2e8fc92ae97d36c8a4c6430690037a72e869c7290cd5dd3ecfdca558809ec34741e5db3a62e4df701bb6b17e07e24407dc3a8314a29ed98452751399efe3dbfe350bf39e466be87abbc86ae6deb051b3079fd71cd5f7d0e066cd865f22d2c94481da348935b0ed094435e27655d63d30124cf3c4f71bba8681f564410a1d08658333d28327f01601648a2624a6f998508f3c73d92fc012bc044055d1285669c42ee9b88bba65862e082b8e44800e302f9f633fbe81fb2a1df73265faa07dfd5fa7ec11b70158cfa9b3107fb2cb18a4658435ca05f04bf7fa00f05e6bd334f4bba77a9bb9b03b3c70cc998d60a61c824508c6213aa5e956e30754a373055b78a9454951bbf72d444ad916ff296d9de8810c962cb1c51d6ce96a153d1c098702abc5588e3a53f262b29db04d29fd48c3d35606aa210f5af309b7f88313e35f702270cc56b4ce4dff3c1a03f724f8ef7830f59c2ed377a3a1c714c95fb37f56879628d1fbff2e5ae55f773aa593f9dbbc3b897d6ff980dee5d3db0466dacf259d23526ab04f6a4348282ef3c55ce48608e7eca9def4e4617e7508eef010eba72c08e7eb996578bb30c6bd93c35f74bd5d7ebfa7a3e27ee8b0bd6d8b5b0cecc71e08519e1f27e272a67eb2985466dba24a400488afe8a39b126660357c7db357c55db79a95c7ddd20fd6b6ccefbfaf69fd93d6f7bbd0c7ec6db46ed0357fea8bf2c56c1f74243d835eb785588994b8ddc2f414c61e613d660a2798011fe20d4769f42da614a4b0ac91e87458b7aeaf80c7346f0d42740a604386cd2b4a2c034b6ee4751c1cdb414d4cdd1882a66eb4bb826393cc763ffedde21ff3971287fe40ba0203e9dedffe477073bf6525ed4136673e04c3fe8c6aff076dd29a7faf7fbfa6edca38df59e2fec64df5e16dff04941a7c4460f489560a1656bc4c60bc6508f8b2c486dc30a4abd8fd7bf805b8c1985ce22caf10d99d25d22338d1651bf92bc4928de0525bae58598ce15e463db28fd6e4c5170a7f002546e9fc5be8932ccdac54ffa523cbd6b52c2e6742fffe78987e3aff5e0c7fccb77eef72eb1c6dd82e9d9b147d2973816e50a76d3eb318f72f6782e86de53a7be40ca6579347cbbf2b7bd17d2d055cd4e28fa9a1599230888538873aed6b6202d5d6874124cc6202a518c7379cb2cc74cfaace439be5dda92a5533ae1b921b9744782d01d63bf401a606b3515050be42d07d06696305200bfcb95fef46ecf98e9af39bdccebc8d077e3bebe6b2f1c36a75e01dd4577ad8d89f3106bc63a20eded42c95c9467fa5c6def916dee17caaf36a0b515e78ecfa63c5a284d1330b39fab628ea7e8660e84e607305e1578b60a919a92cc263d6ac89437ab52f722b5d9330b682ed39d2543f3b892fec758e21ff84ace73f4ac63367a8cab8b7d8ae19c7ee97bfa0347d8156c90c3dc9dfe659f9cfe70172eeed7c2cc0d0d2189a778c3415d2d00da628d9751559bbe6d54a4229a47200e54d0a4d499f9a53e8aa113fb042db0a46419c0752af97d50e80a0ab26940055d52a3f74a477581617aa0a6bee5b0954dcd98dc7549883fe47812cd181a291ff96cfe264737f4bfd32fe6e252c7c73c1d7bc9cf7f874b6f7985984da20e392bc9df6205ce7d7faa1fbfbb28f78a255c2213f8bca2734eb212a96812150ef20b1ec5661360dbdcb8656378a133492ce07b15cf45c12122cec42559ec834c210a378882efb9d5de2cc3fa968562144fb32db6f0a328010a54b29bf734e7d61872eb27fc5c582616d4dfafffac7ae6c0fa5b7cd6dd8ffc0b1534d1c1fefab2874f34c47aaea2eb18c80e6b758a97bffaaca80396fd323b8722c08bb4a8ada4a8aba4c7a3b8726629c4372230f4b4c83cacc886dba8c1d302b0b2ad18453062b591e4cedcd76a3336312166aac78a4338e34da03aae5ba5bba41492957a9d58db4d0022dd53d29e4f05fd5893fbfd3dba98d35d1d374373f5a1ef246de2102bdfeab7d45da50e6c9784c62e191a2b039930a988a7de85e7e775b8bffda5d809527a7daa129590d926557eb5d4162d2beb3e02b013a1b3c7d47078f16bbfd0244f24aa939ce385e698ae0a6e45886742d2ce53e0bd5fd1b5abcd74d7a6cb68dd0498a28920644fa8dc7979b1670c9751887b52fe35ffc3c15ecfa370c0d4eebf90a3fbebf90a2f639ef6e0155657d95fe623988d5b34db3437fb05100fbcf440a0ea085bf041b0b4a5c429488e3ef5c3bfb94e65cc442fac71f78d9cfe7beefb9fda0d8fbc9455aae15dfa140f7a330f05fcc09fca02d2ecd3526c1095f75ea1ebfe74060ebeae5084e2ae1b13054e207a6812e938ab0a4e84d2ee5d29b3250356428b910f0c5554584d989e2d211a5139d3fd02c4c86a6e02e2a94b73d4b915df46d4d9c72ab5aecbe98e776202f66939debfd40b9ce3ff135dc490e415dd2e18efdfc4313fe4e74016aba4e196ec3ee711a68f7108c14b2f9ef4d33e3ce260c359a4e1a5dc721f3cf1bebeed7bf2eedfac2c5c2d9893a52a2de270f61663faaf73b3a1dd9003fe2a563770e95ee5bcef62559ef02ba73f07c75e4597f1b3d55a5af00d56ea11a5b31e13b96336be9d6b92e120d2319b69bedad62bcbc93881212f1cece552a5155a26ebf16e0ea486725979520444c18be5e17e40b8e4e668239468b42aa8cb7354e042df2ed4661403fa110bf5fd7ce87e915fda4be0b42faccebeec017cb598f4713fe21276aff767f81c1c39c32eac79d5e62a2c2295df103bcb89459d796f8489cdfdb49aed5cb5b569f16b1f159e86281ab16934720398af20ba77a958afec3b6d05eb0956b62da75cc156a4a66a314acbb44bacec91b2baa7458b7001ca483a8e08c5dfd7bcaa07990b80b0e476c1e45731d333d8f31fea4bcd918b902a31db377178ca47bdfdee52beaa7611e2d2a5d4e11aac45c15b97d156d8190e586b704829b64516f57fb95edac0cdd344a15389af7b555f87f7f3cd98835dde251aea170c765c8b7ed4d75810c8b83f5e73459f25d028c814321ce020ee7f8f4420f71eb9d7921e8e161a6624c411ea054161bd8da1bc17a1b8a51a6631302638c4336e730b31d4a269c656259de29ed66e582f918571d4677ba1b43c3dd6d87d470e74abd050920e7407df275195e63537ecbf8163482bb917d6af262de123b7c6cd227cca091ed7fe4ff33bf54dbcb0be3a6a53ab75f014e9cb70b64ba0712f4a397743d131db707928a94f84c17227f04d9d539366a9a5688b3e33964c778935d685e47b17388b85423d5cc147c41ab82a759daa82b342ef49853923328c2a6a2fcde6024cfd3f567f547006952ffb4c5ca9d73bb76876aa993e8d7b8a237e1b9362361e836d04e004a97893486ae182e681251a165013ab8e1d6959f5bdf37de4dffc1aff7695fe5e272ed4c3b93df17e06eee57decc9385ac2ac25d374e732538f34b85941a9b9958c52cd6d118b3a54e80baa387b0c33cca7bf77826c773e305a0ee1fdca72bc28287464658fabb2ce71e0b094c23db6d196e704a07ed6474ae35132b6890a100bcef6b1ff31ee2d3961337fd41ffbb06e077fda76e44106bfcab97ecdf772153fff8fe39fcef310071878bb5fd78a0dfbdc5dd21303543ec045c0eac2276328723ef7093219939d988a39d7cc7ea15cd3e70175c264fec7fab6bf8fb95dda7ba9e08cee17079b81c1edb7f21e7f1f377833e6899357a61320d39066c9e447bd91753e953922b08843c82230dbf8659d0b4071944b3356b379d4678f5cd13bd704596cd209d6b819935a5bda06a02a5cbb958c13eb6e93944d962ae347267f6f3011c4a3bfd5543a7bb7a86ffc329bb3aa5683221a5db7ee519eec1ada1cf3e9aff1001ff8ffebb40345146239f0fc97347fd5e7e04fbdfade7045fce1779f314371f8a63ee3230655751ef8d057f9a95eea133efe81832bdb2f2aa34b34bc3bf244ea6562c1ead57b769fe048afc771a6b60fb105bbe8c298e7d3f95cd9873dfc46cf9babd4323ef5191e38228bd7f7e4348fc6fd41ef90c01ccf56a6bc8da8c1b9996d7de9281e8025362563152e453706bc504673cd61711e294bea38be5de7893f56b12630919925a6fc96d8d0c152f449e04498802e28241450f828c73d0ba08b4963ba1537824bfac97f3bfef1318ef25d599730daf12ff5d8c01d79059ee2c31e1a0d0f9d8afb477be4e5b372e2c9b948ce597e8e28570a852b723b07c68c950a70d5e631d568802b03ce551d120574485114914b1ca9628280abba4af3b0e8799812506309e7a9e94c5878df12dbdba09caf5965782e30b5c096d235c7bb25019eafd0337d64bfad8bf667f0e1dfb23d7849bb4588778b839e2ff5834cfa0eeea1bfca7e7d1cfb64737099aec1c107ca13557f1ce4df11077119c629301ca2e265a2d1deb7794ca70e8c09dfb292c61ec92634e4c1ca028b5413cc5368b9b4b210294dc8955489820cd18282458f5894734081dcadcae661c55addd332e99af5c467d2f772f840730f903edd53c0cf619c2ef2ffb945cbc3bd5c8407196ec8b4c267f4d83fb927f291fbc758310f1d256647ecf71fe675e255712fe3fc5640cba55cc4b9b30decba08282a97b07658417674ddc4222c365e294c54462dcab15c9adb4ef4a2e0aabef715d87905966921786a2a0a2a24670c3d246553105347b134364b62aab4e093e564db13a5d93278559e8d17ddfd9a7fe0680ffc7d0f8021b6e9fde01e0ff9fd7fa92fdaf3784ff7b54e4a5a5cde270fe82c70d6ab8a1754c593988c2161ed1e4bc766b9075295ef53f36feb26cee7deff853e8205676db662b438c67768969cf4d2fbf9fca0bf60bfaa9cfb84415d4cb6bd4be8340d9d2ad57e2b31439d5f8c47b1b5fd0b5de25ddcef8d5b63e5281bbeeacd47aee5b73ee7b48ef2e979fc06fd240f4d94511aa01b6c11b0b4b29686f0212d075cd00dcba1eb933b9d00817d89b79834537f8a377eeeec48c85d566e35523a98d95cc1a6d23193b6aecab578c00d205514774a609a7b8f469b441556aa38c83ddb6fe4c732e9e077eca2f2fe6d6eed5fcf7de19db06495945fe77bddc975722c877d8f99781c62fba773f0fcf98897bab04f11b5b122422e512642da4794cfbd6e3be2a560734567a270a2584124a15c451adaa052dfc5058e59c54100e81203aabbb0de2048f73e84262aa8194b771f57c644a8c8f0343e4316ddf18aebabc2c94971dd1acc84c9c7f8d4a7e3755e165dd8ebec690df90b6670f7eabbcb64834df78945473c9c7d95ff39e8d0c35cff5af68ad0d8f23093693ee47e5e7f6e8e67cffb7ede2710956fe199af895b779aa9fe64bc46655d460ada2d2d57f1487bebffadddc7c02e2ebfcbdd9d0e78ffbf97a1ef78780ff7e7ed3c9a238efa32fbced3c424800ef4e9c1c7e11c17b33dd5a42f2a719f06748942e8c596ab12133ce0295f33262a5cb60ea252c796d8ce7b435dd926a045b60ec8d84a495b21352ba9563722c808a2f72d61e332b600f159e6882f78d4bee1af0e3e7ea24617d808de35cee987718f7ba0170b362e5fec06e534de4535ae1b11a66dcc74c787dc236c9cd18ace56d2d199e5752e9379e0377952798aa7d5260a9d70aee85337140f01a00135c7fd1c6089147e2b7261c4e64813d2d55793f1ce0fe57d007f030267ad3f69f63184866f13f0458deb8571baf163a492e77817ba3c0621d30e64d1506f07f3afb8e70e7eccf22ab631ed170c0e3d12a283df7ad8cfd06d223670bc6607bfe169accb7224ed7c556cb5207470146484f4c64314389a0be432b06bca957a8a81511073ccdc503251d29bb8d01f497fa7e349c348fe7b3407e8464c9d669523eee58e19a9dbdd5c4b81b0b893fa633f01d4c0159cfb85406e25afcb0df08aabe7739e39da0f3181d0e862066a6149f555cdd6fbbae6ebf2e39c89a9c616ecdfccf7431fd62c4b3bd0af1858276adb7ffe6eb25f309425563b70bacd5ef762fdf0bb876775c955a8c421978bb09669f9ebb57df771aea1fb4a7fbcaadb3cf7dcdb7ea8c37cd187b57a8a791fd60bed397bdd3fb638d73ff6e9f98163ebf37d787a56cf520dd55c1dbde637f930e7e71cf8dbd8b69296b2e1efce14fa63cdad7ef01794441bfa493d0e78b41029d1a9e6ebcfff9e3e46e578f4873379159eb7d9f4331bed7a5c6f8955df47a1b3fe3b59fa91dbededd9fb376255b27f6db7bc1aff4731a99422c64c7ee3e6d92c08843e5764c8a65c0d4cd4f3302b129bdfd029f4fc42b788e2808842970474e79a128a3ea318ca10ad7f7573954e03ca753f44eb20c8a641d1466e69ee08150dd10c7d0525f461a179e0aafe5f1eb1767be440f1def27d9d91678b10e909737689fd4d6eb09fc7aefebb724ba1db0cb89bc3bd677290ab5fdb79b36be4610ff747493ab04f873edcb816476cf2b9ef9b939ebb307e816e13abad58512b11a5bb250335234e1e98e89e429af9a6fee017514fa0ec5dca6b6e7a9a178a1ab3fb360672e4ab14530b298109e5aa80b7fe94c63e7066ae95763e135e92f38550668a4fbd514c9dbd28ae1ebf18cef0c01fe17fda93fd2739d9937edeff7f76de511e0d3db5c42e0abf8a0dcf3eda3f3fb47f2315eeb90faa448527fbf7cd3c9a13d7c545e77b3919039f656bdc9b9da7a18755e0cc314d353c957bdf720ebe138ba8bb0b3463e96a324f2aa962d6126e0b84d848c5a05069cfa55b488f33508a42c49c5294d27bddf37ff558830e2b40e5abfa2436a1b6b8443eff63f1b4633fc32ff935bbebf03ebcc97f3ffdf9d8d3e5b2181ae30f6948a72890399e8ae98aa6aa089d2533b77b5c3880974d1ca9e31a2be9c8b50511d400b1bc03cbc0c8bd9c1261b58f6e6e4057d20982ee8e2ad0a715bc67162f59b9ef0253af48d7548461cf27b24efcf1e778aeefdc95121eecf887b4039d60ba1233f0956ed82f066ebdbfd60d65c460bf387c0e1d9054b83ed5819ffbbe712723edd2bbe3558e43a6980a0b4f0365dc782a8c16ea18a626bf25d399420ab98e5993798a8397a6ac2316a9ac1c0134d96e92b2217ec87554643ab36b30ef5d906a774a0a60e1e5585b9aa922a86179617d9b5a1925ac5efb6775c3977ce443dfb14fb973ca8ffc1bc767cff95aaf6b0b4ffdb8cef71d7cc18a3eeb9cf3fddc63c6f59798aa7bceff39c8d46da2c2e2988bc032d2f0f33d3df9631f79e39e713dd1e3f213beb8a8948fe7f861cf9c93e1f70ecf1f7999f4874b7b0cf212f6620206fc1fb706eef47ac15ed7047e079bfef7f52d5fcfe357b35079966a5ec32d7aea4745bbd80779a282830e9549e59d30ec97dd1baa34950f448518a52b9bfbac101aed334b947c1d913bcda359104f9d3c986cfb38a76540c40d2560ba8262e2e7a8a039ca1010374bbbe8f87a0c4860485799a9f4b0cea6d727c005c8aa0909e48c4aecf8ecbb18f6e7f77d85e5fb52471c7ca22beec73b5ce1b9ef8f58e0cb301b2cea536aea0980fa92dd771ecb26dc1fcf96944f9701d4020b2cbc024da93faeb0397ef415dd602405b18db4a01793c06c1edca99c453d9d31a2df2c19b27d7fbb5959ed1e9bc8e10acee210b3b4ffdd7b14fbcb29c6dfe4ae1864c0e19e25eaa849357ce2e53fc5165459aebec5757505bcf971ad1f5275fc7818ff68333fd5d7899a57c5517f7c39df1347d6657d2fb6b1e5ed8e7d2ab6fad2cce204e0a9b05a969670262c7e8f68c663563b7109b7cc421ba4a18c8618444c0fb02ddd20cc1e7d2b0b98494dbf82b395e9694988fca5e9ed05414dcada8d50eb29cdb391a8c4ecbb3df2dfafcb05fba22d7272f57d7919ff4546c515da25eb377bd59cc6bf4c361568cb88be21d62f4dd8324e736312848e4f3527c326207e251efc292f7c066751375e2f14a7f6021cbb05d8af6c63c10a07a029cd622059941b4500b8469863b9b97390614d6ce1caa5e22195f46155c0a57bb66efa2b9d0e1fc42bdd7b4ef70d32cc02327de95973a6a7dde08b94dc7a15aff8b42f313af8f7db287c912fe113c7ebdffb7cad3bf909ceffb8ff69498be81447fdb237d2356ccb830c081dc92d98bfd6954ff338d9f717f6c56a786a8d14e68fd588b5d32501455ac880f79e26607d9b423909ca31616653d1a9b419cdacd4cc960bb5e6b8723789c937c41ad729283681852681820b1f70c48242f528be1155dd532dda60eaee90d93482f18fb9886ffb5c97d6899ed64785e53b99fa9d5e15dadffbcf7f1cff45a68728e325798ee11fecd2536d987621d64149023ee5764de63d1fa50adeb8a532223d07c13463be9d2d8552a87e45d77395e8819424526093f6b3119dde2929c4999b53db97902dd9fdde03c53ec8611704d9bddfe3112a45979a51e74958ce7ba715807f9727ea8dbdfd451d937a353bd37a2dabf1513677a3165dca73cbc434b160444c14ce95bd9a84345811316192fa5841052719f202a108c2dda850fa5581e2a4e40ea7f56d5236a5a7ca79caf490d812a464b65b2832f39454f3ad76212ab10e2806beca15ae9a7d5cd1ad9be39f70ebfd7e79e77116575173e4f5905bfe5c437fbe4f9c673dafcf2eb59dddca2e9a88e122fdbc77d3abfc01d826aaa85ee59fced4560efa4315a5dccd9e7b999de321f8a35e7dce95a133f9a497770732ad9ce79ecd038fe227fedf2214595aeaaf780c7e9fd545033e72029a950fb4282c3eed7bc5cb361336529ee7f084257d5f0b62c92ab6bd26098bb73dd58ebda9bb33f3dec74c7f5a3ff5632cfb28a322f6da36a459e23fefe37b2eafa31e2a71fe3ab77726df26238d76dc7fb2858c2c7da9bf3abfd7159249c8e5abded9fdbb98d6616c2566babe606d27fce7e7ae927f7383df8f6e105d8e7b3c778e3ec7bd5da577c9c771dfca2d1e3a5da2cd9ad37817d9968982cad4423db6f482abba494b51fb81580b852fbc903eba25be9df7f87e39c5aa57b61baaa130a9ee7701a08b2575242f234009dfe172dfa1291c514bba9c64219b8c551ac89b58c18cd990d3307b0834318b8eb1d66feae6e3fb0915764979866bfbe37abfbf177fbbde5a143a8f839df9e4f7beff3ef87d79efb3d06d318595208eb6e8652b2cb74d27e390c242e1a1a95305f83e81d358bddff810e78122172e938fc8040c316845144e97b49efaa1b7e7e6bd96da331015b24456eba566a67a21f6dc4a6a29c44baeb95a6c43ed125d9c7ecd3dfcd1beffb1fd83dbe7b5b5cde6e9b72fe40e879156f74b4b38c4c41dad6a3257e82605721269749f12a0af209a319875be39768974463498edb025739adf69cba944a4707c92df6d7ccbed04153734a4fb407315465dc5afea49429c515cd6535a38233c391b83fe4a07773ca4fdabb862fb01abf92d1924b7c964e00ba8bee459eaae15977b3de6207beac4da1f390d5472c20d5e26775232de2d49b4e126a00971bbc0426b643a6b5af1475fa947141a0f9eaa6c8874f63cc015b6a99d56f526988a0653be5da8f8815104dc625c90c0f1a2c0ddbbc5484934b8216aaac7e14c8d4be852e5bea314b1f4ba75210367c3b1f6f3d55e1c74d42916fab73aead2fe911f6d902feaf0ae737feb01d3180e325a3fdee337f3688ebda02ec3e753e298cb00236efe5223c5a95141740432c3b5f8c40be4a3d0a036d7321b85772d85d221669609dbed5d55c0d81f6f820aea487142df84e16a9a61df44985027a001252bcbddfba53497967e139566bf64420de84f72185fc6a13fadf53d17437dc937bce7c11d6ca6a31f78c4bd74dfb3afc00b1fdb2b7bf70af6d3a57ef6360a712fec6ff0194e46ed153881cac482ca41961dcfe493cd7de2b00f2eeb158decda5b99588f4da4c764d409451a0222d70f7815f577dd42a10f29ad73978d1ffd00a3d57abc756d234c0bb84d012a19b9dbb9b2762240363c403b2f70346c8bf5aa906150345a14cc7a9c675d3c8d36183a61ac7d3b37b04bd74046ec88ffff3c7fe95e835bb93cd8999cc13c3ec6979ec71feca0eed2f87fdd32c6dd742a9aa497aa1f4accf34c8f41da895c18f3de5922081f3841d20fc806dbf73ab39d2c26bfda9889c7e5146a71296748e1eb65c88300089530be141608a200cf5ce9ec08c55d2ab35a9498b2125c15e71a876e33605d8f7d4f5ee7fd2eedab5a269ad32c18ce84657e197bba4e0f17be4b4ba5e1165422ffb497cf9f95eed833eda25c41e3e670e902719b100a2975aab8e79325116ea0108554340c145eba79e6c6d69d9e12c139d1b75833155ae088b276be0a1c259e3a7d623a4b1a64763acde0aa6c778cd6b73173623f170a6234f743c7226acdcef1267e894d0e919e94681387deb34f8fcef7c73fcba3fc6cb77de4481c72f60356f539c77bc4d9b87fecd37211e7efdbdff9964d30ee12268b679cd5e7367d77155cc99b319fce15a8f9f18e9cf06e97c95f9a675560291b3485cea2cf365ca3184dc63b97783d29e48c94e09e116e23db780c2ab94b2a0e227fabb8b6d3460a6de8d4dbd03c6d570cc6ae325350204651e9549e86a6bcac0362152a0ac98ef65cf57b48d1597be00fb6e2857da062f557c3cbe284fbc22029f53c56c7d3a186edc8915ca7da615ff48b6548dae98773ba4dad6ff1615d854f8e57eee31047b28d275eac77f338e9dc0bf8b1b0848130eb20a0fcc1d70cc3cd8d5d52de8d52c5c1a4041495dbf7bd792ead012a53f5a9c7ca97f9c2f7b1a91faed3731fbee31a3d8f7f90b5eea57c15a3388488d099b232a1f421065e2e0155950d2fb81f29f2962bcd2460f2d693bf379c66f58a7a5a5ca18a16a87599b3a195acc4f4f73e516090686282145a08dbb8f52d98114b2cc4f4ae75e56f3d62b30d36f1e2028edafb28444e52212562ed96a8a88b434339af635ffa54fde1ef075b94bdb5458b2874b4988d5e6c50f8033b568e46c77cc2efbbffd8fbbb70e0d4881edd89f1eb3f93dfff731b981fb9a3be23732bfa78c2017db75ff6557ae57e1c7790bd2029d1d08fe084173fe1e52ff3d55744ee44016f027aa72c43642da1dca2202b8982423fa7bd90c8150cd69134460cc2392edac62bc66b6ad3699a1b88e770115363979a022d895ee3b2ae1971a651c9b32870ac78ca0fef8c5101975462c735bf1b233c57dff3653dc2156ca70fe31eee74c543af39dcd9b4948fa92af3138fc9a5f9d69055ce232d14c595701a136ab885ac5ce6d84bbb7e48148902558ca826b8a750199458630127623dce038024d68c3c01774a0ab3192f1aba32f5052dc7465aea1d0e671d0f649f96bab1b233db0f9d8cf4f227f9a40bebb0b2ec2d7786fb3ed67f1f0d754ab289caf1f61dcfc67f2fe65aa5ca9b3cca973db1afa06fdf8c79b8e3c3597ceeabf193780b564026a618fa3969510e377e5874be45d5c06a3b64b52028eb09d77813e75eeb2a4d4688a9c595a7d03c9b20e898a9caf7beb5d52830750c78cba5d457e1dd2800ee2e9846aaaf8e4773cd999342df2466bb40dae7bcfc179ec5bd6060ff8e97fc6feded4bfba25789355e7fe1830f394df4f73ef830d610d750db5db4564ebf7b91fd702b0a4fc744bf2166bbe64cc0a0d43999524a199ffb4c76d44a9539c8b4800a3ba2b0241473d7ac6552654b5171c707bf7b1ab83b61424c80e1087fbcf5ed2c6214c549684409a4331e42c36778b12a1cf7baf5c2bc5f0cb9ccf6a5fff30bd7e3fbdaca475eb63557b3cfebfe4af9185bf4b056fdc9cf7e2fa30eb2bd7eddf3fac451af7ce4f1d3f357752de772ccc3bc174c1eeb870ffa27c457e5ac9cffd1e7bc5e7d611ca22c62e8523fe5787e43234bbf812d1efac85ec3fe1eee0ad847a123936ae0327a370f055cd64374b84746a0c88a0038e5a151fb526a648a0c52eaf66ab205b4d489089c992765b12a1d9b4c3dc049abb921ef5cad9eb81a8f038bea9c796daab87a6ce9eb4819e74b7f1ca405d08380fa04c22e56c40db260b0a4f54e5c9d1ff3a537fa1571733f929f11db0f3d26bee1935d4997b6bba884db05c3f5e13c3f9d899779fc08338b70cf37dc1cd378321e79a5ae27bdccfd824b9f349bc0a4b94ba08e2bf360df111ae028a677c065451714b45899ed288022f2590de312b4be4a03411a1f6986c1ca9aa494b204785d943bf722cc5860097e5dd92a1f63ffa91ed23de8abbfd5a5a3fffe1eda62f7951c5afa0327e815cedcf8582777f87f500c9ca697e1f8661aa7622f6006309023a1ca87b437245d37aaabfe52e7209bb944b6b4d88eb859df624673c2384958f31869a9eed148e116d2160abe5f59c52860789b524389ed6c94c25a8fc31aad2a592da14312427bdc359ff31c5e1833f76c5427251eec9eb4cc40da8deb677b7f326acfc5623d1bdd240c7691566771371e74d322c475c268f7c6eff8581794456a264f98f98e8710f0f099d7403d6f2f7cc6d17dd2f9ef39cd0e6bf28ef768264767f88d9e39299eecf5d73c081f7e33b1c61a0f9d3c0a91fcc0097c8e3f98c92666e7e67cfef97402f288e93967ef392acee514f16e117e821ffb184f7cf2c39ad4825daa9226b1e0e8ca76fae8f2de301ffb1e7dded779f62ed6ff339b3d2d61ce1907c90494c7bece6fe731f4755e8fd4cb62053a498a7be0e6d93eaae08831f818db86c9425423e8144b13189cc1891744da1c38b11b18d320808dab3ac4a3dcc204e77c4a0d414c250a7888a8dc6070dfc6448f7cbb8e57794690c4135f69a557d1655a9e8d155c547bf9c4b1f22527e3dffb49f7d1b117cc105b38c51d2ef28b79ee14a2f8b5a792a8814a1f10703654a9edb4a4f771e9dc04043ee0ea375800be20f66f2020de53453264d6331fd60bd71f4f569663910a970b0dd55ee0041460e94e651e11dcd00a7316d6212672ed495759553fa9bbf810e37bcb71739dbaf78be3a003f70483fd8ae9f98265bb446dbeb7ef7fcfb335ecf731cfe736b135dec5dacb3978f7fd8ffadd3012eda934ecb86c46692e8c55283121ba1e83bbd1aad82ac4e60a26b8a7a436880d3511fc5629e1372e6bd7a8a0aa1f903e05c63d22776d0cc488f7d9929905086c549202c54b9b464ba26f18c1b157ce7649f85d3cc0c04fb48e99a8bfd1b3bebd52ddc9715d4b59c5cf3debdfcee3c4797a591c94b48127dd2eb0ea75503884e751b79c8a39660e5c557cce55aec44a0452c2370941bb25cb4c5219c6aa68ee29196ffd7573bf9a66059f624a3477ef4254a5802e85ea2a2837353f979b38a05c98749a984ac74b7e412f9bff758e9e61cd79d9665f6162d1e43a79bee37de6db88a5cf77e938bea25c96df1b7c24b862cd9c4ec6d825cd03852217b6b1e78a34b8ca83a037141f70c0247d882d81d2dcd4620d12c1004aa6dce055d4632283c4a2146930a661bd6326b6a80967d4c45364eab78992ee58955157a16a6202efa38ff48ff523fa18cbfe320ffbf7f18d775c3fcf7bf4328f531ef6b2f8461ec32c43bdec82c9987abdb348e05d8bd47ae76adcc7dafd3e0aeb8c2a7484426ca7b4ae5068dcba8a4e5784ce69316b918a515a519cd8f5d453c6250d394c2c71efaba84181a9a34933f180a3c681e38bf5d8fe18dfb80823a1fc0bbee6362eb32c2d6717da9d834cd4a3d0795fd77fa6f7d855fa350dfbbf62b04bd6cf327918ffd48ff042bf93b69e74da38c00f2210640e708b15bd4809bc75a19111c0ed54c1b62fe984847cb364945245b7892c5a4fe136b66b1e9b6d98288ae64b0839038f89cd59a4453b466813f58e16c874e4156e874cfa4843740156eb9fbbcbdc9e35b1257b610d367cb360f537f4eafb7eab3fdbbf73630ffc6716ee162c3bc8811dd79c2cf10f7240398d7bd1fdbe77a1248972dff350b4a90a6357d52d0a71864aec068aa7a51a1ccd155a71d355e6ca38f773792b0271c30abca553a3671079be9975ae8a74ce749c02a34d99c37c533c2ed4b1c5027e13971cfa20b3455537e762555f62b64ad8f320529ed6fe9947f1838f6a64b1faebb5cf7b696cfae39a87864c4b2407ae8dc33d66e375fc754fd1abe0eecfecf39e874ece07ce9ac37c071ef041d67f6fde4af7837ec8d8abf89ada99979842f3adfb1e15d2c7b9a932b33ddcdd350d23c008d583de1d21d6d4a4371cd2bb23b787650410096446489e8e10e50a2e78ec96f09e0569ef6af7fb582b467e15297cca9d64dd0469d7683f3923e7efc41f791bbf23af1561ff6e2215e6b1459a54a54d34ac3bfa46cce03af27b8873b1630c6b11229930f8282c999f6cec3fce6f88255c2adf19ca52696c120bd1782afc0008dfefc554e4338d4843e156c663487bceda6ca15189fcf183afd50f9c09266466a644e97cd2c225353baf108f4b52c77e79d7f2fe4e8bb4df0055082c145e118a6e222082a585fe3e9670b8439321a7d3f370d6c4d557f88fdf8fe82a7c94c7b53fc6b568f72c973fcea77127237069dc414cc57d5c71c9d7bf806fd205024e482d4c5792d3d8da8f56650385dfb88905a16b4abe2a3112215f1305d7a99d4d4865dc2639a6b19d8e5825a1a7d06c39fd3d8a29274b984de3aadea12a6b58e8299e2a5d567edbbfd4538b76f197bd476657aa2f791e6f9071ab41a6c9e247f60b4341c49afb95e5d054858e08e103afb81a010a44b9dfe172dfa3a93347391d71a57559e8f01544419acb3621f73b4ceac51cb8a348730254022781b058a8a616fb8dc7036cba26a888e6284c1aeeaa249b889cb55fbec23200c164f11223f5cef5580731f39e62aa6fb9a62ed475cfeba97ef8bbe7797c5e8fff7e7e3f9273c35887fb23425af38972fadd8b74d42c96c82455aa725043446ac455910b339b446acd22b6dd2f27cd02537e4f145963bbb612e9e9a4971967a249a7778074e33529e9844abc4610125c423fa80cc5cfe54650990565f618153a0cd466edabb3dd59ecb9edc84885ca938e27562ba310c9994df7079dc42d7237b3f16e663fdb0b77a83376e9dab88f99b8e7e1ec7136316e130bcb746d3cdfa9b4339a282ceec4e1b74c9009ebeef1a99ff07c52dcc56c7417a9b41316ac93b591c7a1930b067a61c1c748a5fd626268b125f37862d469676c9272ac256b43493a63cd7d639f96e37562d1260a711d75a3bb194492fbc6abbd8b468b21a778786e5c2dd4610ecf3d8d67163fbc43c1439cc5aced176fefe43a66a3737112109fd669e02ed38e9f2fd3d14ffd47c07ae58382339e09d67ec5b772adb857cdd5839d469aa82a1a6ed1320ae9f6c8bb727e5e97c6c15c1f0441682891c6d758fda52e4dd846015c20362ed2dc53624617427ddffbe7d29e49b249ad712726601b85f5571c1cd7f24deb24347669e53589056f8e3c1c6fe771a98c777d30a12ab82590463eab77aedf3cb2a2753d294952722db1b9177fbfe7ecb76be12eaddf8d19006979f82fcb52f52bfeeca1a78d7205feec4684cee1bffb2844f783adf2761e97f74961cd7d1cd03e2d9b5da2d6f50a1a399d8acccd61145512514a36c967fdf17fe6bfef17f9dda31b1497ca893718b0af64c315f27d7552f2ed41a69fe4c1f3f82719f0ed3cdf410644397c08182e0969b1506ad52fe802932c44a508690fd7bcfc5406fc552f8e73b96ea139596a1bfa09537df15ebcc6d97dd583ff0a7d57eaa4cc0e76ce2937f132fe894749b9cc8edcee44213236f5768cb5990bc4cd8a80a990180720e39cfc5ff6deae3d519e0d1bfd41ef4e0232c7b8392801a9c421e403b207c4b7080119a58afcfa75f8d14ea7ed4c6bc7fb7e9ef5acb557ad6d22b9925c5fe779ea996ad0f7c8240f39f32b15b72cf2ec2f3942e9b242430a3a9ca2f5213a7428abfc9601602d2b4533a05dc9e05e38dd28a1a41282a71147bd8cd547390bdbac7e0ff77d5acf1bf056e98734ba3ccb935e4d706dff691b997694a322bc03f8c0a6fe8f65ec8f549df729803c4785b3e43e27158955ec8f92da127c8a0cc6edd11d545f16319f8a18e3284652713ca128d9300715a2ca7772aa36aceae7ac92e5428c1d1ae3d99d01dd777aa43e62b7fb33ef91f5e303fd69b7a9b9c476215d7298d797f8f2f9ebb3ed5e99c30d2076eead8ce91f81e7af96c8f797b1ef50c6a1623c5a4c6520ddbee122b788c65a9445a5385ae10a7332f82d6b7c3b1824165c9250e37dae893b87ad0e63652cb90333463cc52c23e2360e1cdfcfa66fc4405771ef5d79b79eeabb7ea304d41fab7fdec697c90fb0c86b0533f184ef7af9de0577735d9d3960fa0776fbef94dbdbb9594cb0e826c41d9951d4ad828600e6c079428b615917288afd84783c612cdc65061b22a70db8d3af735134c4c47b65288b18a141d9d852c0e739978610ba24657ec8dcae21aee547ee4dfbf27fa753f1f75a85ffe55cfce9b37af88762911bf81b3febede1a3fd3dbebef4385c87b90d9c56e0a8a3146092025d2deb76120d7aa5188a12988c822971a4c7cc90da44c6a19183a20d806c33c6acac664646c98440944aed3fdc012b4d79b10aeb2d2025493256d404b57e1adb415aeabd981615bb46cffc3f5ecbd3c3d9aed16119c1270cc2bf11379dd7d52af2a6eacef8dad33dfc6a3e9fabf1b598705fca3830728758d2d39018baca0d665213cf961e594554c5bce69c88f11709673b39a8839cda232e742798b555ba8d48349e07156c84263fb8599941c97d59f32d75b94800c70baaba2c261181c56d75c76afd90c4be3517672d85d3f36f82ffb04eea696d7699d1eb448cbaccf07fc8f73961dfc0d17dde5e3263bc95023dfcd45079b29957f3fa1c66d14f2442710af834d4dc0f059ea6069f05317f50a00da2d84e854005e6d250b16e98a9e9dc080e999b9801d51d77ba942006b9200eabfbbd9c7eebb9686de2aa8e0f45241b54b049d7b11a0976f47f80f5670d88dbe9d5dd82b7e1bfb827e1b546ddbb75edbfefcb7ca1fff3688b3fe771b2c1d5955c326cdd131763490b2e389930d39fcbb88511e78cc7ea87f0f03a1b66162eab41092ba1d497a9d3728e6607e515f3b9c13d3c552b5559c5dc546d8e6c37e3ad2bcdd98e96b20e98b271292b55da1d89358be2777a61ff77eda5fd48dc7ea3bbae4c7fda47fbb99847d7910ecdbceef68ccdf62ab6abdc2033eaa8386fe43aacda3a31e4175a598582daa195b6182fee96a5edf35a7bb2cc211d0a146a7bce0c62a8c13f9055171080073125ae280b9098b321291d8bba38cde96d359e13a3ea5261d5d9632d7bf5470ed4b773edf5cf753b6b405faf1172f469a58b808ce02ea95b9d98efd5009dd7d8c8cf6aff9d7891d8cf3beaa201f8623e173ff7c339cc939f3b37664068399041a5981742397a941fc6eb05cf4759236bea2a1ac67a2e0401042a425dbf5f52f923a4a84d0cd8a47532e200efb8d3359207409915544817cce56166f22fa48236adfd87b4ac4032f8e9dd357eeeff503c74d2983a61303f82edbb41efcc2f633e9e2147bff08477bc5697ac9fc7c85700f340f068e1042677e52c110594314a92a16896ab0eff5117fcd3f96ee713bd2bc7ef2a61e6f6662a084827f0c25168ef3e1093def2fcae95e8b7cad09572efbbc438da2cdc67867ef8e983fe7e9ed79ef741047718c0b970d848d49da45ce93c76203d6c4d5c865630a894d3fbcff697822bebebc7efff115e0070ab7ae4e3784fe7e3991f005cdff30520196c109964c21de9676cdc13d70ac2d25f93414ef2a9df27a043a426301b08100db3280f77d1542e589ceca451ac9734d86703834ac84236c5dd1cf45534cd2deaf4435075755e8f4698932032b58d81cfe5cd71cd4f7bfd172eb6bf8fffbe3d9cf8c33f919b4c853528176d33975767dcb57ff479dfabb99eb91b6f93236a1f7999a408bb47fc73e6558f39a3dffdfec22d7e5d0e49c1f56839453ff241f909b53752e0700ef08c465f8790f99b504098ea7b9343db60626ba8980da4eead39801b3c25fb25c73043689f558587a7f23b15ed8cc0c2ce1dbdc8740298286400719c557c4a07ff0b1637cd5fbec6a43ff95f6fea8e3e723a3ce486ae64f45c1fe1c67cc0ff1016253f9e83dec9473ba41ebfb677f6f80c1ea450c559331b7e91b1bffbd05d739bb3efd5d88fe76056f326b9e8ed2e6b7ec80e9fe98305876529ef961a1942fbc582390741d5281c64c538eab02329479851ad7e44404bc109c0d319c035c7dc69bb487cddb3a84b976c3c709a18625a6c97ceb60f853f5950bf22356f326407795d98b9cba3087c35aee07af85fd11e3fad63ee82f7f9ab5fe2c43f1d5b58fbec29c63cfefc193c13b070c5a79190eb455c00e2902df3f4966a3b49bdf6476eea4de4611ce975bf7010cd5d142f35b2c2660604f75902e50f1ecb2f092b8a252336e1c121836c17806e7f7c8e11e23f14c211adb5a38c6a4f4abbbde2befcc738c74f7babe15d529f71f87fe63eba994ff9a0045cc978f678673dbebef0d05f5763c353344d85dcc841ea05225686f05e7a84e52e0f78057ba5f18470f9857b04449e44ac0a4d3c7536b96ba50b072d54f96d1f4c0966d51e0410cd9943b6d1a04b62ca453e950ba155ca99bf4d2a9588b818656f6aabfdadd6f099d3fa333ec9e3fafda2affd2e5eedeff5f3de1efb691fc24cf83a5fbd8cedafd3cd639aed33a7da6565057307ee38ebe0224efa50b721667092c016528d4554773805c80b6a7297b3002c4bdfcbdccee3ccd2d134193193cf14f3e76115ee8423f51de86762d5d50be6cf53d0233e4df6b4d65a7affc0dafebf20b6cf0cffc7bf18533e625e1e7fee2e39b1ebb0fd9edf13271f12c32f974d3122ac8d32304e1230fea15cb20fd87a97797a1f08b8c84a7b94c4ed036b82d19d016158170d13f890d5fe90bbe311e6f750566333708a072aac95acc817555b88320e72465054f1dde29fb08dcfd4a2e2134f6f77e6ad24efe5fc871b7131bce11f5ff6fa8bf95c340aafccfdcb0abbca0eebd96629b0170a38cf4c36920cd6cac13047b8cd4bbe654dd1cb9214643236e4d42ec9318e1dc88c4ebf99d468a732e6331acf46acfe0a42638c13c1a711209360324621f0bf73ad7e704f71a5ed7f22f77f2d36f1f84c2f1a24ffde997dd19f78dc7f97f1cfd8627c1daeccc89c2e0ea8a2b4710076c7a62ab9cdf86c084d679f681412311bdd199d1b403e17a55fa7bc5d50a8c0b2219250de060efe12c276442a62d2818d7286be73938ca4e347bcfabae32527a918f5ca68a7399337e6c97acd69fab731deff0b7cf38be6decb39bc99fb376ee29f3f6aeb1e1ecf8bc7d7179bbb0acf0e0ed2205f92aae32a4680d193aeee81734284184f3364af33aa762c66800bb267b0c5f9d4d91147352928267c5aa040affb6c6a5b549015ae42b0ac2c7be9292765d05838f0f8ace6ac1adf11606d03e4ecff3f1ac30d4b015799b1fff76a448fdc0793273bb9bcbed8c97578a2e91ce0306cd09c1b96215d3cca99b6595358d4b807aa449c33fe3d04c55e025204484969da73e2489c9b6d996bbb94b56c70ccd70ae286393820533fe666d1e554b6b9a18765796f2aaf65c11401c5d4fab6f9cf13d6ffb206fdf0ffb99e869858b9cbab24f60fef6b61bda17bfa691bfc65dcc73b122c635b4b171df21a5997feff2b6a1a0046aee58740fe901599e4703648cfde336e6f25e0f5b2463477bffe6d6ff3308f7591d7a3a79cef8772d2b7f1e7cf9c148ff9f0a7fdfbeb7c2efa4257d6fee50f66f0d5dce86799e8764b118ef24687bcd273558da759499c40743b1a237967ca7e29da1f5cc832300b2b3249885d22a959603c258368fc879c23bad4b8ca073c5ab2f1f1de08b8135814c929af5590d5eacfb5ff0fc553b8c81bbf7857c7fe46fa1d3fc73b3ff78bed5ecb8bd5cf6306694d28a9d5a0445150e6ef68d50aace59cb9aa64908cc8df3e9bb3eeef4a09599f758bffb4af831bedeb7638692a34bc96353fe989bd9847175c9777eae75c8d1653ae5573df07c2d20b2a83655938a921d777060a4583eee49fb0531f7f564362143a134ea73cbf38ef61f63e46fe2557e45f3cb7dcc06b2960318fc921894f36ac9f3dc3b7e6d79d3039d76a54b8fe2a04f7503a5872cad9c2e94b228ab512f766e4ac470ba74814cf873cc67e00abfdb21aa7a4ea6a51f15962da71ca0a3e07ed68596f8da0d493bcc145b21a7754e8198b49bb88156693ed084f79c45c36f00f63e63bbd3cc7f97fb6d59be0e54f631def9d8d8cb5718aa5afd652d5560ad63b3c9594aebe5a11b4f1dcc46d62145f1855df952e2c02888c80620923db08402f04682b079f474331674d05d27ab697d3622075b009100101d232d3649dd32209b49f4a801b3c9088794593c06b78d73ec003f2ea8cf8b60a5eeb467f60ddfa42b97c5013f8cb5afde14e8437eaf1de2631d1b919763ffffff16c7e3d9f3965d7af6fac349f7487c0ed580a7d221d5c098617caedb0822a619c60126333327d37acbb0ebb78c3d818f3ba58e7a2f029ab7acec343eac01f77036a53a1fcd45554d4004a48ba5cfb4958593b027993702283b8b8e9fae62e2a5303358f7ae33fb97c839bf0c95e19eb5c309e27bdd35ff885ffdcef11dea2e6f9e6d8c7b3f56ded787019f7aa38c8258e1591d2ef846841eae8880366d2a1a8e6f0de0ce3d6594ec94e2134cba6e18ef162a52826732023057c3731d4ea0eb63be2222ea77ca6c008062627c2e9ed34ce4d5c8f07baea4442ed0511e83b1fe4e153fc50a2357eda81f352c7ee8445ca8cf12615ec8f9a7f6fe97bffe4727e8b6fea8f7afa2ff9c28ff318641c768931dea586d68f5af98f3af8c1ea74ef5d7b4eed32d35e9dfa18decf03de441f3d73c7bbdcf58ff1e7fa6c6fcf5e9f7bb7afe9d9aa24c80736456554cb199bda7739f3b52a7193c4e126775a773ebcecd97adf2696de313e0e7fab6bf091bd9d994ae7352e8e3e496a70eb635c8e7fdfbbf806eff7f14e7f633e174ec7ebf6b41754fd0f5c22201cf2c02be952a31a71dd56f9a1a319443f1442d3c0204d667473e9102fa821cb2802cb29e930b5179c15130a5b1a368a3056584b6a8b80fa76e0b48c0ca44d0c993276bf5922db4aa7c59b3a9d7f9b033be9614eaee6bcd9e60d7be4cc7ac7274b6e143ff40715c13211787dae793c7f0d8c4f70a7de6583aca2f21b080d48d3867fc91a75c76030e4886b6ec06a0eeef7b2962c73bb44b8ca1475b591b1d37386bb9c233334ee3792f5836063199a4a2e68d5a7d47713710fd2299a1006a7cb29e9b95b784983dbcfe8ac2e05da66ae1ed4e4a28b3ef963dffa3fa83d0d8bd460a71eaef76b5d37f1dfba4474faa42972f2db7e8eff297f5ce403a979189476401bb50e59bf9a0f72ba2ca523a7c40d6aab59d66c9f366b53b9fe97bc0a0f0a2071677cb548cd1791cb405eed374bb63d6422dc47ab719d725c07312e02869c14157d4ad92683d2a400ec247b278771adbf66f0931ffb4273e1a67eda7fa7a6c8b3757fcdaf354871f4e3dfcb6124aff9373e7306998f7af05fbb9f3f838bcf7cd5d9b30a06cdc21a316648811b3dc96bb4e7f4decaa7bc8e0cbe21d4efe6c032b38aec12301679c309d1413f37a5a64255cb868789617da7340094caa9328b78e1b6b3b9d18f8870605ef93be272ae4c0623a76057d44f7ec333f5f87d4ffbf7f899dda34dceebf6da1ec72e1156210dd67d4863f7463c1099400f8950fa522b3ffa022fe671e967bc426377c1c086f0c44c0d602a4a7a392877a9f984716e44ae7fc8505b7e2cbf01b5728b9df43ea4bd79f8fbfbf469bcd37390315967c68563fee8df7edcef14cc809b405829676c8f0d3c62b0ed783d5e245508b870767408ff99dadd953d3699d0dd07f4bb6fa24f741eeb746f9df4cc2ffff7ba5cdcd41659590cb9536d94c9ef02f6d560836ab2da2f98c847cc2bd6d8b116913b3323887d5a43c441d73287015675df73b73752d13edc016b9371dd65dc6fd8341965223003777d20c2d7dc91516efa8332109157f47d27b57e99c7b93f6bfbc1f31ad5789b462ff0719fbba3aec58b9ce63017e43dbc483f2f43f3766b0dab333eeabcded29d1dd71ce0ab6b2d689231674706dfba03ba963c0099d101198743cefdf40e7e8329b4d721e822e11549a6115282c89cf38208bd0b39ebe7a0ef83860f0108776a8aee64fd15a40eb358c509f3fc5558aa398ef1f7c46cef78a5ff865b667fbd6ed04b7dff77f94f875bf892279b38d7154f1c4097353bd5149ff4e986ebf66762fa5d5a3920a97ac0caa25bc428c89dc290664143a36077b0d831a34f535adc6177b44b98aeb2127f59505fcf210318aef77c35b6b24917a7531d07d3d02086727985ba0c58d1dc909d74fd54084c19d0fcedfdf95e0dfbc91e1fcfb7934dde863be6336bafcb79eceb4b7fc407b0f237c1351cd7bf4d0ef0f8b7a75ecd9f67f3aff3f994c68a58432230c8ea6e860dd4499dec72ca67d280bb44ec7b39f82472e41d6bfc829ae478aedfe58eee53b3588775e1cf8dfe8e19fb3eabe09ed110a6481679a3168493ef19542815f041a235606cbb6755315271f14ff4cd7de29c7daee3fa6e0df106fd29b0cd6add253129cf7c2dcf5f83e113fd295654158231be5ec628a4883369865658de0f0c1510eb7cc89b7b406369449ea43c962c33c64deea91d01e43be7ce66c9c88195f68cd5637067eaefa141a6745010bb451298762c9bd048a19a8435eed3a9cdafc8e17c606ffb27edb3b9e0a3dc450f3ff7cda997ae9f97f9dfe50956ebebf777adbbf4fddcfd890303df645f1f6d500fea993d1cc7bfe44fe195fdaf7821ac05e7fac02adf26ac4f190f87a5cb5346559d31f83dac7323d36a91b176ce5ddce4a0d509eb0785beed381b3bbcb1bddc9c416a1449ea16891c647d67221095054cf97ac3101fa580c489a17ce1f4e6073909bb7f8b2b2f3be748bbfc707d2cc46bd5aad8af15404616ab7d28424bd6d02325f9211911d9b468fee45f7ee0399c6c337bbf8678e6bcfcfb7eeba7f14e3ec3d1de05dc6517fd872bb91a93c86be7b8d4b632d4831481c5e376969768930c05ca0c48d22919524dc8c21d47b22c580ed481197046bc7b6b0e799732e52d18db650c0c61c399ac2c4d1a55d1ca37f206913c1a4791b3df2f1dad974c7ebfe2ac592731f61f31abccc08734b6c1e7b9368a5d6ae82a89673fb53e572f62d6f39db552227ffe19e3e56752a18e67bf9e0bdf9a0ba2658d60e685efe9773ea40216cac5ebd9339dcc571aa28d7dd20f95917590025ab3671aa8bfdaceabfcc7124723f30dfceaa0627b9f993ec80fb0cc8c7ef7ecf3f08d3a16c84c7eae379d6b5d2ff5984ff893e31d201b5cc89a3de7e01a5ef1c9c67695c444cf85b553aeaed39fbaae8f5a1abf89c5fc367bc927f178be9fecfd67cee7e77b3789ed466ff0327c149773f2ddcfbec3782f85757cde5b29304863a95f3f9bd739cbcc3cdeaf7897b9bd4ecc13aef58ce739e719bbe3d97addfdf7f477bbd7bf233a69f8cbeff146ee7c768b73ab92c287e75eeff3b8a79cf96a645e771f62376d5a29186a31226b596ba26afd25af2491b1641c1533e55ad39cab5a52350a185a4bc08704922f58b72beafa7506fa88221b4a48c892f9209dca7a815ac4b4e4ccd471e448673ea8585102027e8d5ffbfe3994c5c16f390baeb96bdec83b7f5837f0b167e61fd40d1caebda7954b224ef194c0f690b236ce845c10436e33703fc2462f549cec6f8fb1ba5693e04f7b097e80f3dab905deaa3b735dc3e1c203791d9e8a4a37f35a986812882a1fa2d22fe6c012a73e2fc6d769d3f6588c47121456c2305fc45a0a4f96d4c346066511396d3f3703b844858f57e344a06f86f2d6262bf528646310b916a58731101e7103a822eef67fee11fa488ef4e97c1fbffaddf31ad49ffbb7f25bc4ec8fb59da3bd3ffedc5deeddabf234b98160c2483d87762a916cf2aa6754eb196bc85eb84e9f72bf8d0c5c48e1b71174fab06aab1ca12d07f787ccc1868c0b22d13dc4317e608eb4a24191656343e9a15508aa7dce0b5756e3220745b5649643e0c7b9a97e93477d56d77ad4f578f23faecb79ff693d4dbe3f694578419718e36d66be5747630ff816fd952686b967eff2860c7371bc7fc7a77ee037e6d35dfca6ebf0caa21569a32ae16880a7df4694e9368cd1544cc98eb36e90901d488c6c62b643a0ed7d6a0090702493baedee608b38e0251f0895955c706f0614830b51c32270b985dd0466ae0af2ba9b042e4a02847066de942fe5d7bbe589fbe4ef6bfed76a6c64f578ff311cbb7383fe0e6b977b27cee587ccb49f345eaeb9d7923adca79ea4995910e1719a18a381d7459d0a300aa0f6f16a0b6eb84e45521fcfb5e4f21caef6adf7979e8e47bf7aaf267fef53df5d7f3e1c3281b669dc3ed645ff253cc0d1af8145e6ea2ff2916bf91c63bf9ccfb5b880331f45cdd37ce0413ee05839b8cd4111e7534d834af1252daa5c747b625420d4922e4bec25316a09957ad9f05530657d5071ba6c48c263c5c3524e71a5e789461b41fd30ab67bb8c858043bd4b2b1c29039bd4f907f8083fc991f5eb33bc6015ffac6d0d6fd26ff76adcafdd8b758679bdef2ee35db59e0bced310c82842a8a28d5f73cff6e470bf09985e4422b70230339615db27bcc0bc921b35a09834caa003a1196a2d059991b0bec16c5c070edacfa1dd24864fd54002da1406e52aa18243692a1cc2fb7dc8fe89f5bc9667e091cf0316b9895b69bceccb7883cf27ba05e6e4d5b8c773f989432489f1900af570d1c7bc4687cb670282e594a742dc8fe60025d4939cc5f810c589990ffe94bcd296faa7391e9fbe6b9b3578ff414ef1134efdaff7cb230fabd00fb9691f9fed2fcf3915d690bbc7b981c731afe3e6a0bc0b41bb65e0deccddb14d6b395d78eb111bf4b0e0c1216223381f489a94b8106530c8920f0ba4fbcc405f4220bfd0aadf66a0e70b6f067985bd3b909bdc18f7d49376c8db1daf60b9a418e493af8398da61f69a9be33fceabf2ec197f48c7e40635899feb77cea53f7f7dd12fb98e7f2730b0453c6c45ae0299a8cc882a476a4c23ea07c4fb6630b03d649e3294eb3781f76dcf4aa403e41bdc432e165813f37e130d7e2535fe9151b48a00c1bcc22e61c466b1b4ee8cafa36490058612a6d5b8ba8a7fe7f3fa256fe583ebe3393a8fed4366da3a6fc8a5eef5a4cd39fcaf6b9efcb4d753bffa477ac16e79de6f64accffd11bfcee362b7d7ddd9b4e136e19853c8715ef7be70c675e4745fc854ae7264c3c024524df148d5ed4222df6751e74a1eee33c75a61673be27066060e2e8857ac15b31ac5838370f20d31dacd9241939aed404b9ea626f13321d7ff880ff6da5eaeb853ac6beeed1bf4f4bd1af7f9f9f3f0e2defe708fdfb9c7418ff8d40f302733e1613bf774cbb92d2303c677838f22cf4e84cb6024aa81465d8d5db64958eb86ac28b281171993111fe45de08cbfe33ad851c44661cd00363908cdfb0301fbd142142302668640b88b4c7ed35cf06fb5295ed6846aa265ad1f8e31495e8ff732f6c1e3b9f6581b0a5ed686fec41311bdfcecaf7bed97fffbdb18f27f855362fc3017965613b83ddaaf7cd567fc4ff5babe1af7b42fb2157c9071d89df0152e7fb8b6f7f58c03adfa08f972498b610efd6d027c83206e46b0a099e8be130756cb29993393fbaaee77a16111c1d607ea924958057d1263899d02c8ba4894c106ced526abfa220588898a3c244dbb5653df4f9b7ca014a19cc9d79a2d1f8e3faa335ecfebbfced068342fab87ab734286557ea08716dca417e134d631863c69697697ff7b0d3f80931b681f401547880fac1a0fa4d40fa40a0c3cb041b88ef5472e852bcf98bfd3f31c1f6d7f9b19a83afb3fe45493ccdebd3b4e7d2eb7f0017e37fe69af1c7de5cc1d1772723a17c1a9ce7ac24e9fc7bfee2e413e35548f61d1642ed984d5de4acc6f30ad3b7b6ec09a5608a662bba7ba35788d269967dfa508b33b43eadc730605b59d8931618d7d97d6d2c3159238562677c75e0679980f5233649bb296eb207640b6eadeaa8bbc9bdf5331d925067ac8ea277cf41b98e3a36dbcc08e9efbaf0e57c7a2e6b7ee385e62f08ba6cfbbfbec65bfc0a7f6593e816522ac528a8b6ed001bc7eef7c365e89910fcc0016230ad760d9d82010bc125aa7cb46ae73260bdc708389a0578de209b5e781e357cad1a9840887acfdb1607a25853fbb03ed46822e4d06bdbe03b33de6f63c72faefdcdd8344b45ec0fc8e36be10757f05e6eac377aa7165dd789f08bc39e14cc489bbe35d6cd26d6a2a769118dd09cb72e66ef8dabd7e0f18c7d8f34aacd22630fc2aa3fe435072909a7a94182d8dcc7682e3fb516a48b1747b2c5d3524da3e048eda881a9b918783dcf50b5ce349daa0a99aa279e6e269ea744835c52c12988525727905a132c66daad707dc147a39e5f8b6fc826af7889d5cbcc6769c63fca77d018f7b7e3d8fc92e35f8b33dff869fd83c8bffe3273eb8257ecd27f4aa9e1797c909dbfdaf6be8bdb2874fd7788d1bf156bd5de35d9dfbb5aeeac52f038b3b7ec111ae7929adb0f18b1cb1d122fe0665d5e914b043168d17cab09cccc0df79e343c6240da2b121196ca4d742e6e2070ac0801d6084a61af1a1f8114dc6dba5c30b1cfb930c10cd6305312b66fc8a1cc9f535deeb75a572176db28fe1eaffde5730ed2235be1ed76c9f886ef754abbb4e0700a44e3f5920dbc25e9b260683f9402c39d5c9b21eeff35809b51a5b04586b5ea249362d16dc85d39c3a262ef14cb2ede10e70936b62dc19bd26060f028a9dacbe3f2843ae723136b9b69310e8ef81b706ca45f28481bcffd0b304e9049eb48793e33ef138f8c05d7c13ce82b7c73e9fe5277edf38e812e11fff2f542ebbf08b5da1bfc492bde2b8881c4b50fd6db370f980e399c53dbbc8ea0224f0be5f4cff4bf4972edf3977d107f8b64e36f8f79aecbf8e79b6f1d39d70e618b9d8fa957d74bd13356dc82b8e08b7a33bb3020b6f6d05c0d91311ee97bc582d3cdb0e1bed71e3eb2e1db814824869da32587d3d90187fcf8d6e881abfc746ff3df28ac332f6053546bd14ad87ebb19d4f8b22f5e4f7882367e1bda1177e651f50eeea32337ef6d0feb9d7ea2677c13e157877c1939c9efbb3d75df0893b214355cfa27198b2d60b07ff0b3593ddb20cac80abefdc0937a2fc76482adce440d6aa2976021535aeefcdd44cacecd0c5598cbba5d67d5e2153d064c881d550b340d82b90f49c3d3735cf745147069fe41a1b22fe47b8c97fc5b9fe431cb5693d7ec80dbcce5cfd901afca0aecc0be4ae7e78effec1abe31df1a26ff9737bb4cdeaaf171bb176739a3c04c77d795d3f7e956b1be4a2db3023d92b214741ad0a299c817bbe456a3d895cb2880449222381d419ed5344f062ea53e1546089a4af6a7650a037699d5b41cd7aca4323a3f847c871a0a81474509ac0cab83360470c6ebd85c17f2fa770e2529ac08314a4386b455e7ae57fc7bb34814322a47ee2773674bd8c9e6b2ee52f7dd33a731138de45bfe42de92beea7f3b38e31901338c8d86f13d1b7cbe35970f863ff7aaf842ed303ac33d3ef9238ecd4d1ee0d5ce42eaf7ef1b15ff7dcefb25a97677d65f06bede837bef36f7cadd3dc677fa1db79b66f382837ec72831fd24b9f43debc57a309cebefe6d6cbecb4d52cd63acf35a9f7b2a62ff54aff9c3fcbae070ca455c7576921825d8b34d82ec839a62acd8d80e399f50cef6dcddc214ce7642e029a5bca6da46cb5a9db4c3a292cfa4bedfabda6fa3a99e2555db64ae65498e065a564664b60f896006e5cac153b517d50c26b164f94779204dfb708ef9c2eee44ffd4bdc11b9e79ff7ea049eced3d3337ff9ded53a8bc060d0d9ab5226b968275969cfe86acc4341aab0fe3a92707d88eae0e6dc09d7e67c8fdf5379c49a0bdf52eeabffff46ff6f72137f20af39505ed5258d06f25c4b7ff95e873fc1ab402a6906d3c0e22e3c840d72a3a1e892e8ab49c17ec801f93287d2522e015133dbe3131f1fbf53cefd5e81ad95b9332badfa7e1193bb25d3231e2bc0583b53063a0495df2b57dbd8d5530eb1990dfa8ebadd17f25aabe8e36bf52fdcfd7fa957b7cfeb7129633ccc85a5971e691363db25b1df7c0cb3788398c9f37789c18793765d5c8054e0cd5ca083341f6de677f3fb947edd90999c53d326a9479abcf6bf27d431a332dfa8b8f8ce3ddbe748c70953213e8cedd41d47c1a1b3ef0e5f7b49f5909afe17297a2f8dc695f05a24626d244d01938abb58ab87a0d1fbdcc02c32f43caaa49b95a87887d3fe43676666a8e31efc006ee2263a35c767de1cd7f2849f7836fee58cbc1247a1c2941580bafd16b3becaaacea771de0753dbbf1b8a51a48b080b15071a991cea0d9fca366a6411b87e92c6248d0c67271c7860865f65221ff2d24fb21ab5d25b5b2ce69d9cda82b908e7badd92528b458c5fd70baee8d9c4d7f3e9ed8f762d057bc86bde7d80b3bc9f97f737d83727ae4d3d6f7c9d9d79f65fcce3d477f6b0b84ec3cfc480a4ca2c481617f3ac6143c267104f7d7e07ef47a4d17bdab42b59ad37e1c013c6c82630799c6a35cacaa4c7141511839e728b58703fe11e6201633003ad210fdd36ad511154e3bb34ea846ce4944267f40eb7d547f607cce26fff4edff379acd3b35602ee2f3a4dd7d555586f8aa6dae4534c4913f4ccd3404ec63f84c0007b6aafcad08a5c2d4313550bee6f9381a7bc269b00259b05d25f54297fb0924f32773b70e477ccd9f7b2098d05272336b57dca5b2f5a753173240f2adf4dbddb72d94961557331ae5f71bdbeae671d9fc32eabcf3c21e7d824f8b54fe243fe0b7f580a7cc947bdcb37738bfc28cc1a7dd6e03ef9894fe35fab977ef25704f20756b7955c753fb080db3bb3dae14acd2364a749e3bbf3a1d8075a3709b5ef9847aa9c135f503f9194ef52a70dc9540f09237751d587aaf966dd018b868d7de08dd4aa268968f42aabd787c44c4614f02a78dd47f5397fe5636bb34fde3bef6ea4657f1eeb741fc1dc753eb516d914fda0151a72474f18907da2c3cd32da42528f87cc681739927b525620ab7bffce540e8fed9e4db5ce1af59dbb72b69cea3a70d51a0b6bb2a0d2c8265b63c9c93e07edb08c6d4d1bdf944d1be65507236706826bfad0dfaf695fe26ed649635c3cd6c51e63a4bfc5175dab7b9abfdbdf989cf10f7fdf93db9ffd10349c73455773fd624c67a3c8b3d7b8510383f27b586bc985e5c955379f0fca0cdc62911bc530370824265e0864f310f433cc0b3b172d52ae0e89a9161458012f6d1056f7235a8fbda4b43b5585306af82ad39ce50dff1101c2def2f9dee708d5958c6099bae821abf9f6793ee7f73a57d7e4f093ffdabed93ce65a09d6654297793d06498c371fe1a0b981afdb2bc1a18c60970a7cc84c52e4c6f678bfbff57e77ee0bb9ae8f9f36bca01a17b896db088630aa11151c7d89eaf1269892bba52641c0b08d6be4a55e02f35a067cc0a134917d07c021348abdd0e82164c1289d162d46ad9b029f2ed03d640dda10c79f85541db05be8b4c4f3c5eb33e797f515cfd7f7571b7cc1cbf01873bec8eb5ddf6f58cbd8dfe5e633eed897763c7961bbc7313cbdbfe8c7ef93f8e8d78e1f5ee44c7f679fa632f387dc4547ff64975d626659f34366e267f1f1cb7df0ed85ed1fef3262e5973d9418e387dce45b75eec1fcd833b98cf9582f7fe417793187a7ef147f6caf9c626079c66b8179cc1f648ccb24b6cf76ff67acd84db02f7f9ec3e9ac86e7385e9ef0636a02e1f10e4a0cb49722ec2ef3b86e1f0914cc8d719f4ebf1d3251a06ce01d66eb43dea88157fb4300b419681b254c89c8552c68a4aba6851dc6f810b87dad34b2b1207be17eb538b261e0f95fb049685813ce5cb5496ad405ee7a27eb351415182dc547739a7ef991b36af1f739b54372ba07fdf2d2b737bab2d775482ad5e4acfb114034915e112455bfc90cb8cd8c62a31a6c2f5c55854273267a1a56ed43581775b6ea26cc2b1aecfa252efd6a814819eabcc7b12a54456a69f05168a83231f0267571aa1a6d2e3992cc19df36ee70b9ce2750ffaa69f0ed01bfcccf9f7d81f6ec035c628e577de2bf729d9defd9b7b42d4e7598fda517ac3bde7799e00fca3be35afeef99cba7bfb29e7148ce35973273ab87b4b99253dbfc8ddec69f794c6ec28b7b1c4bba6895b9ac3be71a50778a91de7a9f06a7b5b92e36f645ca0a0b837e2e39f982ddf122abbb923aeb4d8624a55369e4ae7625bf37e646386410cf165e3be583e24bf4ed90195699badb8dd2c40b4b0704660149ddced8802bc94993826e27506165bce89702b691209fe92d6db3bad0c733eaa976b67a75ae9ef9a44e3ab1eaff4a979fe2c9fc177ebf57fc5350b97a3b1744e79eaf130301193dd7d6756ea0ad7b25e7e7d9d6aa34f6f7ef731fb15bd40d8eb65349571ff2d33df273fc933d5dad1b8071ea3133397c1de53559a7a048b889e59d311e8e671b33ab7d54eb8d32ed5974f80aef0cdd65872ec85d5ee490b80b770c49eccff2ba97a9a95830d96eb2ba6d973177541d98144889793828d119a22cfa8cc99be25e5ef671ccf4d1ff9cdd026bf21677d787ece178dee713ebd4479e9927ffe8e1c477617e00ef76b8457ee68f7338faee673d6eefdb43eef93be58e4f3eedbc96db44a83347fae1ca9e77d6b6614da2b071ac80abada00ab26abd975e60b2555771faed905219444635ca4b3c511cada92e1eee8cae93ac5fdc015e476e51a70dc2acd64310b7774bd7da2a7a3f4a3d67875d320ad0b70385df8690db1177c637d50bfb2d7eeaa56fff31fcd4ff36cee9f9d9241054ee7da7dcf1e67dbc53781b2cc7efc77fb4ed37fb9d4fb8c06bb11c543629c42b8c9891707517968492d24f55d5aff020ad10f83f125342a98b491e4b83c4f77de4fa5d04ed8d8ac9a08c360ee262c1b52f83495725a2ff11711d25f5b8a1a5fa1eb81c088eb749ad0bc29145e337f8caffe67cac9fe18b57a3dfeba17cb8fe73d13bbaaefef37c4d2ef1e89f79986ea27369beec613fdf97bfbe072e7a8c57d5804689c052a08245d4b653880cac7d9b1a2d0a4cf93d613a1175c716b1da61a7ff4e6a7f12414d08e30f5905176163cf7341785e55061bc8824fed3973f46e0e9550d51a2a87edc494076435668cf33a70f9e60a7d93f73103cd391e7bf4e917ffbe1ee2418a531c7b50ef6b48f737d25bfa65cc8b4f7edaf779238bb3fefb3576e07494fab3fcd0fd580a680ad6391438038b19e4553ec22cec31187f4c1bc57cb4ed0ff400d3fc36cfe2f23797e7708e73cef550f3da7e9354041b0c5a99f264c4ebeab08c5b42808ca9d1b5a20aa128f5170cbe1e445d740b5ee0849391745ab474ba2237b426153edc993a11ab719cf162488c6e96b26e1b50bfc84bdbc2ba68854346810100ab8a87e09a3ed4f763955ffa9f7fc929ff0bbd2999dbae93d85f5dbd7f1e79fe45dfa61feb1dff7b9cb1f953472073f5e6dcb7fff2bd8bd6e0eae3fb2885ba9483faa2dc7646743b55b52a98238bc0e8f764d04166f0f286ebfdb65ee3530c79bdbf9f9bbc7b5fa3ebdb8deaeb4fe39d7d9d18c34cf0c349f7febadebc9114ebbd109c101818d4e04d4eef4701c03d159a054e9106627bc33b87acf37a0ce5494be192173a8caed56438c8387cff39bfe4e2fee47356177f414dc059d7f5c3367daea905ee6c105c917c505100d7564055cc34b20256cc42aa260955cec22d0c51e706670c66acb752d08e189728a85b18383a492ab54d581132b7df88a88b69a94ca2bf6d14e458b870422a679ff0c4505a7baf7185ff9836c641c6a4cdc4bb38bac36b6ce167efabf37897fb0aa402ea7c752d87ff695de614157231e5710a781fe8e490549d5e4ec601055f7b5eeb84d7a343049494948422d6432888946edbe5359211e703afbb44d1e23b76517737dc6f30e7ab44202f9ba23e75bf82244676c8ed19d50e2010afe44771593587f9633ffbbb58acf016b9cacb78173b8f712b9bea82b90aaff20138d50fd1f47e94505c2787b14e017603b1dfcf210f03a677b9a161245a8bbbf766eaf8864012474837bcc6353125584c2b53b80aa6a5cf29e81dc92a1856f921a3f94ec5ca4a582ff854d64943a60a126bd95cd573da66463b3ce6f882b731acb7d08d3dc89a7ca0d671133cd169acf37e905572d2f8bd5aa7510475b15335f9426aff7b4a73730e5591d688525e6c826a1c645137a295d64c104c633ec1862ed352add2417e49a9ef2e1ce58571d14a033f1047eea3aa58d1462f12435951455a36d98eb26a7c109497a252879366c347f682816a193dd7e77f275ebc495ee1a441d0250daf657d396b7e9d47874ff5ed2bf9999b6f0333beee31e84ae9c22e327cefe8e3d0a6200cb4076cf81ed758a403a70bc6fb80259bdcb357acfe6a06934e4a819ca5db9998916ae158215d751e99ca555a5b32a3be50dc86212cbadce352d5702ad0ff5fdffe9fae6f9f6df29cc39dbeb7376637f23bcf7be3f87b19df3fdf1b8ff3e82e7d56d77159bb883320072ed082367cae8c6e928a7677bc3f43b635e606c758cb366fa4c590da8a524d428e2cec849bd4c1463a25135cf73e39740fcc25eba4927524fcf0ce508c00bfcc6b325003f17cb0dd3bd84ee89bdce5efe64bf4a597ecff1ce3a8eb6304ac13931f64047fe4c6f8e179acf967df29bc1107018679fdc88900f749ec9ff5e17e33af399d9d7abcafd37574a0587db5b061ad2818413519077313cf700d6550f12231e40f5e2933af70c98c0a92295e29e47f0f2a952e3cbb0ed8b6e76c648a52cf305b436c143fb8660716b7a3bc44237ae8dc8cf96b6a4a949aed940ad87c505bea831acaf9311e81ff9086b279bc9bf1753d796166702fd27abd708a39767c460fe362c1498d75eb05a6d4d9616c63d88a1cea03038e1195c5c392ea87a4c49380cb43ee7690aeba2f0b3646385635a17c8fab7b405dbc16bc1d8e7e21136a1555a18551ebbec54bf2ae0689e7c3b9c04562148fb99377b4bbdfe60bff45fffbf499a7757b59ffff77f4e09fd60e56a990f5fbb55de7969a109d74752d7fb1a1f33c2edaf057d6e65412387a3407f82e0185159645893dbdc99dc28b1832a8a7bf2b30de250dc1f3a1a8ee20212940d562eaec928aff90d09ee5b55c2534ec7963ebdc9c99a9bedfa969c1d349170580270bc16d36f0958cba1f8cebd71c6e37d5860f6eae0d7fc53972599bff9f5be67f865be651e73dc62033fdf7eee5fd8dd7afcb4db2cb6bf6cb3a5edeeb4e58b22bd793bb385595c234ae2c558f2bc224cd0d36046e1fa7c2daa4abee4e82f14469fb61e1a9288ac99e719f26b15e27872dc84dece44330e0986f32b7ab954624aa553087cac85811f07a0d84c046d004266398d00ff70162ad26b0cc8cf12615ecc241f2911c52788bdec041c6619718e35d6a68fde8eb3cded36fcdebe2075dd7432878c5aafb51c6fc39e16ac12b2d28eb745a590f8ab5a3cce5bd606c2734ae12188ee6c0d219ad769980bbdcbcef83c62e951b8e022f3850b3da074eb7104d7bc80c85850e6026108c86d96e29601008dfc83cf9613f281544cf055e27c27a90e2bd1aac731b4d5b13b7d2655d621445565bfa5c837df91ee83fa16ddb635e84cb98f4a4e27e048a0d31484b993e08eaecb35806ac910f4cdc8360f575438cf12473641c18b303454540a83f5a3aed5e54b2ca680594c1f6618d76bcc49102ad454cd4e058516cf0fd12112340adf1197e8b8ff3f22a7de6e827875458432a823f7289bfc1adfff4f945f407eeb5ff78ef086ea56115d904eaa5abdfd322186e84d73df1422762dfc9b868d5a30d3e9bc705a7781d6e974b1e95a145aa60c429fabef4544abdc24f346179450cea5af57c908cb86a246a3c5f786ac4cae24b3e38c3d2b347d82c566448f6594d26995b2cf24ab641c5b16232ca0cee64a0fd8e4d055284839c860722dabfd63f3bc679a908baa41eefdeed893df1d1de0097f6cb98a767ff9cf7e4c27b7b25f73af267e9646c2f3cb2e7833a287a6f659ebf4d2103618cbf082feca5eb9bcc6805371424a6df655e81b0490a0565471c7f1b511446acc7292ceca5d33265a2b53431929ccc96f57ac055084303ce24441d7dcd71f0016e460432e3a4cb3e64a7deec5feb8c1fe5a9b9727f9d7971e0b892274ce6bbf7ebadf2d16ff4f29ed6fad57c2efd8557f6a9161ba6ef8ffb2c4eabd695d322c801b90b1a4de6a68ab959149969a31ca009a728917587178eb349cb6f9bc594df854ced732fec718d0f01576b39c87924fc1576c71b4e25cec5de08abf18f3b93c37c323623837fa6eff9cc4d247c28eb272dddff833fc5957b796e0738a402b6998b9eeec03fac2578ad03fc376b9977b9a1bb54f4c5790f3e5bcf17f33af5d64d46e0aa358dc6fd7c280876fc2d46ed3ce4f68fb42c6219fb7e58b571c8fa796aa090d5f2a0eaa22665b19983d921302a901d7d22e4ff0856e3261b50b7a0b69f95ea811cbe0ec22134a9c6bb60d2ed159591aa30a354470440f2515fe9f1fb2b4357ef6b86dd0a57fdf46ccd5410904e7e79de97f7c059fbf3ba5cd20335d10c535d4986fb05c751e4f6a39c225b0df730aa2d80bddc884c1944268a79ad37b81edb0bde6e325404b4d2df330f35d8490ecbd867018322e1e44718238337aa92354fb1999b09c3465485a612eacd7eb5f77ca5340e3ad9f06de6a9567a643dbf60ca7377dc664df85c1bfa159ee5786ea6f1b72e39fa4e174cc01943f5efeb0a9ee622ac66de9c78c677e73a86755cc7ee2338a81beedf5ffbbb4fbe2538c5997ff8fd05c3795dfd37456a9a1ec66d2e1233f3beede70035dc49ccb9412a3a209f9b84526ddbcc68b7cb0ab7094c601afb36af090a8e36dbe007c9b607acb5879bc20e019c1041a6aafa3a929a533eb5f9b222389d7c3db0b8da2cf84d71e3b7d5f079f937174e53e5f9c5733f3da0f70fc1e4cce9332f6737c0aefc0907fd1fef59fb83cdc10b5eed5f89472fe7e9afd888d3dc047f90bf9cb9bffbcca7e2556b1117d3b4c97b369d0d61ac360b871bdcb3cb25db1f68a50f81589b0aac87854836e920b74afb0f0cc02f7706fcb260d85b967a21b8ad33876cf0d4df50736ddc9968bbf08a1fb2da8e32a8bf2c4ffc8cdf20e30c8637e519c745e6eebbe4f85c7ef1635ff1285652c836ab59775ce7dce507e55ecefb275cd76ff3f9ff799cfd1fceeedc2445defc17d8698c4112fbe0ac29fcee7c3fd5cf93d6f786a4d5083be3896ce4880d6caf5c2283da8a446dedc281ed32d6bb11184784a35a0d05c0b1b694dbed788cef58658d5455ed080dac3c667d0ec23d35491c51fc3d1cec44828e6602c7ca6c5b053514affb79fe7bcef3ffde5cca057b8b1e72a37a1f7b739b3e80e7633ef912f904165983db4b1c70451f2aec89e0248af990c4f92115e392bb7a2528ba4be393cef1221beeafcfbb9dfcc04b6fc2e43fab33fde89b5eeaef6566c04e0a0bfc6bfc81bf1dffe9ae7b0bbf7de9e7b8827b9ddb2ee52d51a2f39501b70b870cb4e26b11ab5d52159634ed261bfe5bb8d7313cde4d89503a7bf74c0f1e16935bf03aff32e679efc4b6ce6bd41cd7634ecfe35c59db0d584c02caf08e303dc72e775429bf13936ca831a6340e0732e97639b5adc020c3d281509cb0b968c16309f9b4d0a4f2217561cd4abb155c7f899ca097b458e75e3bc5ba1d96ae0fd9543a91405bcae48d7197e3637cf770fafe8277694cc04f1d11e735b7f0f96f4e359cb446879f98df9718a1f3f849c39bcb6786b73fc347eac471fbeb19f12a3767fadd5c9042b9cecf38f42556f7c4513d3e6442574ffa46cfb4925efccf4ec6649d19e4a546de6b1e06c19e9e079ebc1e337fbaaf4e5a3baf7fff06f7c0cfe7163ce01be8f27d8213f257db37dec288a1cb7384c73b462702bc9f8739dc4223e12dfe8827acfd8bf7c1f9195ec7cd8e92bad82d9c2d482bbd8a1c34ca1a3e4aa9dae1a9ff3dd76d4356e3943b5699c3f607aead283235cf44b7a68eec170e9e4531d9cf0d69e1ba20a2e169c6bfedb2125ba2d422d47c954fc997e56adc8969b1ceb80e6f8a1facf1a936ad62d266272d8f4b6fdcdb79ed975c10ffe7375c106d6ea0435e23eb272fc95bba44f62133b0cecda0cb4e7bf7c4bd5ee4b51a2e7ff706e6e0c453f24b6fefe5b3f0cd3dd7bc9d433fcfe9adcf73908a7d77f44bf39a97497cf1159a278dcc2bfd05be97b15f48833fa8c95b7d2657f646df4263f263bdd1a7fcd5555cd54678e0bc9d4415d908b79718a855d414750ed8686e584664749c70d693211825031a52363218ff662454877caa71c68ac9c2510fb9874b66401c69bc23651150a00f6a5a4039199bcc23bbb4d1037672e3cef8739c718373eb6d4e9377f96e6fe4e709ab890da213635c3df606bd9ecf05eb7a650e790ef13a6ba49352e946aebfe2b534d2d8dfdd41b54b6bed2e9b64930f05660e9c8535fec26b1e4acdf7c46903658c033eb5d76a8ab6186933acf02aa5c53eaa90211947d2b53691a7c32527e1dc805f582dcd7778a1afece1fdc3febfda9f3fed4f20e377b5f4c16b0e894fe673e3536caa73f399df787e7de10abb6edf05ccb793461e286c07029c417032e5265a65e2bec7ce7e2f18ef03877b11c3c9dcb026592d3752cbbbac54346f0ac24be407a68d8568e9b2caad65f4d5149a1d78a92b6e222b17db0373c6e6d2ed57c15457eab6f9dab77da7973885e6a58f7fd61639f9f2ff191e84a7fefffc708cc3fadd7b67033ebcf21d3f7936f07dee8e0fc7b82e31c6dbcc9c3ddad18bf900f3ccf3755d2f4eee605b697fbb8831506c3c53359fe7c6c88c5cab8cb46fa892ed8318f989c0f3a5465b7af8baa19e1a2543b5093ce7a0406fa99238b2916031fdb623c87e081abba7c01fa29a38a91837c251d122eabeab46459faa2fb968980bb94d447eb185f0d51afe3b3a85a4c8dfe56a0e1f021adca2f70524b17dc2f92b17ed6504c0bc74866bb90583c95806a51d2ae8fb5c74248164ca8c0a840cd1fcd07d0f99958a46f5cce98a34b6bd1070339f3a7b89104e635b288d5305390f8d6a1ff06a478d6e1b3165454ee7a68e2ed37a5ca687ce890c6b22abde26b7cd075652f0fd5cf05e8933dfc46f7db9477e9fcbdefabfe7bce16b2d22770c52a11e1efb4567cd3957f29a2f48eef215d489b8f05335675ec7d71aeb1266f54573f859def2ff9e7390afe34ca3df258ffd05275da2e4a53fbd4ee2e0f9777855974a85b596b1dfbee0ea03af3e17078fb89fe7ff0fbeea4913fa2115b0cdcd67735fbdf1b9dff4ae1d3f8f0f6fd4769ff8299ee28cfe779f53275cf01356e74dadd23fd43e9fcffbd533576e71c84cdea493a738669897f7bfcb27aed2577c48273c59f184273bf52d9f5f7fe2fcd8bda1b1fda8bddf660dde1f9ff1fbf5e69bf089ec92ba3dae63970a6bc8dde31c4ebae6afe633a7e735beaef7c7317387cfa47bdf2f9dce0f85624b8e39315440e3fbddd2538e68f0869688cba9d4126a494b8c24f2638c5acc1c0b11c41959756b6556078af8f40ef8db3b882d8a0a9bd696b95c8d7f2cc5fd2e8f398820bf8283e93f5e570532f6bb798cdbe5bbfc31b31be16489ce6bd0e586fe72c6913d7f0d2efc7b57f90f6634d8514a494d81faa156e38479d588017f262abccea6c5945205a90820af608021ee53eeec97556ede8135e4cd6cc32a48883b9e25d49f521d1a112878a68917f162160cff0f73ffd69eaaaebe8fe32fe873f027417a4d0f874a502a7110b2819c01f15f8440a9a222affe77b969475b6dad1d9d737d0fd6b5aad361309b27cfe67eee9b706283251bd7031eea2cb5ddf886d8e27bfcf0ff6f6a1919f1dee609f525cdcb1fc0dcbf8c77f43f9eeda771fafeaf73c41087b060f10f4c6936134e5ba5d0cd63830b2f68ec04a21a3b92ff655c7fe49438c5d0d77b787e84d7e2cd98c739d28d7cd636dc19f01bfc162615d848b5b2bd228b45d18240b479ecb44b42dd42eaec3e1ea97baf68ec806a5bc1edd22bd182215d790ee814401359f407738e420fd6f7b2435b41b990153198a167a2e2d308641b3fc70e31f59697cdea1c67f0aff56019b1b0aca96877ea0a76f970c7bcf589be15372947afe70158a5d5a13fe7d5f88679e488ba696deea8d6bf3dbb8112f640aab33b6e0e3c6f5c744c7bdb598871d045a6642a63e2d19a8d7e81b86ca73396c214e14c3a72177392cfabda0b6c194541bf1781d448980e6409567eae27736e6fee01aee86820bc906fcee3a42faf0dbc756d921df846cefe827ffdbd3b69330d3fcadb7ff4df4e5c55b79d2f37a513206cd7c0556d63616d9993ad28921131e4ccdbf5ab399feca626fa4d1c3ca58565711b14782c1709f5ac00f18c423da094f834b4b79201e1effa2c36b3bb7b503fc931ce31e5d52cd4d67cd1c894feda5eeacbfd6b8dc41b7131caf9e7390668d212ade555ce3176e4fdfea1759590f7a6a19b25a53ac5b267cfd3e0dbb4c20f712dceb98fa1bec3fa01cc19df79029b11549085d9222ab489015f7a50fd9e535e04821822273b32969a8ed1635a927b366cbc38e84fe62369ccd96a4b0bbeb8efdcb16feab5641807a51ea7a13b2036a6b45cf5d28bfc03df8e6beb7407d64a80c59f9a69fa53398d9bf3a2cae983085ec34a7b3fc4ed49364ae0935f7118b739e9f3ded62b69b8bd19e216e6c453769fb28ab869d0606fe46d52a3b1539d8da89df59441f234e4948ddc1c8fb027e9af6edae94e86ee1363ae3bafc813ab1e21299b7b193e5a64d87f4c1c6ef93c637ea13c65aa9887a9959c6b4ffdcdfaaf137360bca935d10ff12d97e3d1a31d371293e7a7b876ffb9636c199ee6b8ac6ff6330f31b590fa980bf89caf6df63376c23ae83e95bc3bf677bd7e6d6ca7f9c3ad3a988674dcbb20ac5b55d686841ae3d0353db10269c127ca7607b4681a39e6456c2bcb2f781617bdad27249a8b2cf3997e4c617f4aab02ce69ba0c58cff20c5da6b6341428ac384435868d7d6f66660033921ad6fd0d78cd7f4db3ea801f14244b2b379b07607fa77fb1ce7838d73fc09fb15f375e44a1bb8bc2a2d9dbf9d735c74f9eef74fed94de77f5e12304319a605b76538980660b21448ff1636126c4c42258a6d322eb6b4229b18f12e32d32517200b1c3de0c0efc5635778a1bb9beefa13aca3a5671318e4f837a3b6c5bac29c31639b38c893faa1979646cfd33f6eff0f674d3aaf6ae77f7a4c6f5b7b612d12f3a1490f38676dc4a1bcd60bff5cdffedb380824a5bb990fc1363d688e905a1dfbe12fbd7fc2b3de76cf2b54f3698767295b75d2b6813407c8638d3117fa9e872ef2f3c16aee58e3d8004e301e1841ae5a5c7253a2c75edad93b16babfc958cda23273038d8d84d54b394284a02cf39815f834cb48ee0ebcb05e4e81dece7f96a3b654c2ca95b39ff7f7bdc49772d85996eef69f537552bdae91bd5fab97cf76730116096cdf7ef6ac9ea61ee3fd7d20dccddce1c5341cec62016ae568f85687e3c35e86ff39be5b1de6591efaf4aee7407ea4f7182425d1f2587f3eede997d7278ce56db598a472235129538c5d7b0afc4da0333d17ea3e1564443b3913fab1a5a3080663b747837e8ce13e667137cc41ebc4e86d498ed674fcd02563754f4306fd50dd0b1a59b143eab9831cc6fa2001baa3a24638e88fbce2476d5621850be41f5d986ff4461eea7ce5117f728e8f910e5f28f13ed7769e0bc58b9ef5d7f7153c620cf777d369dcfd9ac2695edcc6c152782611ed4eda751694961f15c8bfef104a4c225585e2144e3a29f00a87aac6855bc6540e034d7864581b65fe829129bbd449b7b1ceee12edb2c0204f49d047d8408534e490977cc090c4b4c45362e209fd59ddcde688ed7ae17bbdf54cd669c84f71f9053cfd455cf4dfd7c4cfc7ddfb8d7c1d87089cf217871ed0eff0da29666552e81de10398a23a6450dd2913fbc424dcab6ac100d9258b7f7a74c4dba9a1f51cd54d301ae86024a94fd3ce8760e053ceb1ad4c0a5c364768202a6f1fa70c84ddce52c1bd64ff91e21f20415df22bb8a65bfb27d24a6f8f31365a4ba7dfbc599bffa1a6aa0a074514123d15d64639ba8caf73101b274d96bfb6e3a94332e5b02629fb462c647dc2575d7abfc1c3a3aeda4d3ac8a22db07edcb24a8f0453435ce26520ea5216ea3733fa4d80b2274f282c193323eefe9ee704935d1351d13471980dc5883c71615569a122aaf51d36951f186ea39cbe8d6db0f64b7be70b0b60e0d20066c6d4f8511bb048cc4c278b97dedb4b98e73c76d02ade7d8ab5ce136895b1509d72fabb67bfe294dbb954e36ee602ed9ec73d6a1e5fc0a086834d5af94de2a0bb79f0f967d31dc8e3e0ed3ebff0993aa9b01189762585df1ceaf1255a25a7da6578f01dce6bc871e835fbfbe3e4671997b96074370d759696bd97ef3d7dfe02f7d4fef36da69c7d9c0bdede71ba073ec0d082f4358efd12a6fc99134b905a96d10b76ea121661ee906a2adc2c85bc885ff250ff0ab6e6077d49ad1308b26471f1fcfeff5e6a6eb9d1de98fbb86827ce6bf5f83112ed350ddfee87ea4ca773f74ff33ceeb774f929b13d6302398c0c8f35bf05771d39c67709232d65789c522ef8a20f2843432f4fbba0d05ec2fe597ab01e24ce434f8c484bc6a4508e1ab11c97f33159509be3b9c63d2f778974b23571f0bdaad84e5154f24afd288fe0a927ac5363bdfad3e3e79fe7230f7c026778b93ff9d5cff895fe35cc18dfc5c1de77b9aa5ffb239c3d2a74ebe97effec8c3f7f53ffd07f72db9e51bb00706b4ebd8e5164455dd14b91dd121b35744c4c31b2b7331699dcd625876de8715d245d16262354c71451c9b25a0afee8d9d944ea81a623b7a43c9be2ea719b76998e8ca69b09b9f34dee05955c4bdbbdb467ae6ac028615907ccf4bbbbe1d6354a86cffcba6015855fc885ff48edeb6cdca35f526e4f5c766c7feff56e3df35e009c5467d3a981ca28f777728cc77307c424c7559ca3954fa5a5ccf40731da83ddf1337e73d8a33facdf7f6bdfe6a9bf65ffdc3b29f0dea6ff473a3be7fd24c77378f63ca75cd897b1dfed94bbc4639625ab81e9410b275a43a5bd36309a7b09f8386204cf465fe2c8014ae8e2cafdd53bf82b7f8f7f3f8c759c035ecba171fade9bf2f94baa75e769a42957d6bda14252f45142752f297b30b0b19d8e062b0cd0908c54938cb23b8a78132c5696076c408b684bcb7e4e4277ad60c36290095258b518791b590d46b84425eb323b76261b693e9a2c57fa1c637499fbf8f89b0e7351ecf7c3141ef88f8ff37ba3ef7198a7aff18bff94aeda9b31ffacd1b33dba5557ed5063ff2d1d10cd6dbb9716a46354c9d4b644543434289bd95c13d32b8a25eb7898421713c71a295b870ca02c31f1cc173854b60441d0974187585cd53ca0721d954d158708cdc5434f02b59650e62acf0629f4adafea522898d5117c68a2b2dfdbfbfd37e7cafffe2c98b1a3f378080ef1963ccf997ff6df6fb517c7dc54a562398eb63e6bbc743c58115dec025007622499aa34a0b9dac465bdc3b0356398c2446cb769d977e7544b19729ae6ea9e759ee955684575dace102722ac2bc156d6bcd4e308f21d37514c214049aec565aebdbfaa919c72e16fb8202ec666078e428767c9023c635a5f73419ceba81fe239de448758e919effa3a17ee5f8a1d9f734baf9fe70c277dc05d9b7aff4cab3779f90ff565ffe758543316c79ea4c4d16b795d73fd7dfcfd3d5f15ea42eeeda668ebe4f90cbc790ea3fb860d9aa5106c848356295082d860acc2414fe43cf046d932a2ba4c50fd1497da5345267cae24351a23660d9e8df993427598e63a67a52c23b15a2a8e111e3d2c299cf42874b304655b656acd85b688ed43c664f5c3fd6eef78e37e9613ede6bcddbb353a8f870f7c22affa0cae628bfede6f7e3be67edf1c394c9ef14694dd1e230b57e2523e612a7f736e6f63c4da00d60e2d0851ac766458b701243b3fd48eb4b55605b2e310edb891990cb68b84b933cab22d1668e99591e1a14133b36b462a8dbd12b473a719e3d2aa6223fbed51544e617b438cfcafe132df9db70b3519013671f9d5f57df8a1f5e54d02eb3febb933de3f47331bde9edba71c3f89b0ceb961fdf6e9402b034dd2f1e39686d9563009154ce15cd496c7acb167668614fd769e4706467294ecfa0173d43acded0d3194710f75ee417dcfc73599d91c78801494da0683c84cb4e40953085fa9bffdc4fa5ce75efc0fe258a8bba9902071da93cd02877ee56938d8ecedf47efdae3c6773ca29df8601a9749350b65441d3f926a6dcd4f62c44b348f0279e639b54f2d1379a3cb19b220e6b19b19a2b960d66231c50a75e606851c5d45a3a6414d80a7a4eb6bc371a890d17fba2ed38e4538cb8969d443c97111337f837ff5a3e49d5f298335e1df8af3eec63ff2a07aaff43ba9b5fe24035bea1c719f945bde0233cc376fdc82bde089b6da5e87b9c6adb87751eb1c8f28ac6a315620993a3a448dbd4897a72ccf9dc966365121f17c8c6a5b58cabd48a2876a5a303656f3b425dd3336a3b666c33778a4e157dfdb3fc7b6f6dd9c91fec7d583ff8e41cfde1c3b9c893f18e53ecc82bf3bfe993fdda1e7de61efb8f7a36def29d3d73f0bd70cf7eab6763a04239e56397498d6682596e649205cbd1740af498a3498b3b0689a97336c61586132b2a89983102d290efb0a3202ed134655914890788c1632f108062a0d03ce78497f8b772da9277ee4e141c48d3bfa865f0fdbdf9de77dbef19f6bfda33bb281c6cbfa6a13af9fbd8c374b3743cb00e798fe7bfe9310f78439ed560c0b6e2ead1f42bf424c6d92c06da5185bd65cc029435463a3ae7c07bb55e5f9a97f850379775e2b0260ac92611fa9a56e94fe92f98fb7b5706a08c45aba7e299177f6fdb2f3fd7b7f418188281832d91f3fb44e332a5b84e00b6e2ca1dc6c68335e7a9915035988b556fda693c0ffa3619e94d52345a05ff58d891665a804d0479433b97f8ac767cd1ae9382ccee416db35d13c7050a70c8332fe8fb7cd1273f599f8a050069b9ff5f96a5f0e14f1d39b8dc93fd160bfba9b6c03bfd8bd7f5f733fed63778d2694836eff8ece7279ced8de7322be40e2ca2106be9e82f60367ec456f7a4933651893a29487dd42378fb1cb7f2551e753f069496190a0aa2635d4b9eab474c07c304669e37d228cdb58898d6b29aeca80d0632c7bf89005b1f364f14161d76b89c73247d9e71eed48885240e34994646b425d4e501208ff7b0df11bbeda461d509d537ecb37f2dc6fbc393f779fdf147ecea7cbcbf6f0e5c37a7718d1397ce4df7aa1700cd3da107c2ae232ed440383d8b73f7290ed99272f538e73c0ac618caea9799080c84302c89300f8cd5766ae0273576b932e4606efb3d6fd16f7ca016ca6e3b026b2710a8f0c6ca4d61bfc0e37ac76d84fe4283fd902bbced4ce92c71dafa7a8fc54f71bfbe8cb75f172b12edea50aff8ce19a2d894b6aa25aaad9472dfcf7ff530ca3cc23dc0c783df0cb803cf544fc246ab802b1c8f79e3954d1099d1068f104d725727dcdecab1ce194f0dc5eb883afc49190ddcc759a92917d269051d368e603c57233578adfdb0ffff53beeaf31c723128a3101bb190d614a22775e44fddeeefb1aff17afd7d7ed37764969aa49655b189440df7316f120eeac439f6449cbd478fb9eadbf2560afa469fd36a10a540ed026e773e2599b0b11708b248eced56d9a4c523774876ffecc4383513335bc4626bc523bb55a26f7a7470a790b7232677a2b09ef9a57c8a2ab713395f27c366cd9c2d880b42e3f2117084cff25669c95b25f4ee031ff3493d63cb16bdd65bf43eef4f7db36e7293562a4b4ba2afd9af0bf7e75faf992cfb3b05d14e3afc50c37cf3fae82bde78ffc80dddad2037fc6dc4ddbb99e39ad2a8e3d978b08ccdec29a56a33edd29e5762e289470b8ff884c3749b4037a642b991209277d89761babd87687d0f572d635b33e08338b08d4e3a13c08d0852f00bce47c44a18185cd44d793dc7e6609798993515a890e32ff40afd843d323e1c7f6f9fb669d9efcd03904987ecbe85770a89854db5e6c2df10c869ca1ae677ee7d62d65d32e23d02ddf51cf1356172e4d9fdb5b7e8dfb171b49939ba370f559d22d4705d9b8a2b480bb5f6cb7eadecc79d82baa7806c13284d615b20a2d913d605f4caf6ec9efff44c7cb6c73ff605ebd439ccd14157f78da6cae7e7a98b85551cce82e93eaa63cef06a6f9f477f44c3fad77bde8b43aef0940ff486bdf666bd6aaa6784fb964707362d91cb1cab12c2f2281a68b96b7e4bb36e5358588a1946c2f122010ccca9dcce9007c8b8c61c49941a759c96c88c8366981864c6b91c46d4b563bb6e19d79c54121347569cfe825e71beb657b4db7ea566dd44a19bcf4bb49cc2fd79f8d51cf921ae9d2ffb67383f8d41372f419696f82e12abcd1193038e9c157b5ffaed3335de37f83f85ad879ece16f322633497b564fa49161af35c3f2648e6520fb897cbceab6426b50e99c071805414d8fd5e2c5020b446c46e908264e5d189252a5d61fa6b29cbbee4b9fbe44365a415a23e952dadf88cdd8079fefc3e22fad09378888ff02629adb7b5e261ef0a6e142da2ca3dc5f0ff3e376824dcfdbf83477fe1f4f7d14fb80dcf27acb5a4c526109a4c617617884ce26a5010c75af815b9c3067962884c535d6c3df46b33afa4cfa00152bbefc4700be7633e4e0bb5164e6fc32bc2686195b42203a91fad698702e5f0c7d8c4779cea3602a48ee9e0d6739345871c26cad510ac12a8aa2ff0b9ec7ea88ff1e2d8a7397fd6ff6912a75f1d62829d711af7261cd3ce2feb80a3bac7d100c60effad0ab5f02bbc221a4b0af8325d3434d60383426b47d1afce83d192173aa4e35acf35da8a12b7bc4ccdb8b43b3a2285afb3665ed59502fe32a2bf76335107f311f77d587441c5eb0fb031595c4557ec50b4f6e8648dff1ef3b21feb509f8daba879f6ff6edbb78f9dd4d293a66449c77618a2f59c6b2b28fa638ef47d54a44b555a6bc6352474d060019a187a2db757cba4ca06e978b0f48d16076cbb8df8a3211d77c50b3c4b0c4563276bee617347288979a8977ed9c7b22337fab77b7fd16fe4412712e834e459327c9d6f39eb7d38dcfdcfba0da9f99adb44ef63ce72fe790fc3530afbeb6988f3d8e14d1480fdbe3dacdf0b06f61c4b7cc2d617cd1fdfe154f7f9dcd61df2c391686b09df7310fc5bb5c43763fea9ed0bb48a855a7fcb1fe4f5d687ad084c14d11c07c4709b00ea85746438afd04850b24aca1a29d19fcd35037c34d81026b7b2f437f39cb74191892874416cbab5b47d23aeb8473bd71136a815e0643e9e58dc4444394846348b98d65fe7a1dbcf51c8ebf43276e3422defd4cff1598efe3ab6ea0d5ee2fcbf5fcc0f5de8b9f9b7f01bfe0771f0551bdb46e14033474694224e016e5537d8cc98ae4981364acbbb193300eb902d772b838f5d5b418965a808ae7e6dd2126025f8029b2414654dbcd0ed61bbddcc291aa4855b49d86f893928d310150125bb045ac519f6e7826ff2faf9dfe0be9ef50ff7774d78ac8b7f652d2ee0affe2237f4a5baed4738acab7ea22a511999110c602d44d150693e6e71d9c753e30112830cd30219f33c83d2c948249a715c485715d62eb06d38a778e21b51eb1b7a4dc7c592b1b69d3984057a403c31590606e129234e6492e581337244b477d6bf7fe5fcbddc6d08c4a17b29bfff9c0fbc54c7352ff6e63fc76b3b502ad1ae4e67b739f629806d02f55a0d3fb3f1aff6c67b6dcce05d7fc31bdbfdc91e7bfd3d67bfef024eeb5cbfe5dfaabb820f78abafee2d32e641daa12a80ee300d310e0c1d2763b794955a2991f628cb9611b4b671e501ae070d1d21df170fcb84d99d87d89620b2518eb4453e283ccd790ab22d73809f3080835c86b84b3b2ad0c0331e9789e3d6fc2c06f9a9bd75a90eebbfeb573aadadffeaf573aef93296ef331bff6ff5abbdb5e307fff9b59e97d1dd5663b71b0c10166365054c310fb6e3a840530e6dcbcbdd61147a9da7ebeaf7b34ec7ab9cfb79cfd8953cfb7b5ee2bfb9d74c621df2fc7f7efff373347878c46fdcc675e30e67a13b0a0ac4bcd05dc4a516c499ece2319a92229b09d6f6a4499633dbe2acca62cfd0b132fc8ee472a6c6d942a09af8d05a3358b4d4697af786b6139815cc699d7434d97995123e6bddd8e171a01125e738a7cff6f0e2d467b7b76febfdbe7a6bdbec4f6b2391b0ac4420e38bfc637f9f1bd9c70f0264ca397290bd1affc443745b1e848dfc4ef241490de4aa70b094269ff050e769e919297bb462f3b1274a0d28e0755c22c4c72ac2804cd46820a7869a059d829e83b2d9d895b3910de7483d895ced82920c30cf0a2af0961792050668ef810b6fe10bf83c6eb1f6fe4e9638fa6e7f2745e1d1f7f8185f34a823d86fa2903cf38d9dd6f7f3da5714ba793cbea671f8435c9210ed22981d301da7714f7d135f3e6fed3468f2b870679e903870889ed93d9016999e87599d3a784a608dfc8b5ae4a89beffd6da8af71771f343d7fc2d6a6a65e47b0a98f9cdd7fc69fd25feb5bf2aa5e007a98aa58e65ecf1b17c66cec6ea24a47b1d1de11542fa5dd520fae2ee61294d36f62e135296cb50c7ffd57eb7cc2a1802e39c4dd87dfffeebd6f71842e69d17f22633488476a3b1f0d226e58ee7d474854d59b984f368926cbc04621ad78e1551c2645dd2ae6b753f301445421c66b1c687feb0b7c97b2d596891ec4b02fa78030469117693e8d441da7e35f5d40b5c13ec8d1a8906c2288d649799cbbcf3117d18feca7d7631ecf10371288b3a4b436c9c2388d73d37c6eb99121bfa81f67c25d32c16d81f493c72ccf2bdca1103ce20ef262e806715874543f9aaab0024fb82d366538b7337f8626cb98e1868cf5d037098847ae4f595d73d88e13472f8563b7e968e071cea5074871868ffb3cbefe1aaf855334eaa8c3d7fde173601738b9f02a81969ebcd6363cd395c09bc4e9efa62106e9f8c06df1ba4fe9acb72932dd4d6a7a4d14bad5731df583fad045adc34bba82473d95a3bd988a6c93c0a67bc73ff79e6bac4817e0717f1613a87691305ee591eccb382787eca622ab53936ca4e9664900b6327473292ce35083df814d543ebead63bdff8e63dde2d88f184e5e8df96bffbbce3481e3b1de8f51cb37f7d3995edd3eeec824644dea2023fe340e739b5858752274f7aa37ec123fca265980b50c0f38fd4e397cfd29cfdba15f9a18f3002ce62179d1d8c6c1e1ee7dffdddbb4ec57fbfd9bee3efd5d3b290e77da4efde11db9d02b7a3c137fea511fcfff5b4ef3971afe677d485fd120bcc49f717aaeb33cc7e5d8f85b77c6893f636fd7609625ceeae39e834feecaff47f834be60db3e8a833ee4ce387de7b35d22dda13ee6f4777f721d6f35d7dec7a06ff210177d410963f1cf151f21fd997e0488a02af5e6788f1dc66d8e9a5c37d63951baf30d304a789df9108c7c13bb11ab336a373d3fac7d65441d86328a299a12339b51536a69f7b752e88e3aa499a37a1d95ed38eaf0636a67a110d68a0d9b2905bc272a9ccdcb07c3032aa2455689f160919ef34f7e1e7bbdf8d72ff5cb0b9a47cfbc7aaff87dcef46f51a7c6f61fbdda0b3a3a69c8b512ac49c43ebee91b51889793b73a6e1ff4b75ec7d05ee6fefbc8dff12ee5dcbe555f3d8dbb9906fd13bfa171fafedbf351d2e92305094c28f17dc8a7d85e754ca399a7eb9157b89233379b8f95e7737794f2baa1a23648beb729e8ded3eec21b675b5eb61ba2ddb56ff46d65a2a774acd6bee8674947b652b4b399b3ed5851172ac7153be3a4fd42dc77bad7fef0febd5db74b67fafd9d78398f7541b3e6fc8efeae6fda1c34cf21e8a6f4f8bdb7d706404760e3cf878d880b6024cc86943fec30ec0fb02d87a4e01e29702c724231ca5ac9d46f616388f3cce0c3e629ca318c77fd602ed094835f5b86c874ce9591b096523a58dc4354704e902addcee30314b187ddc1177df872be6e1189364b4aace510fc89b3ff835e88a844ab4858b9147e73ca85eccfc385e739c554b7f1777409c09ab37fb6dc0602e7ea91e6689008374a8d953117a8e5541971a92789e3f65841626a0e269edd84b3a01949fe6044da1d44fc61eb0baba74603633e72715a0d8214299309e42b43af028e51506692537e4d33f9fc5e2a51276974a8c95ee78278eff77f6b3f1f70ec38f7f7f7d571aeffbc6ebce0a86f7acb3de5b3661b71bd0a9c5e4f8d08e5a5fb3bb0b1750f27e0de68a6d294011ecb5d6af83d55ba302ddd9ab17a9b76aa0c0cc262582fc9d8b57059d7ded8e541598f3ca7b98b0a4b33bb35e755d6ce1c6da5ce3f8617227dca855f984bbd8e42d79a8aa33efb61eeaa6bf9d7c979bde15b77be5b2725dacd03a00f38f4c359b18e79d8cbcfd59c786c6f9aebb820b9b21f37019724d2f526a8f432817c12955994dafd152ddc961856ae40761f18f54676fe8e503e2168c015408c41f2e41b59118bec29ce0776e2588f92db6654b60b3e924560f733595883987bbd04f6497005fb749e8b3af03c7f216f30f989bcc1893f726f9f8fe31eeab78b5b71cc7c88c79ccdb83b9e97e92e81644bf8047aa53b54007b4a734d0c6fc9a11bc4656dcd997c24269e26a5d753e6af4d427f2d63843aca39e48275c1c8159eed0355a5dba4700bdaa147dfa837a2fc0724acd18addd09bf1790ee10d3ee1d31c6a89b344f0550451f78a1fb3bb80d5f8725ee2c06713bec2839ed7ed2ed6988f1c969762c3d79a709ff26dbed38a38c6e5679a10fb7df79643e23527e57f8b61b89837f9af3928aefa290b416519e70c52c089e764dc63cd13292c9b85fc9e94fc2e654d9116c8222571652807c4d16daad54401bc8a4a30a40598a4239ec59d5be2d1c04f6876cf6d6951ea3669982d4927d7123613dad9ad5cf4577f8b6138c5d35ff1dd2f9f8beffa2dc771f7737f3a2f1fd617afda746cfb9d9fcb50e67e1b187dc90a59a466dd9031c2bea15acca5989a1cfb6cb2c31dbe0f58dbd0ddaa8b0bb48a475984c7c8560e31a481030fca9e725c8f3070c7cc879da751113b961d193554d4059e90429dd571aed8a0ebb1e0e937bead417e7ad68fdf7959db7a6f9b76b7630d3ee70bb9b8272ef7c27f379e7b3bfe7e6fe844f49f5ed5a07bdfdd23ff7bfe900b7be42d1ee0663e81ff3607f72ff2845cf32fc2da4a8401ee4db64c0ddc31a02c32d22d2d918e75d4115bc2d8c6d308b653e9e83b21d03d0ff9c4a70f1d2bdaa728576b66f2715292c237b2b1ca078ff1ae990aaa86941db8a674d0112e450a098fa040e872ceee522c7239cebec2e3f1894f77e1bef99ef6fc5bbfe105bbf3fabda3aff79d78fc7fcfeb71e19efb4e8ef5dce6edfd9b0b5c48379ccb0f7dc8577be3357fc644f7e07b0d87934db8bac73ee0e1b8ec437d8457fb3ef6f099b3646fabdf62c568f45d1fea7fcfcbf1437beb2d7eea35a7fe957bd9ff0cd7edee2281f53e164e1db47eb11fd7fb59fe5eef0d5e1afb103b5e78ffc4414a6fcb85c40c0366673629d52e400f6630722161c50687d9769eff32e71a4ffcfcd7968f07409ae831e1dae025c0b48b8047b3c637794045ffb76072256d3e4c4683caa30fa61272332f4916382a0c2096a49c402f44e3f8064d96cf31396e9638681d415e4c4f18a5cfebb2789394385387fcdcafe33a0dbf80b9aadc2c82677beeb2affef73d208bb444b90c8f79aed3dfa77bfc463ed33c0349d0781e77ef28c52141f84e9559834be5ce7364494d167ee543c1c92a32f8d40f659784682474eda8ce87f33cdae1b21571ae9fbc502386d2ce331e40306c56be465b5100df13ab5e325c99333bcbbc1b341faff488d489b37da5bffaa2f779a5d70c6711ccf44997f7e0fbefe3e8eb7c493fc20f9c47023f4a71c03d34c7df77d26884979feb60af6fed5f67fd270fe201018351cafab118a960ef337361595ea1a4cfeb59e268c24c544625f7d3520d18456660a03a46baf1015fa7251a2abb360288c72c27bd79ae4cb268bcc4a847f726ee88aea1caf9501a9115881bb409ae604712a7bf3efefea3bed97b2db577776d25437f1f97eda440cf3a22e0625c561efb332388f2783ff79037d10137815fc57397ec41a3e761f4b647e45d2e2671faa60cdd3c0af7b676ff79ef530c4052f6778940ab38acf5347ce1a29d5fee0771ffcc8568ebf865af9ff8d5bf9feb399bbb2fe47a2ee034be7b6729ad862fbad87b3bf6e6790eb99e8bf9ceab7ecada2fa225c9d1cee7b5f04db649476a175775e5078d8c72b2925a476935586168435e82fb54b39edaef638a468129fd294026b3ad3870acdfc9582db8d3485c12a86ce9ce0b8999a989705c2f018430e46eff2d1f381df3261dbecd57de9237b8bc2fafc63bbb9fcc1d5c7886fd5aaf1253e9b4c4590a5913436ea5cffd9fdfe98719a39918bb1477d986b23ec21d9ed1309b629b638a50c744dfe430eac545b3498c074b76aac71c0499f64d6f24035cba4bc61e2141c58e3bcc64215f46bcee94687b11f5b60ad86654aeb6a96318c2d193e4cc37b960f3bede539047a25d4dc53e2ebdc65df3439a0a1067fbbb332af55a9eee9e3fafbf558f34e9ae71a202d7f1d81d62aec65121a50c71aec6aae17693492a77146a775e823bef8075e061b0586d23669bd4ae4b15a24712e28da77d2b29f13632a4312f0051e33a92b94b88a180e4ea9e00225313edcecedce7f7ca8d9aa107dbb4bf5ff77179170bef439b7bc9bf78538ff88c1feabc4ef1cd9c2d6aa4688f67ec80c57af57a6f477737f6b5b3ed6e8630f373dbf41ccbe4c0831ee04fca69113558279db6600c6d235647a26c7e071401ca64392fa32ed52e600eaf02074d64882d29d8528419b9072964a60c0842026bbe9376bf60a50e3cca3a65d49ffb0f17cecc4b2de773fead9fe10b38cf891f73bf37f5aa832266d99db4c974ee607e0fdd410af82231328fd9dc66429bde18214907ad1c292a385f7b465645865c71a816c4c125b555a78cfe44083e4e8b6c3a2f526b9e4b2e44b4f5846ff14262a9eb1eb38d768e6a7a5683f84acd2dc4c6fc8025fdd427f97a7efb52ac04b34d0c75117d4147fb0c6bfb4d9c62029b5a3a6877c22a3e8fbf8f996ec605cc82a6bb37fac53d48b7bca8efe725328903b22954d02f2c928a86c521921c294ff17a3367a88b43d905940c22ae986fd613d2fd825340705ce1d213584aaa47515e989c61143bf51d363298e8c1d2ab7e6dd4f8a7fa53fef4e91cf766afbb6cff8e7983d31ef8bf0fb811cb1472288565bc7c6e71b1ee5a254e7f71d04429f9738fe6ffe1733eb057fa14569656c56b2cf1ff7da24f78f8fed3ef312eeb3a7fd097537dd497b3f749491187eef6cfe7d8352dd73c0e409d9472f3257e8d9fd0b13b8d77dcd345130bab4c3ef6a33ebbbf81b2572609c94ee483d9bdd1f748018c784c5a0a1f0d5914bba0e48bd9281b611b0f841e002fe71e41924b90dd7bb6dd059567301b8cd3d05d7b76cd3d9e6ea97868a7e0b1a7407d27f8a09772be130e1f46657f74ce0d78054f04dbfaa4b57d2dc772c0a3fe009ee83516e060fb5fbd3e615c6eb31b734af2c400f95cb4153370c14bbd8e4b6dfb150f666830f23b77419dda22809844003fcaf52c40930d1368c6a9449cf5a3081039353dc8cb7a4c990f09b328114833ae273e28b6c4b0c6ace34fb20026bb62372ef82eab3800c6210741aff359fd906d7e3de6cb3c3ff7861cfaae6ee5e5a18ac8cebd4f4bbef5b8b7b907764704d631af0d26b0cd90eac536827e952e09774b8fdad0ab2223857a19542e4c608d035bb662ecf718d32276ec1e17ed6416ba15a783a1e4ca9f87249e057d36d7ba4d103fe3a6f8dc0e1f31e02fbd0747aea8b3fe8793e64e1385b87b8583f900637259e3e46837afe42e61bb396248aee0c97ea457f4d8cf73b45987719be333dea0dbc6d26ec6dab5279a3270fe5912549b8cb9d267969318b80e90dd5ed66d3b8d1dbafaa4eff35fe9545dc86b1de2aeb3e7b99d2fdbd8cab18e28c0833922a558f4615ab6a3802aa6984502ca2037bdaff29b7f8a8b4f843ef62596bc4b9dfe3a7d9b8bfa9c336f3ff7262f64287552916b36dcf821aeedfdbc837d2c71f4534e73feea394e7cad37726bcbad3231f1ec3a9e176ae2f1411e9420e6280b986808337d20987c52b0dda688ef08e725476c4bc2a2c51d770341a460641430a053065c316c5a55101e3b8fbda890765a2aeee5b8c70dbb0d345ab01cddc685f8871ff4ff4efc50dd197eec8fcedeffcd8efdf3576cc4857ef4abbaf43f117bbd1ff7b086c77e3f8137c9615cffa44b7fdb7dccb48b7c30e8e25cd52ae8f7a29c6f02a0f3d49013660eb6a4b0d6297cdc60eafee69a04019c1873fd0b24d08a14908e67d62211802586955328c7feae19b1826c65b1da70ca7ad89158765e4f14d928627c1580b3dac7973800921235a73cf8ff1def8a2bfde1efffddd51aa4ff63eb741cf3f51a595922d8890fd1bf697da4ddb7ee3b3c503ced22ea9ab474e3c0d680f27acb1d5cc5850214b18d62ae3735f92202b533dbfb4805d9cc1c5962fb9fde9ccb2d666ee939bc645d0688e8cba4e32db6650f432267ac5f31a62269a08eb10ff0d7a7dff6a2837cbd87a07dd74bf85773fa67dc57f3faa7d7f534b7b7e9eba7420fe3b2d94605f0e8ae3fa1a3a8370f9a553c22ad37ecfff6188849f9b863fa018a617f9a309079bba60a0abf9b2f9a5019452baada0ec6ba53159a10e07509ff0593b05e33072f539435aa43eb80ea3c286b8b1d750c3f985bf70b3d023fd2df7fcc5554273ff3f8f77efe8c5bf1ea51d0f0949347ec349528d30d83ed589572312fc8247554a0a81af81cfd4e04685991dd2755f6c874edfa46e370ee5b9e7077bccc66b4f2c1ccc6980366b1311e4655d4319b8c84e69348cb9e62a40e466ea3ceeba69b744cea045a476ebc0fe3a6fe31af2b3eacf55cf479663f32d787585ecbb7759e4bef9f38251e6e5a03a2d10cdb209015bf972c2b31c4c3a8707150c828b61b4ac6f6d22b9b811fbac3c401815fc95c151261e60e3d96c501c80c66c80133c8a374dabb5958ff16a1eac5a36c451cb25625c014b2cd7dc773e9f491746eeb23940e5f45a17efd3b0f67ffffff357f699308902525b9caad8e8fb1e84fd89b2611682d9fb9d45fbfa6d1fae0a7dfc411c84c5e925d50c87550aa0d1e674f69916df9b806de58ef0234180702142904f68cf23871946406cfe202adbda29ece0bf24810f149a797be265a96e077546c776ad75f4bc8e3a4d4ab78d7fce6b91e910e1718f0cbdcdce5810f7e931cf24f4027421bcae1d774370e36f5676c0ed8fbfc3aa9fc460a50ab313971065f7eae430cb0bb958fd12d3c136bacd1f0dec4bf3d4ecc94d74f29c424adf82eb5b91f08f9db1bf62d212c1a8b1e64417f4746b8a1263782b1e4698107b15d8328c7bb191d005a4e96cce0d4af38f210928931b13ca40b5922230517b5e53fcdd927d0caa3f0d00fb7bdcee7f2231cb46fc63cede97504913115204b87c6f636ce59bbf18a6695e6763705ea49963ea0d0c2c4414f4aa42d676ec172dcdd9873d924a5aca5898dc474afc5a3e007e7a58c85ea94d3dfbdf86baf9ee3d46b71231f32c28139d849b8024264435ae98997f3c738cf4c62fabb7bc3079ec6a6c748c00a7d9732d7a4e35f3b216c2b61b211349bb2b1846a2c9ba4b47bcccc04cbf53de58f466cd6988ca21ecd273b55b619ab064bc9e4e087702745621ef4ab37e91f3ce0254e8aea80b51212244350bead919ce56f9a48347a7ad0daf9b4e70824a56e9560cd330ef80fd7c9a5dcf4c7da551ff34c9deb0dbdc2bb7c9ad34e607f198b6bb9a10337d24fe40237873acdf37e3cfc6d1cb99d6eabb5c5ca749dd850f773c403cfe06e023283ee1a8b170cce185f60a359c561b688041f7028878c4d2ca56547cbde26d935527591250d376400db41f7b0c32223b424b37b5339b3718da81375d296b364d85fce9d867fc00b7d9a3ffe74bdd6f563f9b5e3bc893a7bb9635e5e1ba7def49be612ab5d93490797733de84560a08360b5e5b085ac7277d30eaf0890bf3dc7b571c7e91c3dc0d9c86e2333a3f108855195f5b099c57ea1a69ee042d9a4c415ae6763b7f2caf631d1fc2905d2a34c6259ba411072f38a56e4251f7727030094a35753a1bf104bfc504e6f6f27436ec462dbc4cf3582b7efddaa31df4e43527a9cbbd244b52a64eb09deaa7146a8680712714ec62a8bbadbeeddb4ec77e90e6469a9e097e6e6077c9ed7631eeedd379c4bdfe211033e977a0add8a16d98a39c4f7b84418e1a537cac02c1c0c825c6dbcf061a390240a3d9818f8605eb68f42644019fd5021b964b68b949d15aa884064dac60cc93bc9f0188ba29d173d432294cfc6039322fd866be0cd7c567aab9c7f8ed853a7df4c5ff3f95ccd89fdbd9e4e64ba563a269b69e8eee3834d12bc68e81ff6e0c7cff79dda20805e385805ccefe654efa6b0f5e3b1ac831c99a9ceb6d4e116677aecf3c71d33b299e00445e1a0c1bb7f7a3ed56b8a069b7928453ac241b0eb2366cb36c9f99284f57ace5525783d4b816b08ae5d0e5d40ba6c7aebf9970ecfae6bf2dae7fc3cdfb2af4447e1b16fe734ee29ff72031f2243592a30f17355c4d0e2a4902832da2ae10520b65a10887bb2bb14c7101d55fc9a7e43f74358e51377cbfe0e398e7be089bf1d8b1ccd50d6b251baf1846d45265ace9136bd4a47a9e9b558443b5c58536eb85b82322247bf368aad360118b412a1c7b9e3fa112d2cec64eb7959e784ba22e5684bc6782573067037e922a3f139eb8f190458d0732dad6ffa84aff85caefa49853c6a8eede7b9bba1bed4fd508cf9e1f8a77d7a88418f7c67af6b50c669fcafc73fd26898b4c193b4f56f12463028f488205da7956f06a56abd5d1fff0c5605d407edd37773f9aa6fe3ca7af0ed747f778a236fdbe777de7b0ccc77d7e0cf98a7797fa55f71eabbb9cd8fb5e448e798a1220e9188c064199475ae002751aeed1866f75197ada561ed3c1b64b1cd87c49476cc6a73361e000ed1c2ab749c380fcba46cb2d4e8af85feb5244c319fff82a976b75e51df0565762faa1ad222ea9d61c6be592bdcfb3e87bb5e80977adff3dae18b1add24530e6b12e83e49818d376b7d86e7d1dd3bcef80fbeb7bf884b9eab21a85fd5dadfd7a5ded4da8f58e4d775f9b3cf1efbc6c6bfd6fb785139fd23674329579150af7ee7e4ab7bf44b5aa2def0d08bf8d7bec3f39e7ca529faee39f6f1d6cd9ca41e35b25ec0fa1943ba089cf69e5564c484b4032e63e548736af292d28765aae513ce7d8b157a322f713335e5580114085b1ab8e8fb29d30e3771e3e90cd1d09d058c1b1c4c201e63e9b1160586bf5305fafd0d1f41a70ed069a9aed9e40bfdbedfb70789e03b09d9cb3c9f5e3778783b6f1e291e3b2e948b1de526c3c60f50dd608a9749850133e49604cd9a708cd35c613c8e2c2670e5e78ae21c4fe3c53f909b08c74c92a01a0c7dadef3c3e30eebb0846badeb21126d8682d4907bf934e636637cff9ee4b7359ca70d2ec7dcc08f6d7c9e18cfd3735b1cb631f7d940b1a64dfaa8d79b6a6d2b6362ac413a56be615bc26651b4b5e0f02dbe54ae35ec29a4e01392222eac5283503a02ad2916c66034142b6f1805ce08a8742f4ef62585bc9588fe60edb0685ebc6dc1d7aa21678c429ee06213fe39cbb9633dcff56bd96c1fe4eef6f65e81a177a7c2edf737f8fa928a4907552b263becce13be5689dee9ed7e0fcb94eda6ab7612c28c6a99032808fbbc46eefa40da8ccb338e0359a8268292a6edd1b6e4546b2f46864489a4dbd2a35a5a3d6a9dd0cd2c2b565e88e4538c078245dc1751e97d652a2c18c8ada8f3b3dc05a3a7efeb0f4009e2628fb29eea28fee92fdbd73a577e0347fe24b7d203f12cb9cc63bd9a7fdbadeaec3ea05c012d45dcc2b5970488631eb2326da2dd1ee58e43e48a1dca6f6cdf6fa42edecbf9993c441d6eb7ae9c9977bff3cb7f3e0537c9796591385dab8efbc9630dca6a5ead211a923d3bda766f6185f8efb366a783c53d7eb033f134ffcc9871fcef5cbf8a77e921b6b5308cfc676372f88c6347b4c396fe3cacd18eb3773fdd8525b4f661c878cd52cb1f9d4371e8cd878dc2500418aea2506ee82f10c2a9be0bd5f90525c2ad88819c32355c909b6db816723710ffb15a9f09052f7a7ce727d9153fbf333bc518eae92fd3c5ec3de9cd70dbe7927f68d58a8f521f778d8abaf5ed35f1f707b7eb65e7c4c0c154a8d3315f22ee2f2dedfad7ab254e2deb0842adc2836304bb884d8c44b5c5a9bb820b1a824a080cf08e096b75f37c4b70142362eb81d6b6f1b5783a18278e09b72821dbe9195b4e6859bb382fc94b6db895bfc59fbe4a567d7b8b26620755a3d77f8cebb96c31bfe0c5e4a8ef93671784f86930397e29bd7c735336ec0809ad2c88ac06e4cdafdeaa9e26113e5f24996789474598e6de451a3b8cdfe7eca3975815f7af80e63f82ddbfb560fec302f6f9fa3c1871ada6dfe9c6faa21452e0ab86dd2b194a4986cb9a90355a9c794f2190e911f3b1e6436782223b9104255a46c5dccb5451cb5baef06703eb6012fb205657d27656d85615672b36e14cd18e68f2d13fd3276000b44e65ec0ea5cf1e7f67117d8c8c5d7ef3a3c7ca70ff0bdf97e3fee91dbabf49b0446af7ab18fe3dd64438206a80ed549a1275c0f480291502cbb63958ee468d2c602e37b88d76a4446f3c207a94e97b4f05a05ebdf9c63464d6fc91d6692a20fb1811e69ae20eb746f0afbee5c641e1b719fe568726f0e1e19431345f98ff96f49f93ad7e45f8be375ba03afb46eafc741b31ff153783715e8c04319097ce0f992a1d7bcd6d67d1eebb67c6d7b3f2f56260d5d12d18cb16ef01451d7f4809ed171cda5518f081814ccee0b2fd44295fc2e2eac35eb1e2c326c04cb7ff5ee01be5323b799e758fab96b4770b5b93753a01ce9a6413f48001f900add0785c25ef563ba9eeffaa85ff5ebbee7650fbd43fc988edd3a11da8843a9dfe46dcef24d12242536f6e7efecfb2f688148c88da9d0eb434da6c275f4793ee9310adff4179f61b50fda2221b612e16e92b1f7e96f3be4dd205a25c7fe993f9fbd8001df7f3629791585a456256be625df25bbb73a6317faeddef0267dd0bbb2ffdc734deaf5f382332e8c53be6f3f5fa93978a31b3e3bd75378f5f9d73c1b97d7e1e5b325ea52a8ab64f1295ee3f979dfe6f50e3de040bfdb5367da2c2f1c6ed560979864a3c67a2b03cb484b7dd0237ea34973e1df2b612d12f3e1833df92edf7da30ec07e9d6fe08ebc9027f8be9ff36aecfdddf26aff9cf2e1bbdbf91e528e85b0e59d9767134a95756fe8508c24a436ee649815c958def111f283c27298e18288238f51bef16c8d54977182748817ffecee211f512ead20c40b4ab3112ddac82bed0de3aa61e6c09a238d025498fe196eff8a9d7a89bbaef18abee65df88ce7e60b76e0fb9a96fbfbcb4876fbf84e37f1d1165c8fb5df6b597cf70e0bc9661a0ef667ac568e8647eccfa5f78d936dbe292f4d7ca3bf4a1c150715c9b8f8c74a84967e893d1f668c0b34a1657d4f72ec8bd06b79a90b32520305358a73b4146136951cb1c8249e2ff89dcffa13cceb292b1eb6b2735d09066b5c34a69f13978fb29a550378252f7d5bfde4921dbfa40b157a8d74902103f09c7b7abd37ceb5aaf667d2d44d54f6576f6ccce28a9f0371963aac91b09f7da1ffe747b8176488f3e8c089ad365178c853bd7b8e13a6e9a67d61f4a6267763c71d7bd41da5b0b6bca246bc53f62c1c4ca2cad5119719dbf57fa776af9b0bbc9e8712258814ca304092cbb1a032c425db057ca013212101b5e60cb422d7836987c729d331156a9a14eea31fa69b5bfb9d659819f2c453f21ff0c9bdae073dfffd2d3e3959d6ad621e98096c63035bbc93202dac28e8068e5ff13206759e403d26ddc3560102d8983f8911b33c070f312746e2f4769ecd769c4d0cb6eb873e77452ab24896324e46ae474b45efa122120ddc40e8667a45bbf33cd69259147a074d88b4e2eb831ed7f53c8df9237bb94459badbbf063b75e01e03c77ccda5f7e9af35be99b7c5dd05fc97c14352f846ff77c2702686fd0d09070e05bf7618b96e54ea65c4f090d1cc8d052ab1aed798facb7b682db9ade19ccac99c67772a587538c43d3cc644da134375d9188fb94f0a7447cdc123e7e8292aea33fced95bee7179db20ffb982ff489be60552fe9febdee91386aa95de28928a478a54b77997ba28cc2bd8f2fad3f58daf7b9d4434d797f17ae12888afdfd949844472679d92be1259cd141e7e9f9be8e8e7eeda7f92899a5a6df1c711be4c0111707e0751fc15772e13f703f5f7d8ebdbd38ccdb54107dd2620769593411ec37a9d35f4b6119a77ac28dbd236a2a8d26941dd73ccc20d3f55881b4472a5946259a6003450c3eec2263bbf4e023900518cf35c7be99857ef1d84914751155e13ccf2caf8c368adb5b49f1106bd52490d81eec534cc91347b61520c902a6abcbbd232f73f00acb71c55eec7ea8d659a24e0dc139aee4d2fb476cd66d3536117529b7ad04206b261e77bec88632e84f665c8e661499d40153bfc0231ef42b62f7d781610d044b413cc626edd490dacd9337d293a8e313c1acbb99c0e320582de74ebb253676a541b2382422ed7e753e27c16c44c867731c5778932c4077e27e78c1c33f9fc9cf393f7e04f376dacb7597c0de216e8bca56bfe027a12ee707fff4faf39e34b56ed46b691fe5b07fe0d98cbba217a07ac36d6c2448ee229619b27c0002e93a2ef45324da28822b338588ab31cf128ded396bf1dcb12631c21161e43e65598f8c549382498f8c06c087a04d9cc68c0b2c66e30c2a2333bfb41e87b858d5b2baa6393dd9df59e0a7ecce85f15fd99b97357a33e7fbf16fb3337294203d8bc160834d62896ab2f50bb0635aed224630b76b332e1ea0b4751638de265af48731b30d91bb381d67db00d443457d108946f272b295765f288016249fecf6f6281159213b14c695cbe3aa1ed0fcbc6fea8bbdfc87bbedd2ddf21edb72bc2f2f70d6576e291def754ee8135d1b5c2742afa2f0cf9c9d740eaff0eb1ed72e2d791189abbcbadd0ff5331df744e86ae9a0131ee4ed731cece3cdfd4c8d4c9d9e21823e8c443b9a3150a485a6b2f34d85eadf29d2435af699b09b8a8ff458f0cc49ed6c3685b52495b74c6cb9644ebf4e41b1a40e1e528314019058d002fa9cdca9aaeeb8192d09f736d86e1a25e4a7e73185a894c16de771efbbfed479bc30fe9ff318e24c96176ce0de77beadf66824548ee4b866f79deca506597aa5d1639d04749489609ccd9451c0a0e28b7bc82caa358b0cd4a4dda4c7470f468a48e6e57c1c682466e271eb83624b73b4a3347b0c3ad2c3a5daa576b4f3352aef3bb755407ed033baffcde40b73ecadbd0347f3cfece1c3bc3ddff1cefebe31ba696ec35bb92da4815711cf7c1fa44b3a928de2d822861b73ee8e7d487460830136092045bba014dff9a05ecb426b51f4d73194a398d56da2953f0f79eb2ffed904028d48a72689dd40055dccc77c2a2b5245143f29b1dd61741bb785efbcccef2612359c1ef1cb7572eacbfd909fbd18fc992773ef7f67d654a0428e279f7234bfae8b244ebf92f08ffef2073ad599aa64fd9c0f3ff21a9e73e07d7417fde9e16317e29697dfdec8d0dd25e6e445eb6b1f735fd4913dec056046a1bb7ed523b83dd79b3b71a3977e938445a320b23ee7b796ab28249d7a99bfa3af7efecc6d2d61664c05b00e98ec90bfd228f32fdf258e5e277f34aedff7a89fb0b4a838719ebfe991dfaf23beb08e69298bb7f514ff2c8f2f050669c99efd87a3d679f0e95a775200f847bb3bddafc3596d45397a3d0fc02aaddef0cd7f21967bbfd69ff752eee3879fb1d96fc67db1d587b323f82e2dfbbb03d6e0d63c83e88f6435c85383aca5a3d604c92a66851955ca090c0492dc2de86e65c4a3074315ee2a06eaff63efdd9a1365dab0d11fb44e6890d47838280d126943d31be833a0fd82d0205154e4d7af7293cc644c62ccebf754adaa75f0d63bfa64a63bbdb9fbde5cf775f54c371fa6da9085bd0a05171562cc4935b1f68ba09b43dc10874d1878de4a45cd79d5da4ce51d676c9094432374d01771c3e977943adca7dfe9c11a5df4f5fe3c36fbe74ebeb7db7f7d7f58e35bb51b23bfc30cd6927ac6b4579d74fc2e1b0d23064b4d44b6c9341086148e137db90a212e88a6a63e571b64038e38746206c733d68cc328d8097b6964ee04c4a5aa90d305999deb418403bf564606f14c18be91b8f00bdf0377dfc096fe9b53f9f9babaf6db59cd8e797ffb96feaa93f69cc68a79ed0f84a602ec7a7cae8215e66dcfa957c8c8ea48a40654cb63ee7a13a27521ad73e62f8676c2119f8db3c18c8230505e381bb593b8f700331a2623eb29ebb1a03d7e9c975e1bd4f9cb21960aeadcfe200ff9e5fb97550c64c778f2efbacfd7bc4ea252eb7404f63137ebabdcd2fbfbf06fbd1ff3e857ffadbb71c6e3dce69b6474b89dd178256cc052eaef898316c8f616ac169b506b060c5a2f81aeada8f27682e01abbcccdea6645c6b2c54caca73a7ee10c01bf1c969478414cfc9d5f0eb4d4802baa6766124df4a4823ed3967bc610cf2e7d939ff524d5c79ecb1336e9d87bf9166fbdf2327c553fa9126e96a7f753e6f36bfb77c9bbfcd3fddb8811684ff6e8e4afbf9fc799cbfab67e0f169481896c50925e144155ea989406b7ed9d283d6bc64d238bb2d5dccec07c0c29a72a081da865bddf0b8d3553bd9d655169044a4e0226073308270180982ac410c383b8b71e131a0cd2ba59c4c4378521d045fde40adffbb59ce4d7fd459fe4fc4e1c0effe6f68efe43cc857a3d1bfee25bbec6c15fdc666fdaad67dfef6b5fe22f5fed7afef70e75a12a3dec9b81f7a7b7adcba58bb4ecb57f9bdc561b426e13cc6d6c263632133ad84b4d5912223f24a28efbe7fd54632f196b0a9f0f3721c168be18ae7dd78ab212ae33802a4e9fb7be6abc18d09520681b10cfc0ae5ccc4b1591b2356232e97191ef9371bcc2d08b12e393fe9583dfc3597ec2885ef5c5ee806b14db6c0154ccd1a96ff8cff8ed917bf2463c63524321ca6e8774b09d45c29b3358cd5cb562bda723cd5e1d6c21e58d0a74e6a1b0b5e7858ab30a36a4878dd007033f922f097d36703531a5424fcc105894a696329423fb794fab2166aeb7e78ed20564491add8b7f5cf5538ef2d4e98e79d5771a0cfbaf6d676a78eda947d0be9e83bc0b2fb1d8669576acabc7a777efafcfda29aebb0d8bd0fa059cf9403ea59441c6bc3ae9c56846a54f34aad19a454413955fe47ee23c9b19954250738d0d5b63258e19ef1ee7c4d392b1d7a7b637632477b3710ee755b7e5ac794ab8978485d410674518790ed51b7ea346469e196a13eb6d235f6ddde818335e6a645ff2b7fd1d3bea17382cae5a1182239e2adbbfe325bed20f735873d088370cc4554cca1df853de8d797c2f0f672fe1e75a00b13fd1e6fc2aa7150f84d6b58f7dd085e1af41a24b4049b04d7b68fbc0f342e8b509540eeef12e2d4d33d54d5d727b85c6d63ee308a62cd01e416cf891ca798146684c8db9e32d8486fa40172f14580d2a1898824c97e5ba63d7b0b01fdcaf6c6f1e62f1f51be7fed718d6bbf05888dadf6415cb53d7caa573c487fd338f5b7942ec162b48a4dd10c2c44b6858965f58dbb47a1e649a87690518aad6831bf102fd37398bf7c77af11ddedc3fba0a47bbd3ffe12a9e1cf312b7c59179935180698107016713e6b2d12c62511ab615565e11d2611d6a1e4ae8704447ade28e32d958be64bae481617771d5f239979a3fb6b601435ba94d0cccb196d9c349cc6120b4569b8ded3d1dab3c5eb436b6dbef737255c3dd5193a73af5e87f76363fd2eef90ffaf92fc63dbedd35db9cebfd7fe925ddded71ff2a11e440de2e3c0ccb478c0f90ecc1c4102201f518474aa7520e66a41dd3ca6b47188034644f7a8a468efdba0f269db5067b8c39a66924a3949a54450a285a860ee9762892a6f2f98ad07d4e4cc2e779ff0531d35d70ef3cc2ab5c9f4138fd87fb0b617e31ed7f60237fda3b55d31d0ec5325101a7b38d0150c88e7891e2e709f3f24d5d0237458cfa13438455050b394a0d4991b6f636d480495bb581fc6c8b5e2d0115316e5b310886d10799bac647bbfa26666789b20ca075853fb98f9e6adb1c96d5a5479febe87f422f658c67fe1f9fee539f8329f7058ef636d9be5e97f158fbe1bf360dfdee900b6e7716eeb8bd7402ec7188605ed5001576154ee4387e9c4e9f6c8e900a99a9130449b1441e76b6d4ea96d2475a0b1221f21e8d9992e76a1b33618b04d0c44279432e7d1f380007f4bc6b11eeac3c1a3e13dd2d25ca5763745c69dfce1da02e95963f6ad6ef1a53f24d7a97e2df6cb367e788f9adf71aca32ee351bf879cfedd1bb97f743c5690d44d401c4f098dcd52a502c4181365e3259147451facb82b11d3644eb9c00c96bbb0629bb96deab254533a46ccdf0fb58041426d05a67a3799c35c50d0b419ccd78ce62aa3d01376fb1094ddbd7a802efda1b73b75a9419456629d70b994a3f7b9bccb9fcbd5e1fcbef20a7de0276f92f71ac5fd27bc269bf86fed850f6a46a77983e6dc9bb44d5da6bdd752fd9aef5fe8dd363ed54ebe8137a377e22e3c9eb93673e0fe881b3bbe09efe6d19e74a36ecb3b0474e8098070a0b35d421b21c1ef3e60de061bcf2bc4c486b9741fda9e106eb3c0e0f72186f2650ff5ac400f4181745e766ace59e947683ce3f926aed053dc975b6a78684e35409585b3aa75e705ce69af92f45ef6e1182fbfdef9efe22f0e3fefe5e9089449749557fd5eb8a9a38d88f9ae158eda9ffcd6f7f3f8111e8a0217556d49005b4e8d7c94d66a3be3e81157cc0bf5d6c7dcef8248391909f694618660def031ed12e2cd30c703e2e63e03b99794ec258de0543004423031321b2689c21d6362cbc6dec2af723087c21740ddad6f3cadcad758a99f16d995bb36bc8693314f9c3c77d8272338d974236867e19153e836cd8c422a66581a7799cba3dc4878d3fb0ee38f46dca77dbce2f673174690877d5e86e5100a8eb050b84d74b390bdb25881cbd8c8b6d8c90709c99170ba8eba783977f31daf55332fc1c39c6703aa708b23e43e5e6a66fcec2e95567ff0b58e3e8be12d65e46f93374ceeef8d4ffed51738fd9d7905f2ac420f315f6f8ffecd081cf1d96f9cbe1ff7bf7da2f3fd560bffe81df99243ee733cf23fbdeba7bccd4775f18fb4b23fc160775ba9b3fd49c314ac44a4faaff3e557b8dafefdf9faa8c3bd8975b63ed5febf7c5fb5f4d833f6194ee003de8fa3be8db73e6a0ed6484d7997cf3fd351fee83e1a472dff4a1eec597d4d07ed887dd0eff0f61d351745cdd6532e4e9c00efe771e68c8a6fbaafa9c29bb0a0fb996b2db22817313797998d45a6971aad8201a150c5d4b35091ada85a76be8d90cfb53e56d862a580d84125a2100404e7486580f3d6e5056c88ca2773d53ccc60a033db9b12878d2435f709bbb5f7fd1cdf5ccd37fdef78ea63ffdc5e3bfdff09937e2b5e7a2f5cf1e443c15039544921c304c8476c782a719ac5bc0456528a1d0a873c04d60e459866507aacc08fa19d27616f6f833a5f60e5696231ec136aef29905490df66ac433b6542e34c3d308d7971e911e43637eaca5de953fed26f38ec0338e580f76099eac3d5f7f6e57f8f098ffbc1613fe76631e5f936d5db3ffbf4eff73772139df2afcaf1a108b0deace6eec408226552066773dec633b7992268e9d2667606d863c0ac4e1a74871473e6055cc78580b22c816fa02019b389cfdb68ee6403a2720fd1ae17ca1bf322077cac660950362fbdc554079f60298e6bbc48b86cbe914ffcc076fee8cd3fe607e24ad5c95b4ef1fd3c7ed49f413b12287f4f9c66414a8f8a22decfc6f211730fce6bf12874a1255a0c322a562945db19cf6d5a5bd6bc6c978c0ed7e1a25dcec77929c69851c3dff910d5196033a9fb1a2a6c232cd42a214c489b8d535bdb8bea0ad7ff65def0f87b8baacbaf6182d0e89ee758ac637ee461fe6b7c4dfb01ef329cf3f6918d86d8a7ed0b83b290aeb5139ab2842e08e92d2d040270c55e1247a2acb08dc480547280d2b1b0441df7982a923a8c2103262c6ab6dcc60eb3e184d9788c6cf329d5b22daf73e66b4c4f6d10d08f738497f9a5ab36e17fe734faa7d7f96d3dffcce3273af5a048609ea35eedc968c882de9ba6f0b9437ab3f50d116263b98ba326671a1ba008bb196b6a14594fbe66b239658fac9c7448c728ab194edd661c68c38a4502a68e5c863a6a11b14d346a4701f0f48478a15c0cdd4f38c48fbfcb9cc37d7a45dbe703dde3ff613d559e5583b7b53c8d7fee9fbd11ff91512fcc78a9253535d8a8a5199533e1428bf4561033c4b1816cac352c50504f7aa51893330c3ce153e4600d3f709efb4c1f22a4351873d6a655a7b30ae953a060cafdbdd4cc68667b63bfc03055ac975ff3d25ef8708983f7539e1fd6e2e847a5e1612dae9eddbb60033f1efb6877cb6c019607ff2f3dfa7bdab10ff53cee6d1880b12598337cf475666411ca79813658611a1351127b68230375f3510b858ec768d43ec5dad2240635e6aab15318ec3290136ae793ac40c59cb30d8d50904570c1cadc4d17c32d56a53eaf9a0ad336c68678482ffdbaafb50b2bd80b121fb1d1ff70e2fe130b5879a2ff7acf7ff2b59f72b186997388558ebdbc6b11f9470ee1eb798ffbbcadc29db489a37ae90cebac82ed34b254562195d6b8491dd64ff970912c3edefb8fe67dee99b8b157128e64e5d139b4d6d89093a4f0f590798e4f444c9ca1c0dc63b2600247eac9ef9f41a22be2db8af8fd73ef73515080671ce210f5cf80d5d8c16ab98f792e50eff7f3c25acd49fe280b5ca2526d1e01ea1f0d79a31ee987e7fe06edd843fc748c198be4104febac8d8f7dd2e81b3ab277c96f1d7f66ca511eebb99a4648a51c1ef6ad38dfeb4fe777d497bdb90f10e599b256a9835832962101320c7b3996c5c4a0cad284938b04b25ef02e9f1a4ca170f8121acd8be0924b95db19d5f621ede08cd9fba0949b196d92b07aee44ff6cc4c66f806a04a69aa829430f31906476c657dfe25b1dd7e31c5f678b6fd8d6d100dc25863be5604e98fe68723847c7f7ec723edaee88d1b9e497f9ea5dd3909ebfc88a55d39e4d305d1b54492a207b608a2dd371fe90680c3c6add3aa6741732f5206c0064e511eca8dddcf6c2cc1e6e10644bd9e7c99cb231e6f6c01fe70d53c180dbe8655efdd2e70e10728cc709ed12f1897f70c4ca54ea5aadfb5ef9dbb7f18e7197ab7622f21a31fa916f50501dae12375fb008e561c4baa412baac109391584f35b1f6fb601f1631983bd22750ed7994136a4ccc8c83c7a9c61ec37d7b38937bda8b36e41d16a3618ef472451daae1b18504407b099b80b88d7ad4e1f8c237f83a370b2457e59f9cda0779bf9a818407c73ac43b8deb7ffaf6ffb92f3bc1cd5270b3f8808bf9ddb8efbfffb07ffc03dcd50ff34ac6f17739dc91e3f85372eaabb9b44757f775922864d33ad3056820a20d12ba2ca49d8f62bde1315fef66a3768a9958524d35d86d9c540526ed552eb86cb3f133a0fbe182566cc4145e200829ae60486a4b3bc47a92a99c54f9262e4d48f47611ea93eddf988577b9ba8f31828dd00f3682b6715db6c261551cb1f537f8f8ee82937fe35be59e39e558890a82d43daefb27f33ac72f37680f520deca483f4b8945b54e456c6ed2eecd956b8130d394a85865cdd967b53ed495718ace3a8f9af7aec9b343ae916a70e7c38f5d3bf9fc7adb5223f0423a683270a591cf266eb87ed86979d1f2845d34a18a92b8244bb317ee00064d5e17f799e7d0727fc2f2fd38f72c0aa959177f8df328e4e58e17fe6d19e73fbdfe79ce6ed3221accfaa769bea4d338756c1c632f70b18c7b5428cd1557a9b9ed8fb7af7d5bb15dfe16e9955eaa83a39dfa73fe39fee10fa760ec06ea93ee992129442419f46f251960d0c353661bda819c8bab8125fdea1effbbcd76bf4d2f0f2ccb5cc337ef5cb9a44c2cda538f6e25fab474c2ef9057f76163789c30eeb77cac5fe19ffacb57f9b967bb21fea5887311a0d45ead83d331a9350a433089f38542aa4b99ed1e1543a66175418cc159e646eb3a3ac790822b40a35b0e485377dd4d826a81421443d6080b621158a44561c1a798e1c2c046b3c1a4125c1c75aee09379beb79577f83fe779d8426adcaf3792ddb731df8b635a3ed8ed6564c47ed3853bff749adf67357d43e6f118bac18bb2a6454d8cc60fbb9e36d980a3aa960301fb5d1bc502000aa2754753c6224283bfe082c2b668d3bd50323019e1f02cf897bb5c536e8c351dbe29b7528d42ee6b8cc16e675ffff4eda774964e5c2c1fb69d59ccee5df9f4fb1f38db5011f20fbd94ca97af15d6f31879e378f3c9b50062465e16c2c7ce17435e399891552bcc84bc9e0029588e1de6b68ed597e2f106702070aed32859d29685410497dce6c9052ec4a6aea21b3906f7b5e3a469fd406543fe5702f0cd69eb0bfdfd153b9c77abed7693aade93fdf9df43b6e5b5702bda4c06ba281201d0d0741c156418937482b5771e169125a28d4ed4166344b4cd59edb187008eda93e54be963f1288fdc4854ba1c93e73653da7b24425789a4772c422c8a5524dacc5865f752ba1e14d48f37be9be7dc6237c254771d8bf830faa36df7b17ef9023ffabaef3b66faf9f4f359ddbb0e2c47a64055d516d38a6bcf584dbbc04e5da8c6b66d10af1d9f8b7861d0c9066ef28671aaad12421c8493880336e2a54695a504acc2b11a68b76c62b15c7a5b74276ac71074c44899390ab1d719666069f0702a25b6b3acda96e65e6595db6dfea55b857fefcb4b69b38f2cc69f4d6aff0c17c7e14332784b29073d6a3dab2e71c9b92ca46b848216dd8876eaec56569302014a36c3baf6438d53323ab82dd1cb226656a96ba22a125dd86bd87046868a2a489fa0908b950a9dd295621484869a41c68b494f1957cfa0d79def39a9cf5c38eefe85b6eef3b7a19c77bb34df54ec57cf04effed3fc0a11ff72fd5876bc1e1e698ab7dd393fa785e675b78235f82170b08a34463e340312fe0689ce86ce2476c23b5c60f232be11ce688095d46aaa6862253dddfa74e6cf844b5cc6e130c29601cdbb4ea7662fcbb63bcb1b0235bd6e7a1a8614e476d4b2bc8e9e12dd4ccffdbb6f04adfd6659fdfd77b39b9872ed5612f8ff33de1845ef7f0cf3ccebd5bb7613ee8b2c30e4282e48c333ca2863715510342c6288be40b77d132ed27262aca5e723326c41389dd3006277be9e6d3a9ce5c34960b599af9d4904d062d27658d238cc99614a2f2a9b450214a59582d8e140da32b18c48f6d62915ce330bd9bffe5b7b15ebedabe22097fa4292c44d9506478ab0cc291efb29d705119da9dcb0c4f4f6cef5154a89a97e62c8ea4c0b6e9cd198cc37ab90b9968b01e1b88fe1a60ea052140a5acb37d56c62b62cb71069e35ac9603e9a0bdaf4fba19ed0a5edbdaddec9d5eb6c778f41feea02f63b70ff999aff66fdf2386bbd0d57cf513fe99cf59cbeab6986eaa4f34ae448f7b9920967369ab41b61f2e672c1ba4b5a888234910a929e758c34062e278dd9c889780c026d6419d54f1806968cbecb616ccd7a4510209554e1d16a4067bc025b048e56d92a2d4e2de4b1eb59be393fef42e7da76f6272a921f0e3357f1bf3f59ea8b98bcf7d14939bde0f3f045d18c9312350d1221f2380abd0814bc959c71d7f208ce58ad0dbb47d8efb5fb375ea1e7c0cbc9c72b4150e6d3367d85cc7fa4feea4b37658270152a733128eb56404ce1cb3d6f66f7ff68b799ef31037e8aff15f06a16d8c499e244021a6b32e23ece9b1cf74342e7b041a361b7f169b7de70c0577e2dd7d1beff5fc9ccf4e707b6d9830d777f154da1ec5a56a8901edb4ec467e95bba8f4767e0d8b50638e70d916b938914421361a4e506962b918d689939b7e6f6d11614054b09adbcb2d71f004f5ca27aebf0f75b14f8b67c0ec6e3aa7b61128762fdfe3ddbdf9c3a7665fe35939fcbd26ad9176f005040fda630f4905d7a97b8dcbeff725efd78ff74f6d32031f7c0f2546e0dc1fd1ade76f7ec967ff5ddb9dfa886f7a4f0d5ee4039f373dd254ee3bad8ac1ef6da0e568da232ba85a2b8dd80b1fcb88ba0227bd0092202775cb2de16b0db996490db6a691b509ed4c43e5102565ee721bee426a6e58817102cb9e02b9c1143df9f512dc4b27fa756fa61c37d9fbb8e163dd82735f535aa346bce922f8dfe88b39acb9a9840e8fda2ad3a85159f5eb3bb6ee4ef7f962ecd7bbbd115ce6278d0bf020226ffb230c08f11e50d93cd04824b4b2cd80780219f918551853ae6958214a019e31bd99864c09e6069a5f04baa0808615f0d2dec28fa0318981182a443c73ba41d8432b2e27a65f614770b9a676b74f5cb913cc9b925e7caddbf4f1bddc64ce356db3e08eef8bb94bdfeedbe1cf3fc1616a262ad938e462398b720ddb784d5db526ca8a13b779c90cb50a5d8442b5ec6636249903a3b98266504f34ce3c1a03f1c222f110d33c9f536c61e6ef5340b7bed6ee52a7598690bd48884252295beae50e175673e56e7df89ea7356be3eac49df945ac655c7240fe38d6da480e16227a7ba35e3f9f39c16ee46b1bc371c2c54af442cd2036538876c2c5347398cf4ad0498546988907e6622d7405a46560a0b1bdca1c3399d970268bdf3b7f8c112d779a0fe094da781df6aac08698656331e34a268c7aebb894318ff2415addaa1b713c4320e59eca1637f9f177e0c3fe70ec8b757f97a318ddca83ed31dfe9bca93e305164a114b0a9244af7a997d03143418512494dc2ca6645786be1de2bc31a8e91bbdc63bd5b61c066823eeb338840e8b251a879f614e48e085b3f84cb9528d4e8d8b3c702ddb7cd46f02b9a9f1fdb8fb316eb7fe59fbe62f75efffca358b7cc6a68e31e1571851ee66e0e43e56d09c80ba2379a707f77e162b89e47bfbb949a1bdfcdf379658659ffbc4a23364a1c8963c3dbc435daa5c633e063561123db858e89d2caabb0dbe869c9108e70876df688f9afc1cd58d90fdfd52b9cc777d1fb54fd39977a88a9fb8463f5eaf7ff339fb316cd6d3c59b80a34a1c151bc68cd5893564adbad24b9225c6881c17654577bc4bb70eec20a39d09e1aa2f41d641f7c6264e7be3f964f498994a439ca8a3c4c7b3c4e35900b8aa6d89eeca61a1b07e59033bda112309d5ee119fcd0a69c39e3bed30b82ee93ef3cebaf9dcff52b9fe14f6c4624d621c83a04d02c2381961a524714625aa07146ac0565168c8be755a2c53da36de257a2e1a5f9c40cfc20a1828897bbc068c6bcce1decca2744f22ea0c348ba7919288f93fd9023069bb4804652a20eabbbf5e75e6a2e5ef31d5f3520bed5ff7007ccc3b1d7e1ccc5ff7a275e3f9ff64abfd13fac85db2c42c0401661eceb9d20b5c7188422d5d09a3a798bf421960433e15a849760e787431beb7215da1e9dd974cf0bb8f65d858433d1f1183f90120ea4861b12c503c23148ed36245ae3926ab7a3c4fa897defe71c2c527df7dfe5c75e7b4cdeeec3ebe733b6e4365b3f9e6a28086a3865baa90b070d32aa2c5ae726d19f355940c6287b0ab47c27349cfb500a6158536c0b94194d9129ab1095a851c49612a09adac8c7632f6246de66443499aefa79f16c48b7a1fe186a92cae5bde2b0ef690b7e7637b09939ac8c236f1f47d762ec7be9f45f8cfbea0f1d79e68403f75905cd5bfb05fd5003a1637a81265e4489471998f4c2b57694596ba1b16a5e1d7cfc5f37bfafa75e9bd738ffdaf9fe8007fec76b74ecf979cb81bcda927fe673e6a1bccd67675543049f6c533b6f137d688a71be9f338b87b4d5898636c80eba441fa28c952b594333a91a262abf9fbb6a2ae16f4d40f534b7350db928c92ab3a30c3d501df7be919bc4f018b33b1af4ca6725e242eb36e20aafc64767f3bf3e93efcea2fed3330800a26649355167065bc6148c52cd7c6485e021b0ea18203ab7e96d67f0c485bf905c54279efbabfedd1dd6e3a48b10d7ac12153b72c8fe338fb35f77430e97c9c16ccc94ac9f3b9f9b6a46843f2f723bd1c5f2518701afe1a3b80dcff892e9c3cd344245e2b0360e819655f0b81edfd005d4ee821d3eeb1cc57aae526eb7d2f5f293ff77e49ffc627edab16673233fda20aebc713866650014432c181007c1c4c941329693b0781e843007ac475da6953d27d603018d13ea22c1342f32289b10d26d58e70f491fef67d4db673a5c4c7580129a63e994a6d440f0d83f6b88798120887fd2e3b01291d2aff8bdfd9d30c7c7b18ee74f67a65c68fded180dcd9cf3f671da073ad506db196d03120efb84a3e55cd90631443ca7d2e6b4759903edd46e11d690953ad99ed1f520049e899c66e13bc120d344f1d85b548e2dc1b94913d71ef0b117f24a8e459f69545903a1a34bfed69fbeed1777ffd86370b56e993a5013476d9fbfcffd551ea83bd88d2e970eebe508bcfdfb87bdfb603e673ea8dbde2da933fa684c7609c02baa6019e858049aa9251a3018c831b301cc0c39cd4a314a744d8bf516130df0c4c9bbc456282490b1b1b7247cb9f2b96a84a69602a02425ac660ed853958f483574199739836537b7efc53f6fe5b1dee6427fd53679e393e9afefe5113f7dd48479c747f3755ffc5decdbc7631ffced0f3565daf3b8b7c5fa259ed132dea74cbd4827f7a8921069bf0662348c91061fb0fbaca506c6a1b3d3a600c6714d7b1a0e1d5acb11ae501d2fda24d570ce78004257ce104180b2dc0fb832502fb6993658b1cade9192e504647a768995fd1a37c01bfd5cc3d2a785bdff883328d587ab84ffe183ff48ffe6662da0da5331ff5bc7f0ccf578e2c2d13fe4a78f8236d687db4457ea4f4fdd1bde41bbc62b993ac36de6782aad4e3c7657b13fffbb7d5fa7fa7017576c13eb475cdedf9f6fedafeea61cd7b84781cfd1a328f3c0b79b2ea898eeeb3297a3761796f17636bea1ffb5fea3e5fca6c3f4750d739d1a526515cab3c35dd799f93dde857bdcd5a12122af8823a4a6bc55f3c83fade7c57c6eed5f3afa1eae5f762fa8801ab7f18695c2217a3960aa29b37d4b52005f2484635fc775aab7536163d7af004d09d4e663dc2262cd18cd47043424a825a63437e7c4e23ef12cdf6e28ee7113eb22a1f479358796998cf36b6fe8e5d9753df0dae77be5ecea77aaa5acb39abef60e1fd7faafcf2dba0de370b48561f54b17f672876cd452bd01f3ca344285886f584c30d98ad170e23ba2624eb7e230af25689a479d753e63e33482586a68f9a8333f03ea89536470529a3e2ff7b8824be43c7741c950603c6b19c34bac7b7d426fb385730ed7a9a3fef0a18dbee18b70b812212893efc42e77f141409ee8f4c86778f43dfe8cdf9e34406edb13d12347b0df7bdfee6652cf2de24cb6a8440fa8c425b2e37d5ac90741ac977921b5b86ef678ec19018b5769af1c41cd8920784f46ad19f65e2bc6d6e354170dd5e32ed3ed2ea078c95dd8a0b0ddb25a3e9170a8f0dd386a914a0ffed6e23d77dd5f7bf5cf18964a2b7cb0fdcdd57feffdb9f8602fe38ffaa67e7acf5e75570e77ec4d83e5ec3b5deee517f1f909d33be9670c8f62868950b13ea787b8df62b3b1da212ea682b7d0afb42da9e5063bc38200b1970c3ab4b7b7b26248e8f84132ab48cb21f27b8c50898c39cc0649f9bc4ddd1cc684ed836a680bc60c49d8248417f5b2cfedd9bb5cdda7f7691373a9cef597ffa8a606f2b482b508c12e8ef0f27caffe9ec7ed982ea2d0a3c638d2db161954cb7866e0fac83bc364992fb2aa4be2fe234c1750d2c9b7e26a3f9d7d276edbb7f10ee7af15115ea6fa5b6fcdb7fb34fc1070aa8395cfcd8451ba433a1a50d0b4ac1acee232d018b7b7a40f6e7bf38efa1c57fd8b7f7dc59ff917c7b10ebe3f68524e5bff071ca4f3b1c5d322ef33bb5c49833dfaf4974e7b59a79597539e0da89b2f916dce426762840079a40290696d436daad1b27dca9c4e4f78b379d4cc55ca549b32afa6e3789072dff09de51e734f315b8499e1f5528758f05bf38ea7df4d38d7759ad038bb870fd1261ca829c78bd39d3aeaad94f151a729306ee678a55e1b8443d7afcb55c885a23dde260656728c3aaa962b3a662beae4e31078f11ce61b4a191050758c4398f0a1c588bd25aebd9791dfe3d150f36953a53d5e62a242cc609055de08696b9069c3625e363c8c3ed669bad08db9dae7e3dfc3461df74e1e39304e77f5b8b6a75ac32b8f717f2b274656819780e005717138733433a3dd2e74453d87689cc060c59d214961d3cceca5962e8679c8f1c63796a65fd12d2381c10b8b4f0db57e04723963d90e8d852b34c1030eb6444db6a20265ac1a11034442c6d4455de8eb7ae8dbf9f9e75c7e15a31cfe4e13efc1e1bcee52ddbc9e2fbd578cc2559b70bf3dfcddcc196ece79d20fe6f3a318e505515648c75c856399a75cf0a96183d0916daac3b5cfb33da5b9132a6f1fd3a19646cfbbb0b6bc8cb783c4f69661385c870aad7d6ea20cda1ae2398f23cf2025a3441f4698ab36ad7082209cfad09bcc5d36b8d08fb86eafdff1c45fd3574777b12f669372a89de3ebbf3f9f73f8b7f50ecc6933610ac2c4551db53bc61ca9cde864e0032b964444bee10d900d7459e63a054c67ce702b0ccb48356913c0f0a3a1ec4c4d7621f4b672d49a444365a0fd3224c14b3e463ba60b0d556d14945e91f1e71dbb8c517ed8d7ef1d797aa79c0d32076efeacf52b17f4d75cdfe7bd6bb2ef60c716f7c08e8126ad547bf86fe7b7e175fc735e84de9867d3ccb434198fbc30282124b0c16c8c06823518e9a225743812bdd830cd6cc3b2a5b12efbb0623971914647434634cc335bf659c19e12982f1398d7a88a5759841f672e6bf8a20d5894af309485d0544cdc4fde868bbdf9bfe6b31e7ba2d3c8bfdd3765a24e22b617b5b464058ccc86e58c8b166bb19654cc66d56e7063ad6a93ea58a5e7dff11abfdd1d380cdec63bae41352c0507dbf48c8343b7716bc5a1db4c51a12ca9cb8de0bec9a26692157015f7394c75809331ee1385f1cc1986a2c869a6c93dd5c104bbcfe614b036a1d29d51ba4da9d60735a3a23415ae65494a4fcf6a88b3701886f66e37b7959a53f174affa49ace7db4457651cfda531ffafd6dc69ef1692677fffcc8516de273c41efb4d77fac0b525b476e74119a7bc18139f94b57e8fd59f820ae0f07c607faecbd8cac5d6a785ab60745aa77dbbf7e1e7cc8d56eb02279a7957af13320adb01235cac59bf6e9e4124f78e470b7ca38c26acacdad745495f013bef92fdefa3ffe49f87e9f33876d84c336b1ae3eee3b78dbab7fecfb876fe8e472fd7eaa7f741af7f08696827b40ecb5f3bf7f7197aedae240132f73a544c04b8d39799530a82751b3c70a2aa930e576aea525ea982e14329ebb80e7358e50c1dca5ce2bcf8f2bb125d0f3a9cb6a06a119d47889aa78c04b1632c5c89cc9092e832d02122037e8f805bef1039b157e94abf9f46ebdc64bfd67fd3defded1d1ef7f79d7bee679fef05df800dbf073fbf8d7d86fbcda55eac07a4afc4f301f5fd949bb950e0e1941630c9a7d429b28e5628675b14eb5e701d23b2ea37877750f82779c69ff6a357ce0ff7f1a4fdd8783eefd1bda7d88e31d7d9ef338e1178593ba0d8815f67999f561e1e553cde48106d782b26552371de2c381d07233a688cd2225b82b0ae2223d05220feda69b1a3e98c3dc438b61cce16f5dba4b83166a10d0a1163a2621fba1c65decf84086cce9fee5a6f8dc37fff85cbee618bf6363c0f4a8db751f1b93e9ac9567bccddb9f09dda0fd473d4557dfed3e8e588e9d784b6153b24aee09c4334ef350ba561c13d8d04a4d631daab852534ae028acf08ef22e0ac7de3a30849a4358f23105996e06b8565304e043e6b232e3de382456c76d51111df6a1834d5262f7221efac05fff7bfeff27fc47fbca60bb239f9cebb7b13e5ca7c677f7805ed64f7fba07977338e69d2fdf53ed3ceeedf69ff28627b52cb9ad3434fe3d2054354104c77c8cb78cb6bd00748f236861a3e97d65ed8e580606455c35ed236820d358c17a4c442966cc9d68928219af40ee3bcc444e0c5247fa59d58e7c07c63e84e852d7ea5ef6ff8fddfcdbbff9fb7dffe81df832ceaa86bb6f723fde214630b7d9899b6e931ad66bff4d778b6e6d5c05bbc415243572cc5d46627dd0b32aaf12ae0d7ca03cb4586bf7895fe122aebd930d1b4daef44c1ece32c853473dbce6ecbf936fb8433ef3b0ae6dccbb665ed1732fc8e17dbd9ccfe7efec976f89e2b50f88ebf7ccc0e324421366fc3669efb92c2a07c285abcc960db23d4e8d658f75d82594ea226a405cfc063ef120351a8d4366303ad1835e78a1eee104947bea988ba90e6c04a548f5664c6b5948ede22db91ee7fdf5fbcbc85b5fe7b9a6f7e0c3b918f71cf7ed530ed749d4a869c4f6e948d36ed73fd74cc69a3156de84723ccb2a41335bd6b3d1ba0ba9e989beec83423c6062e5dc061c57ade133e948433c2188d6bc56062322274e06881eef82e8f7963ab288153290ddcde6ae400ce44844ac961a18f3b165dd5cfb7fed9fe3b0cf74555fd366386995de219f7931eee1acbf7211813c335023f4c1591bf5dbb8a86e4a154e233c40ac11c9f8791bb0dc978ae1ccf03c59c8de2f914b3ee4a27b1bbb496bb4fb261fd35d349afeac85da6486f5dae7f8c6539270b3cf9cc3dcb4d7316fabc313d6065ab3a6dab39139438b54623c739703daab7ec6fc7d480760dae3242e50ce0bbf1705eb675075a90e1f024d3c90b25ba75ac766ee04b012b98f5a66307dd8115758016bb6ac04c59c202d1bfdeaf9d80ad2cff2577f7ecf6fe800d9f7e8fdfab386a7bac6df9fdb53eef2b65ca0af2313bbc80c1da9a5bc3442226da1100989e763f7b74eb5f53e75a52e1daff6dddf3b5a40e5434f672e7410470a1bcfabb0f74aa1d04b4ae022d43062257230c5168d84f9a8ff1ac4bdc81110202987a570efa5ab89f2d4d99df5bbffd69ebbc0e495828b263dbc41aeb7cd1cb697ce399ff096eff5bfcef7beedf3114bf59d5af31df806deeeef51bbef68c3dfcfe3bcdfb7612c49cd2ccc102380a1acea3c6e0fabd06e1ff0582c326801dfc0428ed14056cd4c40cfa361eb0816ec52db5c207b3d606062f836cab19b2f25356bc9fc3db7b3d551978b0283184d4f0a962406f6522e96e40a6ef673bb65bedacceb5c0377a9ed5f8cfbf7fddac411ea132e37672d88db3819b91ab0b1e7238627dc4556e6aa86314b843a881e7b0f86ae1573878290973d09db0a397415d3c609689ea73dcb532a42d68b47df1e3ea1cadf12480741453564302d309ef758db0d663c1f606da27388dad060f7eab1fc9c47f3326f5a25dc54d3c8daa786a5b21a9fb1436fbcfb17b9c12ffad52ef3a71777f0bb9a78c3cd949b4a8ec0fab0ef825f3b4ff7c28a5c8c7b3c4fe9026c4414b447ec9cc336b762474e3dbb6517424fcc49de4f81b78e354fc7901921c849cadb276c83723ec6536a304f56dd36d04dcce9724f1c3c0a4abf8b2324909d6ba2ca63a9d39e31b94acb2e4f344879893771dd2ce5d8f3923aeb098130a3a2fe98eff6951ffb0a3ee22e359ce358a735acd09107f0630d844f31371176519e8d51c4b49c65c07bcab4d84c4b314645067c90e733fa653fd6b76b0db77082a7865059d56d631e1cdf2779f08b9cb3df7055e7ea0e7eeba7e31ffdd7c35eae531d96a77b8d556ce063cfc679fc9bde9e98aa2761d80677e45a38ed888c55918dd94ba2d9db948b5910b126e9ad19af058fa9b7ceec664941b01215db6504199cc2360530ccece64594991eb0124843d254935bc6ac1e552ca0aeac44f5dc65046f3ee09afbba4614312dd5519e56e69fbe8ccbfe8913b6fb0f36fd8f2d5a5ce149fd4833f73fe087ce46a088b959087ee6d0dc6b97dffd841f3af20d1fe4030296dabcb6349fb3922b95cc6bb1cca8c851cd74cafd4ed692c5c49afab6574a5b25024014d0e66546d542706ff2a8352ba1b549dcabe5a336d921664d43bb7b62ce4e8b79e3fad46b49ed715e75b7f6a3ef628e56476c223ff6315eb155f106dd03776cfcdbe3f3abbdfc4ed33fc9197e95c75df9ba57a6c4dbf805d312430d62bd21a1d18c50f43c4874c1e74e878423fb58597bdf962b5e212374919f395e8e2a344a6a389663384d1d344eec16ca3a9f841cd1a0800e2b0190fab049d4728fea5ccdc70c5dc1b5dcc01176d2479fa8c1073ae8a7757e8b793804d2796ea5335c9ddeeb37ddfc0bbfe3af3d78cbb14cd4b1aef9c1181738e8fdff8f83feff3e0e3a73e02afd5e6fcdff1e971947adc3c3baef62de6edff2c4b7e5d1b4c4ee46336899c86d9258a720ebb129c62a9e57c35d16492e1743136be6921570948ef31973c03823b6810a341174bd7fd498c114d61ff54e619df93e41765a3defa52e16191f1a4c5971a0a927df5d6ad281e2130dd353fe951f750b16c7b588f037b89eefa2bbf8e1d8c7b7e9cc1b94ed411e1f6ca5cbb4db7180768b0b0b501d4e8812333a5a0f44e483ac503473e0267171c1c7f6e0a6d8b43ee1dbff688a5de52330ee71defe1af374ee0eebf6aa8b7f3a7fc68dbacf765837012b19c4cc0a1f8d529bb94bd3d7ec1de6c16ecef2c5ccb5aca0562ed37f6d939e09ceb1108625fcc5af3d8ed053a6b77d587b1dd2bba7d0cdf7f3c8e3441f7482372eaa865636cef3c4154f2183f6cc4537bfdb0947db3336f13a46ec1e3c1b86d5c4fab08d235c1ceb14ef3e6bfb239fe76d6ff59a1388a7c06ac2528efdba79928be183df971dd386148fdac41f7b8b40973dae843e77863177623d19cb952cd4f611c836d3c1038fe03e88a44005ea49259fe636d5e6362b33624573c636dc115341bd3d3584b895332c73d4e69add448b836dbb034f986135e9892f739770733b25f1c63f9cdddbf06765a62c2de3ed8aeaf14e7231f02b990b6ef7ccf54c5ca951e8e059c8711cea3120f66097408c66638f70bbd4e65078b2a27ba97506a932d3af684758a0a704bd040cf992084e7aa93028f5471db45867e68dba84557cec6df794706021ff60a8fee56dffeb678f18aa375ea8840bf30f8ee65ffcdf614fc53a8e702fddc9bb7c89ff2f1ea03eaef7e1df2da7115259a54e35b7c8ebffd467ffe56538fc3d08128e56532e8e753a390220ad581feb70f71a739c7db18b7c4ea60f3709f7dbb81a6edffa93cf39d9afdfefc33904bd748236d3d93e39d7a94e5cb257fa0417f7b9fb9fadd5e93dfa747eadbfbf5df719473046ae656068ede51821498756c0d88830ba63ce1a2460b2e51c8d09611551169c57724c7aef212cd844a8e79dacbc261cab495c3675ea98a660b02745a98746b38939d50993361acb1d2f27208e04cdaa8feb1799eb9d307623707cafbf8347bd435d789755279dcd293f6aee1e6dc23fdffda0874c104a2c1da9bc4b4a6fe3dbf96c0a98251c3c4afbbce685f718df86d33dcc49936ed9c6b5d22efdff4bde0c749fb3b81711d6e62158cc23ac8edac417df69e01443dd643b1d5c673bbf57348dbc5146c574e6807cdacb2732463d76975b76f83d5dfc9815bf35341a62461b2d1c5b46d8ab755ca817e2daa6b41b338c72260d8cc33237e268b20f6aa825d4d6128a226ac8ed8c367e6234ce279c31bbac1a162242473ee5b98b9b585f1fb5aabea73ff6bfe7bc32d7dbc63aeb8fbccd51ae9dec1ddc0bc33f9fc5cfe677e60ebdcdd7ef53833162583871719d55de534c6c232cb2958cf227e65a1e832a8aa90cd07e6825ce30f4f7adf5b8ffd509a2fac4f01e04efdc241c96dc6d208f941ed739884be62025377ead76998e68a8ab69580a272d607e2bf7f0613d84e1a9ccf8161eff1ebec03ed5e5feb8c607fbfa67fcf3bdbfad1e8c0e3e968bfdd4d901e2e04da829247b7be7dbe56ae6e68f1c4e8000d99e4632e2bca5a8528fb2b277b1ca1b099b691c0e63127924ae702b7ab4f755be89b92ae785c29283d287228829d8f3aa73662c3633ed635dc2cc3d7273a869eda9f43b7c65e1607087b57c87173fade7bb799ceb84cfb7ad692f6d5ecb01e56010ea26f075182212ec59d8c6335b98996d3ec495787cd4fca3e65bd223c0f4269a3b03dd27b48ba942d8c04b0654c821eed81842c4878fb2ca56a9d3e431f19ec2aa5cb14ae88136c4b32b75e10f62319046bfff1b0e34e338d6d136480e763fc22bd1cee075b9cac688e0daefa8ab34311abe708e34e4ca9d2c02337494080c58ce98b78e7b96b00aaf7c18af66503dc842bcd0828d5267dd33e8b5d4de75a20ef419c3033ab63cc21a375cb411b505f34bcf495cf975ccf5fd1aa04aaba04df5f8e8a30a0edbbf7b122efcc74bcdd4afeb73877dacd55137e4baff7117bdb09de4a619ebc3f2d8c36cfc19ff565d9713e7761e66c07b114ebc4a0ad6a6a3d69cf6c20db53ce095b7c78b5f836cec09a1dbbb50599a70210d59b9e70e05a99e3f523b30331dda61d9f8d415bb59d8cea8e6ed322574118992c3c68c2bf3c5af903eb387508c2debc35a5c6d81ccb1ff1b7d1ce338d6e93e4456fea375e3bb2e294d2b332c2f50c8c9b8471f8d7285a8d866faf085d416cfecd8448eb90ec3d6c090ed32f6db14dc3408c055e83e9ba2b0ea64cc364151eab2daad50ad68e6a2c7cc503b41cdbdd4c50375bda9a4f9088de1d7f8bd1bee43a6a33c73682bf461fe16e37d43432abbea431e62e2bbe4d6ba93df08fb539c7d73ff2c426432085d6b896ad953209e824a09c64d572cdae9b49786efe4b34ccffba98e0136d08c438b055a37412cb732de40e9a8001b724634d36785a505e5f3805443372eac569601086bb64815a359cd5e420dd31b7b9d4f3ce31c2d636e6ec4918bf52d16d6beb637108888a929074d6c785be9c03eb99e3bdedf031797454c494edb94ab22ab865a1ca1d5f1bdfee8fb1fe9dc9920a6268989a852bba5883639050acfcb669bf4bfb5b06e2819c37140448ef55c4791571198f5d4915d10b6c82fd132830d4e4b389e39cf8384e00457ed88f6798c98d7251a1e85b66d64055e0abeecc35e7d628baee510ae6a87dcc1c7fc720e07dbd549ae8a640faa235e360a5ac9cdf3dd66e559a7e9c6f50739190db7197fdef9155862fe0ba4843dfab5676440f87e813cd97b01e6d065655eb3b1a7e33a180414f65961ad452d70405899c17c3b633890c4dacf0ba951cd2b19b3ea44f7f294582f535dbc20d6a099ab3ec665d45ef11dceb6d9ff1ecbefe3a39df18af3791ddc8863e9e352d6196d5f7c0047c2cdfdb8ec56a90ed6a99eaf648dac9923cb802b46794782b2d904555ea58b7644ddbc468e57a0c22b67101781ca3a14c95c96b8123a1b04ba2c621dad120725b256c69c4141ede1bd7ca25270b67bd54b7dc31f8e3ee4e26bd2eaf47bff9f4f34e4dff793ff8525f837bf66e07d12fd3ed78f4191eae08fcef4c8fb7f5ee3e32fdfa08ae5c2818bd4a1effcb9affb01feadd7feecac080ecb13ee011c6396986b877bf8d1f7ed99d7f0a6982550a209ddd22076ab98bbd452cddc243af2c345bb660af9a816bb840ac5c7f1568cd1966acf8379892204d8808ebd6d5aa165b26f7566cb914f827eee32272973e2eb583147ae427d187357b5dc8566ca95272eb18d5f73b8bed3ffffbc67f635171ce9581dfdd468f21eef76d1638b9b74044a11597bc1512e1dfa1e4bf7e57b78e4962c93c8bb96ffeb2f7bab7e7e0e84a3f6d9b1cef267fc435c856ec5a0708412971af1fed720abf032d1f29819483ceac3fe602ba851eec24aada4614dc2fd2ff0a8ab36ddb77ee6b03c03d899394380236f92559d480c49fdd17a95564d338f982d2bdf209a108805bde4adce8bbc4ba9b817b6f29f1ad7f93c2caeefd7c1be65237377f01552039b994337c7fed5abf99b733cf63fbfad5fcee17ca7a59abbbf37274cd9f0c8ff33adc43ae6f2c497f5611fe3576f6bd304150e83da367d26d79c4840cbe54eb8be41176dc9c8ef7d42841feae5202bd04832b8242adf3cea6d2b68377bd458153a7995d410d14af57ed43cce1d732dc9f32071ed2d72f0c087bff704fcee036685cc1ede2b5ef85c7ff92718daab67e3330ccd159f6b71af73f1e1f8af67e2ec17835c1e6bd8789be8ec84a95edcaa9527ea04a00582548f997c0c0a4c70e125b2ec16a81766a0792fb1218050f9288b848ea3e72e74bc3604d64a46b8977a13f9513e63ca13fea82d63debd844c857135ac49219f7c87699ca1755ca91c33689248ddcb77d8c77f7a0ff6d3e2f9da7b7d816ffac246833b71adffbd5720ab76ffeedfe1bb1ff176cf1c587096c7cc2e77016fb12c4418d0e10b2648273af4386c566cac8cb4c73ed1c422285b412983696522527abbd080258b3c0f295f232ad885c0f2d2fd3062b57844118653f00c881d6f19844c14964aeec6a179f2a94f79afa3effc15afd65ef0e31aec6505afedd90779b49feed99f318f7165c58ef727ab457ed2c2b9852fdf6e09f126d9be7d99736070dada44b37b1a51c0ca6c8068d0216d587c98077f8d8dbf816f4577c16ebcfe1d7a3aa7e7b53bbe3324bbb54ed6c4fbb5112ad5b022e709f1ccb9822e56f229d15582c72c99454b83f45e92389ac96d9033372fc3920d421df609674e604c5673962753205beea222d1f226d4779d5fc1bdef963a77548cdde73e25380c9d41772f5df3336e6a17bfea5ebcd5dfe36b36e6ccc1c6d6096fbf87ff5adce1bcbe72bcf1ae49f4b7bdfbfbbbb3a6f9e406deef56c47a66cc6bfc12da22090c51c7cc726282d6999d99c419aa2febc0dfb7e31ff37bbfadf9955c60c57ac9c12576f4529fe42e9aff7fc63bf9dc99c1daa376cbe8d63a7bae92c212824197f6e24970d9cdc6cf7d604094b06017c26597dc677db5e4e03b7279e24baa8f39b80dba6677a36bf9a5df97bc4f3fb439f21cbfc89176e2edbf4def19f9cea4e74ce2ac97a10f96a64f644415347d9a4f0222473191f6ccc9755e653aa314a4b43313ad195026a05f35c0b7551c97721dd33ca04eb7e2611b91421a58fd5e49c01077c00897f62e66b12e953a71725cd6e3f7e2103ff2abbab3f7c27fbc8d777ea3b4e4782e7fa4cb39253017b3318b128d75be8af771d9aaf968e813ed57c72a15b36ab00f352904c1018f541f702c84d3b4590545c858cfaa3696247f420e6c1ffbe715626c1173e8a663d825ce2f2d8ea015306b4294ad6180169f601af62262fd2b76ebaa06e45dd6f034de790d41a6ab6a1efe48ef8ecdb839998df3dcd74531d5d92ad0e22e1dffde32f6bb0bf9b04f22e625b5a2c9582e835ac4ac0413ce258f75e1ca3a18cc888c85c15e7cc59e888d5548d808f75e8bf643200d95132828aac442dac860ae7af8048bbcff7fd97bd3264775ac41f8af4ce4d7a9bec962f2966fc47c486cc0260d4eb348a08e273a40a20c462c65f00213cf7f7f83c56b3ab7bad91df3ced487aa342024717474369d0525c607ec96dad7e06062ac3ad8a1d86deb207cdabf136a49b82589f16024eab367617ec692d04b64cb02e15a8b879a6f96032ba6d486866e3960a47374e5ad48e4d5e8c1b354652e91c9c20973c4e91b43423b330e232ba573972382191bb93d2a067e3caca005563026d5e2f6fead5d88e80caa2c4a6ec4225cfb737e51dc18e6e40499c77a446d1cc2e53c18b6a5899f3b77aaf058b7fcfa9137393df6213b7363c2214e9e07b26c99e9947763026d16ad75a0098623ed8da8dc614535fd1aef9e584a5ddb18783c660d6531b0a8387f6288a427ea4f9fd252a388b527600c15764700e57c5b775fa189ddb7f47555b5f77874f4453cba8369673b199fc1f4388f5fa2910b1700cb4875e0dac29cd825ef316aee2543d19642d1acdd2db2190e24b422295d006eefe98c2ada4ecc18a3325bf028d3a529e74b74f2c4090ba484919120d5a58f6bc41a9345a25768a23fbb00d49ae4ae61ac3ebf88197a471fee78f663f4a3e3cdefc4d0e9d4e541854cb6afa9d6f9c1bfcfbb165f41376a047516278718ae83acddc801b7e735b3a69f8a53ed7c0a241646df059d13228b19b06434d466bc3ed513166931085d0efd0431e171acaf6c2e668db11e11597dd662e2cd2762a2d9c51ed8031eaee854b73356e7c29f80da95ede403bc920756552abead66168f648fcfc716645f39477a25bee99aa654837ab6b2bf00ff6fe53cc31badfa6c1d74718b6cf204e172604a05b3a0c6f38c9304a0b81c8c714d12b09d31120f29aaa1a35a0b0b3dcd1541984321d298e91ea4eacee3c1fc89cf048bb159c22159771e39736c682e172298ea0d7e1888539f8c71ccc0f8a54df8eddc15fb8a98ecca857a76d0d36ed4e478a9331c60028d1c25ee476aa87c814def80036cec41945cac4d378fbe96ca276b7db1cb9de92cb70b265f99133a9a2b1a13c072674a445d38480bec216f71c38848cc76ae2cd64096d70bb81868e63032609eda5258a1440df5b10cb1026abc223fe168c8cc65903db1d3da004b01d9b2a543953e71b901dfc9ffff376aa95cd76dfb1d43f8ffc718c2034e3b3ae3f3ea7bfc64f74572e811ee9837b6b8b35f5ddffbb5babe8aee9198e896130b2419c6868d2cccd9b5a6ec1d0f0a6b2f2a9f10331c112a6ee613629a8eb1b3816ab90ecddcaa6030af4bb8d66add016b5f29134265c34c88366309e7dba106928c8150e7b454e36d5b372cf84a8c01079819d4b73e57e65dbe37b57ebf766dcb33bfc03756a764c41e6af2f5317447fe726b5e65571bef73beb2081aa6390ecb455cca8011a009906e72e0a79508ac9986057264649843cfe68c15182fb75602cab9392c7d38ac83b154614567d078b9c3b5fa1c588f3b9311bc2055b788613dbb06a5eb8099160d05dfdeeddd1415e4b5780e8ec6c864579e226ffc047cc0eefc25bae8b52f568bc357f77a3bdee7ea0b600bb8f68432d846b26997538f21b167b32aa6f15e5358ce9255cea772a68fa7db27866c17c95e01b51e69f1deb524bb0a26e113967305298ca04f08d52435f459b7b653f214d8648f6ac0db35a17812da64257a247dc123dec9292e17fe886d64eff874367023ee3c21b4cbc3d69eebd71ed4de3c07bc913fedd87e6ebe2b1fe78813427fc4d240a1efe57ceb723dfefd1cf36d6e2417ee4ae484796717bb9c47ef33fd397f2a8080b95a0846ac0d80253f0713e259935075a961e3d8e02c45486635b20d850c60a2cfe61332b057e103aea53a9888039d0f23a376777e628c7c259ce318e55a0c746223d3e780e433f9b3ce13c693750d5b8bca80f967733cd63e27e46ec5463e377ccf8f66dfd579fefbb03e1fb3a365e77177ccfe17ea496b761c6633461a9089e8e8bccacec7b4c0c97e0d2c43c47cee92b11cbb29b13c8a1cc483094ed822906c9e28320f12565a247b5503a26a49ec1a4af2c0a4068f619862065020850fde4ae38c3118fb7698da909d7fd2df3324cab0ab17c3ed296afdfedfc84595ec4332d1191c9ddbe3a5ea9d7dc3e0846e103b8c11d4b74879d71efa55b6a8e65eee27e4075240eb87ded9e85fcea7f79bf8a47f4cb8b6e9b2d93f8e17e70a1a871a668c272da5c68c270ee0c3d0e7451933f20858b28b92529f4bd2da5b3daee763f0b4b0c90e4f167b3dd12b0d900cd568664235d295e11a5848c770c72de2e1cf271eb07834e44d0ebcd843efc8d36dfceba1be7c6feb67fb9ab26fd9fa7bb8e11273b4f4e03e3cf290b7f37d367ce8efebaabd8fd6ccd1731fd2c26dfdbae22e3ff4cd7931cce76db3cc169bdf07b6658cfcb1e1998cbcf0926c00385099b6fa04185933b932b46535c129ca50ec0ebc6a38d2567aae2bc2034ef6a6b79a6e11f77def5bf1ce8403de8ff1566343c9e6d467bf7e5ce389cdd9291a038911ec98e8afd9c30edf44381a7fa8d6e0d7e89edd1ea858de8346973ff8c53da68f0bf914bddb58bc3cd52d1a235bdfcf816e9aca7e802d5924f592351381d127983379a499bcec8084aef56428ce41bef6e550b362faec4fe45497dc2a70545bb359e802e3e7c2913990921825c0d379ccbbb6ce99f1822790ac3f19479ee38a4d08dc173dbccb2e5e85ddf91cdd5cc71cbca8f73151733c62433fd5f3e979bde28feda74b9fad5666613e52e788f9baf5bef42b6be7659eaffdade74ceb97f1c9b38f0c30fa7ac6d13d5a91028f1fb70b486c6385b748319e359b3a44d6e7b6245b5eb27f587074055620c7b10c9164ef11affec49c40cd7aca411b7381248f2d5b9591a473561d2600e8b62683074362b359ad1a8159085f954fe955d9f33a0f406250d4c0cc641b98ed90a3321e04f5450cd78b1c03a0cbc9c21b95dbe70deedb0e66abc7d24fc0803472eb47f8e9adb582bdcff4bbf97abe904ea76dfeba6d5b13d0149ab9956dbc79233fbdd7a6cbb1c27cd2b75d0824fd27a9e585b6d245c21503c341365674c11aab73d399eebd15e1cd9526a0a85cebc99eb313c1b29c6ced3b99b060c8c3dc1690ad80c2500a464bcae760e5ae31dc0d02254fcc3adc422717342e17ed313080f592effe9fefaff8068e383ae33aea0772567f8d0efb3aed636ba2c81519bd437ffaf9fe12aec03cd3135b988f8de74582b840d6586d62c4d0523736cd373ea3b1338ed58cb87cb66360a0140fc818088163ac7d16d42655e7c104a933c6aee78ecc6a8e2e69d290014c5c5b8cb6830a99d91cbb023c79f01c8208c8bfca97f13f8d2bbb199437987b2fb6fa46aeb85fe74787318fb2dd81b7f631429fc941ba3720304c07d4ae832b0f0e5740a111b4e427cf696b46ccfd7af929bda89d477f3e387da5eec66bbc1e8ffab3aad60f9da57e6abc97c7bcfaa2dc5faf8e7fa4c737e35c3e9b7f412a6d09e990caacc750de87bb8131d1e7060c11e1869139a12956c8f67371e73a8b1550b990503f7dcfd748dbccbf2496ed62cc430d1a8a13396de032b3ba713ee74f4f34db3134cbd6b7864d67ba0224b242cf066fac2d6e6859cea23646e5165ba2a071461d482c0bdb9808790e1cc48271488d58652d854dec959843401f4c49db232bccf0241feb34af034565ed31924c2817968dbe8c3ff95c23070b0d2c4a04d99c4c0c7aa6eb573764e2de060c7e9eeaffb53acaad3cd697f5ff6eb57142069de4ae1bf552da3c4d5b9c30255264c6358ff27a7d23976c1b7fe841a3cdc37aee63fcb2cff37ae7afc7031d6b8177f0b895bf767ff055d4a346d77ef1fc564cd6096ed5803da7d5576bdae6f14150581de4cc17e7fd37fb7eb7b653e7fff74535fc6ec5c1f5be542fef5bed37dfc8b1f7ae7e21bb49b89d4b05e3c534322579e0a760e05964ab8fd5674cf3d488861e90841566f39f7a2298264f810fcbcc92d07e2ee953d33176330e097a121a30059e0f1eb7fe4a17e08ac20505111e1b0f41342ce138cc7c40172ff4cc1b34ed663db857f7db41df1856c86459a2d0e250ef629abe62ef3ed09e24a438a157f18937ead1353074f410a76ad89f01fccf830fedadb66fe4efe9fd486ed48d3d7eeb6bf6a6ebdc1297faf4a57dee38c7ebda3127dc7d2526efc78b98bc4b1eddfebbaef77763ceefd5feeb6233ae6b61fc32ffb918bfb3395ff87ff5b12037fcb4dfe743b14681b78873c963c3025a64e2c6f900a5ba3c1f0d37242ed7c00640b3713d57b43de6e85ca7f2424f24c196178205d9e962154efc54ac5d562f2d3bb77cc61d58d250c5e96240e0624b5891f1b95cc0b531d1a332fdbb35016fe2c3bb67f73769f57fc6667c3337c7bbb46b3363f5cc4f91e459483115350209e23c47dd3eb164eb25540952778deb50b72576ba48f407908005a2606748b946b8a106c66246c672a1cb945fc47ae459e1ce8c650ed940468ab036277411006331e3d8073b41fc8b33812fa25d57b8daef43bbe3ed6fefc3b76568a7d563e8fb75c0172f75a2bf21071205d4bd3e7a76ddd9973fe783ceec17b11c91547d86a93e59583a0292ee60a896de5862acb1880c47da19365117ec72ebc7ea06256502e27ca3b37a15c832d4ecb8c6128b3caa3f1835156635f180a5c239341cecd0bd57ab0b8b27035f99eee6d060bfcafee543c078ca30beace3f3a2f6cf859c7c92d7961bad7a473fba5533f96d1fb86bb9f3df5d7392ef64c44fd93bf758d24542d562eee80cb18753928019e606bca9082b93aa1c59d93bcd915517eab380ca85557d5f5b133270eb78ad4da48a307b81ac0c09a588998f1fb7862c6eb454dc5b8c5a9b892179709842899873b37c2629313f69f7beac03dcd55f78d72f8e28f2eebd58337d34d86bd557e862468895d64f87711d91b636004bfb641e5b663763e34a9345de8e29f058790524ddf22c435c00bd7e6286a245738ff0f2c2e4e41c4b646c3864a759626cdb6c8e65c4d96cce0300c69ef5b887e6f0d9e3f6aac1d3a9c9a0cc84fa4f9fd3d74f8c31f36335b12459f9aa1833a4008a476cb386a13f7a4b0e3ad4ddea61fb9aac98185ba2d0d46ff8da41f61bdddccb89cf4f4b04e5436df2ffd9f9455dcb936a42a0d0d73039b38fa7bdadfb5ac64b48e173079e801b9ef0b2debb225fcabb2fece574e329a059e7fa14ab74a3b67b42eb0b5b4ddf9ffe624e6cee27b46cf0efd46e7aa3dded1a7f5d7b7cb3c6421f27799245ad57da75f16127bfec5bb517deb09b9fcffb05cc5323c3c990457dde831f9d4e39f81b3ae58dda821f93c95ec49ffeba4c76630e1735208f6bd4d62eba798eff2efd0e755e944dc5c834279c99b69c8209b5804d524b6207333ee40d39af3d66b00770c1214810b407b5010d13d4866701716ed8060092bbf62644d0e23d5854e5c81f955660efdd852d6c089f6dbd9466335e668954828fe893e7f33fc94fb76cb806c50953628e3ebc1b1b1c7d4d9c0a5140e59b6cddd63dad98cb6b6bfaf9bc030e9969b29aeb0a7a36b89c9bb1e122b0426b1187de820b8bb9a4eb3a0f74b706d0b277bccdcbb96d890f468dd7e60a401c95a60564c967c2508bf53918a39929830d90880aa565adcb40b260b90862190450de2d687eadafbce793741137f9b62d57fb8a1c50c7f13af88695cf83f490337ffe89787343316c33face612b9c43659f624e5d790c809a594a3e273730079fb3d5b6718687b39df773ef7dc999c1c598ad9cd0c6371e68a5e57e3e77a8437497372ac02c2a53ce3d6b02545fd1335f29652d311228e599ce6495c918eadc36787f54542e541710e29defe8bc6d8789c5c8820d70edc579aa3922d2014ac8c4b04c5bf0885daea0321c690c9a048e083d6eff4a5e3723f7d3b8f4272afb0e6ef12d5ffbfb31e28c07056106f71569cfff4fe3b77121a301f73938e673687fdf993c4afd15a8e02477b0b4db05966edaf5a3801976a6af083538d9f056f1401b839fbe5408468d763627c7285573a0e80f41bc9f1a340c677cb802b5519a404d7cb81fcded50b0cdef6b9b239a26bb7b02bb7c6337e0b86de400b7b7f9ce9c365f6fe8bf9f2fe14be2cc88f2bd7ccdfef9eab3ee5cf393396fe95e5b0177912eb8205eb07e2a2e3c65af011a4e8c7850cf3822d8abe916db43c965cab99552db820b86246aa9d5740aa0fcecd9b2aecba28e2d915a008d67acb10e26d91a26798c398dd5211602873e3cb174af8dc5b77333dda0957ed5c7db8dd8ca8542faae1e617e4d0ef21ece297296254ee40deaf21fdc980fc3fe42ce714e078fbce7641c1c03c170a67b97272bc4232350d4c874300f6051236628e8d050d1c4f0f4892a91046818861592f2c513b3cf674c38d05343306b716ec0e95a8bc93880025d30ec9367933d8e6569c1ea73af0eebafd2eb3d472bfd1494eec1364b07fc07ce33199f079d5ef0d6fea9bea69e1e5186accb2dbbf56ac765eacfe55669653967912e07c0895920ed198bd54d22d1fd13c3ecb46a589b8c514149d7cc49c81b8abe27405f6889c668cc9e6a636d3b6feb54e4c622a60f44c9cd6085148fc969b0a2d28c0b0be45011cac6c860f63c6173406a5abc534bfde3b69764b823a3733bbdf48e4f7aeb2751a204d42fe4f297f92e065fb2bf5a5d844d90a3332d5d3bbfb61e37f3d167f34d19b19be66a90ca9c971aa967332c4ef1deab4165d821b388e5b9c9b131814666f0746440f9a7b57adca318089e228b260c6b9f29e7818504bd2a556b15d726443b23357868d11cc398f798c53a98909927cbb5157fda17bdf559418a5ce14416668eb1fd684c78b72ffe7efc660b6368f4e7386c43cbcee3c3df985fb77ff4cff9703ea0893d8012dbe834144be5cc8e4a17da437701d082c884f52cb1082c714e9461061c7d45aa12f8509e7ab6ec80719861eaee713addce982507a262674cd093c60c0dcda2d6dcc2826589856bef13380e2bdf5a565f49e32e61f5f1bc31040a91cf2f4bdcfad151c673d07faa5e1beb27ea3618b13bdcda268cbccfb774eb7e1feff3b9985022e76056eb736c1735922416f1a2acd9251340fa041c555eacc422508489c7b08a3911197345f67a02782467035c4b95eda8cfc684ccdd24544daa33be9dafd158360c390c355b301756181a2b55d49c7c3d63e92e70beaa163d62fd44671a5de2852fd48df3f9b6ee355473c4d10d79a7eef51b35b25ff858112ecc5d6e59bac97080ba7abe173872e623fa162f65fdc4a0a83b73fc0fd503011ba480a43ba769e4fcf3ebdee7e77375c23698861ee1898be3c5168c864f50010262f23d92f4673d163cb892357d85a6380df5199bf17e23ab26c3850b85adb512150d0a5a30d60bc2e43ab19048981ce92b9a21850e5c1b19160fb6d0d1752fb6d919a3555fc55b2ffd4fa62ff2217cd22e16a386c6be1ce776cc653410bec816d68ffbbd9c7106755390b67910a281f00b36af685113d99fa8b199c84f3e15a305785c6b36d812997218e4b5bbd2a9cbed58c2c5dc2241b91eab4f40062b2b19f2788c5624d577a8167fc249beb1a9313394bc9c3136bf80466ac42a44b6bc00313b7799728299507fb1966fd38613debf730ee9f7fe8e2f6a055cc84d1fb1a3818de7c86cef3ff301dbc60d7f885fdca757e3f6f49fee093cd5b06bed6a9fb67180b90b418e63b020a9e801564f8394d4b6441860a90f80ea364e06dbb9b463b1395491137abebddc217bc9d98cc46b8c5e2e6c8905963121ccd00493d05880bc9e5bc05e8050b352995aca70614bc2b30e89872879dbaef6097f349cd25da7cfc91ba40ccb4e9fa79bc319d6476a4310478c5dc7a033286c894213effd7c5ccc4bdffd5fe3eb583142a2d8a59f0c190fa2bc97d76edd2ff5f66ce673f59920dcc73acd76764ac7d026233dd1d726cc131493679b1996a61cfed420d1916df32e509f8395a11b55e95ab02c3d271cc1b1f1134021c531712d4a1f749e2c4c462d8932947489dd2c12a95a4081d559d532b99099bdacfbfe8b7c5ddd060ad89c62686ef9e4e9990bf7ebb77d01f5ad9fa01cf1a7dc02c71ad52fce74c21057ace03aea61dcea769d1d5ab6e7c423b6709d5c78a76d3d83c758a01b79dc0e6de806f346e82b7b8a466cea2bc3c885fbe2289f8e6efa2fe6b862375861deacd3ddc8bc01942b3f3af47ba8d9f1783b27be2233adaee65cea2a4e9b83fcc659d404eccefc2caf6d34ed99fe21af02526882a2636dce5b679703a4e0d24de41a41233fe6fa787916fdb95c1f67b8f29effd6ed9aa1bf48b7b96edc460f76b930f495a2ecfbffbcbf9665481a33e500e7329a5d3e43a02a68a23ff8b6b1b76c7d822d004134642d5b1e692b5c9b31d57cfbfb5ae372d15796033836f6c6c4888942c6f64a4f8289115912d003aa0fb4956a2025dc188afe4452bb22969c80f4059d7e47befac0beeebeb1f79dd79900ee293ef91b5cdb884e7dbef4cde87112ff5d5f22162771b35eeffa11e9d73ac2aff1f1ca331bbdbd95b5fbdf0cf3f9b87186c771090227ae3556da075013e613d1d06c43f4ed3d43d8e55e1b5345670d155152805a4648f93e00dc6eefc1786f7360ea4140bdb1383515b440f6ae4231eb9a357ad026da00417d866b9ae058672d29e7fcc4187d326efcacd6d79136ecdfe7c56a71ccdf05f761f0be5df16becf22fc6edd6c73fe6f46d68fdf2f5bdfb5ace561b55502ab60b88227dacc69821031fe48ac6919f1adc8b7a4a79f235395bafebb89ed7b978c74608180feeca46a7c10958b91fad43fff7cf987a9f6683e2894a5d4e667a1df4c57cfa3390ea13f13ea66dc9f300a21da9f58d05054452646976393313020c4e962c6b792bde9a2590c6ef7cffa0cd3ff015df0f691b07491c90a311d3f7fb293ab0b628ad352a530b10e189218e110f65dfa2033f1970a6a44b782c163a2b8f8c3129fd71f860c9a034a342d05889b562776725c395e1a81bc295b6c786d088851c8eb52d4ac5b19ec8895d8792a74cb788cf787b45e82b7958bb6ff9584ec0afcabb7e31e6098e873dfbd9bcebadcefb8c14d60d24698063a3b62d82b02440372e2d3329e70135782d8ed7760d1ccca9baa108632251c766e5d0e7f5f902ea0e91106b9a4364d6b2eda539302db4719332f51c590ee0728058b2411c5a915528626e21bc925b94f714baf2466ce4f36123139edbf8de8f09ff129f57927950cf66b095c51b38571e6473a250aedba76f3d67f69ff7896523c2e6315989a2c9ec7758d92bd0526790aaae4e0d2e70c05ce7863fbd74cafb13b246352afdb158f90c15e6805202f44a67724bab7185e17e0e6a6900808c828420b3a60f9e4d56c8511d0cf267df069b39402f73a1fc0dbbb29bd0d43bf9badeb0fd1e647d75eb737beac24179c837347db3ae67f38ec0fa50a538620fbe4e9775f76ec8fc079bc0f97c5efab1d1938d73746e0bd7dee6d31c8d5b1d01ee73ff5d7cbc11cbf56bf898a3d6df9a2dda78d666bf5fcea3cf87f8b97c6d56aa973e1b86fe4477406ce8060f76819cb1f6ea71e071928092bde725796e4dd014c4b203ede18c2874665921eba58607f8a9e0b26a821279fdc403cbb01683276618cda5568773f1840808803cb00d49a7b282b82fcb8778958fe3ab74a536e6f67046fe91f830f69558a45f92c55c28d4de21176febc777319fb2f303f8953c892ad213f453b7d03300d2ce93edbdc9e58a151b06b1730539f9dee48c6ae1500549949258963c47ae0013f236b78f7c5b9d5b76b8d3a1bcd61297d164b19c4bb96da454d712761f28e5444f84d463c267cd929319b7ffbbf12ed487c39f27587cc496bc7c25feea97f8ebd5f8cd5a80d2e7f263dcf3cc5abe626f7c97d6eb3697a320d11d2b1e8a9a02f8851dee8295a80713111929e2518d042f8df7568ceb6062509f971ff4d58201b1be9db1ea027142a599c389c12fd61ed46acfceed804a03c3b16ba018ba661996eb900da0a034189bfb886df9c20e6cbea4a92805853f21399a18d9ac8df3b14bac0cf397f1c837f7c96d1bd52fee9377e6b39d99c37772d930f52b39addfa599414a4bdfb2d7c42ceb05af5b80a7d2dc91e72e043fc14a978c14650ba65cf952197b4e8e5c3b07c40ec5f958372d258f744eb0884d364831c6a644384d09d74f4c897446d517705f030ecc741950542319ac906bbfc8217b43577a3b8eef25ad7c772f2d5ed6abf8f5bd749dc7e9225fd5617df446c7f995583e108ecc44b53566c098490809645dc312a9cfecc1dc36c65ea287c62aae4c663fc7c0288d58df18b5bc43ab3026000c8c98f0447ee416f682f393f227a969a83134f680ca58635dd6525c9bb1911be670e0b5f5a25ee43c79477efa003f7b8de68dd460feb216cb27f6651f4ffe7a5cea557e8ba6bd7ba537f734e17d1c7b254fc64d7ac07d253d38e46ee8f8e73126f1309fb2cf73fd0b71a2324be2d2c6d4486c5b40564c5744514dcd2eb6d026b6bd9278dd429300ea0bcc61de5dd108c9ae604cc09e385306f12ee7dae5de94c3d01bbb3c5c85aa0f341e30e0410732749921e32bc8d152d5331c909231fa487ee1bf6177bcc8d9c15efbb85dc8bc3d5f7e5316e6d5104fc40fd51ff9029b018f137987bb7c7787df9fafd5e418966dd19fc18a8c30ccdd4012d6d046dcc2120d2b05bac91bbbf9f8533e507c330632d9c4837b3a8332e3736ceebe57dfbb7a1197fe6bf6bb066f5b3f375a20933de4acec61746b5e3deffb9c6f8348e27015808c3513c142a9d4f00a2b8079b548cae9dca18eae30fcc2a1ebf9e8bb6039f1d6901682cf0933e4d8dbb965248457759fd3a96f7faf6c5b7e3262b9f01341b2a2d233646d0d935cb45780752d696bcbeef6cbfc9e20cbe2a4f91786f858f3b4d14f6feb8e6ff9485d9fed5ce69f3d9eedec6ec491bded27773c13b2dfd43d03c54867500d310762efdd7cd65f958f288c51c546aea353a4d0360eff6a1ea5feb97a5ead1c65cbfadc93c093a1809f9052a8734b5693d4ad27ed76731b54738042138204af54cdb2e5446386b2ef88638fcb9f3d4b6310a0820da80865607b3130889c3f01a95c192b51d628980165b9f6795db2267a6a25b49c83b7cf675fda864ff956de3e0fff12dad6d7f46e7857376e9fe7e9c376df8e5fed6710d87bcf965d93860031b2ebaf28b0933c2766a9032e140008a79847091e93d2e501f22d1adb2c9899f5e376c1e50ca680376279608c97d58c63c78053196ba24fbc18a92e5cec08436b9f5b3041aada0b1b18b7630d68e82bfbfc8331ea5f80a3c7f11aba27b8705f78adcfede7726575678d3a8f2492233917b005168bd5e3409743cd001a0b26e2b3cdaaa2c6939f50920b1310dd9b80524b4ad3e5ddad3e962d7fa5521f483b34a12b1b608680dcb514f0933025d7c8f498471152f6d01a950ab4c18a8cc945dc4bf3f7c7221f8e96ffeb7fdd7dbbcbbd759096777ffdefbbe77879f7d7ddddb73bdd4b82e6d77ffff7b7bb38f5ca681bfc4182ed7d9cfe23a79b6594fee3c726c57fdd97419253af0c8afb3423c13da6d98604db202d8bfbdcc3b1b70cfe581559daf41da53fb2e62f094a2fa245f333ed46b968f9edae88eae0ee2fe13bf3ed2ec94870f7d780eb7efeab8cdaf61cc3b1ff60d97fb08cc50effe2077fb1833fb83f05e6cf87013ffc0723fcc53077dfeea2e25f245adffdf5c3a345f0edaea8da21c7c1f6eeaf8781c00adfeea66976f717f7e77776f0e7e0db9d4ea334befb8bfd76a7b5a3f23cfbfdfbb73b3b22777fb10cc37ebb534e3f9d7ffd2bf70873f717f3edce204d9fccb73bf3347191c6dd670c98e1437399e1b8b8fbebfbb7bbc7324a9a899801befb8b7de01f8421f35d68c62f9a3bc321cff27f7ee7b8fffe76a7bdddf4f8c9fffded6ef4f1a6cebffeb549374540eefefa27f38df9c6fcd77f37ab1c06eb163e0dc8eeeec32c09ee57411a476971bfcbd671917b38b8c7d17d8f0dff48a36558d2ea1f38fac725525ce1c83dc97071f7ed6e9ae4d9ba7cf6caf002c3faa7e30c77b72d6fbd0ccaeeb79165fd2fcd2b7178f757baa1f4db9d597a3438ae6b7b65045e8b654d5b2593231a1487d6ddb8c7cb71901f7f5b41515eb56e6e5dbda16564d38cf7bfeffac9bfbe1fda9946e9dd5fe57a137cfb7a58b65fa765e48b576899fd9164a4ed1c04eb226a21c9fec13eb4db3f6fbffa401bdefcf87e4d3f4c15fefbdb1df14aefeeafbb8efba91b17b29d175102b836031c0c433f310ae41ca49d1b552f4fd6ef468aae5d5ecdf1c4384ac156328c9129fcc49538f695218ba4aeefa9f4a2efc2833af5fb13b6692cefba4a46cc59068c86f38a5bcc51c6e7d54bada48b0669c7441c3d93fc5416279d5750abf11ea4ad545f351a64e7297de4605197f5a4e5ea1b9f33e874d26662d91228e464d47cc763a246e2c5b38354ed3aed776fbcf44cea4f4f1947a7090a5d476bb85a8953b0210a2d91f9b89971748314309825f999d7f399976d3f17bf81fb88398b046fde15b648013f7c388c49eb71324c5c28d7b346f27054d66fa355edad9bd0cd8cd30baf5d8bab31cfe1d248e1b141b1d27a4b6f5c8e5e49dd677339f3fc3acb4ad07ab420476d3dad2e32459f38f429bb46ef1dd37a6b5dcde38d39ac5a5c523a5cc217593dce607f13de47af337eb692a2ff08372e83a27c9b0bb72d0edc77c01f982fd770c7ef0376c0fe0d1edcd1c3d758f090fff34ff6cfef4716cc1d5830fbf0fdcf3f7f810537b37f850333af70e087ef075ef99d13788ee11e98ff5b38f035f3fd08096faecaa815c7de62cd5f3bcb9ecbfff3ee8fbbff3ab2f90e752eb97cd15cfd0f12e4414a8214577ffd8f6554861bff0f9c25f7cbec1fcba86cfef811a5d5fd5638170afe79876914a4e51fcbeceedb1dced21fd1b2fbfda36950156590f4d73d08baab3c5e06a4fbb90ef2ac88ca6c1d05c5d59daabb2eb275199022e847396ccbcbabf6ddff3a1350fed94ca70cf6cd2e0cd6eb6cdd08463f92e6f2bdcf7bf3f97d12243f8ad75a357f5eefa37b7a5f94d9da5b064d4fd9baba6c9c78ebd86f894e03a3f59b0f9bffa374d9f473d52e2a7118501a36833648d5908d6f77cb2c8f977f44e97de525f48f2dd79094acfdef3eca366544efbeddc5df8b3fa2ecdecba3c4c3619406ebaa19a6b971bf0e8a6cb3c6c1dd5b74f3bee9a8814f1a94f79b75d36756dc7582cf7d8315ad04d4acf232d8e7cd8f4dda52c16ea19b3fe53a4a97cd3b45d56272fbf8bf0ed2e63feffccd8f76de7e5506458b7749be0e8ae2deafa39c3bbff1a3418df31bcb3acacfaf6b1af91de6965ef3b1f7346ae9f60977f0bacacbecf8e3deeb86ec2e709487ed22f5d7e4fc2129bcd345802f2f092708ecf0c58dfb282d8375ead1fb80ecbc3529ae9b511ae565844f77c2c43bbb3abebef652d22fe9f5a362e39734383d488870ba68de3bbbc283b38bf30f28428fbdb8e284878b6b81e5ceaeaf862ce9199cf60233bcbcbacfe368dfecdb1467244a97673fefbd2265cfaf7daf081e061777a2d46bb7d5f1ce32f3cf2fc3e0bcf3fb5e513e5ee7ed767a9d663cafb3324b352fa2cdf6eaa7ed4725deacb741f191b66b2f4af32ca31f681b78fb0fb43aae6db325fa657fef9d0cfb1f69950769becc3fdeb2d920f77150edd6dea7de5a27d9fa13ed034cc2cf34a74b2ff13e0496c31b87f5ffe80bc735f0e8325b476598fccacb01c6bff4da69a77cf4dd46770c3e82da87170a2ebe6c1d24d13af78aa8d17949717f24a2c59bcd1a0afb8116f7de7aed553d397ebd6db90eaef7dcad163d5108836ba4bc6a7c605e37d837feb17cf5c17d81bd34bd66d7e70dca2c0ed2371e57f9f567fc82681206340fd6f7385c3702e5075be719ad7e4494fe3dc1e7d82a2b3ed0e82589faa408d5899aef343a31c3601b159dfcfda1f69dd8f256d39c6e12ffc57e7bb5d93df670187cb87146af69e1eb8d1b91aad52d3fda3e5b275ef931005ebf44a21f3f3ef9ca322aa3659aad3f3bbf88ec9b2ffbec5b2909f69f7c27f357bf3052433d7fe5b5b8a451fae1b7327f15e05777f275ebbca1de38a3ede4f25f7beb1e7bb9e747342aab5feca08848e07752e4875e5f07db9754fef5e68df2f41aa17dd9ba5c7b6991777ac5e75eb8ef34dbcfbff719ac38bdb58c7e61a8b02c3fbccca7b78e640e6749f22e51bcd14111acb7bfb004f745117e4c33fea0fe7cb2317cfa857b9295ef83fc2d45fd45e3567438291fef37fd0035ed1a1e95f3f79b26c13aa641b98ede83e175f38f03f3c59b1f21ba375eea91f0c7da4b3e3dd934232f11d0dffcf8e1d1ec3e0c5e729b65d691297ff3a3fb71d9204a88b78eb26688e5d5a3951fa4413b99de26701f5db588836d94fa9b751c3418feaf5b9cf553569d97f3bf6e71045ee2e5c5474c441f322305891f905f3438dd6e579424bb9edf2ba6a9538b22582fa3e669b33fda4d9278250ef3d69c79d172efa575d5c0fc1fdeb227d519f5d2e51fd97a79bfbf3f68db34dbfd883ad273e331f68a5278ed59e8e1d0e398d71e370affc140f37683337c8f024a5e697fb20add7afad28073ab5523ceb33cf3da2715af02a228c2fbb7e0d83c3fd919da9bffcafd98fc78a37d9c66bb34cc7a85efbc51b3a74e46b6178f4edfda1e34dc6891afb37d75fda0a88afb601f60cf7ff14ef3e824e0a785f7230803af2723d70d37696b7f3a1a4ca3f4c71f5be6fccece5ba751ba2cae6e9f2caba1d742baf973ef111aacf9c3dd7bbcc6dd459934543d4a3a96d7fe3d0affddd571c6ed65cf06ba47ab3c68f6f585e9c7a317b770be39bffc9194bd89f5782b0dca72edb526dde3bdac686d1fe7b7f2acd50fcfac8b97afac831f34c0258dca8bdb45942e69f08346cbf062d4a22ab04769bb5441babdf5a85f81e3fd32284a9a5d7cddd5221e4cd9adfaf92b26ed579a35bd9cac416fb62a82f2dd365b8f46c4eb4f833ed8f248343e6076ef80947446f6e6cfbd1f2d4f3fdb09b6bf7b4b6fd2d9de9b3ff7c9869651eeb528d2def8b9c9ca80e4eb282d3dbf2539696b326a36602f7c1e7eb6ff1d70e978f3b058fdbd66bb1fd8efd5f940d6eddceed7a66897b43f2a787974d062dbc52142fbe3bea8d2b235989e0e15fa5ff7b83b5beaaf4ec6ba324b5a73fa8b273d085fdc2faae2e2ac02672d06bf38b568fe9cbaeff1fa709af1ed6e9346b853dbfb5ff79bf207fb7079fdbdbd6cd0fceedbdd364849b6be7f87517da0d5198b78ab75fba7a12a1f6d77b0cdbfd5f89c65bed12eecf8ca1b2d5e72c3371abff3c50d2a92b468fe25415174e4f8b58647645f6edacdf46ebb03a77aab21771f36daf31bad22927aaf3c6e385647ea6f3d6d65d622c09b7570ef47245a6f5e8556dbb4d5d77e64ebe4ad46071c6d3afc48bbb4e9efbfae9cc4fed99f18ffab21eefdf9ed85cbd83f2f085e4318f3727d2018cd4b8d68fb5fbf9dcabed6a9ac755d393a93756e7bff3e379a76232fd72d9ffb6355bced5573d5f6e05fc3320fdfff23eead9d6fcdf0ebdc5bbb99fff66ffdeddffa9b147d90409cdc5c551ed4c814dbc054975fa4f35dbef239a12623f1cfe9a477d39c30cb67533c061c3d8dc82d77caf4c92a9e5c6eb8c1fc62d905e7819a8c1e87d3c92191919da91785f4703edf65c777500a366e75d5be1a6cd42ade788abc41ca9e9ecdaf73a51c33cb6320a0b94c3b17cacb7e6d5ea45dbfc5d374241edd75e7d163ea7276899be7fc31502d6d5d2527adebecc3744456c864db4026b5da35efe7689c2d554ea73348e3fe5eedf3a072b963fbc3753a4a993f47cbe39c63d731c266cead8bae22843e6cdf613c48288e70ebe6e9f2a026cab0448eaab663d58f7b6da531ea2e1f9ef54571aa4e5d28c4be02aaa6cf06d6cf51737fba7cb606dd1893c506396ae5f3d3acf9dbacd1742432b3046cd06899cf77f9b08155b71ecbd4bc74db7d982a0797646de99a22e7c27d8e46222509d890112ea693c5d9581dbe3c2988f5132d9fa54686e020c31ca848d2cef17f1edd55278b0d56f6a11f2dd96e4ecdbd76dd29e617c7779e4e01b81bac0cdb39ce2a9c9f825a841a41217e6a13684a97f79d45d6adbd90a3d1ee04c72a3e06decc529d9251686105ac66a9be258eba42e66ea956c316bf5e6fdbe247d1acb7cf311be484a1ef880532852b375ce19d7e8e78574c47783f5b3da6e7df8c9cb02d64f5349eeeb4d1591f091874eececb74c10d374469d683b57b3c5dceb8bcf6b9c1f6a2af064ea3b0c18fa285350f0a328a4feb770c86bdc499d9e831b592efcbfe5e7a5caf2e58969925c3f5d3a9bf8b405c32126204c1ce7064d685bb0c27a02670cfcc12758b26f1a62bdabd5b767f5fbcdb17bf0b2be4e8ac3f596c3c0584480115668b76ef76c5060869e688a09ef955bbf7afbee57aec90bad068e0eeb7fbd839ac7bdf8f83a89f2e8e34074737fa6c617939df03cece12bdf0799d5e3c9f305d1f13a69836f38f8faefe1919c5ed3e6ce0fa6f75b76e5489f25d01f1d0e82819b2c33fff7392e177e60b25c376e6bf25c3df92e16fc9f03d92f09648f8ef12d1ce444da9219920363ad2bbfc615e8dc175cf3bd26cd46a15ff395a66db5925ca7eaab338b1974409c3664c4fb1bb79f2ad08b374b96189953d6d449ca9a21708ca1b7f122f0917523f1277aea3d7082e6e883783a35804a0909371b63cb2844a0ca71314fa0a8da73dab6fd86e2f82b5649f8c849dafc89ba7f1a223fd8abef5539d9976a24a2352f7ec416ca3cc1a7194283445ce343d44ebbc2e0a668758f90606e2f55ca60addb8dcbe1143eaa942e3d9486c45d86933ff93b8ba749df6bb4b0f0ab9ef8072b63c9fe739cc17cd7c37c8c1cb05b7df1268c81d8cc2c337e417f3abfa88ad3331fa6362d2e1bd9e255bd99928d63febe0d788b12dcb6c45e61e3f7d385c794c337f830693d39cadcbfb99db7d43bfce2d2e2da7a3efdba944372419ae91f9128f084719afc72f92c8850717cb1e36c574d2e5469c4ef4cce7418146e2cae7d89daf00069922ef3946739f69597f32ac2ee07c149d1e87d391d8d6d47d52d8adcb95639f6be01232b35e753889ef2f45ae5be2929b0ce3c0dc2d4daa3f5b9170a8659fa334ce7a91ab174b3e2226b56b993a8d78cc8195a77c4fcfd4893d8172719a93902128c78daa05ab4b95a87fbf8ba64c8e62507a4b3569d737d18b668f4ea54b98f4eadc051e35b4aabdc7b5dfcababcb1c55178d1e6e9b4ef184fa17527ae5de0f9759f9d38aa8439ae84c2e770bb779b3d8692ef0ffd3a6e7dc5def8ca306dd6aa8d52acb30e2fb96183ef7de4e221d63d3bcdbd8ffeb4135063a5696f1fd6e62896e30430c451375345a0e42a6af4e92cf7472f4e1faf5bf1d86ad5d5ad6f0a3450e496165e7eb351cfbadafa1b7c9a437acae571aedeb6755e1bd57d397d3ce48489dbbd384a99af155fdbd3b13745d5fefcac13ef1ae1ee3f1621c8fef920307c73d90babfcdf0d11ec64d35f0d117ce0798e1798e1ff2da2eaef10c1df2182bf43047f8708fe0e11fc1d2278ff3b44f07788e0ef10c1df2182bf43047f8708fe0e11fc1d22f83b44f07788e0ef10c1df2182bf43047f8708fe0e11fc1d22f83b44f07788e0ef10c1df2182bf43047f8708fe0e11fc1d22f83b44f07788e0ff91de972d31ffb78505b65bc1901ec79af44742def69c39353bb8cf70ccc981e6dfeae6ddbbce3c7c9d9f37c7bce13cf3dbcffbb79ff7ff9b94e68c169cbcbba79538f73983b6350ea4d006f2e3d23879b93e8d28a1bea26f7d682f89f27d19c0218ba3de8bf654b7a2f552250addfa91b8c3c9b0ab6a6d8ab6a7d84b3719e6be022aacec43f2d21b3b46a6b872e160e926f6122543d64f164b0f0e969013733f316830127e624e244fa3c1d683428c9ce5c64bb57c1635fdd37ada0698e94c5b736342725fd92d0f9e8b6824327ed5f4d37c03dda04a9c02d9584c25228391183663d9d2d002a32ea011393a83abc112b4de9de2d143f2628c66cc495b218e4170b0c43cddb85c58f99cb0258e5e04e6eee8a1d956e056a4254e64bef5ca9e003a8b441545a2e0f3a0ba9cbb487182b63861eba9226f02530c2ffbd696c809a9cb83b6fd6cd4f4612f5d4ede4c277a88125034ef2065b1244a48a7cae1fdc7a5c7018170c3aa87c7b53773d17b8257c831589c0c96ae292eed89dac0ac46f071335a66ab69256a3ea787fea8810b5811a7c791584e88d27c0b1820a8b34469e1bcf453b19c2a74837923f495fdf272be2aeb479dc7ed256cf75b97930b7f122fdd343efbde068ee2062bcc12a7e0d8ce1d35386a64c8142b0205c6832c3de00072c29dcfeb743a31329c003a55c0064dc4b61609ae06ada7f853242e67dc63b3de17cfa70adae21b6bd47a6a8fb2a53b1a6608ca0551965b9c801035dfece8b53bea701e4121ee2b9036385d7538706a375542eac23de38dc495a78095b77bd9afaf500e4181625e5f4ee5f61ba99f187df55e31f1f969b34e85e720ea37f85e898777972e1752972b0eb0d9b98e1afa1030c8992ef144dd9284c6082eda3ddde1caf91a9cc3416ea30748325cf541a04baf0bfe5cf6818603a23c2e8f95ec5bef67236c230812bc3465c3b6cff656e7253dac7c281fe0f9e42ae2d24bb5a773ba7088acb08f81c3e1eae0e97df0d83e7af92bc3743a66daeb763ea3d62bbb6dd37a6027ad677676f6bcad46078e55ece2b7da96c831329f5be4f3aa8dae68f7cecbef622951c22d1a3d663e2734fb706280c5b259a39ebed4c411773eaf32082ef237c66bbeb70accf8cf360241a1c974d28ca10ad38918e2446ee64371aa2d5d47a5d38958f93cca9102e206b60d9e190cb0cf82679fa623b18147438b12bf3ac1b10fba3c7c577bdf857483fb6f3c056d8b91cf1942bf27c2a92c3edbec5950f763b66cf623aa9a3547db27e51859710ad0ac0edf2317fea8a7c1ca21a2405b620e3438dd464634fbb5c1f5361ae3311f8e1271e93e664fdd1ebdda37bcd6d11345a553455eb91ca831d7c36242b7c4992edd54dd125ea7cddcc948f4db8aa2e36c3be33a1ae229c39a8cb381365eee66dca1ff6185a01c7bddfe234fa378e942219eca658b3bf3e8fbd657862b17ee339fd799f96ab99b8f1fb7cdf7fa13239b71fbbc997fb3d71d73d9f02a74a27d6d44d5d2e541e52b8fed1e745b981acb860e1fa37626c6b687c5397f3dd18071f6d4c2e61471f0d4f6397a2ce1485c58ac6e4f476c3c1d913fa749487d65bfed2a9a922d4ef6f13465d2a9dc460794e6887491145060fac88e87a922efb0b2cf5daedfab5d1071ff8ef8161cda3d3d5ae6768f476774afe533e734ebf43d136d491c9d4ee5724b920636c3108dd8469e601adad2ccc131c3b34a928427d5b112eccae7982d56e495c7c9293287aff6f164767c9f70b4c1c50a39facee784b8e11b2dedece520dd7aaca7b24e718a7297b397000a2149e4dc57e4c857c0f2d8bea585fbbc851d502999a8823b12fb8897e9d283ee416e3a5fc746be88dbbd9cb0b99f80b85def168f871c72d4c2e7e486461753a5ab323a551a19a1c5871241768bd3b881578838bbc3cd63b4d77eebf38f4ba480c275e203efb61b3ad5f0d16e5daee526b1f2b99cba7c237b092b7f02e23ec8dfefea7a75d17b8eb9dcccf8eb7a5ffdde6870572e0f5525c3fe3b5fbc77a31658b33fc48667bbadacf7b86c2bf93a5a2b07b6fca9ab23b6440aad9a756c6b9b2972d5f1fdc166b4cc97aed245faf8dc9e8e1261e79bddd83dfdf8dada55bda19504fb0fa4d8e95b1d43a87961f89fd4adfffcc218ea76eabf75ebdfbaf56fddfa262538a9d6b32afb398a1e7f4ee54e0ce945c6accbd1d2aa4867ec60d7905dcee74a8a0e62900242975b9e896147b5b4f91736a2c0413d6dc7b920e746e63a8b659b03836b837e99e63d3f155972a602b6aa9602aa59af0a1fd4d643ff38551b912f47cbac5195da775af6c0b1ad787f26223673aa7dae1583db673e6f640dfb234ad8f4d5fcebc4be5e7c6c44e346546d54aaa7aeff47acc8950b9965700cce3586d39338d9b0a3a3f83a558691978015190d9e1ad569d18bc7d349b9759386955dbcdb07bfbe26dad2a455b91757f3e0fa312617ea452fa2f77d3562761a2f316f549d9a6a50cc81ca837211346c5d91eb4eac3bcc77d78a042e148476dda45e3d33c53f0f6ad48fb3ef9c258d68dd88f024edfa3ff473c0935ef598689daa3922ad18ae56bba5ca93102783b4cb63d2e56b998d444a146df3b1b14f227acb867bd1e80c7ec7c0deebfe0ef0b8ecefa026bda3463d5ead03af33b85195f88b75b852e32efa6c453e9fd3b7fe598ea76e3fea1459d9b2550326dac3ac1aa60d1c099c6e5c6e58ceb872d3882624b14bcc356aa8ba0d46c3b51fb13b7f02520f0eca2ef1c130f2956134e3d8d083832d52862b5c0d530269233a6dfd6418a3b6b8391b4f9bbd60b22738c07e0ddbeffc7e53f53d53a3f26370f3054ef4ea96945b1633d81ce0ed41249cbd5b4c1581f5955d311d4ff34380fcacfabe34a1db8b564755b153ede1e000c35685988d0eb4e2007791f7e0be38a9fa8317fdb47b6dd1a88534998ec21bebff387cb698a5cab6b4203d0bc23e9aa04e3988ba3d3a8fc46bd5b5382f18fec16f6ad4f2a217a34fb4a437191d455f530c4f6a778f7b55b76fbd86ae3a618e79a36e83b74d91fa139dbefbad0c91c108e7a79c578daa002affbc387c3fe6c5b7a6ddbd4300f68f459bec6189e0be51235fc2ad126ba2c80c71f4b1cf19741e3d32dad82eba7c5c068b19b651691bb5e1613a227a6fde58fac99069d57365c823b848a713e6cf53e9d72eb9463011b7385dbc30198d12768b26a040a640bb3646dde635ab0efcce5efef8ea7c462de3edeb35ffa311413f5ecafdacf9e9c04b1098ffe891d7f7af3cf2ea26ff8a603e607e8be6bf45f3ff4745f3975bfeadb2ee2143268fe529d75b5f8efb9497af2d93ae8d06fbb392eb85cfe9ebd664012eda55a792ec5daeccae44b7511168f7fd8aa1cb95216a64f4f352edd17929efc7e534697343b663b772cb88cd8eb91ea353828fb7e7d99515f715ba4250a8fb32df626b3253ec528b8e65eafb31df2a2fdef5851239c415fb1357ece9f8a52b67be9badf04633a7c7f63fcccbbedf2ea1decfb595a1d8ad1ff525c9a3a6dfc5f9f734f0ad89d3e82aad89a8fd6e67b5d868a3c1256cae4baa9b4d5f5d79f33e275fcf97996309f6767c302c7dce607d05d433464cdcd68c86841927ff2411db26f6f1608b2b97f3bf5e0bf3e55ae004d43eb7e7105c9cd6b693492b0449236354817934716e7182b70b058598377294c65b17e6dc0cea5bdf11db23d659c5bcbc67491badf9d6d448835379f9066e07535d4e26713b3ee6c250b7a46a0609b76086c04a4517b3a43281542f2c238492ae99d0887c69b72392b1d7c7eac8a8be577082799f0f230fee046f2ced091cf29a253e1059ab0c1e28ae93cf1709fae9a66a0d5760e38fca8dadec582f362c2fc95820ebe9b3c55cc006296087a0102328ac3c78b53fbaf9875eeaf6ebed6e346bbad1a3337c5b645778d795e577b85e5671b40b5836ba13e1e4aa3d4ab91c2b22471da3c19de9be2dd53fba8065851c7deb4f1045a316bfceccd42a451cadc944156689b0f35b9d6058a16af88812b9260a4d027398f8bccabb8e1a23b8d8ce2eafcb76fd568f1ba29087cb3d4a1b993cc50965820eaf6b4f9158cd9a9620193e3fd5c831c66268a7d9c04d496ad26c8095721d28f95ee7be6ff57a59b9acb4f75631a3dba1836a71ebd25c470c0d914c1d8d1529a91fd72e1cacbd5a36ac31516d399f5a961ebb2be0182bf46c8fd1409fd0d2b2a5e1b3790113ea278d2e7a73eddab56869c56a309c8ea5dd747994f78707b9fe880f89b0450af8e1c3614c9abd7609bb46d71b04261b22c5a8de59bbfadfb07617e3377b104fd46d30894b171a318e987e4c81417c7681e30753b8e718427734a367ae65efb58865028bf03e05f18c21d4e6e51990b4ca4c860f98dbb18144223f0d811f0365518bcffe6aba0da8c8cdea300f2694f71cd1f001f2080f1c120b133f56b79e633c6929c9830981180e13c2867302a581b742485fa9856d31c3cfd2ffb7f6cf940e6eec931667771d5c849f6d9f47bafef8595a5c7b50885b1acaab1971b4ade768d1fc5c9f1aa947ddbfc3b5c78d662dbe64fd314737a8d133b961e54d403de368ddacbde76865c377f5d12769ae45e70658089a254a5622abb622a4100a9a258b1455e533e2f33de66281d80ce3033df2599b0d2cb49bcb1a6b4c721dc848c64ceee144e63db31cf98c3107008d5c4b953c29dfdb80022345baa1a014588f9c16ef8d1b34976be044262a8b2ef835d8a0e67b5fc0f7b0373bd9e479c5709fddc798cf4bd751574122af675c277f118596c899beb3962d5fbb927fdaf52848d2e3602bcf89f53cfabec509483d4767701a6ffc542cbd54dbf8bc9a367814246c8813fdc185c5b697af5a590647dfcbab39951d1f9f7e8a1643898e341a46411cdad60ae5c8a63f514c75b0a2992fa315a222d056a8d65214224a1d1bea9e2913d79486030fca26a45436a452269c5168d65480294d75eb718d9221022bf5e782230c4e656b61a1bd9582b9cdbca0c531721a5e29323805f4937c364610511cb18c5fb536ac4debea71bec75f95f3fe6d7813ba49b36fdd8fe0c8fe6fe30827476eaa52d2e2c3e137b39fb5fd7f8aae6ffcc416660ccd6d73980531cda085764832366eac32c18a481e156d935791361617333ee76c592f75477c3692b2d0d390357875e2d3703363110324618e62815940e4cdcdef7b3b35a8a79475406d0143ddf660bcbb45d74974d443dea7b39c1c3572a80b756606f75bc4353c1dbf03f769237f7f09dc6f8cddc847a19bea0c4ee41519b147dbf8cceac6fd1cdd55471e556d9886b63d4119b2879cc1a923cced159ba5cf0096d513abffb427c6b39faa9a3dd66a1495d004440b12f0603ba2e7f2324435f9e95abaa62bc6082aec4390101e8cca501b4f058faa031d8863cfd29f08a46243773f82e39d7cfb169c8f72efdfe567cd582d5cbdd42df568b0d7a201f7399d21ab11451ae291edd776a573f226005430e3e104c8f4c98df19a24c2c60694332cb1d4215b7a9cb60752b1f6d350c41371bd60f6ba69ef762ec818a4a80588f5b9cf10cb53c2f2892b1f0ccbf08043d78b64a8a3daf8159da1d5df66d0a0c8792cfb24a7bd0ea1bda4159d8e5b9311fb1373c3cdccd11917aa0532d9f3e4a9fdfb2deeedaedff7527deb476ced7221f5a15492891a7632a9ddbff7b8d1aff74a23b73a6a3e8379ddd359a6e1395af41a9d45ac9f1837f665b3ef5a779e762cc451c69b80e8c658c5f59e3cb49d25fad637877d22d06185ab21c5ca30428e4a83a4ccfd4fea5c2e146acf64435fa1a9ff9ece5c7572e1dfd5992fc76c69f806738d7cbecf113728fb713ec7d35371eccb68864138d75875b248d89907d51851f2806d1de9ca7ee3c580f519e10158c0d694a16ca4628246c307dd919f4c198538056b9cd0d8181b3f89bd7fd662e45a90f200c803bca20e0632e3021acee5d0840efe4a9edee32f2e094763a22c4f7ba0c1e14ff2623fd5f319940b0f92cd8c7be5b9d3d01e3078473f635a9efaf7e5f38b313bbb488b030d8ed060c4f4e37c8677337bd711a9ad20d7b26460b1fa9ed4e2766ed3dc88e52da1e8616e33ac5dcb12aa0a064c54897048470e31f4f4718b13562710443a6f3830c90dcd5107bab4df06962ce2584d1137dc1bbc9860478e4dcba87c4e8851fd26effe255dfbb33692cbbd337cf1fc70ee3873488e2646f6befefd25eb7b8dbf0defbabed7ecebfd67f73549e4c4e55dcee47208e3d2427cb6d393a13e63969cc118231ccb4cb00a39a484860bcb89172395c442654a121758fa74c1b8fb054337d6245edbf67e3f570cdba4a2a1c1e9da640c806d437179638d64d5d1c706d5be765f531f0e7f9ef0bcb775569dadf3ca6e9ae38a4d08dc17077875e1186cef627ea99bbfb0b94ed41c8fd8769ff53c8aedd7f63fae0bbc437f5eccf50dfc645b3efb45f87918b3b50935fbc4792cbbfdc4f4e37c4a779008506b0d92991bab7bccb03313e4054e5042b83d8bea50379572e5a7e24f5c03682baca60151f44665b9b0b41db04409284306c586a7298b0a0050c389b8f081585a36fba453ccebb5aebbb6549b5159b80975166feb0e5738dbbaf2523fd1f3ff8fbd77eb5254e7f6873fd0be7849901eed65a9044589452009e40e88bb10025225a5c0a77f87689dedaab2dab59ee73fc6be58a35b176d420ef3f89bbf797e8f8f3af760eb8be0ee254eefbdd5376fce7b8f6730fe9c1be8efeeec7f6efdf0b2d8117c3f97cf6c6ce7a35df7335fe6f598bdadfd4647f9c771be6b733b9ea6530a42a92b9b00b78b4db976691d847ede3ab99d269dd3f22279b77fdfbe83da8fee6080b555fff973bb0e8f07dd15edba4e4e7bb8f0ab357d9ac741cf3b97deb35f613e33921ccf5de6364961df474c9861666f125a5b9e69087f9a96d2da0e7cc5bc15da741eab7432c116ce0d6d65d92157681217861ff9c889f4bb078f925d64113736c5dec966ad0462e49b6a235835a70ca3737afeabd86b0887db589fd53d2ea760ed5b79fd26aff5233b61f94739fe99afc1daf8bd8c84b292560ac2f511a21fc2348dadedfbbdfbff127dd497312499d65c7ef6541d06248bc65ffa13cd229b5de3dc1931475a089feef1d3f8dad1be595f74de5c3cc107bbf2d6a50a24565d4a9ab215c76dd891c6cbd4c32a4ba32860b78cabfb90322ac19dcecc547350be239ab1c07ab80fb93948543e707c3160b08ab06ecf8569026e111cea234e1459f881f9404b115c60577e43ae1fd6a4b70f7f1d6c873038da80333538936be973de5508872ffbf52aaffbb7677636b9bb540fb4214c8d7f29df972605deacbcdeffecc7ed73b397c9fc871056633f43854fd35cf8e91207f64c046a1005a3ccd3e43da1e6f0e9fe7c6ad707d8880bfc1005ee9739137c1dfdd7ad0e762b545aef8fbd8c5f3be38176819dde2c823b80415538dddd7ee5bb83a418ae572c7df0a795c98b3af791d345ddf7626cd21ad61177ea04364a04375fc793afb3165a0c4115b6a08b2da692717f26de7da7353fc81b3ef8f9f09e4cd1289ac8fd6a320a9966d8f38e90b0ac76119bed62451e3c13057ec972a76430ceab4652b759e87720f425a2acc29e72f72ec7bf12badd533e80180ec502104a7de4848a2d425e45c9f4a6f37ca57d8c2f7fdbc6189ceed565fe68c0b4be0cb930765fc58ff07800af6267bc19b3df2b20fbb237e3318683fa34ce457e6682e48c507b1e4dd43a024811948a28434b7f628f5da5144724f5ad7a4d0b65389a11615d2c6986d6892f21d3d3199da4de1caa494c89e1e65893fcaea52698474c6e096caa08a4a913dcec7dc418f73115d3737ee657b21d6f42de3c7c2acf0bbc8d3c708c8bface4b4cf34c2c3584cd2e2ee84bbcf47dfeee955d93e86c9f58c317bba6cfbb7df061b3a41876490bd2a490f0f3bcb3d82585561f9b223deb1d70e6373761e0d447f9e4d49135dc45fad37b9db9ff87fb689176c17b4cf04ee8761a7be025b7ddcffb03666923a6b33ab25427ad619914a85e0423951458f5fd930fba890fd7d1fa531fbcd7398b6094262556c9fad598e3c37bcd3e3cbfeac7504ff9f9b65fa7f6fd3a81342e50f94e97b7e7d7145471a1ea838c7b59fbf7fef3e1b9e1e3821b4a8ec1f6f0ace08397f53c734e921e1b4d8c05b78dbe51df737cc139674fb431946d5f5efad97b95b6eae56660c39798ff111bf561fc829df2bf9faefff199a7ba8fe3d8f0834c7b633bdbd507997538f3ef65dad84e65407621448ff161ed8aaabbd4267ef3ef3fc644b2c842dbe80b3fed6af1f793cdbff09ec6fd092646d3c8048fb192059ea0850f94470ad2ad0a6026144c886e02a6c29da460e46633ddd12adbb7c0edbcc3f72e6f364b74a7259468624a4a17cc3a51a65a9837c80f2a7f3599b594934d9c93cc2b05704ada0825f41ff9656ffd9ab7718ef7e7ec49c64d9dfa24f74ecf27578a8b5c6c0fc390abed29c7d5378914639026a59daebec4d6f4b251bb826df4d91c7a7feba50cfbd4f399bb7518d86d18a8ee64536b17e52e191e610e424fc9d6e36ec32c44a2420c18536564d90df5861bced5ce83c0f14ae17aa53225539e446928b861f939b88f32b2a1006b0ec58513a49d64a9cfa7b6b69adadcedd8ad9c10c57c91f93a19138b8cfe01eccd5dbffe7f3a33e5e1dcaa4771e6cc5c98ffdb46459a26c5ece2b3250bb5fbc2d7d24f79cebff6b56429aab8ed6db57edc859f3c3aeb417bd9b9480327c7d885200a29ae5d0d771e47f390368b95897ed1a9b49c4e16dcca1b4f93033f1f42c1c96d62b12ad19a3c0ed2282eec2d814e174d473306d4638c6e1e3c6dc856a8eac2a0dae0090eb869cc0448f76189f49fe0608f7ee5b3bd714e579d1a4e9ef201e3b3cff4b9f1e4e577e019dba8919c01e1813ae2b88d75922670fb5a97b617eaa975c89b342ef0e18e7f2f86d3bfdf15623805da86dcc80eb2e3552ce7cc7c4e7ed845311dad8b01568cfede3313709cc98d9fa151cced30d1b6da8aa386f9528b0a358b2d7b407312f9fa68e69875b0f4ea8960775aa8ec51c8eef62e37067232d256131b27e5c84b90d42947aed4d4d6631879452a98cf5cf9794ce71bf7d34e1348211e9fecc8cff7e0bdddfcd33de8841f6a8bc3bd6db5b79f7db3f7212ebaaf142d120b89d84c1f975357a340ac7d2d9dacbc7a8dbd7ae1410969466052627339156b59daeb88a17932757491d726b3eafb4823edca17f7913f6a19adeedd6ef4b02aeca5602347ead520f1d36a158c7678821ac1e44739fe5acea2d772f69dec3ec8be83ee3adeb7a71ad477f7ed7b31d5e7d869e9ec44c1da58c7afecc5f7f1b49b77f2e32d4624b1909614ec208fb71fe67b464f485dea8b7294caa9ad623838d5d00a75f4cb66afdf7ff8e6dddeeaa0de9eee9b52f7bfdf53da80787a8c337f6f4d9ec63c9ead57fee39b393cbf13fa8eceb2abb840edca036a35252aeeef80f15e06bfd761ed95728807f99226655e8b20d5c4c1aee4c3c7a4d769e7e7d5e3dfd697d67a5466a893f942539c723b8ab5ca88e0507996bde1d3d16d6c1ae384ca65a8cbd0cbeb790c13cdc929f04ce2b2401286701ee578262cb5898acd9e58cd63643182a1bd0d950b8599de865c2c5daefca535dc515aff13b6cfe052bd13eba9fa46fca8bd8aff530c07820f7afd721c57d37e90ff556e46009b288fe855e914c33c319987337bed96d2f7a782092a277320d7b4a8ee5781b22253761e34b2e554ee1750dbcf614a120d30a99872b4bb966523130742772c632cccdf4d64e2790caa1de6602102667f811dfd51fef784b97a8b37fa100342b5e04d160658bdf1fdbd0fb1a7efc6a7fa757f556ff07e5f3fc1449df7dda4c5dad8035d1454ea25eef01edbf22c5b6b51b0ee3996351e0cced8567ac4fb1ab6bae70779b2c38e1896ffda7cde6bddf3be26e26777f223c6e82d76eb8b3bfbd1fefd9bdcf269cc17cce0297f5fe31fd464852a87a2d8009c0f19f5471be6a345948b25410878b950ab122dc4d41eada8c83dcea04b49950476e04da51f5b76ede606f6a63720e4db5664ee9e5adac053c45a51ad8d033488b404c6857cf0ccdf8dc3c35d6c5d802dfac7620af66e65b1ff8b415d3106f5d7181c9d18f14b5cf50ce6f2b00f1824272e87be9ed41ab6a7e7f52be1bc7ea8b33fca07c1c12e2abe8be7b9bb520e8fd531acde604cdfcda35e8e2f97113ec3f73ca832a619b7ae3f525243b364bad9fb41bae754400913b8e295e15063eae807bb70d8acb250c3484ce276e8514b3e2699b9239ad4e650650e547336adc8d264c00124f77d53a310e9b1122ca612e1fcf35aa1bfd99728706a51b26d3c3d62430fe74858b43e51e3fe4bb82bd52db800b1d51cf4ab168d41d6535e07478adba79abd4fe6f9237cf8aa5475ecd307e9d59dab639fe9ca5c0668197276cf326c92526c5cadce62b3cea3a01221ad98a4e96839c19e6f556b0c0d5f52f9282c32f14c091d2b7d986bb5c09a8d5dde740cb205464c894e20968990f2ff6a597fc6b6fa6cefdd3e56f7d77bffc41bd582d3deffae3f7e77b2c52fc3ec846e5eadd9042fb1596d58c96a6ed2bde04387f9ca7461958534349cbc76fc12d1988a499c274d62850331656c658aa9d4898b7364e2c27888cac4087d6c0b4b79d2dc77c4b70fbac38c28ddadacbc93f9505d178bf956769de4fae00ff5ba9fde9fcfb13efd5aef17bcd73b2fb5fae3ff446ee3f3b3f94d7c30bc1216e82b7c30fc01f6632403b160539b0a85969c1a76a89335cdd06201d494a159833b0a89ae323ac5258633232c085f52029280b5d89210176891d0340cf91dc46033f038f03190689531c20a7c2bada6609dddf29c01a1bbf08b98e315f0c1f43f7556da9063b5e06c90588779a92fb126277cc2156a1ecf8dddc77cce7c7faa41f5cd8b74534431a0666a9242b61ebad3bd890d09cd773848f7abec465f293c73b39b3d9b8e80d0d126664a6305c07e1702c74f6b57679ecf87b79c8aad30d9389e8c4ac7bfd32517bb554152cf928107b120c50c3a019a461fb921fea6c6e17ccee0cfb98f2c864616067d9c7fffcc03301e5c8a335d2705ca3e9eddb376cbdfebaed37e9fe27da7bf9f7c96cb74d57a3965f55cdb37b4acb003a449f50a46960685a67e39812a98658fe54408663519a1f54896b84e288e782e743c11bf7036833112f74bbe695694b9ac733a6fc26673d88c69308a7c76d3445dba9d77c9c0b3ccfd757595a8626b5f27057a14cf3593c987fdfb77e4024efbd60ac7dcf40b6fe5973ae32a354f59c8f146f063defb8583f3703ececf6be1879773ffd0e1bd03f18880d124a1c3884fa477f02f18370c2797c265d532b614a13a2ac282b9492147d447baa7a12a42aa76017b4c0a349666a579104f694606ab4cea645d3bb1564de63aee88aaa0ccd85868a1e17179ae8ef70ff1e0efe0e27b8c59fdd402e6a5ced63ccb092520d31687fb57b0347ee1867acfd5f482b7e2c7b55e0458c51c3d4a4b65c9e779d5071128f8798cb2d949c8da10a24e78e0f07cf739eeea0de61a24c5fe739cc9f35ab06dc46bf50627f7c79ae27fcc8fffc3393ee3d7bfdf9bcfe37e5789d5bf1df370b7a492e3bede5b855cab4fe35ca46fe3dcb6e65ad824398a588ec142bfd193a2fa2534f381f399165b42f0a9bd8f2732c54ad45e69b3e5545a4b9a37ae56433a1e1209464b9ea78f3e6cf4509107ee8b5c96c4f282caf21936284bd7be35a4948dbcc4bcaabedd4b0ef6efceef55cfcc3f845379cf0f7415597fc67fd8c6ba544981d304d23a82ccf8327ffe114ff8a3b3da73b506769f2759f05a9df05167e6a3b53fe1a04aa81126cad197d610fb1ad51dcdc02b73ab110a1c1a6012eb3210597aefc1e1ce9ba812eba91b06c26393648fd50c86454dbc4c98dcb7a9f02591bc4e799fd74d53a71be9d497eba81bed639f84114deb0bec869fe53dbe832f87681b8fc1615dbec703f7f758a52ce4cd76c1ed2a2e7aeeb7d79f4fdc6f97f10d61edf70329ec49c4d3d6cd5840a06d71ceba50277accc822e41426f9b0f282aa5e65a80a755b316df3e0586884b5662e4ad64426ebe2cea64b6e6489852d39ad300dc82f6e852da5722a390bbc5c521ee026391b43fcd2ae7b69ab757cd74f31c1bd5ce6eab18f2395b80adbd736ffec4ff9b14272237fc2e7be3b27cf7af38f5ce07adf1ae6203fba056cee230bb5e1a5f5f3ef72999fd71ebfcf71fef43c01155bfdfd3f9da7e7cf07fdd5d7a85d14939ecc061490b1e327fbb89401edc28ef14a8b4d764b7c9cc716216e304a3d95469136b49d806152885f22c32d2d992bb89c85345589ae94f06ab142e603eb842f956d52164216d8b90f8917b159837dac7bc53f11cbbcb446f825b7fc255fc515f6ec9893ea6df97edc85dfdb7297e19f38a9bc699513b31e84803e8439ea18b7779ed9b884121205c93ea14c395394638005e383ceb364468a2610d03643281ca263ddd75221a86c3db3fe453af50b2b264476d38889e22407052f53d7f7d180ab9ff1767ea8153edacee76ceee7b66949cf3dd6ec9e30f9f84a7971c7ffe36ffc9dec78dac7d39fb7cfb264367cc397f62d1992ee22a8f2f04b4e3ce763ddcd8f620f7813c3ba12163a72cabe8c5f3bed91e7e112f9b1f4ea6eae0df33948f62cafe6ab02e9c402e9024ae8e60649784da3000986a42359b55b51d44581e83c9f8c4226a9ab5733d2ddc00520382a71e1702c84af266196eb8c621459d52faca53056a307a7bcd9c9b3b54e3fb67fdfd6178fedff3962323ee0375ec5876ed6ff7b2e0ed4ebb16617aec13e0c6c75cc811d9ea567fdb62870eab0508f61601b8b60943e6152fef7583b75f6f9e3ef1fe779f4473fccf3b0c73d0e6775f0932da4bd7aaf73fe6bdf0a4f58aa4d5e9e03d7b87bb3c9dda3e37fe64f0cf77d7f9c026dc937b8bd12786c81769229ffe3ac7b5d77a9dcaf0e7686287e7f87e3ee0af9c9e7f18ed8040ff47d3d4e5c7617728832cdeb2492533b72ccc183af35967f904953741b65a4f07c7b2ef86cb0341dcdd55044a7b4c5b43199622537377bd7c7f3a423ae4f65931483bda768c3ba118e26e68e67a9cecb4ad069dab0c00e05b5d7b1863fe710fd966c6baa05ef7333dfc3555e41d7c6565ef798bca3bff4fa737dc4865d26df563ec9620d642bde9454c3392bd4635428d32d99b744a389dbd96bdfaa0c02884e3870c34c2d3d34db518e96cc1788d16118022216ba0359514d7dea42420d9f70a428533317e47ba21953dab17b91039d5e22df7e661ffd3336b48eabb820fd9e25450a5ee383bfa7079b6a1190342c1ae57ce5638faf84517f33666f9fbdae77ad4fe35ce69f01543a79d58ae0a6a1edef07ea63144256f1929050232ed3d38d1b88b16c6b448bb071fcb09519e9225ecf9352eca21ccc488942394989c7c426f453169b77465248e698b662606448b4311680fce201dab2b31c535ff9674f7da6409ae8f81566f34fb56c1f79c09e319157e6877dd3cf401ff53e64c81bf31bf5cc3d8ee96d6deea5754c781b43e32b5feef8de57880dc4d6f05178c7737718b7d70bdef7eb981c0f4c9d4e3971861e449eeee61a892440634ed19214c3494453e2f8773fade1df2fb28b7328c7f7086c75c28e7eb596578bb31cd7123cb57ceddeacebabf99c6a082f58636d2fa62af4011ead1029f87a0893a29978bea4921ac4f32964ba73c59c18a862aeb2f76bf8aaf6fd52b9ba939c1c5b2e4fbfca6f9ee9adf133bb671beb2c17815071498ef53f6fe7511fedd7cb625fd254a5b0ecc80d462e53eec061a3910fd39a71dc2c4db58cf4d13e6652b901c62eaff64eceac98821de78ece38fbe5d019740a0dba9ce42b333162206cc652c3a54d204c44e5b4428223dfe7e96439c1d902fe44b6a27bf964a31fb976bb8f9cacac3a9dedff599ef8b22ebc67bdacebb19bbd6efc0a6f772dcee60fe31e6dacde77eff9c30fe36a3fe26a66b647287613b8d1a380ee56d60cc45a2d421d5b1ec2fbc414cbb8c4f78b8eb63e1094e6f51a4f2b17f3e1239f4a4e32fc8b15a066d670196ac38268ce830b6c33b1c4620128584e48e1f3a45ba26ae6428462b33e67df7ee5873cbdeb4b5fa1b2f7171ff1dfe74df49fddef23a7465ca05a7c91473bc357f143bbe9f598bd9c3d9d8bbe97d18947dfbde86e0b7368cc3b3c922ce942dfd6fdc28e3c53019f557b66e132ca25f011dd496a3b0b9dad435059cb836d9d93ddd21205367f0f564cec31b50bc76205ed5240f850c41d6bb029061812b1a4c39252190a0d75f4885bf9fe5d0b9e30d35fddb53ec6dd5dedaebd8cfbfaae3dc7ce4e3d80ba8bee5a802ab7a81e12cbc6bef97be7997bb89ce60fb175a725fecdceef10e6b9b877941d6275b7f320c0a1ef3c08ad321d7df3c074693bacfa45ccd44874d178a6f41d085c5c805fb11a65913e0ae32069e23c3742adba5f31fb432c312cd4e327f7ebf9fd8eeb6557f1b1a7c80fee86fd95efd99fd56b6038fab997cecb3e95cee12e5cc27f75ac25f16a9630b2c1565df222d951d84c6521d6ab9ccc124b7ad2972397a1db988386e6e93c2ed30d5595ed6ab5c5986b38dc6e59912efdd2054b136306a841a7781c9661474d32e18acd4225069292ca9bd8b5fc9853de255352c5d048fb1aa1bfc8d11dfb94e597f24e6731ecf3744abce4e7bfc35131b8cabdeb73562c7f8b1538f7fdb17e7c7959eed5a274a0f9cc2e24ad9467857aa8d96b370773a2d28d07b09978db36d27aeee86dccecb12c302439056e3e6b3c542df894f824473eb1d23c9e6e8c553e14524f374bab318565c098825be1fd7ec01ce7b1c6ce724d7fd9ffcd62db3050efd6ff66fdbf4f3c497f8bcff26e7ee25fec620ed283fdf5554f367c8cf55c43d7d5314787b53ac5cb5f7df6c347677da99d43755690d6cbc5a357c81d9ea6f7499eeed9b402ce54b51e1a4d3d0ef2040273e9b328b6a4a01a4ba31c3d3a79b558e56443107149a71e5c459428c06d98ef5bd90e1f0564515ca86dd4d6b72c5313d2e11c03f6b126f7fb7b74295f73df33efe073c5a55b0b0e2a39fd7aaf7afd75953ab0619d1cfc406e680bceea28209a086627797c6e5e87fb7b3187ac2726b813be20eebaeefc0e51a9a3282a7146031b24e5085153157e77b35b31f548a17ac4cadc25b9dbc57408a4994216d81397a773c9675d92e57b498df51c6044351b107f44381f8e97fe48084ba4728abd2feac4be776f0a9cca1e53fb150fe2cdf57c8597314f7bf082d55df83717f9088ea7b51e6c5ac777760c568598b0db380766c82b203ac4dc8278cee77ef837d7495442c75aacdbdfc8e9df5c27660d8d22e2b293d6b07db6a75fcd63e1d3cbfd298eb0a78f5a01b780f374ec976ae6646c1365a94e74b79d6b2e7014d61d4a3c9aab5f09b5757f7ad3726e1a311535f7d3059d0a28a7a28e0b7340f594d34ccd7db6d122bdc264120efc6cd6caa24969397a10545c50fbff1dfd33d416c1a88df59b977a81f77d4c0fcfe9761a425648beaf45f98693eb437e2ee6e84178208f82d9a735ea921b55123075d4f327bcda9fb9e2f4830d273c5044bc510bfec4f5f95ce37deedf0c8495d43d270a27d573de7bfca157debf848b1aee22a8be3aeffbde4ebeca791f3e449c9e6442fff7134fec65b1765eca9614f5d42b5346338c3c3e0ca5f9fb61c504c29942612617b1a506618194cb64e12a345e0682279af1b880bf1f7890c025976306b04fccede0703f2835727f5deb244b7f11da140e24965fec77919e3eb0bfea837973710fd3a77d890af455efcbebc5a4fbfd60f7e1b3de7cfe5cf7b6ce85313b3f481e424e325156eecac2aea0f98383e4562abb4dd6bfbbd894dcef466b324900d5d31067778dc3f180c2bb86417bb09ac801cfeda9d721c54a628a4c74919fb6a2b3b79165b0a8c4dc3781e573b1a6b902f28bfe78dfb2610e3237605ac4f7f5d77d27cf60cf7fa82f9382d63220553c06d5b136e4fd7797f25599b5b4c2865155265c41529a8d0890b64208c726ca1963a68428fbdbf57acfd3fa2ff06dbf19b3b7cb757b97e84e1d067679ecdf77312616b84ca805b44b3f4fb7d422ae739023083f3893142c83d1c8cbe4ce09ee76120922d19d8e810b5645b3e13c05521b061289076ada489a692ef31084baa92d91f825289e629e37ab7ca00984b2e574a4fb48b57d8ddd77f8bc75db48a664b708ec83efb38b9f7b947dab57df35700ced2a1869710bdabe3739d4eae79ce071edff34bffaa4332f8bf367681f9bca74f4dc48d6c32db55218d14d23753b4ccc46ad18b389862247e199af14251ced633fd92d4dd388f3c68d75055979d3d17cbb236c64257c00228dfd8a4b1508a022bfc49e444a784cae254d06de253d35ffb1fa23a29e38793fbf3f57a937ca0547c79ae9d3b897f612773c300a0394513ad385553f322a2cc2b123201098926998cb6c6525df3adfc2626bc9bf3acbeea3d35ec32f212a2c597f6e4fe3d6c79e2597d91ec21a2209098c7de2ba902db0b9eda8424b47551327b705a376ba9a4ac765f6246155edf34a23d9c136477347d96b679aee59d1ec88b21f5d6d684a1ddd2753f9e8f2611a77642f78b35c5afb8ee6552e335c52f5131c36e89ee5c03bfec61fe248fe8ce72a474a04f6bb3c3dc62220e919dbe83cf6f3236fdcb938e4ab675e71be7df78ec1619d4c6d75d0156febc8bea8fb6caf2147ff38fec1d6cac5b1b77fcf77fd36677d1cff82bb597a80e43eaf728f0e91ccc4dca3d8e45cb57222e74237bb8576cd3ace0b72d63fcb8d5ddab328179ced179c3592a3edd7b6f3cd23fe7bbfe6cd9827f9a292315049c0d278ac9dc6b9aca730b594272058bb01a91d6e765e891f7d1317783df47d4b8421ac0c3f637069ee1b86d25fc2c4b537b5432f239bd5b82e593bd41da626211ce8ab2c2dbd92f81125a34455130194161668e700d4f896b6f333e45fb7ee1fa7b1b5ef71aee2f33a6e95b4a014815b4701514981b417beec9fd48c9ced8777b01541cc9f7010cf75a3da59acad850e3efd2e2c2a15eaeea775a687e7df721b9c9f7314e023d7b5f73a9e40dfcff569cc93eff1fc7b1fe61943fb5ef4fd93fbfab04fc77e7eb6405d024ffd599fb1f91ffa091cb9d1a6378fc9d4de496bd8f3772e0ab10db9ec5eeef639ce7e5c098bd63d275761a8f8cdbe3b1f79f12c9545e323879f18837dd2f71c20952cded4f67eeca10bd32a8477476e758b653d9678fde919781aeb2defb8f747bcd87f55add15b59728e8fe9d5d9fab23e91fe75acfd65bc830da9ba23477b7eb2f7e965185b33bd8f4cd23a102fdd7cbb77cb2a67b4f2294aa3b824840577bb38909876cc931d1961d8b85e96efb929477e276c0a6e76828d4cbf643b672a36091d46ccab1999b0790c87b9d4f0c8e5c38872b723051b79fae718db0bf4cb405aec28db3ec7ab5ea557cdd319e879618ff584efe6a1ed173d07cf453ac6f1b574e0d1614a91ca3dab99d3924c2817a6c744242da12f7456f8fedd43a2c43dce5c83e66ab62a70bdd0c55402e4715368381fba095516d371eda814f981bdf428d31898413cc5c2a10df234b79539bafd276a41cfc44ebf650f8a60548bc02ebfc2ce1cf962ff9e9bbcdf430ba8a490ead94678faecbb97f3d8533177002b3d9f941edf3f50338d629f7611343ac9b09598f421ce99ef0733ddf7095c3294096da6d32eec3cb8d961251b9f2b8bd26aefe6b65865c895e32dc4851d25e8a6a3be74569cee7df8dbf0d96841f899deecdff61f6e3ed6847c4ff6152298d5d2faddf7448c7becf277b04ece35f6ebccd847bf5914ac5d0464d7e3e10aa3d7d9a7712f927f8ea97c611a3b19e099541575725691a28904ab469e6933a9f020a675278198101e0e2294e81e9025e948ba34012701dd3940ac71c902ce87bf225819f1544d5616dd7bb96d47cc1e3bbce278c27cdc8d0276d697bc54fe89aae7e298dabbc462adb4cee471fec13d399cb7637e68a4929254a77a8f3fccebc4a5d45ec6f3ef07a8e0b4be778ac659150453180e78ae22e20df91c5460e5d563a1b9506426c4161d789dad6348cab81c2ddcc01e138bb504a8bdefbbd0634a84b07a8c2071fd1cdc536b6bb8bee0249f0de61df63dd884d7e5647ec6f8bfe61c39fa63fe1fed9ccbf2193fb8c7474ccf77fa405c455f9ec67bbaafea51f0a7bafb4b7a122ae114f62f5990409876e56b8cc4d391457319e109eb4439dafb7f592b751e6ff36ff42b242ab690715897c31a0a8eea935e7a3f9fcbd7cdc7bf9222adc34069f3ce6908c54d52c82e99902ad4edb9afa79ba8fbb92ec1ef7048df915bb1ee1e65c3d75cd357c1a4bcca63f7f2e9657c0dfc007b427c3f6d1cbd32854f07d114b184576dc8d06d1c5491431bdb9b289f013467d6c1dec2336cd573a71812993751d4492f54289425317ddf0e496076a2940f2c53135717d09b10c7f54723b6ae7742139d9b6bed7565923adbfbeedfce771ff624e2f2f11b188ffd95f2aa79ac934ac0c399a0a773f0fcb93e62242fcbab322aa704c882420464805396579379971602840fbe12d055e9830b48cdca504fe016c6c5f09ea02a9225bb65d498b220dff362abb16034a37d4d22b9a7dde83e316d3dd4d044e6779ae0c34296ea975b608f5cb7eeba8eb8519d7af3bcc662fcb1c7d51ff0c2a7357c92777615af872fdf5d281b6430da8a205549f655cef7e6633ce667b2172456a356166b8ff587af3f6bfb635dc1f773bd18ca9930d385d47eef9753315bc0198c0a91b9f0f720ecc8c83787f65fda7d2ae6c3fb6ff3f5b71f623e3f93a16fb9b70ff7e7dd3c4eb51317d977602235dba139b30f3e8e54ca72b351b0623694306d301d80848d3661275c9f57262e6c21a0b46233073c50a680fb07672a0689cfb867d9d8d744e35b891e59225815002c910b7886480cc52666c48e4ca57de1f77ec35f3df8f86027d6dfb711f055faf67d18f7b807855bc7307cb11bfce37817f9af5e0d6487aa385733a6462486884b9afea2a50ac564d6441ce339c48f724226abdc05894a1efcdc6924ac6e19c3d4d79d0766519de4438835b4f1330969a7060b38b4573c75e884b93443b3b93eda508a66d2679fd7b55f88538ba191899718a276790c82750b8efa1adb907fc93779f0630657b14b02a70e79df17250df53e96a49216a461cfeb8c32d9f746ebc7ba0cef6356bfbc4ee244a1748988ef5855ea9449c7a9e1ac142bbd1c4fa9455c1f84cd8a092882eade2f0c7f3951e61c08cf99dc3d50bdd29c02fc72801a3b39c9a2f6f783ec982672d52c80bd63145909ade644d3dad5d9fae71feba5d7fc5c9f734b064e1f1348a6761573a545817895f37acf6570554eac73fc249b307893d3f850731859a85b04d888b9bd8bdfe63fcee6337aaeb4631fce9767cfd4321e9e8d0b5686c7987dbd2a581bbfc14b9ecdc5bce88f57b1f733cfbdc2b93ccf17fc390fa21e137df4265fb33c53cffe0fe64d9ee6fb366f529236e240bd3b531ff239cf989af2e02f90ddb1879ca125853ac8d834293ffff7921beb58bffbc399bc4a1ef6bfbc0fe94196f69c9e95b4581b06e423aee06c4cea0a71dd9e9fa7bfb39a08ec545ac3be5ee4ecf747accd65715eaf3699f97b4080d2c31c4c24b40d09ab2a0e64e4d374bf3411e02cbda59d3de7b9086298b72e6f5c1f389de0f6a3477343b6c3a53f1d2d7949465833f79c3629cb893ed77eeb9e2626820f6d96c95b3a1518c3f4aa7af23df7e22b8eda7772f2b87f717f678c2ee2cea7fdbc3f916b67f2af277ce0e12e96e4554cec4c8f9cde570569327e2dcbcecb2811b82f7defff941f7edb4bbcf98839388e79caa3bdfe3df0ffd67dfbbfdce47f383779b0e3b4b87d9f4bff2296b8be06b68e757d3e24181df45d252d058ff52ce7bed74e76d265f12f571b6e634b465e4952c67f1b3157c22db0e3c294328e667e51cd49865d1e380d2b544e267224a14251861e78902e044334d489e372f6cba5c31966d582e6777bd1d9b600a3479cd7ba9b119b4dd28a9623785dbefb834cc1696c353de7d06bf983cfca1f924a8bd64f36c81bb97946763ccbc1f1b7f8537f1eebff877a0cc656b509037b7d61dc462510a77d1f46384cbfcc0bae3fd8cf3fd4f7380b0fb61d97bb3038f94f6fe6a19df8912eca390d163ab323cb9e3abe3d4960653879855827cd65309a85a5ad422652da0e6f1373d0ad387e5c0502c588e452d3409c8929f745800bda7a6ca4622e2001956214343c53a34587a7095591cfe522ceed8d1b24bb0be2bbff5c3cf6d803f72b4ee6ee4a5c41aff1134f7f3ff501bb2c062b8aaa91d4014b8e4dac6183750224b9117addc8724b5644a0ca62a8a6a4bbdb4b40009db27b3ea18663e13166448bad41eb98b46574a6d17618b8cce6094f435188289ed88e5f487f0e251168647b5cd5e7f9682ed20d45c851d7f7e00e6c1097a48af957bae1e6115f05772dd230700e9feba4648fd25227ee9073df6bfb45965caa1bc649ae5c8c98264c7ceb433009d9dd2ed6d89ee443d7c988e771bb8a209ab8ca1c785ca52213519c516dded68f1120b62c73e84d55b82ae983d3b16e35211de5648ca7c980740450538c56f9701f2146a2c29e9fd30d5fdbc17dafca4ff9d63e72369d9e3d635bbeae473fe987333d498e737baa2ff8b3cd2bd244279528f39798fc7bdc73cfcb26545234bb901f7359f223feee1cdf6ff3cc07bc1e189fe47dd6111f9ce3143f734efadf3b3c7fe4f22baa4bfbd2166180b505ef71d9f9b1df465ebfae23ff563dd3df6387bf9c47ef4b16a89363d0e3c485456b19d8d5e28819dfc587b3323ed53d5d766f020fca058309108c0da4b223a2cb60690a280a3bf52672c411de380576e61dbec75c60a257cca778c0347bee40c21d68ea4cdf0c56be5d2c74461c8b766e2682c33a9309ded18e6a9122644953ce4c658b6fd63dbdbcefb7b1dcdd11e771bdfd10c14d2d020442be3fe88b73dfd747cee0cb303f22c30df5d58e06b91165f628326db5d0ee0c963b86134827a6f5d8d5305b4069fad058f83912a4639b4497b758b31d0f6ef64b9a6698a6c22f3746a8497bded683783a325d4d95c4429544a2732678c4d06c80d177f98e0e32c0ada312efe235e8a475eae572f25f232e8c6fd5a2fe7d8dd269adab2e86833efe75b0999f6bb2a12a5627fdf1d57c4fbc8a17f6ce6f36623cec7b1b455d3ef050b56326d66224da90a69a28ee0047aa8a72751ff2260ce1564f206272cad2586173451bbcb28c59847048289927341d9089ac13301b90c908b81034b155eb518ef9729a42a9a5faadafadbf2fb39ed7e5827d49ae51e7f0c7f15fc9a8fb040e1fdfee95761aff22d9c45dd808bfa8ddb893da8a55ad63da3851769014c8f419994b58cd7041ec90a6d902ce766ea146186d5a3f180d12b38edc926a98a307cec4dab1c82d2b2509f3b075ca8af91c6c8495340c562de3d52f970eda9f70e584bc82af74ef39ddd7cbb098b3f6a5cfd9993ea8bd2f22f257b1fe4f7bd92750d5116fd257f265f5c40bfef73e9fb9ff091fdd69ff5bc1497a8cc37fd94fef2ab6e541062405cb438e5febcaa7799cecfb0b7b2902b58f332216ba4863d3317c4e5a8fe1124fa4c6f3e19e537b1903127a50d22595829b62ef99835da49495b4f5961cce2d541df76a27d4ec5b629105cb8158fa62c4a6155c953890eb1ad1f6b7e6410044f9c1beff3efef9d27a82e3fa742117ef64ea776274c9dffbcf7f1cff45a6271015e2b996581eecd2530c2fb90c2b13901ae7385f29f701976947ac6d1bfba98f4be62c9198ad4c43f77c31977cf6207cb5e48c642e079d93a57439217b66992da6724e596844d968c2fdd1d2096cbcb4d2059ede41a1db7b92d963cac307a7443acb2fd1b54ff6f617f7a4eff7771dd9fd46565bbd6c3ed84df0e21a580d6f4396ba2e481efc89a825c306d1ec88317bea42a23c138cb04e00c99bb5efe35f2ea81e45ae14cf878f11149388564daca4bb0a58e3ae7fef3c8e26a493b3d8aca184366653b6102529431fdf4bbe6f4f36cc6531b77cf4f2ce10ddcb9ea714eca3832e5d7f5a9376f3b23ec37d520c072b0fa4c2224f7ed61ffafdbde4f217bcd909285fe52fcfd4e31ff4472060c47fbff4bf3cc35df367bdfa9c9f0067f2132fefce599b14cf7dfef7676bb75efcbf5a42d4c6afb96fc66775511171235f70602c0299bed5411f9f8d2da41dd6e63d16f9dd73db88cb8d1c837af5ae0fe74c0d8efdbc3fd49c8daab8f8fdd283fa7d2cfb28a352f1ca36141cd52ffbf89effb1d74385b03eafbf4b20cb6460ab675bc842ed4b4fcaf37b9d40561fecb2d3d87abf0fef736025a9e232afe3a90d5e9ebb4afeb639e85bbcbe18377bf61c7d8e9bbc4abfab0fe3be955b4025a5bd4bd6da69bc8b6ccb9d0bc53ed4b11917a48c73c205543686b64ef27a24f9a015e6ef076cdd0df0548c63ab0e12201f57ebe12da35b8316ac101963a4185af164a639414a23da280fc970a10bb60caa0782449830c55656752bb534eb63addff57b8fefa78781fd78a6eef0cc7abfbf177fb9de814c93c238c8ae67bff7ddf7f549265ca433920e21ca2570cb64b70c90167668bf0092729fa8c45781cf6cdba5f8215ad73366e15b8f6e9b880f349f8520a422a5d431788e6d3919e55e26f749c6d61e0fb5188df6de548c24ba695781dc33d328934e6e92233ee8bbbab8f906feeabd7dff73fb676a3eaf6dd2e7c3fadfbeb01f20cb56a533109a72c9d4e6071b87f0bae3d4ce64306afc400da896867c6acf7cadf1689932673d34238ef972920c961478aeb2bde5b89e859d0d985e31198c6e938e08da91f92ab76bb74cef0f7eaa5ba6e68f38d14b5bc900bf8a2b9a1fb0bedf9141116fb6478e19f9156e5bbf565ceef59847d9a3b6f1b8e7c1298577c29d5e26771a1ffe36c8bace7dc66ab7b39d10ce34b7b0b92c8c8557a6945ad524f66a8f9623852d694a2adb55513b1802c48afd4e5895a03a6d7d4888a346a9d3ddb47e467609af7dd1a92ac9c47d489bc0cb6c4681d85f15c35ff63c3f4a403678bd17333578e243fc5b1d7569cfe18f36c8e7759c57babfea511c6d143d0cf2fe1ebf9d8776ec1f78597d077373d7c026c8fd4e646e9143e2e73a37cdbdc8edd1921b7a12240f2b3301ab09a29c2ad73bd8549dd3098d550b582f9320d75d25672e93832542331720421566989141d88de61175077159ad43df31842ef0b9b3f12537e39771e84febf0cfc5505ff20defb9d37b9ba9f7038f98c1c9ec5bf6d5c1467eaaef7865ef5ec17ebad4cf6e5239c5da37706887b5ba028f9cd88601e9e4b4e7ef7bb6b94f7d4f9aef73c7f5f9686da5460332551b5757959fd9ba479146b5c6c685cc9693d98ef0aae185d3c4d0b0b1097e2de07e9f20d9babce92814c21bff6e79ae32e6d5ca81c391534a5342fb97c7e4d2d365ea64d85a4eed0d5ed72655f2e1bb9c68e2600b72961eeb47bea8d568afc1c72f76c91aa890e3cd510f3c8f7fb083ba4be3ff518984c89b3d8660b70c84bd62a8584ed503eb6c8835f3c1c9071ae5957221b3b1579bab4c8549812abf439580838113c8fb88dee9a4981952e15ba60b2272438b194eb179d7d26248d8d46eb9a5a0402c8aaf8b93ae9216f458e9630fedd779bf4b7b718bc39a7f631f671fb1bf3fddc7e378c7fba1dbc73d3df62c0117702c4de61d19316a5732c035416887b33b8879732f4c44c3124f31dffe65bdc761ae5acf45137e1d97bb4a4fb4c3b98e3d908701499fcef9f3677fd6f720bd2c8fa2b50e1d744c1bd68432460bf980f39941b4e696f8c4934cde92226c9766b38926aa214029bf68a6894f3841298bcdca704ab2714abc7573832d4db95f9aec576c0d05cf8755a8aa39d65d2038b6935cf8913acb43fc651fd044578f21acab67dd353ed672bcd35d7fe84bf06cd3c28f9cc3aa16de91732679c1c537bdacbf0a87fedbdff98ebd14eb761d71f28c41fbdcdf995d0373f366cce773c5557e941f272ce045ba09f0a5259dd8db6a0ecd774bab2e2533b505fcdd9009f63c9a7a314f05c9132db18ce58a0f1f65c9d279e7ee93126584038ac735c71d3242b6e9dccc05584fd761212789868b486137f24320bd61804bb170180517d8d197f2053dc42d2822ef88899353f61817f821d67afed753cf01d5f5fb525e2c5fbb457938a7cdfe7bfc9257e1672d92d6680547db630fda3ea6ff661e277be4124e3b8b32ac790a6356548bc4345bc71a3e4693b47315f2624661d4bdef7577b1bced9e7a967d9d4b7d1fb7fbe13a3df7b53daed173cfb4833e6a2fac1108d22aa180d08c0c5cce666ccac6cb8005b1571744d9994787a5a7d938a2c3311dd78a5bca6013799f40c95ddd6cc2a2e62b2e356732dab90cefa436d309275a620e672147aed06a6d39315b3a5169b8ae4d62d61770bea769a2a9c74427696c357ea8db553275cfda1f2f7d1ff77ff8ffbd9d1ebfc337a54929abf8551e2cf8818d1f6477c75ccb78f4fb7fc7a395e3df3cf6f1d269f37b36190c1dff63ff93efc85cc98d1346eaa506e24b9ed72bc42fde8fdbcbde923d863a39d80e276ebe133fca65710cc3e343e80615e613d748b470c0f91e2c2de1bb40ce718021d51a1072b5a6d334a4b4b27c0b8c7d68534971eb98a070685d516bb8279a66f885b2a2420937c707ff327572b1c185dd0a6642971a9c99f9defd6efcf45ceddc97354057b09d3e8c7bb8d31fea594e1c4197e6a265941406f77db7a51457849aadc79326cc93c1aaa8761e05b7424f0309d48470b6145329b0227001f12d856c9a5878c72764cfcdb4f0001bf879cd630db57169a324b3d532c06d9ca3c1ca947652207fc97ec2377b598d6364a1b7bc34edfb7c549a262de8561cac63d874eff0efffad78f49ec7f2758ee9937bae5d092bf566ccfe8e1fcee24b9faa9fc4a2a63e471a36d91cfb2674786daf7c7b2602e1c4d399164fd932caed5216e01e4fccce8388b8bebc9713c297e64ca339e944399a459d0ca8afa6ac44050f94b19aa4b7b41d3a38138b58bf7b48f2caf38b7aeb9b5bfdaadca3e508c4c1cddb3e1f7fcf7f7ca1ed25b7319c7de1d7f6f95efdeffdda7eac834f5bc6d670bdf08fbf7b1997dc109289427e59b9be652ba1b165ac948b196322afec28b0a9e8dc073e95986932a55c1086f2bd57b0c795694099ab059d60e6b443cd65c8a7a6020bd8cc56281514547582d22da3a94a28b28559ff72f3e6aa3586a2741efbf33e1da5d2ba7bed977dac1be446115baa8ca69fd7d446dcd888e0b056cec9cf7e2fa3401517aa0e039245e3d73d5fdc0fbcae71f19a17f91c776a3fef3a3ad5e6c7b001d2a26fdfe3efcef0fdbf504b582510a5a17ea99fd29fdf3e87fe0ddc35b8122fcff1ae04a334e9e3d6bdbe7e338fbef7d2a5b5ba14dd7a5cfa946295586ace03e93a1af2e25c0ee61de3b122c0c9d331e7e457984b174f98f2a74923cb59b7ca679d54952302a5c404756ea7367161673e748c05c0ad1f1c1c20dba581fd40f48d1632c7e0c550bfe63deaf98f61b30bd7d7c614fe447eda693c0679147cd9c7f35ab8e3fe4c847c5f0b4bb547bfeced3c7e8427a6608a8b3af701db2cf4741c976ab7e4784e0a667bb07608771a37505672b0ef186118a5159fd026f2ed25e164e04f538781d48e72761f07682118061e98e98989a248918631b163137bed14295821e108a0ae2a5b236e54cfb5a2ed40ff7b5d7af7cf732debb88a0bd29f81a448c1a5fd63051c7e25878c23dfee15cedc9183e5f067bdf47abee08bfc039a49c5f491c6a76cca83548f78d53916e3733dece22e7ce0e65de305887b5d9a7bf910098e8950a48ea091c94e8d5846f2504f76c44a07919f6261350d9d92cd6a9aee79a9aa550e7ead7832a08ad424c0d339b8a067cad7f1d79be4e09b4f7bbba78da687bbffcc5979903de762b137895ed5616067ab023d2ce04137ddd47d5d50f0863bfe4ccd14ca228b9dea096c95044c25cf9c21e1597b4158acc70df63d1b5a70d8e3fe9c3de73eda0f7c81fd9abce5143bfcfe19eeb027be97677bfd35c7c887dfdcc6ba544981d304d23a82cc483ee7beaf230eaaf0dc9ccf3fbfef6b940bac3ef0bf9ceb9567fdae3fc1d69d89273ef961601f0676273cb00d83bb2bdbe97717f75afbd847f08b5e34eb77b1fe9fd9ec6dc8b11225db2eb8e87abfeded3cea23ef7478912c881579f432da2ea7a37512a422e4c62631894860aed1c21df814a990da239c250f546d1ac7c4d8e15a172a3262b940c4c239a608b83e49b14a00e7f59467a8f2553a5ba9ead712b99099f6c2b7d85852a38dcec60a2eaa4b3df1177dc9777a853c6e9a1e75fae1cf53bddc65bc71855310e87723ce7c712bf846a7451d78b96c054fefc3b2c22eafac6442772cafdd64c234361d051e0b352f4f673cdf360bcd1e84b9f0a415ee12a8468ec201b3e87ec9714a2cc0255262a524f2b83da61df975ce2ffeda177a1fe37bcb1f751d4e808be3a0877daec3001b71e1d49135dc45fab7f6fd0a3cb77d2ce998e76bc12686c3879773f0fefb1ff58f13241b716acafb484f5bac2163c510f14bf5c027e92faf23ae2c092253ccbc1cb949208133118c949b26b6669004c2c63eeea87507bc097a607a5a2e4d23f47ce62450782ed80c24bb33fca2160455e3703dacbf8b95e83972b85d09a84ef5c45faef7156a72fa755d475c567d3ea3d5decfe3c4277c591cd447784c3bdb890a7be92a52e06c36c05a85c29cfd9279558a923c908c35a4a86b17fe3622937889897e7930653e6ce673980e9616c931627ed2ddec29941da3861e762e747c395ff2bac24c6984e2adefdb85c82fb073fee37c3cfd9a17b185bec20b6b57caf3f5f759144d2a5eee523f7edfcbe082fcded1476246a4557401ccc6831565106bc974547a149542e15b674a16ac6411e3d54668a0757cf9903002620ab6384785cc30f218de0a46f584556c550c43620aead29412d3d1fc7cb823ed305a21da91406c7d36fae823fd63fdfd3ec6b2bfccc3fe7d7ca3df9f445775580cb7afe4ddf33c4e79d8cbe21b1c6fb865eacbc07616804d9cbcdef289a947c5ef4e2a7bbaca46e9aa400109ee803465c38b0424e6efce57cc20b4e26e66eac204ad6468bbcaf1c48782c99c6d054c1721d480e3e7da5cb327b41495a36cb8d0e4c7f8c6451809f7bfb6afcf91bf4ca549f19ef3e00cfee93d57c4cfe5b21106f6e3b34c3e8e7feaef7b99dfc90234a625aab055010cdc07364553bf208d4b7fefa9857c96cb8e9872cea84d64b1350463819f4b8ffb68427269ae94daf848ee7c5fce29652ae6c6562a91c9f550100e32a7944bd6a563b79b69841b2cf9821feb5fbacb79b2069bc3fac6bd0daf1dd6f73b1c5bd7d8bf7363ef16de7023a6b33ab25427ad619914a8ee795efce3b897ddefbb3d6764e76558491d7521db74712e28b34c28cce6964c649704770f84cbdceddc071fe2f9920e01d6ab88580d75a638a46034f3a6b32ed4958a15eae81435a112330207bb58130297d5bdc8d9829b12ae0a702e56f555cc601d0658e1cc3dadfd3347e9474cb0851ee2f66d1fb2bfddefc4626d087b1e92c33dee39babe8e4f5ea526e1e33e0723951cfcf59254fd7c7b8efd5ed67f6bde27ece365b83e86c6b2b0e90a8db64497b32873a0c76ccbf145e85b87bb6b339931410275eb74772082ca774ce53bdd5de770915140961c110f77778095c4226ad3863c15b873ba55367a58f9e95c6624c7b97a9c03dccd75f9933372f64efc9113f53bf2faa00bc6200b39de080f748283f4b0eee1977ecc19ae9f9fddff3ece758c61d13a81ac0eb9a1451c1f6dec3fcfaf3ec5932e92ef21442db5ea6d08d80603fb96017b81350c9d4c7a744af208a90d0bb08a2d732739050b582d5645a50410909ba4f17ddbf64d6a50df1e1338303c55cda3092a97139925130a139dee482109d5ab8c0167107e1157fc8e8f79b8437d4ea7c42a5983fb2ffb128d07e01a3cf5a7b53fc6b582d9b35cfe381fade7a1bc30eea06198decb82158b8ecd08ddea54492a10fbc514dbc493f457a43130d79a6d48e9de63ea9730019085ed134bed57a6ed25e6f01123b6915d1aad289b106e0e9c495a31e50eb889ef57c56fb8b2809013328968137d97a7279aaabd08eceacbbe3eebebd4debc8cd7cb38e320d322eefec87e09014e23980e42c5ba902a90f0aa90a5c858c0603c1e5af1c4d19c7c03719096bed98844a90105b85d06a8f6d643e4e5db07daa559a21c1853b5a5dcdd85beace660a4b0e9ee7d2efda42411359b5fc2ab53f7acfdf21596818188bbcf31527c2e0e1bb04a3cc754dff2705da8eb9ed673f7e1ffe94ff3f89cabe0c3fc7e22e78e631dee0f905ce50bfff8bb97f993e93dd588273b51f29c022f07a58058f34c3b8b9448a3ee6630d76ac48ad4f7b83257b9786413e52f39520282fd72c2fc05b43d416dceac994619b142662f9329992f790d3847cbc832d67ece6e23682fc2f5f02cf63c29581606e449c7bbb1c5d204d23b198c0e3a2917decd9db47edfbdd80b37facc1ab6332bad044c55b21edccdcce1b6e7789b3edd29a39b59205d792370f82dbfefe76e3cf5e7dfccbd5115af4799086c2de4ea7166e12a29308803ac85dcc844e06c6753b98938decc2cd5cdacfa31d6e5e36c4a7633cb56b3e9a88da1bd3de80f69a96cb1beb9a390a999f5b27732bb7b1416830b686f6398ece27e0ee0690e77a238bc0351d242553c751edfde49bb8a3ff6fc3e9de3175eb7d3e7cb74f4a9b7cf82db465f675620104fbf3ab7d78a7ba9323ed8691e58af3c900b2e52c99b9e93e60ff3ba340ed62c18c6c99464b2b0a771170edc00a50edd821892164f482568ad7fe8ab75613fb28883be3ffb8237e9ea4b7e926bf9a6aa4eac612bc7601b0695715cb337f3b854c6370b6a07311dba8ca57654fc6ee6d0887cb31973461e4529b7528d1e3eedddf6eff42bafe280b587ff0efe78f4753fd9e61dbee8677a9403901487ffd23439d643bd9bc7e53d8822985638c06d0487bba850036a618aa1d93a2c5daf2860ccab77d7f7df6f1e97e341b3f42e9513af31605fca862be4fbd4a3289a834c3fc983e7f14f32e0db79be830c583bbcc2c212c44748f74a3127b4461e4aa0003270b85d7c2a03feaecfcdb95cb79e14689f9c74b073f95ebcc2d97d590778859e46ea313ad839c12937f132fe8963cabd0c9fdd0e218128c4e3a1882db3fbffd97bb7fe447df57df805ad1302d2cf78382801516209d940ce80f814252063518157ff7cdcb4d3dd4cb5e377f35feb773675da264dee24f7e6baaf8b19b54928d21984f71c2a15d25ccfe870261db30d4a0c160a4f32b7de5356df0511da841a58f395379b6a6c1b948a10a2ee3040bb900a45222b0e8d3c470e1682d51e8da092e0528e29b54d3eeb1d3ceee79f737a25dcaccf6b591ff34edd95f853ae6619f4f61c7edf048617f8656d6655ae8b1e6e08637b6e63932ae660284156e5cb5409ea470253f761c38cb52929129906bc8c294035cf67cb2608384c70372c90de84c46e425cfa66aa6194690f9b948adf63a42eb1dbc83a72421db9672fc9fffc79cda5ce1c580877b23dc7972fbf3edbee95d8a19e6ae15835215fefb3d21bd042995981118e18c06c3240455ba48e64a2570ed559327730a07ca20780b97ea9c2acb07b5400c1141c51c3ea981def78c92c69089312d6605b0252098fdada3e28d4a3ff3e06ba8a97f0dab7f558df2d254839bbacfe791b5fa69f71d80983353ffbbbde7e76eebbb9aaceacb5215f6ba93d44d4d9ef16f604249a67a72be94df549275d1c10dae47317dd2536f33295db92e5188f863b41d0242c5a4a9cbc4d1ce96686650843b9622c1031941128d6b24a88842307f5de63a24b3b2dd4e4234eccaf6b20a03c75f66f310937d101fd97eb14d43febe117f91b37e082503febeda327fb7bfafa8c71b88e0f621faa184c01ba0f00dc841cdf2585379b730f04cc5bb1d5c31ed9b890445a3e844a8e451f3a458f4bd560a2b6828806d99e4b595dd272b021aaaeb9e38d921e3b08e64de8089b17aaceecf6c73cb2e2b983c915fa1bff7c2d2ff28f761d479e398b9e7a10fe96b8a93ff55bc16e1182537fede11d7e3f9f2fe5c8780120554a65bdd86357158b88b909c7bd20f23ed3f281743c0f01c905633035ea8a2e871532bcc2777396702048d9ea5c7970a63d7684cb843975b4205987a82a056f7dc1c40a53cd443a6824f45c7e5badd9833de7595534679d89e3fa67dd3fab417cda9be12e75589e2ec12e2e6bf5395fee077d745fb7975daab72ae683677d999f36f36e5e5fea598c555e50263798a211a3ca8a35b411f4a195dc34c2a2f532588b98db8055022cb8240be6efe2de7b14abac9d73404350db8c30266c1ca6ae55f863c89202da4207d11c7a65c66130d5411833110877b223e5dfa4057913de867f3126e19dfee3a775ed1be0325f6b233ddbe2cf7934273eeceb7876c215b4630da8396482d91ec98a462d2ae6318699d4eb38d3f39dbf2af43941205539f2955a878a51baf2b485fdb81334d390eee9a4b47752577b6a8b8617a2ca96c3392ae3166bb68e4aacfb0e800b86bdc52758d8ff5e7bb9204778131ce7d14eea9ff6517c29e6e15c4cd958768961e1606581ccc1bdb0731f03d9c9321f85a55889aa9e93121a9ce2791829ccedfaceb7154fa82c51cfeee7361b51bb21c215865f79ce546bddc04031b2453277f12a5ba1a54f941f83ba45b77dd3564908eab414bb732dbbfb3d3fecc7b9f69ffb76d257ff827eca9107ea94d33edbc3e73c456f7b39bea8f17798fb31cf7ece75d0532cfc6e3e5a77e2f7bdcacfd503e295892e5a3ff24ac160925479c78bda1591b72736a221f4e6987a35d5e55692ef9b54f754585990c23a647cb80b1dd92751ad2faa78cfcb7a2ab5e19dafab28a479115698336dbd930e08b215b2fd95bdbbadce5c9e67bfc6bbfcebee0ee1404d8457f840b7c9ffbdd3d77bba53decce79c9bbd2e1f38d3271a57a2c7bd4c10cbb9b4d520eb86eb39cb0669254ae24812446ac639d6309098385ebb20e24740601deba04aca78c034b463765309e66bd22880842aa70e0b5283dde10258a4f4b6c9aad0e2de4ba6daffe6bb73f4e99f7a55ff06ddbfd7633ec5d46c209d53dff0799ccbf3f811f4a48698cf5938b77d83396212f31c8808c6719f578b6583c2dbd7a7f6b395fd36eeb92497dccfb800a9d31a09c75a3202abc39ecc226b977cdeb37dbbfc67074ac9db47a9abe210d39e35b3f6e9ab3cc7afe779c6bb5dc33db5431a98719b0e78d908c2a4ca221b90eed140abc0f47b9930f2967beaafab15661d38f6285f84f1ff73bce1f378cff7e3d1f635ed7aee630de0ded242038f982dbc940e5bec987eb0f2d6b817a36cecb5b1d6405c6290f658e31535090b76e158cc6914ef849eaf17c4dfa73d05928b5c54f974a6b54538ce4c62b7bd5f3465560e0688613f349485348fdd3677f9eaacffe4a13dc4e47fdcb3f87deb932fe01123bf49b8d94be71027b162c6cfbdea4efb991ed4fe461c6607fba8d30a69877859f0e0641f257c4cdde2c927fbd5ff9fb953afd3dd94603d588ce18fac975e4cac8de02898696842c26f7d40bd4dc00148d483c180a553fea8cb88f6b86ccd990636688cf70b86400ae13e2d72178dc53de1f50483dcca6c354f55ac519e0b1fa0282dd898f4de1de237f5dddff00bbccc43bdebc53dacdd299fc7d536d355f1a2dff8269c0cf3bf215ffeb6b7fb0bf75d131fb97c3e8d2f6f94330779f6fc8e1cfead75d7e7cac18a80daa10cee160aaf63024b648301b1c55deac81967165df075872aab8e759c30f761e097f932ee86b158e1d9ccc009d18631d5d086448221d79a257c18725bdac4aec37465b984489639d448c0c4f057d0bce2aefb57f86e69c9aaf8a44fde2c4ad6a59fe174df9f912ffb70efc77eda6f53091d6a4924d42caa55567e3be717aecb7dfad55a0fab1a4b5587315196af0a6361fbba8010a7043b1460c26c334a8ac6e34c51390e3a34168a303c4da9daf9d0def04add6780ea483d0c52379ff9142e8355d1095b28a1b70171bdb5342c458be61ebdd70efb9ff0ff0f67f76fea753cdc43dbccd19edeb4c3bf9bb3d6d155b6312702069a2a93b11a481bdb29b4ccd43603eee4774985cc44cb7b42ebc427b9450d2b67468d17d4eb10542173104f14d317259cc491b203ca885f0ed9ac47b3cc697f2476ce920a135a98357665eddbf13eb9e6fdfacb7aa68e670ba4dc539f71e1a3ee9d7ed4d7cf79c59ab864dd93effafc35c9aeef4f25411be8aa4cf44c1724a70bde92ccc11a732d45a0405924485030be50589376ae63e6d9a80fdaa9616df92ab74815effdf1778d30cf4763844360d9a9fd68c69ad449f55d27aa8eb862a3d4f15c0ed560e198d5e51c3e57c57eddd762bfa7fdbb2a577303cef60fc77e3e879283a588263ff338a79ed68bb9dc4ffd4c1ef39dd69be9031345164a019b49a2749f7a091d33149428918770a4a837843716eebd22ace018b9eb0eebed06033617f4419f430442978d42cdb367207744d8f8215c6fc44a8d8e3c4f2cd07ddbac05c75770765dbcb70f6f7575fe5dfde9eadc9b76c93b7fa3f3af7b3f9ecffecf5eb72bfb21719751ecfa3a5ac6463d58d86c4acbe13d77d07d52e1221bc3e94c6fcd6c0c1b520ef60b07dea5caebe7a3a691d45b0b005759692e0f3ef162cc62c4c5bdecad495a806d5c0a7b51892da6004a17da98d630edf3bfc236aed5d5f938f6f8ddbe75a75cf32df6edc41b7e8c1b6bf133b7ff663e5aff05fe16478c7115506f3935d40a6bb009f521983b0c890a8f656491249a80147a838cc75a4c839d2c837dac055dc67d2db4f77ba40d7f043a03a10dba39f476c8463bc2a10ab4c60e56df7798a21101224a14365824822b78e3ff52bcc1e17e15d1679814fbbd06cf57efec279da8f3f93b8f7fc6125c57c7cd18e2dc1677fe2a9f1022cda9a6223e163ab1512fa2bc485d71c7c630080bd3a19a0762067d4ad8ceb715947dce3054115a7eeba63a1b1326cc30424b42f23129dad82fed1d65b2a186652ea082212c8ce0b6fc66bfc6127cc0893c8b9099726f97bafeff1cee20d3d96579e4dbe4ad7a113dfb11877f9f63bdebf251d3de5ba50a435e3281a2f52e61b91b17ed9abade7dc0e16ca6815c12b6419cc519513f7c82c719f4a8a870ebbb961556b42391e454a1247155c234ef6e31463ba41e8c3961fe6225469933d1e9ca72433deed1871a7cff564e9ac33d70d6abfd9c877d3f5bc5b7793fcebaf4cf77cfd3d727df50bfceeff72ae1d6cb1030904518fb7a2b48e53106a14835f4489dbc41fa104b8299702dc20bb0f7c3a18d75b9096d8fce6ddaf1157cf45d858433d1f118df91020ea4866b12c503c23148ed26245aed9272bfa7c4fadff40d9feebdcffa9fc277fcca7f6027276e9c9f7672fefa6427da75fda6fe2e00d628a34d9456a2888dbc0d290c17aeba4fc658f71963980ec7a16b55d8b1f70ca82ab31b1b17a05f94a8a30e2a459901c97383ea3208b4d6f6958c160e6851a9fa244277f3b1d4162ad8fb110658cfaf880f2fe078fd1f7f7ba4abf682074d1c795d1c7d86673afa49b7896d236c66c7da0decb2129a4fb6f8663e67bf895ed7dbd1352e2d7015966de803cbc4dcebf968e8a4ba57cc396a33588f642418ed1e077184c28c299bd0761cafbc9644b5e6f3e11de21a488d1c07467e2f00b3178e8a326dc84959680b0e9d693704b2c48fa1d30a79db5a492e4b583fe1ff5eaf877acde3f18e97fd577d06eff4c655d6813cae0e6f145cbdd0ae6ce78738919b6ae1061ffcfe97ba75cf7a94e00a7feecf6b86ffcf9c299c6795f7a936eb073afc5fbed75f8f7bceed9fcfd98bf3744deeb69d1136490b35c6655d62dbebe90a15996b61eab415e6e22e66689ffe69dff561ee3acb131de4d9e77c1a37ab87fc1cf369ada48a79d3c4d1f72fd53f884223bac29b70cc76ac5cb72c92ba5c1586ef7a80f166cc56f2dee7e04e00e1903e389c25dd2f914f4b9ccf196ee634efc838db73650139c61dd1f28a13cb39f85d92a851a07b7140bc5e407bb3185babc4fe7f89a7f1797d0f31c72575cddb60fe7f8ef914f31882c3cd21e6fa12075464d5c815ebb8cc79684b7fe10cd72cca0ceae46e6630c5c658a785745290afe938dbd042ce7da79e85516c4efb3c60408d29c3adb4a19d96b25bd8c3c62f330d95f92e1c7fdf883e075cd5a345013aa9848b1d70855ffcafe8f73af1ec3d61323eefeb7fdb57fde5f3bce0b04b97e0096bf0b4df6fe6a39d7591afd35d4c1452f172f8183a60931aaa98bb9e49a1f04243dc07fa40c363b84935d0f2b0d1b348fd48142be31e0d16b4d1e818179c0e0784045a06ea2ead20a6464d84ebf7073f39538c1288c773daf200888a3866f5892ed045e7ed629fee4618f5f378a775d7cf7eddf59a870051b3a09aa83283ad630a46a9664ed94af01058550c105dd8f40fd7a6ee8f1cd1152b45c9ba4f722ffd8d6aa93f32fda8110644295476c451be9ec78cf8d7ae55b4183f001189814fe056904227ee7a809da64c464d4e61dd86657693b5ca74b4161ce4b3087771743cc39fe9a81ef1c337c0e29dd62d42abc4614d1c8283cf7ab46111fe5cc38fe6372347beee2beff77c19176882381e7346011be77eacb175e2b235d2f2e97c9c4fb8cb22df807d4890f0ddfa9e176226540d4307ed99ae262c1c4e176ebd41ab8919545e1ff3c92ea5a00e21d412a20cc2be6fe6e3005065291f88633c7bc1ddba1191d23fb7d59be8c11cc73ac6643a33e552ebbfd0b36d2e78339df5814eb5c16e4e9b8084c33ee168bd50b6410c112fa8b4396d5ce6403bb51b843564a54ed631fa3808816722a75efa4e30c834b19af61695634b706ed2c4b5077cec85bc9463d1671a55d640e888dfb69fe0fd1d31f940abe1827d7b8c23ac3223685eedd5efb000e16d38e352076a2242da2c7afefd87bbf983f968e00b5a798660c1265b591be63421e5782ca01a930a6f4824230e212594f5526b3a5c789b94e05502e03d61629db8701d52e0f98c51bfcc51b27c6c13aeaa90e715057583b8a469e485dcf6e6a92699d021e5040e6ebabf9595c77a930b9d364985cee7c75ba0e5c91ff9bb7b639f3871d2a868b292b592b35e7ee23ba1a35ef79fc7421f8f7db85bcfbc3d1c982f34639af3b857c546b8c0735ac45dcad40fe9e41e551222eddb408c8631d2e01d761fb4d4c03874f6da0cc038ae684fc3a1432b39c225aae26593a41ace190f40e8ca3922085096fb015706eac52ed3061b56da7b52b09c804ccfd457b43ce10ff9d30e5a7ff9918ece7097e8ea49d3eef4c6bdd57a29459e19b81655d1481d76e9531de0a4b1de7dc023d4090ecfbae06f35d6fd9316ef5b7edfa3ee2adaa57a538bf0997ff3392f83dee45a2eb9a7527db88f4bb63de577fe0e5ee776971ad6f2980b3bd9db8bafcffae857f0700947ba3ef8dec65a5d86f0fb3eace04844712f74a84d0d6b8a97df06d7f3501efbe78bf37e6bef74582f3adb434344de2a8e909af1462d2ed37db941fcdbeea4ceba5887bd08c1e14d3ff23e7d309f2fe952e0def39355dc4a98dba9120e2e86f51c8a44b8fe86ea439c5418073d2a843edc843ab671ef35ccd15a7938eb84ee896293a0182654f30ccae06411157bb6b2bb80585366675ac251c9159c4c8d3c58f08701bb4697e22fee41485d0fcc38ca633dffcc0fd66f143f3c66157de2403ebee32fbe6ed017fa81c3f29b2eecf51ed9a8a17a0d16a569840a11dfb09860b211a3e1c47744c99c76c3615e4950d7539db53e63e33482586a683dd5999f0175cf293238294c9f171d2ee11a390f6d503014180f5ac6f01aeb5e9fd02fdcc995ca53a7ad7f6a950537d2cbba9a53a98979a3661cd79f6139fdee46fe1b871b118222898e1ab72fc6ff8a3f0e2a5f138a8e277b629b4662433f5e7ed30363ad6327d0f0cadb0aa356be53df21032f179567fb95b4d8b2d9cda950a4c815723d7f6aa8995f82c2b7d73b512a2256b08f09b4b093c7192fc0541f72a90dd14c67ee6db58d914a0f7eeccff7f9f61c26ffce5e9017fb3e7c770f653a3bfaf19fdf416fb577bf7407f582035d9cecf1e9dfcdd967be8e2765e59bccf6720651c956e21027e719a48379f41d88a2518946bb341ccea56edaa98eee59e5014a05f1c3a12e28a8845b03eaa02dd1b41ed99a1e1872c0fafc47381a3e2e6c96a3c81ba51a562c9200d17cc2aee022884bb5fdc06e9efede9fdc01c6934d9a3faed5d94c39dcc65caa8b39936e92a303795ac24abce04b7a338f6b7925da195168aa318ef4a64106d5329e19b8aa59a0209345beccca3689fb8bf21b8d88f03ad5f1053a4137d1417e1eefb40e4c4b9c61f1cc4f7771df93dd30859aa4875bae18f4c772b580284999d891d2b31164f94cfba6fd357d2ad76a0b833ae59f73dbbc8b37be666b87b18eef56c2819a91d3efbd2e17f7b067e5609019963735240857f01e29df10bab98c19ace6d01a24633c2745be445a43426a3698c959c22c88a0372386f5284bf5235d36f3440722e52014e0bb3e77c00af5d60fbf604bc1b0432bd46586cc296757604b3ee61749b96acefd8aabd429b649f54b1e8a8bdf2874ad6f7a9c03283ee50708071aea6eb6d78d70263ff79be3e571cfc7d9b57e0a0e4a60cdb4ac5b848d274a469033dc488769be0143be6c02c49b20b1d18caa7cc01d13e388153c822ca6ac4e35c8fc70e867c403598fec9911b4612976c8c9e19c799032ab8b8b8911f6ac273aba0b95f0defb2957e1cbf46bdff3e3fa9ceaf297e97bf7b7f0258f36a12d224b9d78394f7b76c40c44fe99c3c1bfb247007529af2de478be8493414a544b5c6b224b39a01a5ab35113a7003df2b218842bbc9de9d013cea05fac8a4e844386c632f161bc5bf0fd86e90f26ebbf6ba89087d1ac940fe774392c538e975ca91505c8631f9fcfcff034cff6f87cbf1d6df2577edf5fbef7ef75893fc587dc20c7c75593f0231efd5ccb7fbe9bdfcce7cc917915c701f881285b49c7dc846399a75cf0996183d0914daac3479f671da5b9132aaf8be9504ba3877d58595ec69b41627beb301c3e860a3dfadc4419b435c4731e479e410a46893e8c30574d5ae2044138f3a13759b86cf057f4177ce19edd2647ad08b4bea48688fedcff6e126ed629875a7ce2ae7ff97573ea45b98eb36741eb09531026ae6aa9dd32e6486d4e27031f58b12422f20d6f806ca0cb22d729603a73863b615846aa499b0086a786b23335d987d0dbc95163120d1581f6cd9004aff918ed992e345436515078ab8c3fecd9873980aff35c66255c8910a8856be5e98b7373d641ff53cdfe1fd79fefc37ea84f73f7275e3f7a8b737db0c13a3bf506be18ff943f45d79d638710b5258a894c79a380329f2b487d23575cd9862801229a57a1d28c4809a621c02b61a0a9e0d0cf0c1ccc00bbc750ecb1813a44876beee46bee64ba5836adb4d703c9553205165b388dcd7454852cf72fd5f34d3fcd994edeebde7fcd9739c503cf6fe2757d11992637476ef6b246d201162a40ecafe42e20d8090a01892dc65cad35dae338e3cc25201fcb553c9030d824e5a497e5e38e562a0f810c7c68d1d0509174804f356d1f2f9b5c4046712496590f03cce1c43ff5c05fe0fb1f6db539d9dfa7b1a6f1e7ebf83cdec12e8ffb99f2e1f68cb9ba8e239fe59345f1a8cf293cf8fe2aee155b1479e7f36635b7d92e65708d5cf483417b9002af9c43dc63c32329cdedc5b8d8310e6aac65260e870d216824192e49c91ca9e37950892e63b09d016f42c6d620e4ccc4c5879a46bf8803f23cd3d43633709e3a2d890dafce4eda1a5fe33874869b84e3fc29cfe577877be21d7eb710dc03cf35a5e3f7c4ef7854847eb82368135745231c56c6117b94af70c1efb8575ebe27cff5a777dc7387bbca455a563235ab3c9546c5eb3bf77dadea3947355103305b656f7021c7fc1ec85c6b9755b83fd6b59ce18befa7ef6b6c15de497e7a77276af001eee198a7db1efeee4c87e53387ccf25dbfe6091bec9c79f1caa1967051ffaca59d350c7ff18efc2257f46cefa7f37288155f9c81379c935fe422785fb7b8387f79883d4e7e6c6a582a2d0febddaad8387283bc5f9bf7b8e95d76eca9183ea6cec1ef53ba084f79cfe31c3938f83dd7f952cf3ff73ec7291cb694fceddff15e83cd5fdee2dec22aaed8b187ea3c6e733a5fd955ef40a0891f0ba544c00b8d39799930a82751dd6105955498723bd7d202b54c170a190f6dc0f30a4768c5dcb5ce4bcf8f4bb123d0f3a9cb2a06a11954788dca78c00b1632c5c882c9092e821d021220376839bca95fd5bce0686adf702e5df3d6bcd7d3bb5caffd56b8bbdfe8b55f8db7d304f498af2197575e1d2ad988c27445d9eec2f183914201e4eafb3f1f97fce62c5d582ff8e08ebe61bd201c18d7d69a331d8298e27206ac44405165454b8952135ae13d77ec36615e1dea2817dcab4360b741511719848f4c7be8521be922cab1800f0045684b6d6186bdc48bca02c285cb402bf619cb1d510cf34ccb8b05356d7c452ff4f5f5821beea7c1f647fd38f7c80dfc981a934fee49ba45b7d05f30debfd7873bf383f91cf61b5cadcfc36b9e54b2e0b6d2d0f8fb80505507111cf331de31daf402d00e47d0c246ddfbcada27baa6c50c8ab8ac9b29a821d3d88af5988842cc993bd12405735e82dc7798899c18a48ef4b3b219f90e8c7d08517a8dc6fa051acc3fef9c97dc757f5eaffcc25db0bf20163d72a3dec2e7cfdce0e4ef1bd613274d7b0d86272e837de20a921a39e62e23b13ee859999709d7063e501e5a3e5e5e4bb9a0d72e2e0ff75afc5ebfed925cffd3da9e753b4f5fbfa9057e21b738bdfe7ee8520e1f93a8beb09ee8dfa89e78882f409e3aeaee554df1fd7cceb9a9ebee0054b224eb999ff5289236aa332d8fb2b1227e21d982e445c69b3dd60b2d50822c56c88d23586322d4a2624b7f4c5bbf606451e1984592052b3146859ac50a6e38f182b49cec521a680ca85d52a050eac820d7f453fdd5f8a2576b78c61bfc1e0b0a6e92277e37eec1677ab5cf8778a0398f771d071c6349a0893084b020955732d77245ffb0f1a99a873c337d6da22f0aba8f598e582136b28711aea44e7a4c52589b12503da66d85e8b0f46db89f01ab8a758fc81efba4ca75c2644c3803c29028000ffbe09a5ce35fc601375c26255bc911c83303d5e2d3fc4b7023bd9b77e31eeee5677ef738427dc2e576464ee35de1037b94036d316609e70f83990663e20a4623d485516c64bd37c6da97eb695fe4e87efe5bebb4427bc1d1677c2aed699c3fe76d7ae65fe36a9b19d61347dbf33a27dcecb3438c7cccc71ec7bceacc08c29a40ab1fa9f66064ced022a518cfddf580f6aa9f33bf0be900cc7a9cc42b94f395df8b15ebe750b5a90eef024ddc91a27d4cb596cddd09600572a75a66307dd812575801ab77ac00ab05415a36fad6f3b115a4ef7132ff784ff58b35be081b82fe3c6ef9b97f91ff7a3f4f58d9ab39097c1d99d84566e8482de5851112690b8548483c1fbbdf75aa3d76a92b75e97895ef7edfd315543ef474e6420771a4b0f1b0097baf100afd48095c861a46ac400ea6d8a29130a7fab741dc8b1c0101926258881b6baf5ccae5241c561eeed1596475a961a9acc2673cdf737ef0cf735fff720e809ff67a21d6fbb6f7fd4f9cf7eb797c49cf8c54ccc20c310218cacad6e3f6b00cede60e8fc5328316f00d2ce4180d6459cf05f43c1a368e60c13eb5cd25b21f070c4c0cdf463976f3b5a4662599df713bdb60bdde2c28308851f764c592c4c05ecac5fa2ff1c1dedbcb156f8a79cdbb7d83fad3bb715fde3fdb37ef7677a5d6f0808d3d1f313ce12eb23257d58c5922d44134ed3d18ba56cc1d0a425ef4246c4ae4d04d4c6b27a0799ef62c4fa908592fa6be3dbc47a5bf23900e82926ac8605a603c7458db0fe63c1f606da273889ad060bfd71abe92abe7a88b360287d8b178c583f2aeff062b51aaed2126c9cae15e449ef674af9d7ec6defadddb9f39e605fb0507cb546f5ff3acbcad5594afcfdaabdffbcb18f2bf85b36ab89d7153c911783cd8afe09f9d0bfb56e7e2edb8c773912ec1564441933aaa970edb1e730ed79e8ba86843e88905c9fb19f01e63cdd3316446087292f2e61edba0588cf18c1acc9365bb0b741373baee88834741e1b7718404b2734d94792c75da33263769d1e68906292ff036aeeab51c7b5e52653d21106654bcc7315d1c7f145b7488ddddf6db040e06b355b1bd3a27f4a46bff0936f0263d0cc7b10e31e4701beb473d43ed2a7c319376a6c3bd0f641442d6d362d8e395dae2c2d7514f7beed826bee11d230d2fcf5ccb3cdbeeb567e360fb8fa90e8b93ff838f35b5cf6beec77eba5bf800bf1aff78560ebe72ea0c73313ade8bdac137488e35f9d3f8d7bd25d023ba6c11c8abd4c19ba0d89bb1f11d246563cd7450920282843fee89aa7556c251ea5ad304223ad585ca5cbb974059291f625a59d3a4142e2aa040913498337453c082ac178a42cb10a558fb91ada5cbe6a39afce75c5a11dec53adca6e579ad8f3d7c6f79090eb6f1b2f7f0b9467e3d67b8f1bd398c17ebecf1d4cff9e939bb49af503602ab989b2bc17f6a89befbec74375e89c1f60d1fe40302d6daa2b2349fb3822b952c2ab1cea8c851c574cafd565692c5c49af9b657485b25024014d0fac79caaa5e0de64aad51ba13549dcabf5549bec11b366a1ddde3367afc5bc767dea35a4f2382fdbbf8207f25a9ce63ee66873ec8be0471e804fce6f7ca39acadb9ef46fcdfbcf34fd8487b80ad7b5f175af4889b7f5574c4b0c3588f59a84463d42d1c320d1055f382d128eec636575be2d37bc4446e8223f73bc1c95689454702cc770963a689cd80d94553e0939a2c10a3aac0040eac33a51eb0e55b95a8c19ba029f79415fb6dc3de156e6e140ffb87ffae95c80c3995fcf22bc4b74b67dd5b7fb0e1ff222fe8f9e7bba16e83d27dbbb7a5eb48a4f3dd07f8ee3b8f27e796b0fffd713f6dfd213963970f3a91ed0a956f7e7be8261e589feedb067fb9837bbe75add75da765a62b7a339b44ce4d649ac5390f5d81463152fcae13e8b2497cba1893573cd5670948ef33973c03823b681566822e86337d598c114d6a77aabb0ce7c9f203b2d1f3aa98b65c6870653561c68eade77d79a74a0b8142ffac4a57fe6b9dca52ed3fe2eacfdc7639fee72e93c1c738831f70ebf17c893c6f735bdf7ed8cc67bc9501eda2627eafb66eeb01e451393b9569e96b9168387763efe97e8679effe6cc815da65fa0ab7e0bece9eb314f367e7c13acfcc40b655f8f41a5ad1d5675c00a0631b3c2a9516873776dfa9abdc73cd82f58be9cbb961554ca65fab75dd233c13916c2b084bffcd6e108dd677ad38795d722bdbd0fddbc5b441e27faa015bc765139b4b2719e27aeb80f19b4e72efabd1f74d17da256a97e517f4277a3b7609f70b47bd19ff0f2ebc6ffc29b90c2a2a5e1304868ed06bd77478c78b758f9a6cfe43db3830d5f7defe2025599264a59e53b0ef312950f4662c466da35511aa166a1549b15d0e024ee33cdac889143e4e650b8f69e198aa52a2f439d8d3285741efd25ba515bb4fcebfbcc9372b8cd74b44e1db54d74d6c92bf30299a3b69fbd3f475e9c5b686518569d96dfce3662ee6624defa8773799dae4991294bcb78b3a17abc975c0cfc52e682db3d733d13976a143a781e721c877a0c883dd82710a3f9d823dc2eb405149e2c6927b5d6206566fa256d090bf494a01f0143be2482935e2a0c0a7daa8306ebccfc88d3e0b39c8228612f47a0131ce7f1338fc507188c9fdfdbc75ca8670d015d958b57f8e5ecad6f5aa60ed40e6fd1abbc2579871b3fad7584343102bd88bc3ae66dbd38dc053f714a6fe3d1c3cfb592ab55d2813235bc268e82461eec5e4779e6b0d7dc386ff3aa87f7af54ab19f776a9ae5dc4affe0b5feb38f79f78eaaff85707fb06bd748226d359979c710e59f5598dc6bf0ddfd1c9e69bccc0c52c422a2bd509531179c77acd6fe677c6205f7777e208c6c8b50c0cad4e8e11927468058c8d08a37be63c82044c769ca33121ac24ca828b521eb55fc3159b08f5b097a557876335898bba4a1dd3140cf66455e8a1516f634e75c2a48dc672cf8b09882341b3f2c25e14c3ea4e315fd01cfda98b389f6f902371bdd3591d81e37d7a5cf3b79f5dad93ade914d87bb91271c6eb51bab22664396401c745507e1b08b0eec2d2ffc731c187bf53bad89c71cf949ff71d83d921bebd813f90954c936ed1c495d2c4a996fef6b3069d62fa2bf9e484e18f7d9339a00b2ae8847ddec4e1378368fb3ed3f0dd0c08533a580babc91e8d831d656c2aed87bdd41ecdd4999849d1b6f3084f17540d5824354aeb89d461e7175e2b1d6521478d194046daab29719a3b5cbef30b2edfabbfe1edff438e997d560e572242fd89fb1fd7b1fed8c49157bd7bcffe223ef6ccf576b1cefaac035b11e55ac2d166c661278c279bf9d5fcce3ac5d7c5ad7d6a30460c0b272eaeb2d2bb8f896d84ab6c23a3fc9eb996c7a08a622a03d40dadc419867ed758d3ee5b2b88ea13c3bb13bc7593705870b7863c527a5ce5202e988394dcfa95da673aa2a1ae6661219c7405f34f748a2fba33535d1ecee0059c016fdfe1af9edd6175ec17ef8eb1ebf3f8e73bb2bf4e4f480609cd35e2b48f88b6455a341e89b2d61f5bdeb4cf07a1ca43c465e42b6830a0366c2ceab012b9ef787112e124d4ed1db7414775af4879d6672b2f4e4b580b776dd28835626c71ea4094a9fa11af149f47e87dbde00acc26ba9ee7757fb06bc1e9362b597381ee433b5b3ddce0dcbceac33b9d9557f338f1d9ccafe3ee3590861369e4388df2595ad13e661380c61e9b828701aed49e54f55214eb4dd0b39852bcf10d16254a0ed255dc2202f39002573a79c499173317529f52906ab52ebae6312961ee17c36912365c54624c803df863be73c302e9a77ae937c23d9fc63aaeb5e4607f6d1fd1399f60f0aad864634470e5b7d4559a180d7f708e34e4cabd5c0566e8281118b09833ef31ee59c24abcf161bc9943752757e2075db151ea3cf60c7a0db5f7ada8027dcef0808e2d8fb0da0d974d446dc1fcc27312575e5157b920a6e16631e3c3f214a3b03c0d7f6ac87c103fecd212a99fb1897f358766e6b2ed82a3733eead33ef05be447415aa9d5611e273ff179fc735ff875382a0ebd9e96752196cd0fc4c1e3d42876a890b3105a495c79ceaccff7be52554cac2975719131ec71e2c582b05d62d7011eab3ea6781a166d20abefe654334950591dab8492258e79a59669b9ee62231e108d15fe7b1cd5d7fc95cbf6661f7f76df9dfb08fffcbe3b8c757c8f40e6d85fda8b740c7f9002f699ad4654136dac82cd227c04b81cf6a95ecf3328f678556869d97a5343da2cb25a3a562aade43d73c4643156a5efc835e2e6684e849e8e1ef505c3fb4cabfb456429527986a8ea202b1a10da13cdbf2de7c539eea68dd087f9733ff75fc18778c9de7f8a6f8c4ffd0f7f8ec96d4f7e08ec4fb9a2ab396a10229341e85a6b54c99e02711f944a306eba62d9cc66bd347c279f677adecf740cb081e61c5a2cd0da0962b995f11a4a4705d89073a2993e5b595a503c0c483974e395d5c8220061c596a96234abd88f50c3f4239fefb37bf5a4f10b568903b769c91e5fe673d09f7316bde58cfb57e166b38829c9699372b5cacaa1164768f339de7b720b5fb7959c01118226e1a84b0d9c67fae3e17dffe8f3e6840bb90ec74f2a96138572548ac71004202c21e10cde85e570e38ff174a1b0ef5364a112ba891b83ac143eeb51200c684d35ad0bf47ccf15dc06d41f24e3bc46b07612cd2373f800680537d8f62601911d727295acd06cfefece79b5bffce5febeb6c1c3f71e79c24e6fe553ccf926af773ddeb01491b7cb8c177c786fed78f4c6760f63b86a7fe66ed8c7d1c1af1d6edfe44c7f659f8634b26de6c0837fb24bcf31b32859971ae8457cfcf61c7c7f63fbaff912627db8cd0cf6284f18cccbd6e43ce653bd5c46d63e353cedcd1c9effa6e8b2b3728c81c5a95f4b9b456c2b22b48a23eb64f7bfef15bb49efcbefe770bcabc1298e17c7fe313902e0f006c53a3c6a1a9ee771dd39e2d09fe9c336197fef529ec3b4670da2eb2eab64cf8a7de76bcaf09505632a79e848ea57c291e3dc0a22d4f94e5b4a052dc4f19e3bdf4c062de0bbde1d3230094acca8233771091bdf59ef44b906bcd0060b7e694ed35b5d7257cdff3ca7d6c5c777d05b9d717b832bb1ae7d5cc82aa3cd0f1fc09170733f2eda4daa83c754cf37b242d6dc9145c015a3bc2541516f83322fd36533a26e5e21c75ba19557cc215e052a6b51247359e052e86c10e87215eb68933828919532160c0a6a0f6f1b77384c6523a0162e563f7b51be7fa8919070b33ef900e798e31d4e1cd469a99a83fffff39d9d7c80133ad661f6672c587378ef52ceb6f2ac6df9ff3de9d55d57cfe8e2ee973ca197d89b8a393ee1fa5ec660bfe7257f8b9dfadab92f592ecefaa4a75c036c8e31d2479f13ff7ade57eaf184e626d2da9960f80e39c3795a362b62af372914848c859e39ca11ec419fe9419f023499bbf598f5922de0f72ed5cd55e23c6ea4c26eb0b235dfc8012eeb09ed512118ae12add971989b29cbdb050775c8f157b0a5755ae6ea7047bde04af9885be87086ebb494ff9f70d8319e7ce6760adfc544c7b74c3aea71c6b1ca5c4fc53ad444f89ab3e94f7dfcc9f84adee093ad1549e4ed3fe76c79cbd5f4b53b4e7058084775476dce17e31fede95a0c2b472871a91177df065989d78996c7cc4062aa0ffbc3dd468d621f966a230d6b1276dfc054574dda357ee6b03c03d8993b4380236f9295ad480c49fdd1e3262deb7a11315b96be413421100b7ac91b9daff236a5e2a67d2f6f711c1375e404bb45afc9e06b989ec3beb14136328f38f2d438fa47db23df857141bf5b778bfccc6fe770f0dd0ff7975ab8dfb799ebeda4333cfab4b3523cc65cf6c7b7b3bb12f34eeb3a28711854b6e933f9c88904b458ef85eb1b74d9148c7cef1222fc502f06d90a8d24836ba2f2ed546f1a41dbf9546365e8e4655241444bd5fb513d5d38e6a3240f83c4b577c8c1031f7eef08f8de07cc0a997d0d0fdd1ff44fbdd379bea87feabfbbcfe9e5ddc42190ce43239de1e6f37ea7e036bd1cbf1effc9b63fc43b1ffb02afede520a24a005a2248f598c969b0c204afbc4416ed12f5c20c34ef476c0820543eca22a1e3e8a10d1daf0981b59111eea55e477e94cf99f2843f6a8a98b73f42a6c2b81c566425ef7d87699ca1c7b8543966d02491baa94f98952ffa8b9783c19f63b2e3afe8fcbddc93733cfa7b1e26ff263d036f31eca7f7f2f5675fd1f7d306314782c39c86c4b2120075a43c8be835f40d711f5315f3b2a1f348ee90dddee3d21b8540614cd9362dc03ca8ac59c631cb8a42a73d9eb3b135a3b6dacd80e4b2580369d31d1f331f2f87943256fa0edbdc562fe6148f3df9f4bfd679b9fcadbcde1e8e716c274bf878096fc16dfca69f639e7df2e3b9cf2a91a7a3b3b6c5157c4c847893ac6b7e2c3830386d6ca2d93d8d2860453640346891365c5d181f9f6dfb82facd68b03fd5f9835be4f69e7fe6bc1ea778273ce3064627bcc1b57908d6e7bee4882cb8396354d992283375bd3c2612082612a4e72bdf6596d0ead1028a9e32342320bf5ff056cd1ddbf40d18270eba9b82dce2703d880bd5fa65a02704c3c4c145ba125056c1c61f0d99d49a0dfa50cff0cb35843aebc02a353c35e3e79cd24f7ce147fa84aff0d3af72d27f03b6e58b5ae43f39ed795b279761cfffbc4ff960e7a7b9abd4519b13eeffed67678efd2b346612a056a29777d2a92758d56359ca9cda22f7f5768f7be5a73a5bddd03e1e5343aaac4479a6d326d199f91ce386efea4c979d7d8335a73e99dfedc1f71bd5e79fc73bf94a11022967dd8c7cbf16db37107cbde79c610c7c9de8accac8c3c0d7504bb8a2be9d273e7fbce19b85d7593904e2ccbd7ccc2b75af7de4cbec3ef87c9ddf6a9b7e719de5d9df90475dfdc915367daac9f9cea4e74ce2ac97a10fd6a64f644415347d9a4f0222473191f6dcc9755e663aa314a4b43513ad1e5026a05fd6c0b7551c17f231a679409d76c3c326222b6960f57d230143dc01235cd8fb98c5ba54ca7ddf9778f1fbff857dc0f5c1ee2ec26bdde2ed3f8f777ee7b48403952d9fdeb9abf66546602ee66316251a6b7d157771d1a8c568e813ed5bcb4a15b372d0859a1482e08047aa0f3816c2a99bac842264ac6765134b92df230736d3fe6183185bc61cbae918b689f34d8b236805cc9a10656b18a0a5b8b4afab64207bc2c37fdacb15dc22d7791eef6ce7113aeafa9e7fff753e0351db70fc3088092ae36ea8120d393edfef6780053e55bb4c5720e4b5c99c0723b13d9d438142a82a56a2121b429b8f0b833b12242b8f11adb5052d4050645d4ab29d8ca419d396b3b128e30a8f25c0e6a2ba0ab35aa77add3fe508fd8f7b605fe5114fdc9e5f88934a7c41ade426fd48c7b14ee74114f151dbcdbff62c70bfcc77b2c477b8f4ee1392193320f3a48484b07ce317433f0d9b012994a21c2312b111d2d52a59c965d28bbb8478cedc966e10e5b5d0d116db621f16f992546a1eebd20c0b5cd3d1e3202d861d276cc50bd91d75ce2f390b475e7bb0945c949fbfadf4467909948ba3a6c04917ffb8b6afe7d1a0637dfc4a7ee7ea7b4ff56f7ba4352be18026d43df7e0e3902ac754ab3ba47b2e5388273d2373ca5a9fc69bccb596b4fc66f8a346080eed85d31888e2626e9b0159362e1e8b65529a22251e97cc0201c89bcc65429660fc015ffaffd5c7ff9beae3279b3ce580c79f9d8d1be96b9ecfc6e1ff45f4f0f26c3ccde35a7dcd1317b60319d544cf389c938acda4de8c125eef0eef67401ff599ce1052a2ce2a6152281ff94a8e02064d64079bc4467a32c62354b61eee9a2d75f03a2e4419722f98ea9262cd5b6525ee890e59d65bce14d423f221f7f9a7f91675c6a2fde749e3feba1801a9d8609d08c18f4c1f6e5fc69abff79ddeeaef7f95c30081ac7ce25438ebe91fdffc8fe73523478dfdebea50cc067cf9cd44bab924da00c8d1d09f1968824a20fc82e5b12e7eb0421a598156542f001ea3a584debd5fc864ee5aa54f1f5b4607065fa909a26b80f4fc0753b4a3513dc8567040bac649a9b726868089518f0907479ea90bdee4173c06bf3b27d9211e01373827678e84d3fa9efead1987b7f94abdaa20d5991b2ab59edbf90cd91e25dd309f335c2255bbbe2154da0d2d046a9e01d551cdd6c355be5d10b58d5768e433d1654e03c8b2b99bd32144912c31617b543c68c4416bceeafee017522e9761119808d6ce47bc269fe5a7df6ac54fd4e04913fe17b9938ff9c65fe9e89c34659ef6ed263aa33eb9fecc9ef60e140917e5e7b561fb969a128d7054295ed9d0691e473cfe159cc6a7da9e8c7d5b0d661a9ac65a6e06ab7c855cb5c9ecdc0d29d489abeea536dcc51546b33e2fa600e34483c57c6cefe282fd10c09a64a558c624685965a9cc9818897ad8c971ce925113fa1a8be79c59b4674b11363f28535768cd5e821b7da5b1f4c4edf277e7bcdfeccdff71d3fcd770d39cf76d16212d35bccfdee5fd8df7afc90cbccb4afa6a1fcf9f35c75eb42bf7933928918544242a4c590e0b4c05c974dafb4e1b25dcdc24cb662ab4e1482a6b3b77651846784f9947e248ade3ee51cb0c6467bddfa3886d52a729a582382ca53f03524f69eeb372ad718e74bff20d4a112617e308919223b04af5e126e1f4cc6172490e29b805b6b01751d0c4fa7097e84a3df93a4feff447f33afb41d76110392b68f13048a937c34cce59a138a18d4a0a732b693d481dd6724a775ca12206c160a6992a25c52ee56097190fad5f592be90403dff53b62147bdf6ee6bcaabb5497882b1fa41c82b09fec161cf83ef7f4d41517fb4109c76ac6d13ae6e656f0cf6ab8f67b6dbcaff943b5706813eb799e96a63ad570df7ea69d7b00aef28f5ac4f26011e11617cc0bb57c83755c13aa3a4eec7d1a099f56624bf983e62fbf6db03e1ca5b6887c7dd21198fb987883855def79218a94149ad4e93e28e18ead5028b5dac406ac502409d2d97e01b1eec35aff0a3fc6e5bcbe529d38fe719770b34fb8ff5b2ef20fb8f99fbf7ffe1b4dbf7f1e7b826aa19b793a026ae1a8cfb40cfa1bf5fb1e79a563be6f4494d7f2c9065fcce3dce7785ddf2f132c5c05262efc0123f07ee1ca84b8b9172b4cb302ebc431cb592f2876e48097683677e580aef2bbacb7fb856b0d90912f711fefd3128f52279f6785a8fd8221494598eacc4eb5fa1e19524b20f233127498d7bfc74c5df4d60db709f79bb81cee3ec5d41ef96c6fd0d7f66acce3dabfe44d39f3e65ec9dd0ebd49321a5a7317ef592f3b491eccd4f51e1340b5204277dc0d5ae17806d56bce7409b0e135a99b4364e05c02d160db7b0c090c42daa204e4d6c2aea934e05a18080a86278b72dda32200810e2602c086bce748b880db116aa97ed420efd323b6fb759df1529e9b2bcfd78957070c0b71ece9fcf47dbd553efa032cf071afdfcde78c4fbc12e79a6fa87a389cb328296a478c733fd3f0d4af149e193262469ea78605330d8e1881b1281b34b7ed4db2fabe998fd934a0729fb9418b4ad4f94cae452f6621f796c8196e181128e37b3d28863fa60603d96868843afb0a6efac46dc43d204af18485fe0ffa12d7ee79dd3ad0271cd4a9039fdfc0dfeca576232df6f35e664da6ab26e16d7e3a832ff6f3cdbc8ed8bcd140bb6a4fc3613beb738c6cef11c17a1630eb47b2ca2311795e50d45140db59a2c38096a293655ee255be996993ced70b2d3df844d0fbe12f8755dac3664e2c2f5dc92deebef5dcc6242e863b7fd4ec2511a12c102544855803f8525fe9e9ef97ba2a3ed71cbb555ff6f3da1a09c75a327ab5dee7cfb4ee946bb8ca57da12034e105185a0a89d3314864e3bc808b464ff00c2d2d4909be9a121fcd080112bd50695436bceea4d0a739f14ea3e756185ecb85b441ef529e031c33f8208eaac92852859828ccc8829d2c3223024971fe2dd3ef39592c86f44c51e5357d6c2c5ebd9b9273d7386755a3df9371fe4b30fef9281bb24fadec407dfe98cf739f560fdfdba84c7b970b39a55479ef2dda98e611ef6b1b9a48fea86e7f7353efce85b6ac738f337ff7fee01bdaefe9b40394eba619df1d848ddeffb99062b66c7c64cc705e9a1c70c4c88b22caad78f8b02d53188411279162b31f40f365ba1ada08f1d52ca45556e051a18618ec7b2f836108a1136b6d8a2c028197deb68546ce6eca698b1db6a00bdfd993327aa74bdfca59fee93871718bdc90d7a5f7ed747fd8f63d67e6373e0dceff6b7c4a3e7fbf4756fc5716e9c6dc5ab3bf757dff3a578d59c47f938a9b2968e277d10c9cddc663a73add582ee3b52a8cee76b436aeb7ecee34dd28b47a9bc2dd5c0dd540777738adcc54acd39b3546ae30d1a7b1b62acf5a9011fe76efe43148f8314a8bbc591dff13ba08c82e0a63ce5284f9d7d131fd6e5951ffb917ebfa8d39236877dce1cd649e77cdf3ff785fd329fffcff7e9ffe6eece0c9c67d5bfc04e23a4c591a79d34893f9def97f03c49f9a00b520c903d1c894a0c684ff7d2c1c22fcd9097e62ee8e92ea5ad136ac3103358ca3ed750a44ce9343b16a1292dcc812c8a1d26be9945b4cdb4604f0c1c8504dd07bd150bad2129479134ea5a0205f87b3ccfbfe73efff7e652cebdbb709be9c5e7bd3bb7c101bc1cf3d997c846204f2b549fe3806b74e75bcc190e23d6c751d6257cb8628e5a7202a74974d4499ea7fdc3f579b7a31f78c6268cfe599dea27dff45c7f5fa53a680437b5bf8d7ff097e33fbf751ff57f9ff11c5770b733cb21acc692379ed4c1e3dcc63d29d89a47721717b9290cab4afb7f0b773b0287b729e652a59fdee9fe763eba052ff4ab314f6727b25456c2eab01f33721ae7cadaae4f23ec138a7698aa1972982d57e21e1b7843f4212151d0e351b3cb8865fa3aee173600fcd8db0be72c12808d73850b0f1007947465d59ca9bbd0f65b41f275e6d663a4ea7ee178808e851d72f848a8b871dfe6f010df6d8f7f3f674d1261eda70e89fd9e9bf8f433c71a4e52c2ee67cff0db1ea3d3f871c5aaf3f7f41f7f0f1bc82347eeeb3be25d6ecef09a19c7b974ec9f71e8db5edf23c7f5b04bb92a9ef5915e682dbdf99d8d88f03ad5f15b8dbdf73c0e9c3eaf071abd1f337b7eaf8e5a3defffff03ee829febe66fd10d74fdbec029f9daf6f577ff5f08ee81776feb7bde87ee0d67f897ee48e1b0a5e4d9e14c9ec7d5fa632c7e1d67fb1897f51d67ca4a08a689236a1a897a51790ee54c6710c7a18bb7810123515263318656e24898e9882e5622898bf6603f3e2dda40724969a446d279d0c52a4f30f33863c8645aeee0d137831954936318df568b08f4afced3b53c8606db8bc8cb85ceb672f4013ee21776f8997603ba459f1c87e733090effafe2531ee4a3cfcf5a0ed9759ccddc5ba77d3e434eedc5456e2d1c132c9cc248fba0238697082dde7185e7b181926425b6b4684cc6c126b15b2723f938b495968d86e58288356535e0250866faa05fb0b5c90a8fc5d5776d51ad77297b18240e10f4c61ac8c77eb9886909df3749f4c4fd627f986b4bb8b916d1e12d7ac511f32eef914428cf2a2f3fafd57f7e51f7f83d3ff3e1e7de73a4ff2ed7fe11efc8af784afe73254fc97f3ee029b9d6d7d87df0ffaf70e79f9c8953bff3f2cf7384afd7efe80bbec6bf137abdde289585af581214b59d80fc9113e9c6453d101582f3d1702b8b66c328633ecdfab9e3b799aee648c10095b6496160120e26c12a77d3caea63801a426b926af180d8432fab8281e4c14e024b4bf5dacc7aeca265f37bacd92deead738c1de958c5fab0f81c4b7a23ddeb8f6a672f62fe17f3f992fe75ba1c92c43175ec143a2ef265ac44294bd51db565f4bac655ad4f0d7f40988542db5b2d9450d4112cb3f194b8724760b04fdca04dc75848cdfbffd9fb93ee4679f57b18fe40ef4480c92a0f8b1881b1918350039a01f2bf3008426262039ffe5d6e924a62a771cae79cdfe019dc6bc5be294ba8bd9a7ded3d89ab7294d98d252b0631c74f09c84dea2a4a6fc7ed527995d4af7a667db2ff7fe60b48870df25bfc72d32bf864fb350744848e719c579f0f3ef465fb8ec0db807b7a568e930c48cbd7140d34d9c59576ef13ecfb50c18c58100335e1b7e3a7a032ab44173cac460635bc1165711712b4254c3d50a3711751b9415ac37c159b02ca6e19c1475f5977d2c8d771f1db14ee75f5af53ce40e28ccbb771c293d8e21b9bf1af5dffe71a9c2da7b8e56f9e1d9933ee77fe72ac8fd7a9f10d9cf955f4569096b9d626abf130e768933ae3fe791dbdeb4f8b7ea0af9245d6248844984e767707bb0b5da142033d21903fc5a009651d6bfe0476218745683438b57f6d66a033968e6fce06abf36be92fa3186047e872f2673b0738480b6f9bd1f16d069a123b6a23b4dca545f9480c61d0b3f1bfafecd5bdae79953af0d9c7039f63cfff63d860101f6ba63ebfb7a7d7b8b7f76dede65a3a702b42a0fda036b9ce54de2f9535f17967fa556b325b9b0b178e92097313da6de3c2bacd6cb39036d2c45e0bd5da66208f912d35df318b99c1464c9b82a5dd3e30e7cf06d9a8a2bc9b22b7b9970a237f3586dcd1a6dcfdadcbd5f87f988b60db39679de470fdd7b7f9bdf379cff342f137f1e2530d2b670c122e9f9e71c2537588919df24c894db6d254cc5f78cd0eb8e1136d7eb94ef5e77847b6b31bf4133bda816f35fb4f7e433d250edbcdf3f0e61d4f621d6a9847076eb137318793be9fe78e3c1db3f12aa95871c02da2ade0af9f2fcfc45afe3efff69ca7279cfa71d5a8d8089ee208edb17b7ff7f799fed6aff957fe6204cef3ac1c9f7fe16c38706c7e8829f8248fff322e279c9a6fb90e8eb1a20fb99b3ec0b8bf9c29c77a98c3e70bcf251179ed3c42cdf23bdc3457a9a1c52aab409be9eae65063f6fa333872fb5d745619e1608509c11501f241aec63175cb1105de9497e83e9de41342a446b8afb152f39186ba84d9db6599193370afb17afa484b0d63673c8d8937212ad04390b354613764f9d41f30c3b6f648ddc66291ca33db4bbed0b3f977eef9ff9b3a492071bd8de4f25b7a9a57c0e3bfb477b8cbf23e35587dc037f91768bad82d76300d57bff48ce40bee7475a67b450218f7c3d64e75d82047b0cffc8e6f8d0dd7d4f379f0757dcf55382fdeb4791823d58a67ddc4fed95ebd6c2f118e40a6a4ed9779c2cb4e0b7957244ef78889570a95cf92899cf9656b8744d952df3efa155c51a86adfd106a9c1a928c7d692c1c8d79b9918e09613c6458d01056ac16b368fb57c1314c8c186dab2aa5d9fdefbff391b2ce1a639e75d2fbfc035a37d8c3ffe671f4e3aea69196aebacded7eebc6a1f1807fea88be6e6862875e7dbad2ef49196a9fc861996efbbe54095bf5d440885436c082a73caefcdc5e4b79654dd7c41333d8328178ee813868b65ddf8a12de2381c8f622d032955a1a8b47550a8e992d99b99866a32b1b81fb1cd2946effbbed2a57393f6dab958eb77b01457f095f06667f79c724aefefa70ffedf91c7eab2fde56564aa71db03a86e6cc4cd2d75f2358122c6402cfc7e5c2fd9b49f1bf00e3b684e4a73677797c815ab94f86608594e746511820312d95b41351ef4639a18f9cd4c6b1e848b0a4458bd8894b95cb52223bfb717c4ffff631a39d2f9f5cc0bd066157c125ff291d103a7f895e67567cfce232f4f2b79f48b4efad3a2cb74c8f73e302a5880747583d41f6d4959ef7364c4bad46994afe2521948638fbe2eef96849521c78017b8c7ae50c485f7598567f4b6f593703c5d4e0458d2f596946c351b3c3730d493a008859572b3c8b3b08d08a9d6a3ec2c37c13ff1e03d49aeadfedab9d909f7e74f359f2f8d934867acc5fa57386aff4abca17823393ada15fb76dba3f6ef657594c01b2d203311c3beb4c784d6d8cbc216f9137f9381d6ce543e21763e92001759c4089d78059a205f90dfc37c508388bc074a3d6f59e3075adfebb86a6722ba37f1edf83e759819b09c06a5f4a521131665667aaa6bf52ff3ff941ad6c11fab9f6b493ec4beac9213eedf97731ca4062b9283ddb27bee90bf888e635c3517db997bdc27172a33bee6725b5ce79c30f79a52151b0eb55faf3f83ed3e7e7899c626108e7713464d27ab06085d21147986cfd75a56b2a9b43d8b946d2b5c5626b6348392e54939dafa5cc025cff380aafb4c1fcf495dea4b923d867464fa4055992d80d44a33896083f4d69e19b911ea39ce8039bb207ef21fd3c3dafbbf1c1f737adaee4eff263fd37e5f5f815b63376fac8c23af8fa3b2dd9df3afb99a3ee9df71ffd38bf6ffb2c2da02e68894cc1691350fb5e92387ea8edb905317479297dbd42db7a4c69b04b22136b247c6b53c7494c5b46094b81ef723af9ff7e32952f1a36f633d2cd01d25b64987d25850b04d1de80bf567945560e45f9f0775bfd78403fbac82e6bbfad3cbe69e9babd4f8d3667b0cb4024924be8a771edaf9774e0c2dadbccdf256db66fb98146ee4a156fedcf747aceb65f7bc840d9b0f6891d1f5206c5b1386057dda8225573316793028acf5d231dd04684ee85a202c64872a6608783fca06bba79177875db988abdc0b1502296d1ec504620cf3dca76618903cc78567f951f338d7d476195d350f56496e16d2d98dfbfb3ae37378a27dcc7c9570d9a4357e1b573cffecb0e4da2ad5bbb7cf9ec4e0e47db2bb0fb8b7593aac9c47569f70ad918ed2df6a7c7c58e7f03fc77ecbfd388b7d5ef1eb18c855ea92b5b4c24ad4fbbcfb714dbf7c3ee22f2fe36e4e6b2fe6b534b8ebd9732dd8842a574b2e6719c71332880557f71d99c47ae87a23128e13a4ef7c166f431df89482d11617f089b87f86d4953312513d88e48c93d84c1cdc2c1de8503ad6524d0d84371085e3895f5ef5ccfa8bf97ac5d77c592e779f67ac0edc64a7b9fc23ceebcb58285a8dcc7fbeaff403fe7077371ddbddcda93e2fcacbf8594adfc0bceb85dde4616506710983d900616a60216b9864fa74101cad51241b547a5542c46da8308b81b991c66f3d36c49039d93651f94daa3c1a02fc90866388002c0510b7ac62168502910acdb181a6e4ba9a9eed21d6ffc205fbe33d790623d87e0f43fdefba50e941dfbf7dd164bf203ec92ad9c8c8ab24807a1ac96dc00353549a8b0bfc2028e6e924afff313ea9a595ea243fe0eabe11a3bc162fef49bb7b3b8c9b4d16b1632c651fabfc094faf462aa892c883d4155bae24114663649ae54a48fba51284b9ded37cc87d14d99b90b311afb4a9efb02952c842039aa4145a8851800d7947151e510a936c283566c398d8662768b7a1d05a9081d5bc12d10571ffefe428fb6564ede35e3137cb54076fe6e63947f73fc8556b998373e9d036adc620e1a2f9da7e0f4eeb1a7f64bfb3ad702010a1f6941ab811953ae2cece7d0f0eb9becbf0b72275029d1756b8a4486030d563bdf5924a54188c09d1b52977ee3b01348589cc6939be41b6e6ceb41c25bad62c6d2f464ec3d24af658cb173cba37a466cd834a03290800e1e66d4c3c2bada941159a276eb0b96e5e7b6f3bbdca759ed1ebabd07dccbbc7bfd897735c32689356a211c65f3eaba91a699fd878661c794f9f63e955bbc795dc6aeb386acc2f9e1de61c35efd6f99967d45366e03c753a256eb53a75c6ab9877ebe5b3bdb8e7be3ac166eee35a99038e31ad33754dc75af225877dba7afeddeddf5c6f7ffa7cba5b7f1102f3e8edfd111d6295a7b9e1675df0176dbc53cce95bbeb897fa827378d39170b236aee020386e9e35f4ae55bffe9fca3d2e39dba41c3e9dddbfc5dffab63b72295ef6dc79706acbedf9a39cf5d7b1876be410f4c3bedbdd6fc776db63adc86531653b18824244a208ba108c052d4599194d8b5d8802203bc4049f1b0c0574daa301cd42dab5a45f0f4909d7c9248f910b6de96020000a7d5d8ca4e3f9986a37d4f8d3fb0a968963da316874493ccde7825f197379a8f18b1058eeef929775da9dc3673f731deff558f46ef3b2aefb138ce67f277e1579cd9c37ef7ff70c874a7095b8455695bbf5b3f7eb8e7fb7e8f672ae236478731629d31f10f623552c48bea504da01d77ce9cad827bf4d5c481a7211a530eb38c79b05946b9fabc66748858e5282ffd986765e5187f97e2510b7d7fab2b08685c38ad0f04d517b1349bb99accc32f809d7516d6969ad8a97f9f97b375c3a47eb171e62dee5cb2ff0b867eab57e96cb3d69776f97f4e9ed335ff2eedefb73e99eefe654f4dc5e6f022e5668e2951990a394358eafcb079f7716aa9521bf5d13f90dae54d73b3c73abedd7e8956dcd4b7542ced7517ca96df1eff86a19e126bdd576ebb6171cedecddfd3e3cedcfe57a4554d91da95595b9d99096da138f844e07380f4153332a736c83d1f7f8309996f0af72207f76f6ca15f46cf66d1dc680ab724e0ebf7b195f53bbe091df53ce1033ca47ac498700d62ea2fc292dc4340078eb3b5b8352cf46bab65eb88dcfb8369b0de540095be0c25aa43a8259651a89861f39140ea954ecf7e32ab37d3de6822c6c7c1fafc6f5b29021d2d9496dc70758b9fd3b1dc6023799116c0e9cb087f1bdd0f6d8fd9b2307e83774b5ae92af7cd3e6df397ae1633fb473591dceb84c593e0a48de631761a4a92d5162156a689600f386b9591f862d414c0e71a9d9698940c824a11c6e32605ab12601ae9937d7d4dc67f861a998872a7395e8b2c9283393495e33ddac4585f4850d073151d637b9b58cc4514572abad5223dfd9fdafe3f7ff251db3cf62d5bb73ffb3ff7fe979b1f74b57526b4a59585608ba6de6740e27de9c2b2f460aebcb882d903e7e48eaa991baf2510ca24d27569f02652e985292a11e8186f843d667bc5bb0c11e3106c5b292221cd44d426521222fca58739752f6b4606271dd58c6ce57f39add1d216fdfea759ff1cd56a93e5e8b9d5fc09ff1beafb1be2776e26b9c42fbcc6bfa3ad7701ec7fc1c5b7add9f131c71f3377fb17d8debfe3fcce9f1bcf6d066e717c7063ede8d5fee8b2be4c9cfb6bd3b8f9ef7ecce8e5fefe667d7f6fe5cbabd908b9e65a3a5c3288b649e3aa35142d07cae23e173d3e56e53a64a24a9a3caa042b930d402d7f856d8819618f9535c602a4b39a7857484421e1d50cb23cb609adf51c62632c25568dc8f42568e68d554d29e6e6703bc2a5f4112f96dcae15bbbea24a6b25f9fea65dd9f8f0fecd6a621387cfcdeef4915f37638e8dfbd60dcbbfff3eb383ae4ece7fc6f0efa2badd82bf0df3dafd743fefb563b62025e9dedeffa75bc632fe3af248189894532c8d4825845525b9b7890b70434c69259535a4312f0a0f32bbff3216cfd0ab6c26649563641a0953d29f12866d9d68f9a69c8702f3878cc2a1332580ec2957d5cfe191863fd6eaf085d4c38c5d7e5de88449ef0ee887b7c3b1e6f35314fea6a3ee2573aad97f916f7ddc9dea852c37b5d3bf341cd8ed0d2ea7816bdefcb191e8cc481bb7d69a6dcdba4ee1b7eedd36723bf3de04982f68837f91e27d4773174e1efbd86dfffd95cb8aeca7d3c94774dfaa55d762ddc9e6cc4be06575bef39b97af0be1f3fc2f1911ab5a996e7a98b225662840db65dc27b8d16bf47896e9ba2ea92a46a1ae28a292b61c4e9782e1d352724d7921a27cc989ab1e655a2828f3383114c82d10c8c570b7b1faf8e33579a82b16649b18d1474c495eb9c4fb9685fc5bdff1dcb79e9b9fe768e4e73b2c718e1df3ab3cf6b22af92877cd3e63e46fb86ff0b683fc83fae38115552509d680cfb4ece7cda3ee0d2b469c466b86237196dcbac8426aeb0272261614775999253a9a1755c69b7a4d4a6d984e5c9e05568620529c967cc1626215e9b45f9231ec493d0db2919ec4eacc6ebff78ddd1e5fbfe94ab42676daa37df9ddfd195e657a57cfcf0773e7fb5effbb18f675caa594635922875136b724180bd1591b442d7baf16d6d9441e5c85ad6a8560f4b0217784023e9b04d16ddeb688279a0ffda5065d5693dede640baf2b66de20135a1c23794e4501244850d3a04512e759333aeb9987cc19d7595f9d9f96a424b9deec817aded63b2f3c8da24c79af92ff516fe7dbe76b66d2579b73e9e59ed9ea722d4b6e9de87dccddfe7fd3cea315c369f5163a61c6833833e66000d5493269ea86e8f2350f1806da127369ac77a37178ebae11cce58c4a601f933d0b27b880bf9440de6a6152e0390bbb2b0ee93be9d73226f0985eb4c932a1c30133cd3318b750ee1053a57ffb17cfe6efc5466046dbab3f7cf609e5eb019d18157fbebfcc755ead4dfdf5baf79a79fbf6bd15e4f717ad17dce6d6f16ab6020059e25506829cba1efb00d81d4c4367a8875e82c883727b6d931477302dd74fdc8aa160ed658943bd890804e848527e229d11b63c1ed21e4b8a135f67d407b39a01976149c1b79e31be24e5c170ff5ee2c3bd8d98bdbb31c475feca34f39ebdef0724ebfa5cdf73f5ea3aff9db3fabdfbb12a6eb6d9bafb930f7dca62dfa819e6910313dd470cf1c8189528b902310ab6917f66381351cfa24d35029cd58b30631c8d5827b252b942d23a86505ae6521f2d08053eec07b54c86461ab960e32c2d1bd4699288881d742657da61a28b904e8babcb927b6db0b6ee47fb066b20a6e33f72b5edbabc584fb38b2b6c718c1f1efcb73431222bce0cd0d025e97a87c44aa56e05a583e840b49b5b9747f8ffe11eb67ecd69d08b52ae19d9af3678d99efe449fd7fcfabedeedd7ded8c5a8b50cba5336e13becf717fd02f70d470bac8f6b66499174b76af859549446defe69b2c79d307553b5d442a420e3082483d2e6e7f99242a37d80ecc5437e722a29b05c195343c94ea48a5f4574f299ce112aed3cab4c9aa4d30f41f79d558b4605a4cec0d85f1e6ba3c8aaa9591b7fbef3e8e5ef37fbc8f6d3dc7f6ded4b57c1a4fc97455a7155ccf391b252fb140ff2cb7f5e7f53ac77f178eb40bf7e52956e94bbeac7f3fab970eaee7dccb339d95c941f3f25d3f00f8818f175060de63dad882370967b1914ce836a8c6f764f2dbc4d1d46415f40417bd5f7628e0f140006b331b3d26e5b8f107ac78a430a730660c3f6006012f1b1aeac8f16dda33dad2e4b6dd6400fb992e170907e67fa25ef7521f6fe9e26fe82d04573a5773b0bb73763ef9b1ddf6c8a176590cc76e0523b009583ee390d501cb9f168c8549a5b419d0a2c4558cdbf9202bb145ba5648a6da05c784d176eedf8e27498d7b16492788727b31996e528aa2b8c67e06e4032e552e26961146682326f82653d8c2a7fa22dfd71abe1d5d8a933063dead9ff976bed277ba827ff6d2de7e5e385ca78e1ae4ed4ff61018a48edd84e36419d91ab5a7dbc504c7c4660431bc251a0a03828c44e5566aab88f05c4b89f7482ba4cf87a0a3faa8175cc3be83cd5883117259c2ed4e25b59ccb2ad37184f4b8c26b566e1fb152303602638fb93d8eef7ebd3fc7ab3e8d797bbf450507e9a86a198ef3a48edb03f7b45a7f93cff1dfe39bc0aae20881840b73aec30779e062dfeeeecb3d0efae43b70a8e1baec4cab6589ee1835b7dc4551562aec031bc42c9f105b9571d5f9be8bed8c047d50661b5fe506d2c7a3b852eb05ffd31d7821ecedb2c6c42fa5862b78434aaf4a2aafcfb47b2dadb68fa9b2d6883736d59b07c43039895bedc626624d767eafecc6fe85afda27d3a72ff8065ecf5b951a9e11475e29bec4cd5c893be2cd9c894d56cb3cabb0daebc4bcf9fc23be089e825f8f4849db7760b82cf295d4e58c17f936d1db5152db46daff321613afa0043e2c48a08550d6be335ef152ab430e4bceb2813accf06fdb3c5db58f3e833e022ae0658e7c1daf10930e2ac701aaff8025d7d09bbd737e8cb759351e2d432d170efe8a8bf65af1a20fdbdf731abade66e9966dcc7199ad8ef6e465e30c96441aa962e51c48450d3867b6df87d5f826d3b7dad296abb4ce595a322718acbbb4986e96cad2e743de2c5d6524918553261269b04896a69b96de2689f0ccaf65b37425cff8b8925abe90dc1e258510a8f0d627f7fce77be29335feb12d9844d6618caa66f810e777663fbde7899aebea2b4cecce7605d7b0e30217356985f76b24ab722ddbc70a8ff140f2fbc9df739f5e74ff98a4647441ec2db6cd3c64d693d0d413b1bb40f0ec91e8f2268b50b38818428e46e26acc5054ead9242788e21bc230c7119af1dacba55e3e06d5d8268af1a0b27bece4b38c41c1a8d009c595d0e816159eff850d779243095c749372d8c7469327fd78bf1fe6116e52fe1d6dceab703dffce8ca68d23af5856f071aeefcebddfed814f6a6f4bbfe9d331177e193690e55e5078715c3753668ff484332fa98447586c264ec7635d048c4cf56cf0f4980bc13458f0328fb89ddf2d1d9553d5084cf11c47b24c2776bf608d2906ba9de962c359dc2725aaa5eb7514d87a464d8d28f4fd5cf8e77baf145ca86cb5f78f8a54379fdee38fbee0c1cfe36a3727f17f87135a87abb8f6943cd80bc7bf8f76c2859a906945cd39500d0dc7f7cb52dd7322b6c2c64f71e9816521ed445934343ce14fac606e343a85a845917587ab768dea5cc386e7a62a7f9a6b0230db5c88d2040117c922fcd5d11aabc46987a5a266c6114d78f91557d1c9be79851b6853675cefe34cff25cd9cf36d1fc67cf77cbcd7deee364297fb78f6855a397b9fc62fbd07aa70b284389055ae8821dcb8f486d41684d3314b8ce923d59b40dae3a7acec027f40d54c131e03dd8d881a9cc1a6c898a891dee43ed802617b711a3537c29074a6db5bbf500fb4fea3511b353e68b4e410c73e33ce8dfec539a4cf0bbbbf0667daaead437eb6d1e7e4d9febb68dd3ef8bae0c4913a737e697e21f3b45662499b3bac6111569e3b33c453aaa09025dda684b5296f0b9fe1f94c374741646d13807c4295ef3b30410e5ea5504c483576a99edfa761fbb82c29e08a9909f0368467e042fb766f2fce395622fadd8a086a7f6bcffcb3b894fddd7fab3d64faf8691e21f08a23add9f99ca22e3fd53e3dea3a0db19eab94dbed6edd1ee68fbed4bc9dd38d795d0ff3526ff8b92d7e880f73b87ee664fd2fd8866fda7c95dbcf5347d5e9cfecc124b3d19a956dc7edd1404b799bd2b6892b5c31a3e902ad04a9633ee0886d48dd30c4826d0a989339a29c1bf75a469b29ab602f79db271cdbc8693462ffeab1ca51124946a3bc5f30d9d108e79cdb230e3d714e0ff783b84fbf5b3349e49dafef3893cb7b5507fa418cfe077a696fffff4735c1efd7e27f0abf013ef083bf3e6339dc0a6655dc061da3639245d9361d94975061a586e0cb4221c4fc0e3bd92382b8c7aeac08670625623b37bc96444cc585044c6b1e2881fd7282fdd428bb20f26e852e3719955b51c34ed825c8aaf19370dee763ced826c1abfebfc17dedce96f77acfdf998b33f8ab9fcfc5b7f2b61fe2b0beb21323918b0ae9a86c1f986ae6549737fe446c48389ea252da41ed59d2bd1fc90adf530e1fb1de3861241659995ba82e87d0468e4f9197969d39d3a09f91bc64761350025733d0da2c8236ae1048741cb221008240e39d9df8c5fe7bb9db3ac9557f36beff1c0f3c93c73d708bbec7333efb6b3fd6b77ebd365ee93d1eeb93c3d738b0b767f7276bec03ddc8b367b976b616fd3f95770d3fd02bf86a6d51acd1daef046857410d07425b8f575d2f2a61a42eab17b6364d74f49439cd80980852baeda80def67ba66f983c57c1bd3d4c01586f75b31f1188b509c41aba58e8608bdd7d990193ed0f280a0d94cef560993ef7d906badad737958f0be9ef238b7af3e3fc79acf63f93e3de3ff4375956fdbdcdbcffb397ee6e7bcb89e92484c586e2ca972d904adb1ee59a126f30599f64105077fd8f3779fa9433ab66b6033754eecb6337176ff8ab8c4e77ae957ef7fecc75eeba5bf18e7b40a0ad507a0b1d804f671d534acc42bbfcabb10882951ca5f3a122443be60cc1bf10279bc96b60f629dd47814ab3ca1143da50a353eed1e97b7ad879df1bd80d61ad7bf7bbff00c56423fe4b9e265832938adc3fb740d57473d128e36e97e5d7d5cb3706e9e965ccba583bec2290d578a8decfc87368e70911cd7e773fb7b0cdac57190dfc0d75920cab115466c9be8520b213363c32b900b670bdede2c60d3c89d7fc79b1c336cf089a4a11b6c79387649b9366461e531c97b4efe74a8cea344dd1b59d9940161b1b0b52283c261768bb2b00da592dfc7a07deeb73ca586d7c6bc6b96d5ee4e8220f91c5fb44d76f3cb21885feb1c7c99fb827dace7dfa803b98eef9055e87e8fe9d00fed1e6b962ed027068fb1dedc92025684e6a520f90245de54446a9444561102f980a97d2ea69e67867a8af5b6f94a53cadf73025ce1ac8d909956e83189f675beafda077bfdef4b38ab96136af02a1e1613cb4493bc4f75cfe44eeb2f4b9c243af6e9801ecfc61222bc49b92ae6115a0bceb6ffad793ee250da4cef767ef7fefddf7d77e486bc0ccf9500f32e297117f03f46e6fed972281761b806947b37a9aec2b96ed204e41603a626269e262b739645ccf6c3f10871dbc00c268436d4b761b1ace1dc87f0091572c3c33165d0ee88e3b150870fbcb6b63e284d093f88d1440ca43acad3ca3c8cdde7980bfd3aebe9759bfb3da449675cc4dc7c4af5517b6ce7325d2928a7987ab364a25689061586b9480ab82013ef36504a718873e2b42b5a29d30766820cb1a0055c6544eaccc8a7749287335d4d528acda04440f23f3db5b559c2e41aeb5d936879ee47bfb70432c609a2e25427f353fffa2fa7cc0baee68cfe70d7cca3035fbcdfbf70156967ea988ad4193f89bf3c41e734cd8edc28da0b5fcae7fc9da84f0d34cc39ec85117f5e7b558dfb34d4ca38c2f9dffc10fd8803ea705ef4da7daa8f1fdfd67f9d9cfdf7c29db689a306e98cebac82edab38d2991abe7d1b65b6d2ee93088154977dcc41bbd7c4d4d993dce7e0fd7dedefe79c5187bcc5a14e9ef5afdadceedfeb44c72837776d24fc8dfd71a2539a72f81473a9e69195ffadaf391f6b4bb97a4ab8d664af6bd9ce6854eff6475ab13d4e3f33b04a57af6ba04fd6c936ab18906ed9c6b502e245cf999ee5aaca5c6f230c4f6586ffe97b6515dbdf69592df2f4f31aec5ebcca477d38fef5fe99e758c0df1cfe677548dfd09e4d1cb84e4ef7e2f7b89c7e7e671cdbdd9d6b476ea70f6b0e3ebb2b0f7ce078826e9192159ac039d154882b3c2c2bcdcea836c186ad31156f24d5aca0981a3e683ce26877b3013d04bcbb5fc03f20a3180817d781361d449d83b8ec20891ab29c4c7bcaf17d5ae222ac85e6d7b4134a182731e9afcfb60ffda057bee5fb77be8cc7e9bd0ffa260e71d616d463aed6c778f7db5add13bfe22cbe035c219ff6591f0e7644059bf4a85bfdb626540d477bf2b2ba61862cc4b53854b20f79d03107e2a41223c6549d385e47c3f13de76a13ea9a1fd622086b654ba64209f35870d321a5f69014f89e6a08f814557e940f92e584bb1e58ba1e0f067627275831b2c78bdf62e78bbae133717e598b26fd22d776d095fc77ae9e38127ac27f1dc67adf2e307ea06918b3c19b108a5a5ec1494ad124032a0f2be887466e2d9565e0c23784ca1b9fb6eed236ef76eb8418964a22e40b471bf1ca5ca5b62c7c3ddf86508ab4ea821968ef589427990e6f924930302d5f848e8c33c7eb4e62fa5fe09e0ebec8a7f7ea1bfee333d8d997fc52f6f777f433f7492739d344a8b509dfd90b38cff4f5ebfae5fe731fcdcb53073ec53a2be7dff3c5cf7082ffe84c5ec5bccbd30aedf6e02b9ffcb43fc77d77a1462eda509d31325894b058477abef0296c63950fe180cd38820c19f821a1f93aaef310c3e62eb3ff6c432d336700293ec12b5ac29c4f2c2bad73e0bb78e4975a9f416fcb0c8963661921ef3c0ad82c818a2166bd8f3d7fb5ef567184142a82ddf9f4e5f987ae8227f0f24ca73abaddedc7c358fffd0cba83bd7819763f34ac9cf36e9a16394010f1b81c4f03a37c8c0bfa1882b6966a0a64ed0d7892eb712dfab85238acad01e9628e217e4caad6ceea524faa729b29364b4a7f9b18cd8a542c20aebc59baf62889d4361d822ee32cfa00d3b6eb639ed5652ba23d06793f76dfe08beeafe23b55ea298e3c73ced9483aec69bf570e5c801ff4eba88d78591ef3013b0884abb1c7145cf16a3c5bf2762368be4a60be257ab7086ae8920a19dc6ee66135aed1c48388e63685cca00c13e13493d0c14de2340fbe8dd769952b4ae42a753c8a2a3c253aac48091b3ae49b5483f32ff86e4ffdd66a3c1227da32677289d7d044d60ffcb9fbfce1a1dd637de1653eaaa053205960d252de88c1db08d782b488fbb8f40c0a3a9d71e6067d1bc5ca7b486a65e22a7733d03ec5436e64b7e3d6bf6def6984108b0413044d7d156ff184e972b09e820adff93c9f84d5384907d6863ad3c253acf987355c9fc75d0fb65dccbb46bcf0d77ee4c3c256f0aed89d377febbcfc73fee677f886d74978e0f3cade71f79fab493ccb65709abf5c4987edfcd721899af79c92effd92577a3e2ffef8e8ccbdf8ae0ef13527ef877ca4dfa8f77993d3f8663eedcc38fe87722ce8a3b8d757f725f704aac40322e28e317b9b40da857ae3901263491b47444d17eab80f22e5085b2959423b8960cf406e50bd5ba5d45b109a6f11878f7e15031f5aedc26e28ae15f22bad5b3aad8b2ab34e407ee71358cdf5ee7d2cfbe333e6d4d7fcff7cc9ebfa921f9d41dfb0758f67cc615d0ed2ddc7773edbebc7df3cd5b43fee7be33bb9cf776be1343fffe59af873cd35f10f9c155fdefb88ea8d58562822e5d8f21d660434df2e0b0b2d5d4be07a37a7c24ceab2236536ecebae0c78838a00b0126de69a1708ddecfd70ec6223784cb83f24b4a14b658f704407e660e4134ce2483e31c55a0ca87e72ef9f59236ffcfef0944fe973ecc39767e6f9bbe78767e617fdd9d9695fd4de7f883bfbd2be58d6aa4d097d94613b040622cc50f622828b98b30756201bd7e23e006d91da6d99448d8869c324cdadc50485c46956483789a4f249387812da52f79dfc71065a81808702de0d4c67730499128380ac1031e5ff0b4cd2dea67b5f93fabfe192f8ea9e63f96d5879d40723105639975c8b31b1540a3ab6a078925428c745d987a05b640cb7b8444f78805b51e4a5646c844b6948f85b0f68a0a755fb200795fb409509f3009920e8d7d91096b8c1e1789410a4139dfda7702317704b7c775f7e6843be5e1bef3049ef63c2c733e1ba98a4333adb3f3f0f7ecc05f1d5daa25093654b33852b4a4d414a5548c70b7dbade702a292d6c0311e12e390a323d33e242ad048c4decb24e4653208c588f69db8530cf93496cf022f752e61b0cb01bc4208fc118a48e88fcda4b70c46a3911ff29bcdbb7b821ceddcb9f62926a2f8f75baf385b7f1d117fe564d0cb902c6ff4cdb7bdff1dcf7879a98eec2584813182c086dec08c39bf2899cfab58061f84b5bbad68d3f913714e4b7fec4a299cbea8ce72d8f304fa976870ada2d1c6d229987523016b8ea4a4cbdb5ef64dd622235518d6f8403a74293f358534e5cc45d466573811ecde779d00aae636e168207ed5b8cc7f95c63ac8f9f621d8239d7f2ecf6b966eccbda995556c1e274cd9db5d5ffbd165df7fa98a3230eebf9efe33d7e219ff3c265ed0c6c3b5a37c8d7a44d8d464f1ca00ba06efc4855ccf16ee54408e67405a6ad256bd4661425bc14069a881b544cf5148a8705bfef9694056cf08770c2a633bdbba5919510f6bb4b867c3d1bb251e8d8db6bcdaba8d43abddd6b52d5cffeef3366f5d37daac32271d8912b746ffb7f43bf37be4eddb48ef258cfd53147b37f3f71ac5dffa05fbbf3fa729e48fd7e880174a98d3aa23531d2bc1b546096d6658f3565f1d25c270c928c8b9560562f00c47e24e70157f79c6b13c6cd3ea61e086b3c8f810c919bdf20433a33d06dc2d27fcc0ce4f05ae8887a352e9477094fe41778bb75aa9b87f737ac4d5abfc474ce6b755652c9dbd71afcaf70c4ef6b4b76e7e8ad56c41cdd8b501b04d7f2b4c64d6cf89feb2fe9cc94ab4ff163ebd4902aab509ee9b4dd3dff2a7674eef937f8b4170ee38f7297f5dfb1481df5f84d0dd26fc47ade8fdd7f173b2d74060edce72c4ff7b8b637fdf939769a9bb778d53a7ee4595c89890cc75b64780fcb4a5a334dad90d3559ce57de66c8d98089ed2a667243776ebd8a7682ed5ef0d8d644054334dcbf15aea1e4db45217ae00b85437b8d4c892c1382ebb0d8330a0b5f59fb281b7926bdb8fea62ced927df5a975ffa3b1fe1f67fe4ef9ce9c36eaebb8dd4591feb7010a1f628f6f9e7e94f630820a3669c29df5838634400357c60a2a5bd06986a3e8d104e0d1989227f08f5f1269ca81a197910472264936c8bd4548fab168785b039f1a820124bdee6bc465aeae6b93f58062572950cd63625384e68de5e1c43f8143b80f2d4d9b6f1ce2ffd0a5f79254d995887bbbb73afb17cbc7bfe7efe513e52decd805805babacfcaa9c6805c61a554a62320758d863a54a8f6ee12aa6ed2e8be4b38ea0593b3d960e501917e58092de339ccf45f3d9ba8a7d8b00a5ce31bc22058aabcf21574b1c114038dcba01ab2c83bc1017c7eaf5cc6afbd3f9bb87adafbe5353a70929d3f73cfd9176ff2119f7306bfcf53fc2c661b734da5ce7e8f6de6e19bcfbb7374b8b49e974ca623aae15b9f64dbb496111de281f106a436bbc30495a98371105979a8f2240163cf8f18c295b81105ea69cd02c1e534a6b9ca0ca544d88a25b41fd92088549e4d59acb3c82b898ec3844d3b4490119ed5e9fa8c4bee6f2ee7f3da87f7b8c36bc5c4f7b1dfcbf422386e42b729b1dd8e628d3ec6251c18f736a1dd0598629c44d936a34cf92e2c918604e3a321746481ab2e12ba67c7baf0b1810c027221a8ec43bbbdc183ba418a0951fceec444715c6a15aff3801038e20a5d58eb70019eea82f8f6195fa9489cf163c271fe15e79adf9f60517f78dee59b4457657ce08878d5fece67ba141700cc99e13f123d786483c5c3b2b9892369a7dcde0843dc1205bb44c34dc61465a0d3783536830835b2461eb261ce343c5996b9eb4fe20db3b5874c8fbb58536a41d16a41240b00bb4fea7b2374c51375d67d763b06d7aab98db969bef681ffdf0775dc87b8c1710dd447dbe3c4f6168388847ad1deaf77f6dab9bcab5ca7fa748f751547dee669bd9fd70fb45477e733ec97a1b68da3635d70fd993eebfef78fef139cd54048ab719f72b84ea2e60d36f6ff7d9053ded9a4c2c14d56ff7e790e856fb1a167cea466776788ead7979aec57d2f17c6eefb0a643ad492bb1f9d88efaecfe66201c2494ae97f8f6e89180ce2111be972ebc4b0a5c85c49b093e1d2d6c1f040026d4a53da29dcd14abb97dbf0d089a65030e08955d568db6a1a21d1b2c944cec0d2f7283d78da06edeb1c88b05f5562940f8423c51913a65bbc7427c1963993ef9ab6be0895e6301f667ffabcf478ccb65313413396843383253479240c73ce1e64342f1ad64d311b5d1c4af3c3fa995cb5c095366ad16d49cd2d518c7d464a8648c6879c160b9c906c19352223c1190280463ce30a7f98413cb25a5248837158964f0c5b971c67679570ff079adcf95cee6d76dbe8cf3813b82f8edb19dcb74463558fb65d38be87747fb5f8f942018ebace135c631c00133f2fb2012b7b26f21ade2ce27712f0b3c24bc9d65b5d824a536c5358ce524c72113f731c9596aff31b34a32dff614d32c53c27b73aee11b1ec1358b2eadcdd8f945de9b3a83d3f3f559734ccb3303bdc2c19cc7987cc0a7d01f6da04fefe397da8ecff164ef6b3e7e3adf9bb43ad8a98776c1a18f177013e3c1378933ea125d4cd3beb5792d71a094454ab1097435a5c43eab5b796cbbddf5fba00bf55fd2e9d34fe35a07bfeba43fc7daae6f738a767362954b96df510047cc11c9dc107d6a230f6958230a7a888828fbae2eebe7b8df36e15a13f7dace86deebf2887718e0cffda26e233956b2624fd2fdea0cbf1267eb6edc0d563edb29cf63feaa1f3fe27095b6aa85e3254164054c05239f5916d1f39671d42d6cb5480c6b9b32a98208a180375bbf644e4ab50de7bec138bbf1e954f72ba0071c974b3b33534d788ce56640bb48d8904ab781824342783e594c50313f8daf7e61e71d7890a6f5e8c877e4bf8f41fed519ad47a3638df8e767c4a1b6ab48757337575ff1bb9ed17ffb99eff5beddc31ceececf691bebe3a75dbbf2161cdbbbe83e0e69c926d4450f4857dadcc857888fe79ca3019739c95ccb21953924ab5f9a5f8e3983de3c2ef00d9db04daa728395f1b054a24d19de900add89524e660085d8b5aab01f3344fe00516ab53fe44968a31cf36e7e2197e2f3bb3fedfcf9e35c3dd7a47d67ae5efedd7f41a7ee4d9bafe728ad607bd01addb573d1fc94c4281f7d003536a0dcafe52256cd348c18e2b545635d3e6083f92c1c6b41b9dd48ee15bc8c4da2e52becfc1a892a0664c84d56ffd6822ade0a2ec8c26530d5d4064536c0f51f43c0d224bac458cbeb2042f803fcf5d9bac62ff3bafdd5c6f4a5ddd7e39a196c9b39e3ddda3fb677d1d87609f51e12c35a11daddcd41eea32237677a778f5c7b3b07bf3ac21a2729bc904f443c076d4bb83dcc7439c3137433d3a41112982c4b3c5d4648cf68eed201b57422da656506b1de6eb9a3193e37bd0547b3a456e11e9bf7d1d87ea746e03a3ed33e5671b4e78f7fefc6ef52ae4e2d9f69ac63ce1f90e83211fd98a4b6d445e5dd603bdf0acdd3108016a5e3368d6018dacdd3d2c9435eaa4908046393b28b6b8f27b6b990133a0a801631a2820c782b59a000db2861345fb13ad7b0a3a67ea581d3bce9782b1db5492bb8fed46fd2f7715d253eccf59cb579465719ebbd2fcfcab7799e73df1f38871797cd8143e90810e65592362a74622306de2a28b51956f97da8213b0bd77d02a09595de3a65deadac908e4baa05e5b40b6133e72e26b884043b7999baf7e6b21c0b69e4f70ba7b38563ea29d5ee44f8eb117154a6809517f2e7958277f992bf7ecffddeffff7dcf5e1ab729874fc2f9925b553ff8a2d7386fb436e66679e4527dfdb945ab832f71899dc488e4c2f566b8326742ff05964ed387ae459735dd2e236f4a6de9a51c0f290d4cc49ab5d014c11c3e047cd487657b839ddc66d07217bcbd650eab523a5e918967cc75b316ac794a78f7380363bea0c8f5f5c0601ff142eef9d1c74f829b60ce599b44187c8b2bfd7dcdf24ff741646dd29dbd79aba9942b201dd61fcff273fddaf900c3a5397f5a0543a6539dd2e963067e75cc951daf9a21d6602f236f8b99e589f2d7766e28912ad4a485c073c3b37d5dbb93119e4ac5fa00c0fbb0662bdf989abecb16f1aa2598a15b49e99632b5098a72cb39aee2080ff4f298fd26ad502ef7f570bfbf18fbdfd7d181d6dfb4795cd36611477b2cd076cfd37c81eeb31f823ed4bbde27fe86e94d2526ec2e2d353be68d2606c8820a87bee15f1873193f894ad5998137d997faa4f48ae3221a6120901adeb3bdf6ba1fc75a8bcbf67b4cb579e67a75323091d8de6249fff488e70f0b57ba72327dc413da5323eb30f4c2306abaa0967e36f1444c548b2b4d2cec3690b500b2d29e6292932514e182368817f871596a362af2855f787aeac030735a85cb6bd51be18ddcebf78fb77ff18067b00e95dc63ad44cdd6732edee6484ee2375a9ee8b4158eea3fad39aad9531241ed2f4f6af6296fc307ba459fd648bdd39cf95077f5ec9ed5dbe6cbd8d09ef7e71ab1c0f126d1d5f37a3cfc4d0e9caf97d5a53746568a470c9a1163d30153b5e12ebe9b198a63129b984f8d50ef9aa5e3e582c248941e0e0aa5b31a2dd2d57833d394810a55074a120af07c31996a09840b618f1e258847cb92f9a240252ecdf55c6f478976c0417f387ebcf93ad775b5f8da61dc920af6afc771ff994c2fe701a39a31d36119ebe286ba79411de6cd062b4a5d1166f574e3eb9dcbca5fdbb80c0cc4d0884fe2914f60b184e8de6772b574ff184bd8dc62b0ee0413003bb19ee9e528abb23e75f227c69b81951dc2a556c5caf36474c245f8756e607786450c247cdb26dfe35bb8466c697f4eca0837e9add63cfb146fbffb81ee9a13778caa3ae34ac7b5dd890882258428b561c918b3a50e8b0befdd773c3bff05ad11fd4d9bfb7b37abc6c39e9ba792faa5dc6507ae4066b18a6ee24a2e42a70b04fcddb19202aaafb70b979a990d6748ffd52d6fc7802908f82433d884dda44e2e129719449380556d10940c840ed671c18a8c042356372a0099961078430a5c52ee8f3257fa3cf28c0ff674bf8c2c90f67bec6999eaa07d8ebd7f2b267685584b56abad747eb559b5f30fc6edc1bf78e675ffb87f3fca0d467197399d8727c85c44d34d0aad7b59a9991fc99ebb962f22c5422a2d5e7824b44dc16c96670e30e6436e2db8e953676c4a25b6bee6cde78005b8864f88b770599926d3a5e0a539d01a0b4e5514d7cc5dd8eda5fbbf141c9ed6f29c62a7def305fd0cb7e8b0fc58b7736cf7526d23bb0d38ec620dde221d3fa68a39b864057164cb09b3b1eeb9b191d7e7fc18e1b095e4d9d7b1f3fe1a36225671cdeadd1d726cb745b797638984338652c77a4a7010e86c8eecf540155cf8aa99f8a52718f5f2a52bfd8079938c352de10dc0c56eedc199afbc95efe65b56751bacbca7008c6d69c087cc954f011fe7e980b782778b85b31d68d994b24035552736e1a7b1f2f458cff97cff7ee6930b87ed35adf6f99af77990cf712cc395d6de07edeff63d567b7fd2ddf369bdcd29f517f993dd9ccb3973304a2aec11c07454365e00b048220f20d0d419f137e43a5c9dff9453120e53d9adb6fbfd032fd8977a1af41a73f0aacdc3b8bfd24738ea67d08bf648aaac8656b28d4b085202731f34435a761351c41b0aba8a3be86149479a2c72df67385e567892d2bce7f63d48dc3f8f42cb36728022d0d11332ee47023480eaca0e222f097429a4e3e5e9807046bb760e461d35ae86d77f8b5dfd980f4865bd568b28689308abac822035a6ff80c13ce143688eb68596f2e7fce24b8d0f38d59bf25be14020426d13578d8a8d37fa5427faa3bbe7ff72227cdce72442478dd2d7f87ffabeafcf6d1e6dd597df3be967aa7b0f62afcfd2aae5db674f314ecfcf5670d86babae5eb897ce71351eea2adddf4f99eb6da433def385cd2bb18eb97c854b78cf1dbdc7fe35c2a1ed9e5fb23255fa66de4ff28c46e2a822b93de066c4dec756bb35d0c88abe1ef3534d0f3d6f627d5fabbc4e1d56ec63ddab4fd7c0735b6fb9cfc2d77c81ff522fa186bfbab65fd64aec6d3d74a656f96735decfebeaa02f76ecc7c767cd97365d3e4daadcce0a5490d29bfbb67723209b51cd8a796502cad868ae6b0661be46eb0c0444aea97d6ffa307703fa4b0f190ae63a0bb06d6ae960e9890befb8a28f8c065a588d37c2959380c20d57b0f48150016dbf53cbf9ed5acbe733f87bfaafbf9fd05538799ecff9bf3ab0effad1fa3fe09125f678bab4d55dcc2c21ec7c1d2a0f041aacb0ad38af7125fbb1264a309a191e4f8a182c98e7856e53a4e158c786c454e58e9c883bea420f2b39a4c48b31d57a522a28a10c5181074ea08f696bfbb5b008f83c6676eaefecdedb6a45e4d55fd939c7baf5ebdcb18ea6b24aaa97717efe4c0ef5f897c530c4ccd7581d125c877cfb48ed3c49091d12dd1c24434e66d3c7b4648444538310ac2f182c04981a74888750bfdf20253bc2954369b30d4a4f2c0b18c8dbb58e2a2fc9e0ef8112e92f39dd12fd97499835c71cd7e77d47ac44c5fa7984377bdc74651eef9e2ff5d686abacdfd3b68f7ecca96edcb14e78b80c476a7954c78bd46043e88a844d3c9850b1e6154b029adfb24890a5a3cd3343f200b06ae1e411026d24400662922356326d3e201e1742639ada2cabf661c93b333072e5dbcd6dc8551814f081158146876ccb3471298e74f7aecd1e73e57a9bcc61bd74cee8089df51dff5d735e38ac4ab8a9e691d5a786a5b21aefee9ae73938d3af9fe4f6c140225871da3ef855e72f2b8ca81e8f78a9121c8ef94c6bb465d8de0a10e8a2b075e4d051387806d2719dd6d63c88bc5becb01e6b6a4b48a0874c89586f9e121d07a4d41ea8b3360322382ea7a3d98048a877f1055ae09ffb621fd93bb7a3ee0b3dafe3f81df6c37f81a7fda5bde3f9541d72ec976ae7daed92957d5c37ba80b20c2a7587195c67b608b1760f5084aaccb5d0a5e775ea4053f0601ff7111cb6ffbd31799fef3ef847effbf303ed8261597bf72987a6bc5d0f3e65932cf2eaccf80d128efab01c8f12677d0e5f52a64670d8535ff887873aa96bf8e86370d8dffb7ce3abf6c1a1deeb328c032624ef7ca3b105a1a3c4852ce34d1f337897464de2d3ce0b278a300dce98d3c110a02972da995f8db12cbb241964182b18cb1adb64671744f6206af9c80a35090ca18713ec07c4b2d8aadd082086a004fdb5f672729e07fdd33d9c1ab811baf98d3ce8ef03f7ebbfdf891be9a83addaddfc35a7df5196c2fc325efe78b61205da60b12474ccb74c8c3d27f5c38a266ab76c16a71cb9d76c21c8dcb420ec9209e52bdb1b96a7449c78c94922d8995240366999d633c11103b0df19d661bd4b20828dacd994a75a12fa3e636d63cfb5ab541473ef8178edce77ce51758c35246d65a44b9ca8aaff22ebf4f7ddc9fcd9996399d5a3aac3fd40bbcfe7c98b3efe30ced16e9722aec7c2ec1afedc215d3b93ed5934a1481fe6b140fd822f6d8bbecfc7dcb8df6c5d96becf7c5bf6305bfc1d196edb9f52fb39b9111945d88a9c208743aa7e2d687d2a4b53012d7d648c13aeae40552164aca408f95aa0510eb9030b1a4b84e6fd75b59e71d62621a97da1daea12f06792f94bc49233a621396f80c6e4495b7cc56f7617431bff7deef4af5f882bb2eb806def5a4ddbd1db0f30bf9b87a8b6b0b2ec4bd824719655dc24d2f8422a07c9cb39a4d97ca33b913f43e570509db22ad0310188d8d222f9a0173e247f281688c307b3ccc34ac101077b29056628f0ca97c73793bde8491ba27f0b746e1b40b6fdb6d02a115ba54bb9efd6616afe2b7e0cbf86de4b7aff489bff683f63c83ff3e7759afe5f19ea70b16f2b05786397fa5874c9edbbae8ecf7c3ba9923a0f594db2306fd6d52d9bd1c90206577c3b89c054006025a77ac8026ab855a56cd2255fe68418347a6a6dbc56d4b9675d0a7d1fdc0e9b4c70e7a9cf7ad81225c8591bda1d59805547461d9b88478e6d5ea425fd5ff7fceb7c286bdff18597dc2b5463a4a7f35dffd99985c25b9798cddbdfffd739a307b0e90dd79d4277bbeaacf639e89038737fdedcfeac10c4baead52bd1b3e7f3735cc39ca53a7dbd7a2fd7d767ae67777cf9a4ae810249150f3a851d9beeef39536dcf762c8e763cdaff2c9cffd3d8925fead0f6bd21a6ddf6abd9767b04b2fcfeff9363e9f87e767cd73b567277d7ec92fd73bbb176ff6da12a109b24ab5e2dd9a3ad1d379e16434b7593506a9b1e7403ec4fd2304e2c8039fff7bf61457e3d1076bf2eb1c52e4b7c75c03109197cb632dfb97f8fe7fd708389713d9f90ce7be6f8ff1eb8b628b3380291972974772452832e25a1949a55aa93528747f8f8288096e8f895f360956729310cf4aa1754707a4e2caf442a28c3930fdcc361369db46402c411cc8b19b3d9241ce7189540a1447601cc8121809bc161eefa3bcd2491ee3304e7cbfd69e325d156fd6f5a9eed2c7e7c1c91e5047fc0adbad61f04a47ea9cee5093f5cfb8d69733e0fcded61978e3139d3b875ef01cafdffd248fd4643aecb30a9aaf7f0f853fd7ce7e93bffa1e4f9076259ea09777d9d9517ffb018eeff4036e5a3b7f486cdcfb3a5a04e57a1bd44dc9684328cc93b4c698457f366924111d5828076c21bd0bc2a2dc725b5a64101ed57e6f04b36c52b38def8afb8c8e1316b60c4fd82cd5c7a504c80af838a13c1870c5acf024a7fab1fdfae62c3aef57edce0090f6eff3655fd84757a97b3f77c71f6da493ef41f7833a781c80f13a756412d63867fc97997225820af9819e53c6e19454cd0c1728e091dfb14a9578222da92b9814f09147f95c30486303fb016737011d4f116be6b4fcb31583e709cd7a42656b0405f6d8246f686d9d723eff434c636f2b1d34943ecddd7e91633e6f1f18aa8dabf1fa9d9df2f93ad151bed70cd0c7f997fa9cab13cdb69fc5b82254c491a5e65c6ee28346e7bb7e1c6bbaffffecbd5b739bbaff3dfc96246132f565b1119818b9081d4077803c21466062131f78f5cff890a449dc3aeeceef3bf3ccfc2ff6ec3a7523d0e1a3cf69ad751bafca606a8920f3023f64c1b840ad1d562d16bd76678933499bc0a442957c3ffc55b8837e2ec9f33c5138c7b4d200c07ca17cc954426abe8f856372a91085ad111ceee4c238d39ef8053719937a9a57c1324a8acd95b8e782af70aafd5df10f2ef0a5fc9b7f70ae2b1ee7f7b5c6b8bf1dafacea76a779086792b804105bf40a16959dc6bde3458da833d82e72647cda3f6c35a490fbe2498eb91d7a64440405b937d8872edf0b3e017c3f4c2211c84296a9aa55968f8390d59add234d157682589aee025ef94ace449569121e6c505734471dc5ee0b3de7d6b7ece51a1f7c82a7620ff75ada203be3572ffe9cfd7c3e6ac5dd944309f6b1f8094442ab080c7fe59c947234dcd0c4f118fcb9273808d2daac524e469c954126714d4cfb4c58b4ba47f64ab806cd999acc4579a7e3754f1232203ea1ca9d00dd973ef145442b7cc72c6729047e4aabf6466eb477ba2897f99eeaf738fab7ef5ef25fc82697b0cc0ffec64b0fcae3459fe9ad6ff3cf7ed551232c93ca7ecb495ee849a98787bb709d235c9d72efd4a4167ddd2b671bfd9933e3b5c6943ecfaef2fba8b2b0a2eed48347cd3411fb2c86c77ebc1cd9e633f7ffc5deea6fb89faf3ec7c15e1ce76d2a8f3d81958a212ceaaa7b87373bd5606ec455e8a9025da27a614452226e5a5fc362401b55a7359e1080538e1ef629d8ae42b484aa82fedc081259651255cb5ee1b44f994ee68bd20eeb74a385bb55eca811d2e588ba211a32c2e893c0ae1d63c5636efe50477f9d83aff7ffedbfa9865be35e8f60a5a4d84ee5e15ce1f5d95e7cfef94977fdb69cab4cfb42b8760eb13d93cb7d24cb918a87939950e319c316f3e034aac858c4c386bac3e718d88ee405cc7c62b15e8f98db3d856333497b3191dcbe9b49e2c7f17a35f7765bea9240015a66099545ffb38f048d67634aff36c7594336f923ecf55937f225d67f39937fef77ff684bfee91e3cefe5b6cfd1e030fe9923f91c2321539ffaa2ae3fef19ff725bffbbdc2dd56868d1c72eccfa6a10e376235c0272acf6292f81aa1fa0c4a6cd2af394ca5d9aa2b555202cb42fcadc1077ce7764eed9930c9394727a5ff07240c7ba2be06440c70e8c10dce55e6765159133bf441a947fc01d7c78bf23564cb7aaf9d88ff6394e23fb0f71da7fb03b17c6ffcddebcaed1bb393f8c7f9b9d51e31c9b59069d0db1a82d9bc936aae09e1bbd4f3925c26dadac7a40ca3565ec859bf47138cab80be42220855f6e63d88e348b602a3b25eac956b943a9217ea48bc9fe608f725956aac749d604226b5a872d825bb9129ff46f77dba5bbe5f79ea5b7fb72f2f9be6c825a79e15f3598dfb89d489b4bb34e93b7394b5e38efbe707715b5a8d2739ef0aafffadff1e4a73d910446792f79f6f7cf71d696ba9147b353853700321ea254eec6330eaba2324cf591a571fbabc066c4ea21976ed788b1f1a528bdc22d6753d42ada84abdc552bee0ddb02562be6911103b48aa12292552812f44e376d2fac744545b8216ed769a9fe7a1e0b84eb37ece6d7cee3c177fdaef37861fcb7f3989052d5176ce0c177bee93c0a903335567ecbef7b3528005d853518f05e41362e65ec97330d2a1437e2f11e719b19c35380bba29f0cc4f801149896e142f8b1c1722697db08565bb6c07bc6ca65dcd301a9f5be70d37d64707ddf073b0dd51ff0948777a65f98e3f03964e9b7ede1e3bcbddcf1dee1be01fd74e1a29bb13080ac535146112c566cac3a2d884d41900911f811a22676a1432c0a69b57b648cdc45b07d569531b21a3e67488d33deee72a3a3792276d1e38f4d2cf198f67a92bb1dd22820c21753d5d02665e449cbed9e7ccec7fe35bf1179aff3bb49658b8e7d8289d3e6deab9efa855ea19f0f93ca799b27ebe07f97f654e24af993bf6b37bed5febadc1b360afd96f3bccc9dffa6e7fcaadbfd2927fcc7bbe82d4f7a4963fff5dd3b9504fb377cc2cf8bdaf56f7b015a69123cff56afd95ec68eabf658334eaa4ea3d79c2db8ac43a9d669427bed4f3ef6c07df8deae55a8045309edf75a16e77be1d25de299e7d7f97bbc58b3db2b89abb346c5076d85f0330fcff1ae5455fa2e3f1e7dd2cb5492c0a2e62ffec3364d8237accfe5b5ee958448bde2d58bc33a7ccaa96bcf3ccf63b82e1afef6bdabb8f64b6b7da577e55b30759fc67db5d5c7b323c5bea887fb232fc5ad7906391cabc65914803e2b4f3f53ac9a8c5756da682f0618e68ba062fb35c8c60f4057c13a83ba17c8be9b82a1887b132ba96a22849703b50e17d16e8e69cb3c3111f061a30db7e775e70a53eea41083ac1a5ab147fe12379cde5123bccf5fea187fcfe57c8b56f1a533f9de6efff6f3c31c3fde8a850d7754e046f3c09af666a7bd70578c8689c01550896b0b00e398e3718696ab18d30503661a4af34c5c2889c45e2af07826da719c445be52eadc29fc0b43235f17651e196284a681436c62a309d292bb4321fffc5f7a0bb2fd429bf07f37a983fdf7dddabc589cfed665d1a02c462de8403054c44fd40ce4db4a2b2eb250f163a71762c31030eca54fac184815dcc9b52848f43379344cec6c560c6611c99209e8dba49da075058add089f3abe8a9e23dbd9f57411735e5d321968a9ad2bd9537b1a8052c8ef1e4ef75b7e8eff5e38f3a447feb31dd7fc22dfde37afc3ee6d1af6e736f7bc28323de9dc7b9696d0a3edccc78ba522e14390ff7cc238fc40d1e45a39e63d00e04769e220456dc045bc568437de1174dbb6263dd51a1d653449fa42030ac8615674194b2701b5603905b78c5516167c90465350e0558ee8520b2f8ae5a714337af3d6e4950e66ff116fc826e577dd4bc38de9ffa73ddf333bee59bce93795623d89decd1c95f7fff1c00dc86293ff59e465564131756ac578ba8ae106595255d77abaac09949db2a926235770b381f632eb989620f83a20f7b05443b45ddac482a2b327a12093d98613c8920a6dc1041041da4bd739ff1689037ed63ca425b598adcc867793527f9f77afc1f727eafbad79fb0877d2a9579d91be1e3977c8dee8d87e937dfefefbec46fbedaf5fcef37d485eafcb06e16dd9feeb65da97d028ac733f680dd561b227e1bcd5d6a672eb1333ed86b601c8d491833d5a4fdc37e0ac45321da452887cf31a364fe385c87be9314155e1790d4923f6c42d30629e42bc5c8266281457dfd38af4cc2aace4ad9a4a78b729f8dd315c541929deae417ece8703f95a23c69135cf5c5be010fa536c52334a924cbd33cbe8edf1dfb6417e14df3983558a96ab725086e66890ae602d733dfac441f2002dcd5c11672d99a088980c49d3b5f98b4a871cb7adc2a341884897ecaf88345eb89ad0df9252c455565835c9092b80f7b5e0fa9f083bdf40c525864f967cef17fecb5f953dfdb91c3f4afb633b782e3fc7d85f7847c432cfe32decb7a298917d9e88f3d227fe6dfd8af4124c4284b449f734af33e1d9085586735758417f4b417ab1beb979ba206c77a7f7a9d47fd5b78f30fef9fc7b04a135abeccc7eb6736792637ebd3807dc807bd00c38e722178ad57a49ad814ec7e5146632df42f5aa7fb99bb5b6663b3a3d01856effc825149712972b7b5c3862ec386aca3ca1633576f67aeb8cbbda192d5b04d4d7b4fac082a4982a2522c33eac63a25eee7d25e64c880b7383bba54abbcc02ffabb3f977eb4fdddb1b69b50bb78d3bd39d52ed8153e90a3ae8839c7ca573184df838d7d37e6d1f7db14356cd5b9de711ee7369ece45d9300facc81807d3be5c294b50321a6e421ef5bc32135ec3a5e4ca27bef3cc1ab3c91b05d3780d423fd8a54074621cadc4a2d8cd25ce42300184e9415a074d6491b1aa5bc6bd0a91846f44af50dc6341c4ad1864d54f9bc3d9dfbd6ac2fc0ff06c75b1b70f36665d781864a7fcf5bbe7b81dc7063d2e08880d21a26ea785ebee436ff89c8dcb3e3238ce054759ff705b4f4a43bec8a93ff99c3ff9b77bb3ff9d4fffb7f1bbf0f1706fdeb6f7e69ed9318163e2978ee225d77c626ba1bb7ba43c5e9380213d8d2ad8321044f748a4596238416dafa01a170c3f6650d9ca8ab6a13774381a5ad14263e5d32d0365990aa789ad6810b2209a49fc780fa81b5fc1bfff7e3e73cb396ac6a572fbb7bd79415bee2a9efb3b72491fc73dc6111ffbed5ff49e6fcb739820b79433af604ac6e6e0bfa97ccc07ca90b1004b58588a315f94990ca2392e695ca930e7c1afd4501859932d93e92e4626ca2dc767cccc32ae9e326146110aea54ba7b5a3fa0b4090c67ca6146f198397fc8f75fc203fc2fe6f6d3b887b9fdd46bfc4f732bbb4436c1b3a800080d1e675c3861659a5006fecc6f9f726008437a202cad22200caba92599e2fa71b86090186a398b1c3e80029713557562eeda53510f9da2b6f73499ec15337d51dbcedc2ffd38094ade9b4f18f9efd44afc4f188cbfc7e6c7f9fe22aeeb42dfd23fd9fc77631eeddb3b9dda7f8acb7d263120aeb827cc45a1ec82390b262a5161ee4f40ee8b5956058daee11319bb7d8c308d987ed2632a67ee04f08af6aa712659af13ce8c2f1a5ccbc4d8f371f98bef872159a8696e3dac8aaa8d59ddad99bbb6be0b1754f8a22b46efb58fffea0fa1dd26bdc2737aaad914ffdd0f3a8e75d40d3eeacb9d7fef6ddc2b9672675ccce6c609d35a3494dbcf52fc8442883aae4c5b18da9051976a00138a30550673c99c7b25ed016b148a79178590f7538b3a5c90284ef82677cb81c486c91a6ea5b713b127761137556cb523f66df888cffed01f6b73b57956e73ad15f7134b579ce3c71d8bffdd95fb8e027dbed7b0dfdf022bfd6071ce0475cfde1779dfc27694eb8bb837d4ea8f9f01e7fb50db9377c9c264e591c79d5af62fbbf855bf7b4e78eb5ab973ebb0fcf01e03f60c61d064cc3211eabc46963632c3e260eaf6d7f3e5a4351db5cb360121953cdebc0e7e3082abeb3c244ed43ab1d8596ca98276c25a35d01423bf3ecc7140c17b378c88a0ada8c899863bccf80be231e6633d16ebecb3e1c7bdc5fcefc896becaafefef1fb355e4f256dafeb7e4cbe4977ff602382321fc12a4b8293dffafe39baf05f74f6798132447f09f9b099bbc1f35cfeb053d07a8a9b69067638edb133e76a47c601159803e9999430dc86958d955f8673779748d73c51d97605ef0cb7c4942ff43612ed93f0b110f59087f5649ff96220aa5d23afc44d37e47c9eb3f825560a9fc9dff33c4d7e159b5b7d13c796de9cfa840eff07f67491de7ad7c60489a4f069aab956735fb759136e9548577a4136e4b14be3310e0aa1a6338fde33204c0a712d3cb8ca6b62cd3896c4a30bbd1fba995fb6331756b98f23ed9583b9ef647369ee58d2daaa2f63e1415c8062f55dd8e9c8276d5ed3a3cf52d4252cf6c3f61573361aec2ed5dd239fdce512ef53ab2db3fdf0e8df4c13dae6f2f77e8d4bdcf4a44c5169ce35fee373a9e4153f8a2edf237fe4177dbb0b2ef549f8629b7b62a09249ff96b7f9a839f5eaeb7fe837b8ac75987b434b25c15163fb1257d0a7ef4bd365f2d2335ffe7e31828b54da0b253fe6442ff1f79fea4fa9fcbd2ff563cee9d3fd078b7a7bd4c42d10ef720f0f3e6804fcf53c16355e28a9603e82f535eeaa13275bfadfef3eeba8095c6bb9ed54738a87de3f0738f63792dbeebe67e1d9f7844d068517ece6d894795d6e29367dc668acc62589a428a3ca4564dfc572e16e23007639238fc2c59256c24d5104a34438c47391e885ca80ce426966d22def64b31c88b1e251d5858a079035417b2be6e725beb99a6ffaef1c1ecbf4c40576f8ff5907f2b61a845a0495ae7e6c85e18821f14460b012a0f58b5a2cb33ab8631c3fd1e6279c4235e5fe4fa831dd0a602471db498cdb69180f47732ff07843eba945da88054c406ac2b159a49c76a2a14a266d42b9798c4c08e6cd6df575d588e7332ee323b67777cd6f38acc3549e72c053596e72d47d6d5dfe7b4c785c8f3421765e875de60d3799f5b64e1f7e7e5eb7dbfc08c9d3ad308e9fd5dda05868679e18cab96d67f06130afd680fb0a504e7bc15b87fbd8d2ec27125cdd8572f7482a8162c6fb023a4bc21f7619d403d59733e95690f9a4e615c966be4867dc5e494eb3a89e6cceb5a33fcc71d02a64be904ffc2e3ccb313ff09849ddbee4143f3cc7794e6feb6760988c781f84591dcc22436bb2980c0868715a893b5db58d6ae88a2ec48ed65d17a11f76e6d2b870f15d8c4ac1d0eefe1e958399472b82052bfa9f5b8e742fb86da57d8442a6ef67b26b89308072b2662ca8d5152d9acfb9ade37bd7b987afe9065ce811fcf77dacea5d79d209781bffc8a979ab2e001776065a3e85ee2e462d178880c2779a98e34619f22bf4e954342213b25d2a00f721d3ab42509873b82615aef582e05890b512dc2a442be6f530a5aee2112f397543c0aae186ee87d91cf39e266acd84f3877eb3cff9a5ab36e1bfd7e08f73f982d72ddee6f3f539ceb581db784a25594acfb56649104ea1188755b79663d7caea1fbd36813f5f38e5bcc6094d1ea076f54ed6052cdc1f3d33c2a6bc95d1c2b5940bf75ae0f5bc22638694d095582b544e530460c82a700f82316f541b9a004d81fe437fd9f15dec34099eff47189fe37cce25dee78faf73791cff9f303b42ec2213ec32469f34d3fc1ed21d05765570fc2bc44ec9a1f20b40fdd888114fd46a268510c0f6b9a97611503ef55b95b9bb2407c08a0dc64ac2e7dc5732b5d28de4a24bfbc062a6184455b827ae781609f9c86f7c8db76aa9fc499779a6d7ded18feaa6b2fdc2defdd857fc6f737d69ec93dda5fba92c0ffedfd1dfcbe383ff77c6f8df16872d436c780e96bd4af4ae40380b91ed094c4b52d39081c82a2c3cb807a2516e08eec170112fcc2fcdf49dace85a8c9d5e6212c56eb90f11b195b469019d5d210319bbfa798a869e64ea2eab158e61e9eba6ed6eec457a3cc40e64111deea1bf636f3cbccaf7ef39ceffeea77c9ac3ed215651470cf1ce147bb849ebe5573022df71b756c5235c1efe2e477a9f4ad0159ed8a7e888b15eab3347e31fd6fed2739f39c76fbb8b390f506ae8807b3b5f83f229ec55c0ab74474c19e6d0e0d4084484c173fea39f8dc52a13e13616613f1b873b5513265c3b157862cdc6426a577972119419aeacb02777a1d7d933b745c48b502c072b6e852b0d6fc33d5cdef75fe7103ac64fc798912c550c7b25619937b44dad2fe89c7f4b7eebf09d9f5d8af022f3785720d1a5c77523a773fde7e7ebce3d8db7e9fc21bce75eb74ea1581218fc123098124050b8d031f7699561b3140931b9e76eb4e4708adae9bc6e8d820a4997ee180b02e6729bb36044d1c08e4d7b9f8d71331beb4531e6a8b0f886d69a72ab5d08180ed2cfeb79cdb73acec729be16fb2fd8d6238ffe77c470a71c8c53160d31c5e3611f1defb34fcf73e412b8151b9c4456e6b548c974437889e35ec702d24a24ad14b25ccffc764513be62deaea4cc0964d2562c112835c4cd1267109960cbd00008595a33dcda94139cb287edcc33528ccb3442ed5ddeab412e0c202e69196eff80bf2eed831dc9e4b5bce077e56f5fc73bc65df3c431456daa7fc3f31296ca6e39f70251201ce8043fa946a1140aa8ebed86d6db9e8c837bb210030576a14c0235c784150bb3cbf97243793bbd3fec492b60a486418e713545ae95c55da41875431736dc0a80344e38aff92ae59f7d83bff7330b98c9e8af781b9d88568d3e6068cefc09bfd9a9dbf42d5ec7bdaa6dd15fecbbfac7bcd2e95d7e7453eb387e17ee4f98a89b352d78f9c4018d75af1a59711857b0518880d80d16995165d6ff1cdc830e8bba64b134eebc52cf626cd84c62a310dccec6824d51102b1e48e14d0017d44b45302b7c7a88f5a094789679f623abc4af0c05d3f471f85bcfc2fb5cdde53ee1175e61f8388f61a5a42ab5dc7d414bfe5bb0b82fbcca5dda549df2449d26627dcab55f7eae5bf921c21832963820b5d423453fd0ccc5bb94e12991c3aa5844209362aad1fab6dc9b8427dd7bb92be75fc1d57e8bad31dd49571faed3a43df191bd7f8e5b6b45bb290f929c0f2321ca20ab7fecee919d31773792823eab46afb571567fd5d3fa1c3fb47922f687ff320ff757b5ef469f3079ffa64323212ceac37f6559a0a306de87e7b89d7f3943654b12b2cfd07093d566c03dc20972f7a1281fe71c0a11779bdbeefef7f5ee6b678bfcf75c409bd76a9d49bd3c9fa7d7f1cf6708dd7286d2057e6292d69cefa8062d8a2b31a5bc4c48ad13d1e34755fff50cfd2b57efa51abd55d4785b9c9fef4aaf4e9bd7e5e14e0657b5341e4f98aaffbe17eda53af22084a77df83afeb91ffcb6787535b5949f8a073085669d3292cc1b43224b71ce87a99422887db563a003798347ca1777c22db7f3c6a1b2699d02755326cb2cacd62b2aed5126089925adcfd130a0b520052ea773cf050a1b232b430b29ac63bcfa59afa0cdeb6b76eea84bff0dfc01e6393be9493d67473c5ff84c6ed219816d6c397181cbe81e903d1f074ff32418e8bad865008a0297ee5c04825634d14930486b5b8a31465c38837ba8ef668918cb849038c14a0b3262385d711797b22a366aac57bcda4d79a516333974594226f7087a37d76e12a75487d8aebeeaff7f97366b5b7847dcfb7376aa91fdfef91c3bdfa8ebdf73108f4d17cbe5b6a88301af8c5d5494d044402a260352edaadcd342f5c6e34864338f422e272882c20f6b131795db930a2a61f0885bce5eb8e946d6c2d196b239131d7535648d0ab80bb65165d6e11ff03947eec32468b484af1c60573972bf633edfebfa9de6f4fdcfcedcb8b7cd6bc8cd13f176bf9870d653ab1c11d98da837b0e2b87b0c1b0ab80ba7292bfb795de2380952ea8b94f3689323dec76e1b0a77b72c64d9508b6c35d2364511627c686b1088422824a559d045b1cfbdaea19e1dc4deffbde6e25f731487f5ab4d939d7176ff831c79fb56d7895ed6ede5f3b9a6735baf78e8b692c41d6380d00c986a5eb7a3b8378f9ae33885e9201c5357f9dc8a98435512a102946d08549b736ee7354739a3230a71a64cf07c0fec2c13e56354af015dd034e7654d711b648913660bb395e3b2e2376ba599fed4338bf7f3187e05abf05df9f3f3dcda65d154dd1b5ee1f3f3fc5b3ebd2554044a25212a5c6a2bdf408a4c55206e318b4ce63e7d8c994e442d0495c33b05271bd5ebbd1a3b03214d27b9bdd6a68d693c9c86156ca4a14fc2aaac702102558b35f3844c812033a6bb3ca13185e5dff3e95fd7977d9d933377e7f11e2d3e708c5c3f37c34dee89327ffc9dcbf57fd1877e5cbf4d8e76269583ee551febc8917cf1b9ceb6f0b6fc6c6aca8a0bbda29c8c04374e0ac84af1879d96b61557bba0c0ad4aa50b45a3e05c6a3617e126ed83b55a14bb99843c86ad2b9810caa571ee3b5538c622abb0ab104c6638a80b89a37b04e354a848f9930dabffaf6de1df715b9f797caff22a7f03def43dcef2750ddf9ee38cddbaade7235e603705d0ccb050c20d58517566de8840082a346ad302959b7051a11923303725098d59c64670be08c0dc5d6f142f00410162b5bbd1c86cb9ab3a59a9a6781cce489dee287011a9290a3d88e78206f39bb15bc7f76eff67fed71e2ece7eed71dc7fd2bc17a68e4d641575b7e57cb2d5895315884e98ab93a251cba86aeb14a93b56d9a586c66595b1b928efe70b2710b5f1d5a280ac2f71649c294714e93ed8d3c72ea480f4724c3db928416a4dfa74e1dacc2359c1e877d9bb4516c3433cba997c5d77eb3867b91598a9841be58beb58c6c793b6cb7f8ee18efbff987bea724461eef1173fe1c3f31c62bae8c61a2440110bea0ca95d9804b51238cb9a722fabd65749b0652ee1310e6694072d47fa59b39fab1c05266e1ccc711b0b39dcc49eeeb3a445f326ddcababdd76078172293c4bcace2864a01961bedc1a85810375cb89b6fe319ff8ca9b9b67e559a5033952fba1d57b1a8df13837fe6387f59bf0fcf0376b7c7e460932e68261ae213b884122b1027653f450fb6e8cb675dab5041e2cc79a7944f7d01719836d82675eb84d22c72a99fd4a24c2234e431d286f7d49a3301a4c49112ce4627adc7389ea5b5fd346374119ae5eacafa5dbc478e7ec517702fdfc5bdfe7ecc173b2706da3be160cee37c3d3799e04003224229e2991b5ac2539354965025384dfbb2993f7624be313759ec61ade56ead91a9b477d4f0ae540cb7393257b11a17f839fe7d9e1ab1ce7ddd2a9f2ea7926c94c7bbc21bfe1e8ffce539c1fe562dcfbcd72486259ee17625394c54827784ff58913e0533165ad2f0c19f62eb2f61a746dfc31ff436decbfe3963a846b7d7f6092fb6daed4064a8174bf8abe0f499b9937de616286a7eee0b49a694ab4acb1f40e316ce38e453f08098c1688af432f3ab3ef47e4092883a956a103f0e43e53e5833be0b8b3e98aa26789e8d05676e67474c8f84fc4ede8bd773f3a6db125fe3523dfc3bf35c58f4e0cb193582470c502a77eb6bfc41275e91ff8e433aac5f26ed5e7b07df5154a7f50b0ecf63bff8957ffcfb13b7dc6d7d6989ce66fec32e6b422b96ee364362c147c371ec824d08f02803b8d3b24d09d4913678451a0143a0d6f37848b23e02856f98963b5a78f684f61162003ec5ae4ea3c409586d4b82f15232c204b271047eece70bf1898ff71ffda1f3da6c3be599fdfbb8ef13efe1c11ebce0d29e0b64aad7fcf8fe3aaee9a8772af1f64b7eeef7e456ba34f9f962c70e7f3ee7176fcba9a460985183696eb5fc701fa805257377e7cdeb5d13431309df3c850bb5cd24a9a4a183d93858a675b8915e0ae2fd10c86af84b6232ce004482d16d8ccc869bd2a7eeee9ed7832d05c012896308ea62d24f76f32be7f7f279bba4b5f6bfe89fba38f6cb9c3f2ba9cb930e0ebc5349b039c71ab7e1c1597047aaf68e272ae3b56b472c50c42ac7a4a6944b00a8219c433a13a89dc6c228e147205c444871c8e31a0679efd07bd8dacc22822c543af37683b8c74e5a4decb0a69e927acddddd3ef3f5568960ca7a756bafe2f15d0b0f5cef65fad8abf0ef73becd5f63b8c39f01b8ed2e3efa8f36a9c438966a394b4a405dbae6be5933e3a499df3e159659c53e21b159ee662e66858793b9c176d44c8014014fa17a1289ba4b7959ce3975a808f739e49b1074dbdc6b9731164f1a9398d5c6d5a8dad285d3aabfe32a2fdb8c4674692dae69ce59df181f3f6b091f553279ddc7e7cf67dec01b391dc7789c49b552bd32334ced1c93adf2292f3c118a0aeeb421232ad49df029887d8579155964ecae0acfce662e9ee9c5cf6d38a684575b10423ce52e5dc7bd59504bcd8ab19a49a333c183755ae95426e520bf923bfa83fd80b90c4c714bfeeea3b6d9bfefe58f637f9af7d7bcdea95e7c23577e20426f174cd1c02689437228a69a1914f220e36341a29a649adb4c54ed8ac9cea17d50c50d1e137fb9a768b7a250cc147f40334c60ec8b510c02770a4b4fc55d18e3e54a2dcc28465d48458442d76e95bc92abb86c3fbedaf3fa4df663f898bdfab6873fdfeacb1feb9b55d16097f66491d6e46eee973836c186c172c1500b94ff73173f0ed7f3e4e72ee7f673e897e5bcb6e3a27f58e58918659ea6a9153ca70dd9e6d60394635133abd8c69e4df23aa8a9dfa2bc12842674475d714fe58fc1155cf645fb71caf51f35405b75359779c4eb7f4f2e3371ca43cc74e247a1aff9cc0fcf73d6abba2da749eb08288047e96367a7403b39ef369a95864905224b6c39327b2277f1dcc735f1b03bb554157ac40d1bbc206e198663fd2bab88d1bc24c5a28cf39e8e73004bc5c994ba93ed148871540da5402dd750207e8597e1a24df99abef70b8fde77d8eddfb4bddfc63f73d0dcd8478a9930a5375f4c06b10bac79dc05023e205dedc6051203e5edd0dc443beeb6336ac8484b4c197661de3b014d8a81e054893edd848f9d890094736efab4028308d8a11c07e514e22417643b4f4a4579a908209f3868fe35bf7988b33ef1d25cd2daf4703f4d889dcb6093fbe1fbef5e8bef1262be96a7f89e58ae40e2b5a673fcf3c98fbc2d468bd7fb14d99c8ad64826eea6c8a4140561869d3d03b88cf74392261c66bd30d277ed6ce182c87262e1295030671bf1168615b4840998ac4b5b1a3d9a370f7ddeab94f41564fe12458df348cc644b415787bdfe7b8c76f91e38eb54145fb97fd1f7d8a9172dd59773f3f2f99c93bc09af0cf60ad1bbb4ea844e30e08cac25b7f742502ae5709c63679933bde1090742d22d872d29c6ee86babac9403912e3128766b9cbc78ecd247d245504e695edcc7ded661ca2990b2b2d77535e0def29b0d72176b7ff7427fca62379b5ffed7b7cca33ee6dfbe2dbbc7c3ed7f9a39bec7fb41f8eb91bec62a89f754d17731f07910806733e5c123fdd09213003645278da4d999348a9b731a01e4bc85d6a05518a54ad7a01335f33059d3173a3bd807a90272eca12d216d672402c7a27c63f77da177ef66dbd197fd51bbf96c307f3c4316a042f6bf07ecee1ef3e6802ffb3fd39ea75cba84b93607fe6a3bef03c47cef71b78568f3e14bb073aa69ebecff1a4e7bec16943d229509bb48eecd4c25b5905501bc1eefbb22c60b0939c12e692c7b0c164de44bbdc5ac29c89cd1ce3f1dc1d3682d3412674cfa09a658cda294f57534b20e5ed263936f04a0cf6e51a4c9aa8323bf33f9cb941aba93c6914bfc7067de249faf21da592b0fb4d03e5edbbece1391cc1679594e092bec9efbcbbbfe93e7f17efdadbda7b6ffad2ff039cfda7715feec4d3fea4bfedc3dbf2f28497cf31275e562b376a481c22ba2d308e724f63d5b425b79c5b7b8cfb69a24d2abbb3e6f7ff2817f536e6cb19b594c4ab5ce2ed3fe59eb8cd22330119788039544fa110966e529bf4ce5e0bb18a606ab11e77f35a4b5afd0087b5d38b60c17050a5ccf09c9949516dad10b7914e225054c38982d59656f65e24dc8e2af2285d775f204aefad876d8aca4f9cbf5ff0198eeff8a29b7e35b7fa0d5889dfc77cdd8348949975f00bcfb1e46d76709b318a322f588aaaf4995f6e322c2c029d25b508542202da043ead8769867f5af730f0d9c2798a8141b3783de058ab08625e24d4a19edd144df92b674143c66a998387ed3d2a065ab459d4b4a46894a48076ffe2379cf0d72ff58ced5778d8bf275e4f4c59d483ee9593eb3ce71f9ee7cccb7e5b7e4ad42d5372b2c9ddb2cbd0d056e3723f178e8c79871820cfc48d76191a9242542bdd603bab5ba1eab09ffb66aaf14fa0b0f9357701203ec98adade7141ee38a27d689536b30221dc1d8f7a138a8a480576cfea930efc755b72be77bfe2137fcb7cbfbbe75f74f76fe7328684db1507aa292cb14c391ce5c0be170b2563e83429247ceef2dbf6e0491bea514b559f749faee632be613e4e3a6169236a558ba3a6c287e738e7306ec0fb083d988d85d1cdc32e94b6993115ce17a59b21b5bc4738920dbe57fd4d76f0a940c3e76942169927ba3486a0a8f1713ebea0930dbea5667cd6fd4c516972e976079fe5647f8f3d3b7f793e70e269bfcd5e0ed23a18c7635145d00822a201f308cebc1266633d89170f83189750f4645780aa97ccb963b0f562a432cacb4581751b63be899bf22eebd3fd8c07fb02e1c7298224e325d55e656b00a3fbfe011011448a1179f41b3fe331562a31e8cabdd37f530fef71ace3fe43c2d68fa0bf9d6b16d873d9dd4ffb087130d8cc7817b178d867922ce7c6b598a5d239d7aee49d2f3cece66e4728204eee157bc1d783180636f1dac7d08b0605508bfbdee17aec28296d9ef9ee408e8358d67aacfa0270e30c1422f2db7a9e3e9dfda366f3d5fedcdcc3401db52e7fdff77fb31bfc9b7082bb527ba2d723f8fafb0f6b77e1793af20ff8048d04bfb726db0cd21537b88a105511b04106a0256049850b7161e96951a9518600485147198032f3ca5de61a12332cc4385832b95c85d2b40a98a58224cb99688407f7dc9423560f7d21752970b59bbbdfa5c7e49429ea4a855eb4fe5eb506fbeb6b699acc3f69249ec638ccefd59e986fb16f97c7fed14dd1458dc5ee3cee6d79ed8ace7895ee73619eb45706dc684cc08f811a0d5302f01df51f406e511a7b5b3085384d1bdef378e8f1468f684d9af4b1cb72404b212318fb7a4618815c9461248d457ab529c060256a77cb2a513258a0c2dcc68391ca16bd7140ba1ff52a8eb16d8e86ab4cbee9235dc2a7dfac8dd9fc853f717fe4a3fcacd794445d8a869b0c19f3c6b7f0dadf01aef56be4de70537881c9ebabfa35dfc5bbb3ced1709bd6e2393d61677fff7ceefdbec1c790b4a13d894249ee555546a1dbeea25aa010e9528fba6d5ca59bd9f816de81233ea29afcae4bfaf73cc13ab7b4296a521687b38e847d15fb197f4fffda05fecfd37c7e7a9e73aee036dfc30fabdd135960205dfa2c2ae531540d8469ab62dfb11ce2278df13844b4c95137552ef5c31af29c61301fd38e306726783962b06551a329e7a53d678e0c59e0846ecb694fdb14a98cf387d51c3b76362eafdda19ff7ae1fc0a93c71b85ed9bb17b85cff6def160d7fe19739cef56f9f3bf20fb8c6b8fe8194bbdc1297741cb5705edb566c080b2d4728a13b351a4e424fd5c2dbad242e1b0ddbf61e895d28c4384f30d5802cef91080b687e494e2cc92a3b94d59ed67849bc875d540912590fa010744951d067fc365b3897789d7be674ffbc725b5fb9bf245ea91856d95762976ff1416099217eec6d3bfa1e6fe377274dbcdbd644f5c453e2e73e7477338d4a8779930da9c81da96845dc749fd7fa4e31e769bed0206dda3d1d075624d255de1b4f717ba218ddb35167c77dd0a9b1733f45aae528dd15c8dd459c2ea58f5b12771bd1e85f2c1e1a7a2556febaed22263ff85b6fbec6c7b5ba910be5b7dff77e5f5c58cbf412eff1bf9eb3171dc2c3197bd5243cfb4eb773a2c8493f1374940aca9449d19c1fe27e47ccc6664ba49a2ad9e1b0061bd6e867ea0d170caabd16d8e3bdbbd1b5200ad13b2d9c455e0d49d853422a62cd7131c8aa874dee973865621fd54357096169262631fed41bf2677b36faf95bfdf58fe7e93995da9c7b0dfe47fd23b0cc6bdca817bce4e95cfdfe1cb7e2b8775366c83d1092a0ae231607852c2cdab4223258e8aa7c2cea5d96f6977896a0d15eb9515fe1628dbf43dbe975bcc3feeb54429739a2fdb9c7e0cbf5e830869223b80aa59d09ceb7049101876d27eae12cad2220a4bb617d74db9d274df7058db58fbee2bff917c7b10ebe3f6c7379c4e5a15b6de97cecc87c51f6855badb425ee43fe03f15e37791d945c1603ee974be2dab3d89b58312401ab2116a06bb9cb01afba5f85b743996c9fef81bdca85e97211347c9c0e72195aa1b7dc531918e1aab8b0825e234cd5cd7db5a77753de75dd52322ebec38738e9ec49fa783a53873986557ad42d8dac9b791178d045f1d00f9b6a154b65784f3799458d1e931d37cb151f8b15f7ca710c83748ecb67ce0554d8ec84c4389343473077c37c77af93b0a7a32108795be73d5d5266622a7054d4c18880352cc07031af5a19ff8133f9fc1ec7bad517b84f76d345f81d36eab876c7bad8c9f77da76178c678f737f6bb2d8a1a3e458c3e329fc6330fd805df6d635f35734cc6198e56d21bb21cb7edcc5d82fc7158c6923e87d6d20e6bbe112cb2e4c29153cbacefa15ece44b12563e52ba06424e18699c946d5b04a4dab5248582c84f954abfd7befcfebfef9b02fff16a31cfe4d9beee161bf6e73645fcf977e578cf25973e0659d3e3ccf3fc5284f848b85f6ec553cd6652e959c5a2e8c3ddde508af4359ec392fbdd804fb940f419e3c6ce3c6090ad90d323758c6f1701d1bb20ea54d0aec02224b992681c52ac1191a26549a2eaf6946309e863898cc7d31b8957b2597e63993b0d4ded5f8baffa63e94dff589ce73fdfaf99cc3bfad0f65cedb89301867bed971772784a7c18c4f06217452cd54125ac180b810e9aa441c0a24bce146598e9503ed3228e8bd65dcc24cb6310e367ad4d90c902a023f2ccde8528ec956200548dd2551152c0af9b0159f63947fec4309f6a93cc4c6625078f8f96dae5f78028b2b71cc71eddae22b7dd28fdfd1270ddbbc36dde1efce77c3cbf8e7bc08bf31cf06ecbcb2854c8238aa3066b8a5624c064ab49420d5313e1ca95e3d0b607771d5f114e93eae45c97c02f8682818a0b270755f2cc4af0c97cb0c970da9d35591d0fb992f5af9d84522295714eb85022665fe1fee864f6b7391b3ee3bfcb623cf6b9ebce818dd86012a805e71ff6125ea96680f3aa48269b8d09b88512faa1466ae1a4bb304bca7692185cf6039d68b74a071b4caea49afebf58637a68ca18e42ecf0d83289f660c801d8a68f5da9b0e034518f458f232af1246cfe305ff5b052129ef6ead5decbffae21f736dec1d7b337ca135d8e0667fffe362d39e99677719fda5172f0f1c46226c45dec4f76190a07540e3b2e1f40815ace59b9e1753a103ef10b43bad8a583593c14b9343eed0d9e2248421040e1a999e2ca52ae3dd24db0e389bbe15519867e19a8c478ec061dd32b1c1acb1c75adf2f0fe4d8366724133889ab411cdefdf219fbef3678ecb3febfa9fce7e9ad045f64e6b30faa41977d265e4cf452dba79fcde9efd41cfff9ca7e6cf647f41e7c712db23d7a37fe42158e7d66fdfbfa03ba4bd217ca77d77e93bd23ebc779f4a65de71307cd4c56cc4f68c9d7fce2ddaaadabce52f46ff91cbf5b7b57aef435d384bfbc3f37d9cbf7fb543a7718ffa6a9e78d4b2e8cebfff1ff85c899735ad921cb704d3a5aa0dd5b5b92b2a4555a2b8c0e5447bf6b810ba564c0f428e970a883e85f48e98f69179419d835dccb00315a474ce03908d553dc32de646096e992476953bed75a21905a1283ff6a85ff2732e71defef96c9d7dd0df70a7ef756e3ee640def9ae671ff0a885a2d6a9fcd833fd675feabbb8797f1bfb55efe6a41f02fa3ff4e0fd3d0f92d08a1bde474067456dee058235ab749d7bc3c96cacd7a211281cdf963ffaf3b9bf3a57f0b02f3fd9a37f9cab02894e9ffb475effcc4e76e773dee4aa7fdfa78928a9976e386e2b51eb3dc3742679196bdf4953865b5e9b698ab0496b33e50c8fe29a6eb9dc25f13858479632738c2b39e6b04076441b332510df15bea80a198c63e6eca4ab6a86701f7bd46615f53ff9f77fcc215cdea7976de957d6807fdb7ebdf00cc73caa4e9c237fef915706ed36c523388f7bd3fe3de51d642bb34657d235808c7f0e18376d94e0b11cd38de05daf20dfd3043bd46afbd038db636d5e6095d66d770f5b2c8058889e3255a999f02740733893352c434fd8c44b61eee9b0a8bb51e8e134c498e49f72e4a7f9f9237ee6357efa636de3fc8eeff5872e69cfbd8b0f3edaaa4b71433ddc7e8d7bc6fd861c88bd29fc2396f239b79c57beea5bfa82d33ada66be62b95552e90b96a2412feab2ce241884d004e4710dbec7c7c28f69139c6cd86872855fe2b09761997be64e7d8d43f082cdffa7f8f930af5d2a77edbce6bf71087e7e9e290b6fe7d462cac82684cc0f7b61d171969089b07edabc0f7c915403e5e355e1ea96b881e4d6b2a708ef32ce914a5a982e7ec29005985b2d905858824f50d4ab204601cd60b5e79efd3845d02558ab1cb563dee88506bb5b7b8ddfbdbf4e826bf81970b421ffbddff8d3b8c758ae1eee7389d759d29a6922f6f9089cc7bbad1f4c88764c4d30e192ce8a5af1c2d5cd6cb4dec5dc0e545ff5d142dd51e694d28592d69d150aed694bfd2298ac65632cc154c9bc0232946ea3e4e7867b7a911a621177379bfb8a08581295884603389663c7b9b996fd827d96b82f9069aec57e27dff81bf2739fc63decf517be2a58161669151a9cf5516ee053e286e6091d10d1aa6cfcb08944196a23686105815ee83eac88cf2e6a6abc8edde60dd91e9eed0bd8d2a31ed1f7cd85792e2ce705a3feca299949bb2fbc171e2ff7765d4a26ba08b46b0e1eacc21b3aac56e399bf1cf0def43311ee633e80d39e66e982947211f66a21fa1936bb1ce1bb08a83b56edd639d889993f81a222fe3d282c81863be62b2712ed46547031670414a31fbd1c3b51fea77cccdb7b7e89bf98fcf7b3fd3687a73cfdef9fcf5c9db7e5b642446cea133bf634c86565c54cbbca1016b320a4fe4fc4c17a9ffb1a692f6842ffe7962fb0097180848f3d2289a1d6c32aee834a19f29433fc18034a44453ccaa9c31365dfa31f83b45725810a66d5b052feff3d57e7071ffe103fb7f9e10ef2834de189bdf68cf90d73b5bba6c1f5b6ce2fdac0ff0baed6d7f3bb528939e5e3de3fc73f71b3b246385410c1a02045bd0ba43bac63b7bba363f55860078616557a4c06ba6e670a07018f3b4f89689bbbf62371d703012756e89292fae55273bbd122dc4bb75851d4aee61c5acc6a7bb6105966d120976ac9aef481fed96ed92f36f32b9a57df90f3fc34eeefe7eb394d489f49fd7cd4b6bca1767dea9b3003310e4222e844fac4297cd30ae1a818c1e4be0f70ec3ba9f4388c65d5b3b8ab89c757296fbd889765de8b32e72a16bdba0fdde12f52871b86f920aa3920960091f5b0a7603b98c97240c104494cbad812ffd7f8f8cf3d9a9ea833699b69e2ec73cb314543cfb9a4f3bf893ff044fc1d53ff5973fbd3197cfdbd57fcdfe1f354da468fe0fab0ee4a5edb4fdfd5fbf069dce37eca1fe1b34aa2eed80be689e75b7b214e7c0bd52ec6819ab3b29fc2609d8200512cac18962c97dd2feac26a3ea6536e8940d7bb4d846c2af972cf3c3a8aaa7097264411b704aa2e538d782f845ee5d5aecc00e6b2a2cf69d32ef53808b2a6e819c3b8e0ea0fba5dc3e7145de73bfed4d3fb8ff3999e6a9e9bbc26e6306fe4367c51427d5216639208508a0206bf0a90da79a5c66451c01096e58cff155ff4e55e3f6d0565e13bf6f9fdff7eb758ca14f56e93cae8783fe9835fe499eb358b631deb1bfcd63f8e7ff45f0f6bb9ce11ae4ee79a9a17bdedf3f8b771c371f34b59ae253dbd565e376263b328c6e22903ee26976a1625a2cd7a67261b25531eac0bb75d7218ad542db6052396e4b8cb218e0bb77d5255812251416d699e03bd11c2e9492d22eeeb5ad50fbb82d1e7fbcf358d2b186d017244cabcb6df70069ff100a75ee5b75eebf77a9f7fb345cd5153f13945629dcae03a2ff25983edbfaef149abd15e28f9c615fee967273b745b0c9e845608cb01834b306f1c104a514963b279a3960557256904e232dce9468b9439d3d00d2aed9a4c414c22de3ecdb879543298dc8376a54097a5bd59de83c99608671abbbb5fc2db8254b67ec8838e358194f5ee56aea86d2ac9ead86b278fb8bc2bb62afd5ca7f9175b657dc4acfce83eff0ca03fe40cffaa2b14a2a0ca59f01c2e04c82c334851cb62ab1d91e461902125e7de8e284ff7a971f6a1ab57b22656ec93b0f08292d464943578acc7789a7b649cb91dd64d398925e1d1027ba28250a3619b99e59e34a5998f05b9d2a7f1e5b3a5d0f0a56e674f17e945ccc66bcc2331d4de43a7bde1ea745f1fced7053ec0d379785983d71ccbc40ce0c5bac5e7bedefdffebebfdff7f5fefaba6f2f53cf17f8fcb2ca7ccd091b3739bca6ef39a27be2d8f063277379a61c7267e9ba588c3a2a7b61a9b745e0fb745a2a57e1cda14d84bb1c0a37c5cce8407c705732db22013c5d7fb7b202c6128ba473b4391084346dcbc7ed86ba41e0b39b48471d208985fa1bf04dac34a5fc6a3bef0d3f653891f8f7391d06b1890efd290bc38f6f16e3a73be157b58a6075be90b707b5f9bdbd1850339c21366d48c8fd6039584b058185e78f839f3e9428eddc14db16973ead73ee9ee7e41e763f40dba6ad6bb314ffbee306f678cda79ff59b7f174ecdcb8692351094c8513df5b1598f94b3b04ee96ca683b17e5e3cc779ca831be403f36592f94945429cb51e1e38f3d4dc8af02757ddc043b8276bf62bfdccf93403234d829d9faa41e3ac5b82c335ffd8a057667fecd7af6db4c92cdb9d7ee7acfd377f046584e9ba2e1b96fe4785ffff6191c75546ebcabd792613a854e1b577a1c36ed2ffd38bc0bfb6a27c090d3519785e3e03142baa7b542736f984a2f45d958aff4c26ceea1ee0a04ef6482f751a21559909ed5fad7dce560ee8aaa604e3217e2597a6aaa78b0e79652b77274149e79be6637c9e3c1b67d03c7a3e5b4f989eb789b497b3365e97378d8bbb769045685714021bb1547e9564b35086b5d2ae9f6c20f6c5a9b51ecd1592c691aa3143277b0cd3025b371c0a45b81395681aef95e839dc5eac20e6bbe63224239234f9120a1664ab25e1b0a2b748f604791b03fcde9dff325757ac46a07467978a1dff51f7dc29c9ebf4b4a55f3eee0b767d26e32a9ec773c4c1ffb7c6ab54e13da6b7ff22e5ff2a9bfaa39cef7e1f756d38498a236a79a5b12f46ff5d98f3c03877f876126c96a2ad5b14ea74710e6b5e85384b7ea55473afaccfb79d84f68f89cc9b38e54fc75fda4d33e84bdf6a2ae40629f9deb5445732dd71a9e62aeefd99b17e7ea741ffdf1f9cefd48b7610d688253e23b16c5ce5e8f09d17ce844428c98e05be1ad6106271b29c998315133e3e079adc7ac0feee2859828f3b0d575d0c6633349abb6c93ddb5602f76c51a1d86a9f53c91113da2563bd95d504a689e2457db97e51f881293cf1ac46f0785f7f890fe9bfd785b7452db64adad5541e75ec8f36e1c3cffe0113a518670e22a6dc6555f01cbae56c0a85a33c3acafbb2918be03ebd8d23e5f04c40fb559736067cf6ff3ff34090efd98b7b9550308fe1e33ca1e6a8f7ffe967009e62a89b6ca7479b621bf686e749302ab89ace3c584e7bfd8b8d494ffde5461cded3a7f7c5e22720a32115bc05f1d8b1e2deacd3857962be6b6bb7b5e3a414daa234ae4a2b4d26fba8c120e32ec83849b8a53733de8699d57a7fe040d916f570a11272e4c29ffbb44dd1faa805fa35addfff9ef32afc609322d11f39f793129cec1dde2b2b3cefc53f3ddfbf7075813eb784609643339f36451dfc4a996bc58b62a593f297f09d406093a45c47643f74326f1887fbceb9dfffd82966facc0aee94dcf9593caca4df6299189436254c2be111a39fc3c66c0b44788ccc34ae94972f70792b6ffc613e941598c2fa427ff977f03d5bce3e477a7f9ce3837d7d1bff7cee6fab0793838fe5d330f7b69079f4390686e8dedd866eb59af9e5bdc413a860b1e7894ea4ec38a9cdbdaedd6d6aca56e3769ac6c39425014b6bdaa99eec43533ea7d254f385a15ac22ac42a4a39dccb7ae7cd446a17a7bce285793c724d98691398fc2bfc5bf160f00d7379b0b146c5f65e49689fe6f3dd739ceb840fb7cd69af5dd9e801977010231b8608c784457b1177e9cc5576e1da7769adeeef410825c66ed61328509bccbd010a19dfa5dc106ad1a580269698eec418e3ff8fbdbf6d4e55d9f6c6e1aff2afbc3d73aff0209971555d2fa2028a82e1a91b7ad7a95d4033056990083ec055e7bbdf05a889895193e95af7dee7e2c59c1168e8a6e91e3dc6e8df6f0c0576c738f696ae9806b6213deb71b404316254aaab4d2fec0b9fb0c568f762acc41bc5f462ebba6ad98021bdf9165ec9dcb2308996de4031b444de9a4342a17ef705428552867883e72aa78b04a9ac104d8194d9257040ac2d65c15e4e05f280e7e8c59c83be2b662510a4dce4375b94a8cc14681d73d0930c900ef530b74c1e0139924467886f950390b8b19abb8c9d377879217fc5df9fd01f0f7b423bddb4b8b03f577dc784cc5de6a2dfa1c96d7b03bf03861cd7e4e6aad7d643fd3b9ee3d7625e8240f768e90589f6d29983dcede7dca444439d0a54184b85163e76bc818410c36f74d2a3d050307510155034699709c626af721e23f07a94cae6106da67a3e352969e311c4200b455048393be65ee45861a67c5740835eefe45e5cd2a33d91bf861f740b1f585557331fac5ef0ad7e839bad13713d8fed492a51440f4ae6988d968a89d61ed37d31921ef4789b53442ed3f59cd504b0f1c0138720c71ab416ebc31987e6bdc41980953a8f181c6f964a424c6fa88c3d966c90c91598410fe6509a6033e82b03e13c7eef0bf3c16394c013cd1c31dde060e35d91fbd7bba8435636f14d7c6bdb466f14cac6cefe321f54518c51471ff6164a824b9346cf6a4c1080dc1085f9645262561683a9c704e584d1688d55a650e80195da8e1410f43c980a5824aac6e2a941713298f728359a758cb83bb4e7bd1c472aad2720740930bd04bce894667e91bbdbe48880cac286dc0ad5b1450fb630755ede0834b20099403ab559698d45a1742efb8e8b5be0e23c0b100ccddc8564eec55dcab69465bd5e9f3a6f347982bf187f97b64dceb00d14bb7c6e2a661a9834d1fc285d3be513a527a9690c84816aa040630246b1a4d810bcd214f156d573458e948527a49a1b0983a938eb3886e66871de37cbc05680b47528adaff33cebcdb505828b522fc927b2e8920fe162dea71be89867db50c9ae2d8664ee14745ce3652d35c790dbcd6d10d5389ffe57fb9f0e8c7e77edc1d9468ee985061f69d700633991588f46b23c57245c4aaa0685218882040c24464bd48e6a0aa537ef6528419a6a80c81382f514682a367a853fc79449491100bdc461a4c0357a2f1306bd282055a643721a979148f36b62904d7fdf962fec5ace48f3dd78ed7c11c752da114e3c337f9169a18f86816c47dba5cbd099cb044b9c28bda98823151260c2ada146e94a8d83d80df3be390c124594e6ca5c8aa682365789b7552c1ce0488b11033a2a83e736a32c1d51717042581f08c8e4bbb7d2892204c1a6c9f7085ef187fd93b1e552376edefb57a30f7dd8c33ce647bfc1127ce0176a85633dedf68fe9b9cbd039821cb5c332fed7de3e3ebb06c52040bbfce06ff5b9f37c80f7fbb5df1b2b080a51837ba8f376101b52d53c3c753edfc5e9fb5a9e0782527d18b1069f13305c502ec5ad1c4691f530cf00516425411bc744040eec351a286b939a75fc48b1141a74cc81b4766365e114390378dc970db5f4874074a2c090198d00112f75a66bc321c9e150e05c4824f411db783e2629e416c8aae681fc9a1ff4941f75e70bb6188dd47aaa353ac6bbbde7885a5aeaf6e90859bd024125c0a2798ca53bbb1ed6b11223c7922ef9ffca8fdcaaef8f833a7f66bdcff25a7f6557295fc5a040457186266b178f1d2fd6160e15d88055d098e99695ac30d968a3c76489d9de482f1ee9314372b7c8654f0481476be254ecd29a258dbc788b1c169b723f5bba719afa16e0712cb306859002d412c39c81f360eb9ae856d8ca777b5cbbf1105efe5e957cf3fadca6d2155c56e33cd15cd53cca8bfe9b9d3df6db6bebd936ece63426fef069d560caba753c9b498c321be226fed3491ee3b9b5354dd558d3d584e76480336860da8c161b34945933cc23603c158e81649d893ade5ce963202c0c12acc64c9e23733b1d5320d6c520761241316352ca563af6452ec3c6ace30cf9b5226a1d59782a0cfaa954414f077cf756f6c2f5f93baec1d05e1c1b9f61682ee85ce1adc6c5c9faf76362a717d301aef7b0b5b5c38006531d7e35cf294a1c5a0915c1646c80c7ea5c33b4b9e4e0681b2a25e2544a7ab159442312f43d0b319a35dbeaa294eb746f892dadc44c6ac95630054442723f8f6cb87dd101d1edb89b1873fc2c8b808240c9ec98041a1038c322b7d21d0afb957b504ce6b34bebf5077cd319194ddf2876f8db6f457bf1e6fdf7abce7d2b0ef55414e6100436e0a38d0a730dcf91ae9add17cd501883112428a44b3020ac5b6ab241a1508d72649a4070634e312269a3b342042c4952884c1944dde8744f728bae051234562c4d98d033dae0ed35100480e63de2dc2c2664a353377eaf5a773e1727aa40b0ee8302c7c21579b36ef5cd5eebacedca18d4f3c74b50e0365cab2fe5b9310c69e415f98b0f69169a396f507c695a260d22afa398ea56a1baf3937ef0bd6d7c09dfdaf84c7237061d7c139b6f7f8fd98cd75d1fee72d96c9afd1cf5ab98036bca6f699b563837ca816e6af4d42299170b81c20202c882754479834d21d123a903124533a9fc19f25dce15cd8e6d44a5078285cd2e9690176c380f42dde20b3440a9c2830512b595120106f7b3cd8406acce64ccad30978e55f3d60ba4d3b9cb68b47bd00b47a7ed8b0677b5b1f779200efbf7f62519b58b49063207e6d7e1c77e3f67f96bcc33b84d1de6f0cddf9edbe58bbb3a7ed176027364331eeb27da8bce2347655162839e681b4ae6f11e67885d72761ff9fa75e074bceb439f5ff025c6a0c490fe883dfd98afe33df6e47bbeab437d8dceeeb120af7399f4bfba4f1f1067de43080843b344cf08e2ed74302b5556501ca06e7461b1756ed3bf9453e99e103779cd92da87b7522ec96deb927faa1abb37e007b112c13bfb07f7a9268efd977247d28a2c8e4a08b0e6955897e905271bd83289c0c96630520ddcb70dcc4fc58081b1c700d3a45d73cb3954da310112e438a5659ed8768433db0c5453dc2ea19e5bc61cb31a795a621a2850a4fb5ac46f6c6033989026a6c7c7fdfc0255f627bc9873fc56f891437dbb358e72ea71f9ad9ccc134308d074002c87025b99d8851de5c4ef7765837adc8298d820ee143a85113234155aa454a1869098e65e2c201d8012c4b98d8de05911857c5cce960a00a10d85a13b10b68ef848d996d053416f64109ed26825fc041351200b947becd7df9063f350dfae0f698f21f13e179ef2b53e0453c88da683209019349f3060a952f6d61d3cad0178daeab05b3a16909c8498ce002fd404d920a24710626833688813b53335b08d58f02213f06cf01ad10dd0d74a29578a2e8d591218023295188598575830240f9f60990b146b57f83de5db8cc1589b377d8722bbce0bf0657c2894e3608d63ed418ba567c7f0d8098d0327160c03044b39eacaae9e778c8810136a8a6181bec290b933c7a153a207c790c4298f87aa15a48851561a8f367a14844642a63683393dd252b39f75dca85b4003cc61840bf5f4fcad638b4da044a3f80497e13d1ef446bc338f1162a41ff2f3d43c86e37650742d13bfb66f557803c570cb27566794c885f4c48e30831861ea0b82a12723d68e303469b45480cc6916bfd5c27ce38992ee96de664c13629b5ac7613d5a13d58e417ad331857925965e5c42729920da1c820114e90d0684714dc5fe442636efb2cba92d5f157ff0066b74d3a78def65f0a64f0fedf8968c546d000c2d51806d72536ce6ac4349a913777b261ff4f4d25e239362404c0a9c1015305b47a1a49e694594d6cf172a8b160a3f625c9e0cc70ca7223108b5184936795a225a1baab152a0a1f26c0350cabcbd8491f4fc41ffbd604f376bf653f8ab599b2f70f01462b3a0d2897739c61a1cfde5b54bbd85dc281154682fde73c0f6ba76a5079c6e5765bb7c85e7da6012781a868f9cc270a1417568dcefca13561929318de4080436835e4084592f52e62613d1da4009b1203dcb1176a6c35e2c9bd916981d16cec9483117b4c2042f80988569a51d6f2e748c22175d535a182c121c361d1890fe641fea137ed47b995274ca5be41e3e1d33cd5bc94587fe5afff5d6c8c46308671d9dcf289568cf1386e780683330f24a1c83f584e2594850092dc9500d349e8a1c37855c2853a32d48a48dc382e9985d700665d2984182623d31fa40936d26403051aaf1a121461a6b838882d1479ff2f9d817db02ebf4dc86ca626fa79dc851f1d166d8f709d45214dbd7e414b9814f703f06e8c881283efa364d3b76b945be98fb8a9e6d746bb656a974ae0f497f2aca940ff38dce6349b590ec9b5dd660ba21e6a9f55454974010962a543bb2de0d359826261f142896026520404f04a537c72fb0dfa5a602588ce951a98119874cc150a044c64caac10bf1f07f23b7c8fb3c662d07f13f9183b81fd39642b9ac74693dd9dc480f3df4bbc76a6baff17bbd3ff7bd3cb7a2e2e0082b86157138ee469a890c8f314b59dc5a0ee4964e988f11d5ed63d25b4d8758d72d6d6302c9b02db2b08b8cf25885f74ab9542cb074c53cc644d0f418cb131a33ae19c8205e50102a8c9cc8ac692a9a013fe12830809a40655dc714d677ebe5c57c48f59a79036cad42709fdee7a8db71f00eebcba976e54daeb8af616d11d4747d10e46a940b80e2a00e90a233e0c588395a4f820c5902d2f4ae6332da1c0c666b2306f954efe62eec96fe802f3c51a1d060b6f14ae9d9379e363ac5397e22ad11453b660972db021339ec72aeb9d9da09caf0677c10864448a7e78e28acdc185ce1b7be892dfa1ecb558fe177e7767ebcafc5dbf70c609b434279261274331f39148e1c93963c126d6591660c41625c222c94c1683da6f05a8db7222895508eb6b6c19b853f0cc69e908a48a438658889cc4b814bdba599e0b16fe22d2a016b969878c3c0c4f39e83930f6bc4f978138c90b97dbad2bda3a398d61f30b5983471dc6a5c40e940f9ec3ee289f86b87f253fda27e9c22860bdc3e4d7c915c8a19577e8c45fddd31805736dce4c80ad2c62f76dc8e1de6fa6b782c80803e57392d923bc0109efd21768c6120d94433bd48630c918b27253235117760ac4ca643dc31e7c18357f2a53fec75143608b5d2deb8b1d677c560ea45289523a06013e92e0378974a9f1516538ea0c89ea1161a4cbf1a23b274192eb50b3a7499ee251cceb6c97bfcfb7dfdb6ce4696bde5ed51db6fe45796cd28584c28be83873d4b61257a3a2099176f97c0d07a1e9bda78204476820d87200bb160e8c574e6f3268b45810531cdabf15692414f32787a0979a1a3138df56090781420800f1e9cb9cc68033070cd2031213dfd225e34c062b7c99fc26c09aa7903676259c5db000f15ca0bdffae3f9e2c2bca1bc98ac10dd8d1054d648bce80fbd952faa3a97ba31fe854450e3d81b1ffdc7f6ec70175fc4d7044b93ccaaf96339512aa241207b94369613a24d586c0136085cb6277894d0078660a33857a63cbf74e64fcbe9008c55136fbca1ba5562a590015ea0124d7428858ad85d0203291edc306ad47d19b380f6fa5d5667c0873974419faef9b3fb7ceb3b5f3fbdcbb17aced7bfeb372ff718923b701b1cd690f3f142dfe712f8666ce906e335b194d48524b36b5c58d4c4973ed92e8afaba6f965a7bfa63c734b4be3bd01c9d1254275e7400030add94c68012649dc9035390622f410b14d91da7e8f6e5b9922a22f7e0c55bdd998fd68879dcba46b4d1618775236f2dd3016f32d2b35b3e2dbda1c998091a009ee2cc082b9ff9c3f6ef8419125d957bef36b66733070a9a75a0d6c41ffe708edaf14abe24ef56062b8c148344c854b653a0e8bab8ed7886d0c3e58cd6638e52861ea3b348d659c10231592a71b73705e9d21502d988c8b33b141285b70bdf924cd9a4a10db417d5121890e008c5c051588fb54d85d12395c5102fbfc8434fbd828e31dc66bbfece1bbe0bbd7119b27acf59781ff3befa565e9f0edc4449476ff3f75e379f8e315fb5ce425d93f787baddf73ec6a5d5edd2df7efb53d7a91ad7f1c5bd8f05a094e584215b34c79937785aab109bdadc5b23517b964d626141999abc6038f1f64165c81ccc41ea450244bcb945acf4e2311cd1cb11034d8ff1796160989280788531ca2006403165013c683cbd989492e6eb19772b6cc0a7bae7893c2da8ea339daefa6c832c897220288f38601f62148026a60bab15f62eeef0ae6ce70ddee3baf5f4d4b7823bccf5c5783f3794d3491dff6e5de7c8d3b9aa6d79cd57aff4a74b659a182dd417b1f19ccf2b2fb8145479aef4309375340b999ea870c6409aead668ebcc31abcf650e85f95289b78c197386612d96aeb5e0540a3f4c4d0e9922c83431a3e4387ff6e7f6d2839b8e2fa6b15e066b68a59ccca43d730034607c5c77fffdf18e67c688a550b6255d11f3fa3636ece7b28f2eb12814b87f41feecdafbadb102d385129bdc74a03dab31627c41a6e5a11641435a99245db9944c4f185ad6a2fcd98c808612af830780f32d6de9d2a0d48934f587489a506639b5045ab6145ee6bb14a0a2d2a0e40d14f1c464e83960f183636184417a2b2ce4df3d56361328ac3ce61237fb44acb9efaf47fb3a0fbadd7e6ddd718cbe12c374ab41a0e916286dcb2b1cd89d039184d010c68e55e79c98bae5ec4b7651dd8eddfee0e893bc1d9fadf55e7fb75755e3d869e226daa538e8c58d62877d5aff411e9fe4c97c357e039f9b3c522011688722ac0b371d6da84c351820cc74437d48124fc4ebaff1d615da134161434cdce412d6485e4d6f828b3caa739fc38678b19054fd32319a7abe86c7c7b26969b2612a6bcd241345043c9ea3678dd59606d3350c4b2db57ebef68c1e27335ae9f3340d6b4e85300516a2c120205a24d18648c7e6bc9742401e745ede22235878c374a090b4f44589360788d7a1901926bad9fae432951ecc557d912348a778a89137b67e714227def980c18b7de0e28c4ee66bdbe5293b9bd30d5901855ef5aed339b662b4f6622a47a240d9fa415f2f4fc4a2adf98b0ed4ea38ae6f31ca1f9ff936fff7e77ca2436eeca63f4ec5bfddeeb18a4a58d9da1fae9fe274bdf65bd1a1dfcaea77dfb48e03842037dfeb991fb977128d4ee6213a191f8abdd17ed7aedec7fc9097ce689eff8d7c5c032d4e1f20203dc7d04c4744a969a1d44f24d18480018266eb436da5b282856293f50742cf11b1e0318ae9cf916347db10c55dd98cb62a86d8342dd2c7e28c41f3c0d180040150384005a2d67f64016b527820d8d7e4e33a99b3efd379b41b2b96fc763ebce12e1daf1df5bfa3bdcd03f7ac893f6cd5314b02f7bdffe533ff4071b3effa355e623d07bf937f10848ef8d8d14bed4587d248b58215b68254611e2939ea1630c6e2844e4d23564a182f189748131f80dc6102594bf88e4a05121e3ead5112318e203818a4b9d9efae6496385380fa004a1b65983e4c18da9e8a410e41ef9afdcdefe41f9cbbac442616a01cb8c99dddf7ff75da97baab93ac1c1154f3a07cc5e29ec861b9eb438f110a2f167673e6933d91a6ecf95852074eec7b79be7bd7630cdaee3dcc5332f1d8de78e7e36ddaf83e36c9a18d34164936811af1aa31c408d44eb6fed73e37f8f13de7f3377e6cf33539f1f88f76fd5f8adbe34f61990f63e1534c07a31600a47d3dd29650dc2285c2a19e04b147999d09c3313a93030d985bad943b7629948ed9614cf0c4d80651c18028ae19f4a73c5e7943656e32b4a21365adcd03d9a0488107018dfa5dd61c6a6b2721a5c27bcc98b92217de59f975d1e7bf2b772aaefbfb35f3377d5e6ffdfc6f7c126f38c49fe78bb924bb60676d32c10a475aaa446864c71244094abdf8710998ee8b63a2071ce6e594a755c30cfa369b42047a31b07abc1e6d5997da9ab2185032dc50d0c27d9591d2e9b037562d443413446e9c8f7cd0e380f0b476ad5447094efe22d9f511ebda97fe6bc7633b3f0fd5b3b625dde41502e5a57c85cdfec1e8067e2950fbe2d02ec7f9d17163577e2da78821f45528315ed4753c0af7649a982a8db7764c2f6443936581089ed113348a0c60bfbb52632e761804f5b8c39aacd43181bdd50d656300f262b2e9706a456b854e814c6c0e0978eb5bc25226bd67cc06993d7fe2d0f066396a7264690b97d18e7d921fe2a1beb7bb1afdbcb6afcefb0d686fd85b7b956d59d99962f7d2be1efb51f7fea68dfb21cf68ed43fad09e1ae3187e357783b051298131e30de7b11a6d500183ccbc74e778e4c6cad84c10a3184f5bcf24814de50f26dc3e4f8a5cc66c309fead9c63324d6181246e1b518276a47ee777953ec14de50785613658c782d75196c6bf4881b535d06d3d2079fd1798ce3877ca2d7ec4150b6d5bb84bda23fe623ffd6f7a9ebaae61e16850dd27778f5af7178128f04854f7a03196e3939ce39c0d31334143ace000c1d73bbb1e7bdbec77373cc2b34aaf334f4361e15d80a8f6959e4e6631674003da27c3e7f01e26cadf04a6cc2ed4819a60b4c34450ebb0214e9111c3e3138ecd217f229fe35fb07d6535e3dcb3ec469aaf998f4673ebee37c6e1f6cf1a8ce6f5ee711ddf3199f3ee66caaf7f1bbc50482e035be42a5737e8cb78198eddadee3316b2caafdbece856d1d616e3ee6b23a1ddb83fa50ce92f36a2d47d6ecad0dfe11c3733a26cc873ebb88f5f9bcfc91bc543ee4d13f95876d17fbf9447b8f38bfaf7b8ba7b9bdeff98b4dec9c4ff7223fdf533cf4cb877ec66250b82c489cfe5bdfc979ae3d1641e1ea74e958e9157c80d12dfc9814b2a47c6229a9df6037df1e57b6e697732c612adb987144a1a83b74127b0d851e371594be2ea40347dc74548a62b149cf15801463800d0f124d1ea643a5c8c70a40c5989614d3d4d6bac8172ac5994a948f00e44c8d22b63e9029606a8a43f71e540038dbeaf561fcd5b89ddac28bbb34ba2eaeff0d309c87faeafedd73426b4e78717dbc2a59a7792468e34989b6539eb35d119776ac2c35606fc794b6b661442172367fd889f1467264edf7842ec6e1bf0947e8b8ce4a9fa8b994077c86f2b5b8dbbb3147cff150b2b48134822495b149329b093287320b24225b8f67ac3e97261a1f71da1067e3520a6cd243a8ece51e8b355d44cfaa4534502a2f7aec6d3d21a2418c282c289241525a6714dba546a51661ce13d0d2e54fc7dfc52259f93a9d79c9a5dc1c5e259b991b8cadd44da2dc1d4a74a3071ceacf953ae6bffda57ef4230e19656f8263bc522cc9f609de18831e27d392210f48699819a330606803e1656acc360a4c33bd244325e91936d4622f26a6cda60f061f8850e4d7bea8588a484b668c72971f71fa906893223710b5d980b940ef72c19fe8c7c7fc1b71c24ef869be2713dd82fecc27f7d9b51d3ef86be356b7f84201411f0fd08336002b4fe82d5c7e0b218f45632eaf114b7439ec6e0d4a9beb1437f581a6a081c6d831554ecd00d86637554d8a32797a2b8b400191bc0662def1c3dc7162adb44b934625e17c6bb18416bf91852fe6424db4f57e6f6e6249811be32b74db9becafedfa1913bf4f1736e49286a3f6b13d13c3ac638c7dcdd6b4697380537f8e6cc522823717e69851124c848e1d4b122e31704a2531d888463c89b0b0a0bc486390b9dd3a4329d2c9d3d210a3b53e9c3178482632cf097698151aa5706e0c068699a61a2b14aaa90d4c8a5b4e87caad6ccdd42be8158674f81a93cd6bfc9e676d486d8da17245defd9bc481a15c16ec72d834f5d6fb145f8dab0670df1f04c03780690cb567939628dde29786f1544e5865a20d255ba5b6237f88799b1568937e2aec522d0dd1dcc8c52357e7c920425fb752ca21d28312a1a51e8387a9a9ae1d714b7c53b0012f0d8d21662101ec145ec8af7ffd375ab96c8f3af21d1be779710d5e878eab75f1326f677693f955ebb11011afc98dfef63897fb9dce57f53e45d4423f220f9e855eb08853c300052e85a56249823ed4faaac94d5ca8d1480c86be2909364ca7f24088358b2c6c53909ca1b2d6298e5392881d53643a351409253d110f319a42b2750cbcd4fa790753f9c2b494a91e7d5996719e0822db920adb8af26a8d798bd9bd342f6e903bbdee6324367b0b134b5bbffa01ebb9f269fb76f3e76b1c522b8db011d886c9099a08363a95eb633a40061df400e9518005a92c6e3999e728970980c728ec9806b96d06a90ab039158302cc85c20b1fd7fa00c171d9e371b4280d9adf4e81cc29255164711b1822b2a743299f0ea45bcab8a3be7ac74d39e77fa1dd585afb7d7ae3c524772c2dc5f15579d26e80f5052b3bee762656afa8ec662c12a659b34e9dff6a2eb9da57434162ae658adbeaa512a906483cdedceaacc639660abc08f46571db7123bc344c34f286da58617906593882f3a0940d49f3a22e8f292e74783236592dd7e33c9281c04391df1a44ea4d454194237eebc7d91a5abd8fb9a7be9b7b3301ab7ddede77f9f24fec43d4be8eaa5ce2bcc696dd73204e96f55892db71373b2efb210f3feb8864eef4e9d06503823e8c9137d8afb36b29582111c4cd3ed43571157e3f6e37aef108a8d93ba8f4fcb7c74d6cb1af61672057402165311d145abf6b4ea8d4461649f4448854ea913148eac8e68651a2a0f0796a0de7b8d6555dba17b871772af3f6d68db61d99d9b27a44d34a24b03a8998290c22c70a028d08cf18769147d12f9a61aed552bad5dafa8abd687c2abf973f356e701457ed99851d66328f6eb367b6c76f14d47a87d7c977cfffc6de983450289079b136b6cd74658a52cfec675b0d762968a12d4c945066c0dc1d00d631501fc511a346a909a0327559bc516285f1d85e228ba9edc79c0ef89c77626aad19b887442caa041115f4a06172739dc2a5ced3efbfe505d97018f797f6c6f266fe1ee2341df7c15e6fea3fbdc7ecbcde7b0d6ee32446e05beb795ee73860e8f210dfef4b381c3e07314eb125c5981218d7c21b15aa1c8ae9a136d75e90a9417710245fdc1fbeb036922d86afb9fefea678591feaddc9b0d4b3c00e774356a8f8566c18da8805e25892600ed106126c2036653dba37c48259f804196028ad2665202b16bfd621e8c0981ec922182944e929a532704da1a70093d258fc6c12ad639a82e395110d78c136786e8bccedda147a53a304098c917521b7d5f5fb17acc479c3da9e0ddc585bbb8d2f217563efadfffe825d0736481428a4d3ab7a4f222697639d54b6f22dd624ab17d9964626905b6391c4ce2e1edac9f346edb3ff2277966468801c599038952643758ee60e455e508c8606ad3cbb66603b73213120101446d00d764119a6b7843cbd7421e9a864463904ac102b0d21cf217f8e5993cffbaea5adb581a6b89114c891b0c206d64d2a5fe0fecde22dd7fac59bfcfd27f19c8e28644e71363fe7dc65b8d881b8c462b738c45939a307f95028f6f5d6f18c4fe502b07a6b2f517357141e7cfd7c59afa0e78e7e96ab559549dd44a16cb8cd1054f37a2f2b163277f73d777b5e1f309e8e25e7d59af86e6ff5dd1e1029271609bcb87378eeaefc89f815755c9aa0c140d0c772ffd37cecfb9c4587f9f6a19d1f63d61c70b51fcafaa2964ca014780c889c837f46fd308fbf88377d1d2bd7e04d6fb7beedeaadd6386561c3edf2f3bc6397e434456903a5af101c2b036162d044d762adf4639af74c7aa0b13c0d88bdc626dd53e72356a652c910e9e771a9bca870bb980a33ca33350a0db544a547254a02ca8eb68261a5863f181526d4166ea4cdf504d172626e1141ec07397dd0097f0f6f6a43ae746a594db257fe877a0a67bd7be669fcc68874d89dbfedac9e73d66f6449e904a697380fd48d78fbb41747950ebb9ee887dfb9d2aff1d95ff315b1d2045884934b45932d329f1ac1c634045e85b48c87d8968d274e9b635387c872056f0ba1b69e0a3893214965a0105d2404c1d946e783d814812cc748817cc6f8f35e3915c15c67650e25d2009bdb318eb948fdb84778766df68660e5d75836f3186b7f7e2d2edc43ec623ab3ad4bfb8bb7ca0df8a1deddf7d9ec73b657b2bef3d59c81b24e8b1e0926134a88edb95aa0a132f445dad1e64ae2cc854c35108759ef26bad0a93cc0fbfcd397fc3d27b1ad177999bf8f7f3b91f3a4eef78fedd9f97aaec6e5f0b949f8ad9190d81b7aa51bd12b6821c62c85894ea5093071a0f154e7e4be9905d24bbcd49a677393f7afeaaafd5bb403d57cf7dc2fc98131c521af943464d296afe74340a1670d529c2f722b250a06daf069e30eb0a6466acd7df2a32d70cdc5726a289a6272a2cc736b9b02859be02510731b4468ea80593961d0462d518088dcd1c4209c30f841a1472cfa24c653f32e6fe28e9f1f3fef75a5dfe8bfb7f1179b7edccf59f91bb90d0c46cbe130e84d8712efd13c0badde14c4d2c4a4d2a591a4262e25694ccb346095d030b595ca6a12a015cd86ddd28884396035119bd11a9ad91688e9033023c68da52562c856b3c8622a62cb8d716cb37647b594686a7eb20fce04a9cdcc723bee762a9dd0ab39d384722cf477c5663fe7ebabe6e9b9eb5f8dd95ef7bd9d60070ded8d6ae6b237ec651a890a9d4e753840264e086dccf1da89d34261b6acc3788c0b371b2fee4abe4110b280e1cdf1d82c65564e84cc20de762a000d5a6902cd8cf36332b419500056700c8616dc3981c605dccbf53847524ea094a2b771194edb1895ae1fba4c374350584de01e9ff5d6977bd23ed8ef57e67becd75b7fbe7252e77f834939b4c73cf5ecd287559b36c7d8b8b3eb345e38505934bad896ecfcd27fd31ec1c9badf8ec7b9cb547694425575efb8d85fcc07eb757c1198c0c2812b763a8ea14c268c8264c80de1308d5c821c5724911a2b0162c9544bb43ee255da6183953dd74c1ce18939c722228a64964a0ead1e0b68796b0230c09616ebeca2a383a863c6698cf9d1665cde2caf69f53d73fb101be9b43d56e31719401de9081fb083d518c2c486f955cfc30c089c3ad6de5b5bf77c1ebbbd8cabf76ea19aeff6edaec9b97d833823bb7164357b8613b8db532ca8f527eddaad275f8b5fa70c88200bca0640939345e5c513bb7385929ef50473261fe81e507a68c01776c96f4c481536a4230da4854e7a036848536d1804a07cdafa512081a1445c3d2fdc0898d05022cc4aa13e5000b024801921419182b48ff9ecbe29d304c68624db61749abdc43e1d788914f8d6f9d875d7c7c4bb2ac6c887f186e29ad737778ec6da07d91663c8cdb158ad8befdb7282e7d560d577b2705b1eb5fbe4dc381e37ef62a99cd3b759a7d26d59357745b2baa82b1537d2951812d5bc12b84dddfdfa7dd40eaafc5a6ea1da773cf5187a0d4521f3680c359e1e62abd78173a0cb8360691b247685f4c589898ca300aa002383ca29c7cc95e910bc6021b5bc39999b318a6d982d31500465305b1acca8633052e00ac106b3840048388d5719d344c9ad7cc7afb1bb708a86dae2537e827e5c576d6389606533e4b44fbaf16dec7057d7f89bcc5bfa9b8e624154b2ecb83d14fdc9fec065dd8c440c8a17b412758169f416c010264e84a69a20d07a84889f081334947abe89221d024635b5d4b3244b1f62c315a55c8d38451f3ed136cc0a345737a6487574a289be4915ae25741cca63dc182f75fe712b437bed8abfc9eb8b41ee32e9515c8c4bfb93d393f8f5efee4f1ed75fef53427aedc4d19e3b904f3fcbbb73493f3169c321e4c1a6f1d4a0f80db2704f1ff61e649eee78021171821325212fbe214cb552e96011ac3d6bc128030daacce3da24bdc44d46db098587b89fa776a9a43ad11e4c2310b0a19888a7b68aa00498e12080f450333ec46d3835f7ceed2d5e8e65f6f7fa652fb4e7319f30954e8f6857dcee62ccd1755cc689d55b3bbb781bdff3e3d20f3ea47345cfe931ab0c3c5ab17c53e53c930b104ca14c69228e8381ce2899ce68a94f48a01340eb3cdf91694976e211eb1285d6182e42bc32d2587be388d952a723568de89e3b542c6466148020512200151268d7f871cff2954fc8ca4b73a9d9b3798f1ff94b6300529f70b72eca36c84b639ba8a531d7c68e80681704822c82b521989cc62b2f36238853439a183cb705222daa0c3794ad5e3c15351a5881a8b1983207a8a70dd0ca6152760af952875a6a269a2c5366814b65ac894498b0412ab3e81999ef75b40b3affe5f5ec539937229dce19eefd7531064feeadbd191bd653deac339fe43138b223cf8cb1b7cfb9260efeede4c1714ca737f1879af650cc77d74dd5028c4e6b051091661032d5a142d964b4d58b2ed2684d970d8f5622ccd974af44250ea7508ac09cf0d812686fae25788e029d1546501416ca1c3b539ee466892dcd5ad026407383d53244bcc223a98021a6940ff1ab6f35b6eaf857ef786fe6bb7db9639d77b72e9fd585bd58d878c32b6cbef776c6f76cbec2b67a1bbff615ee7f7fddb78c05459bc2f441a1a4ad43828e11e7484b504f16842936e9091e3e75be86abadeb20138852573473dbd2d62e2497f260dd2a6e375b8d5ba4d3b103b7640205ca65e8d42e9a3e3ad5ae6fc5f136054617150ecec1d8254aec194aead20ae72452dfa1669c0f3cca3570cf8759675212c5d7bbbc36206b37ca09d61f394544ac17d16b9b01b9514a9a6aa6a20ab72b37d2a6633ae5cd22779c48d0150b04b2de5541d8bd1996d6b54051fd7344a13cd89c3506443de54f3b87bb7dcf67ff10a7fd104bea03f7fd3cf6bab9afc6589f9b6f1d247ab91d0b25825a7a05cee5267cb5777bfa95edf9ae1d14f59d9c5626c52d3433e5114c1d086cd619981b35ee2e8cc113a759230ec48284202ae468aba8d02e0d0ae41eaf2c9da89bcaa546a04534680a3600da8b06040a46a9a9338a28f36601ccdc74faf9daa334d963f0d481d4a5b8ad1ffc5bfe50234d4cc48b710a6f20db9a7864d5dab5ab37dfc5a9f8dafe079f236008a90a82311440a282603505407762428f29da728604403e28718c360a43cf3120f9146a0630f389dcef0e9c442b808545d50af8e960b4764dc5b2134df628fca2452440831eab5bca1a0db4078f683d0d9cdefff0a190b922b93216c70dc6e8a1be4aee91c015b7a9c7eefbf06b7b48328b238d21114cc85601bdbe3c985190df0a66094c8fef1a66c49798496d156e2540d10b0ca9c2a1a5390e1f2919282b3906b969f4221f2a1a28351a92404630657516553a7d8963297205248f298434a8500a75d487e35ad74aa8f1dd8fbbd459fa497ef7e7ffbd7b8e66777fdeddfdb8539cd8af7efdcffffcb88b12270fd7fe1fd85fdf47c93f52b29a85c93f7ead12efcffbdc8f53e2e47e769f2cb07f1fe4797a9f3a5ee4ccfc3fe6d922a91e1a26bf16d55fece74e48b2ea67d23cfea8e48fbb2c2cfdbb3fb907eec75dbcc0fedd9f1d86aa7ffe2b0febf20cc5d0ffa0e97fd0944177ff643b7fd29d3f989f1cf5f3a1c376ff41717f52d4dd8fbb30fb170e97777ffe7248e6ffb8cb8abaca81bfbefbf3a1c3d1dc8fbb51b2b8fb93fef9c0512cddfd71a7903089eefea47fdcc975b52c4b3f3efeb833437cf7274d51f48f3bf1f5a7f5af7fa50ea6eefea47edc69b87a28f5e34e7f6d798f44cd7b74a8ee4375b8f0a2eceecfc71f774f7918572dd17defee4ffa817de0bad423d7f971a764d5996eb743b33fbbd4cffff971279f2f7a78e7fff971d7bfbea8f5af7fad9255e6e3bb3fff49fda07e50fffd3fd5f70dfc65dd41559fdddd078bd8bf9ffb491426d9fd66b18cb2d4f1fc7b2fbcdf8d837f24e12cc849f10f2ffcc7f17078373aeef1c2cbee7edc8de274b1cc9f9d3c381a5bbbab8385d79c369ce5cccf9bdfda62b1fb253bb917dcfd99ac08f971a7e70ef10f1fb63ed27ca71e665559712184c4cff6a59b7a0f87033f3dfc36fc2c7f57ba3af5ee0e798157557dfff76ed7f8cf6742ddd230b9fb335faefc1fb7efcbfaede405bef1179a2dfe8817b87e38f0975958f724fd07fd504ffcb47eebbd5438fbf2bb6f7a591efccf8f3bece4cedd9f778d0225ad6c4893d705ec2977446185c42df1f6cacdc744d76f9cdd95d2acccbd986c1a277e2d647b2311d16edc6cee8d86cd26ce6828118fedaddd582b47436d3de20313084fb36683039478b807eb4ab90d49b3f0c6648544d099c4e93eb045e8314ae1583dead8086a023235f7706b249ab306205983b2a9fafebe1d8fc4a36b7b453868dacebd78af8a7a65ec06de2e80118a85c02baa85882e30e4ea44c8a37e67ed402e42d66ce5246f80c66fc8164d5b2a83bf339be8358074536f0cf73b6b37ee4608747709e341396150605b720d36f312b0aa0308e8ddd0819db5cd6cd3e61d8eebacdaba531c4387011c66ba451374b4e75abbf3b60528670fc6db7fd3789bda0c58794c03fc52ad5e6033c18e64b32f73ce912ec53614ca4965a05812ed265aeac2d720314ab10b50b957162a252c3afbbc95cb68c47d05b216ef36cdc3b781b78e36025e95f0b00910740c20aefb484dbbfdd9fff93fb75f6c733fcbcf2fb27589fde2da61f76b2b43777e761e3b7487fe8d25b691769fadb0cc4397657e3e3c1c565866bfc2d20f8f3f7f7e6385ad9affc9024b7db2c03e3c1e1658ea27cbfc647e52ff5b16d8f76beb3512ba3acac35add3ab7f2deb695bb45fc9f777fdcfdf761156fc6cef1229e5547ff1ff6533fc17ee2157ffe7fb3300f56ee1fde22be9f2dfe310bf3ea8f1b1252dcafb9b76bfe3fef3c12fa49fec76c71f7e3ce5b24bfc259f3fb5755a0c8723fde1defbaa0394aa3998f9b9f4b3f5d6461be58867ef6ee4cd11c678b65eee3ccdfd5b29f90c747f5bdfffd46fff867d59cdcdf56d3d05f2e17cb4aeff9155787975eefecf5fbd88f7f659f95aafe7cfe8ce6ea7d962f96ceccaf9eb45816c785636719b9b5b8a9fa6879f662f57f98ccaae7bc2b17e65ee0131254955683aa921b3fee668b349afd1126f78513933fd64c255316f57ff7e1629587e4eec75df498fd112eee9d348c1d2f08137f5954d55427ee977eb6582d3dffee9cc4bcaf1e54f54fe2e7f7ab65f5cc4576d7e835f7d5a8a8159cea2bcffc6d5afd5825b5186c3e74f5275f86c9acba272bea915c5ffeefbd32f9cf3b77f5ab6eb75be47e568fbb385dfa5976ef9661cabc3df1ab1a1a6f4fccca307d7b5c92d06d466eee542f7b4fc25a70bf8e1d6f59a4f9e2f0e3de69aa6c0ebc300dea8fb43bc66f2fe2cc793df0bde343cc701cddfd70e23e4c727f9938e4dec71b6789b3f7c50809d33cf45ecf04b1f3e6e870fbd249f0ee93bebf94addc9cf8af1762ccbd1e54f7bd39f23a6f0edebe401638f4d111c33d1c1d7334f3e6f85d953979d34f5b8eea1e1fdda751b8ade66de22d7098ccdefcbc77b2847e7bec3a99ffd0393a13264e3dad0e67660bf7ed61e0bf7df8fdce103e1ca7f574fa5c663c2f17f922919d9054d36bd76c37ccbdd572ed67d7945d3a61922e16e48ab2beb3bda2d4e1db565362f7d92fddb3f0dc6b4aa57e92ced2eb4b5613e43ef28bcdd2f9d25dcb78b1fc4279dfc3c1578a9399133b5775cbfe8efdf7bff686c33770c86cb10cf320fececdbee77debb6d79972edbd9585e85f33b4f737644c745cda8fc365ea646165d2e2ecfe2044b3b3c52a097b45897b67b9748a9d38febc6cbef4dfcfb95325764221f0df0fca7785f78bd789e5dbfb35fbf4c27de63949f27eb97e5b205f447e72e67291be7f8d6fa826814f527f79ef05cb4aa1bcb274ba20c5af9090df537c0ea516d915853e8aa82faa508daa79a1d0eb62e8afc3acd1bfaf2adfa82de78aa66415bb1fe6dba7c5ee3dc70bfcab0b2fc87b59f879e14aa5aa8dcb6bcb2f96b1935fd781ef6fc2e1af5f5fbc6516e6e12c592cbfdabe106fab37fbea5d09f6b75fbc67e1cebf5153253dbf735b949330b9faae853bf7bd4f67f2fbd26925bdbd05a91b977eefae7bcf491d3724615e7cf30159887db7d122afba7de9af3f4af9cf8b57c6d36782f663e97ce92459dad8155fbbe1beb16cbf7edf5746c5eb5db3f01b5505797ef5677ebdeb20e6bc451c5f148a271e90f9cbf5373ec17d9605d759c657dacfaf3e862fdf708f17f9e52e3f67a87f285cab0eafc6c7e5a25748d3a6e0c138bf5c34f69711f1f36578a90fdf17bfbe333fdc798dd03d71d36e10fe5a3af1971b9b2cf0c701e8ae7efd72c8e23ef03fae36b34523a6dcd5afe6c7718130c6ce325c5455ccde5d9abb7ee2d78dd9f904eec37725227f1d26ee6a19f9d508ffd7a995f54b5e9d8fed7f5fe2d079b19366d7b888ae7223f9b1ebe36f3a9c4e97cb72bc78dfbe4f5c53af25327f390bababd5fca82749ece45e90d6eecca3925b27298baacfffe1cc76a27a419c64f6c76239bbdfdeefad6db2d8fc0a1bd173e2b2e76439f7d9b5c0f10287a13ebb5c19fc7b07cdf9026fc67be813fc49f957afd0a9ab1f1d38a74a55ea3ccd529fbd52f669476459707fae1fabebaf7e86fae4bf5237c2bfce948f92c52609163b83ef6da16a4ebd3ad93e5c7a7dd77aa3e1448974b9d816ef2f644576ef6f7dcf713fdc535d7a55f093ccf9e507beb31323ef0bae92daff74709886c9af3fd6d4db331b679984c92c7b77fad5b31a38754f577fee1d4cfc25bb3f7bef2dbde6208f2ba91ec6cd9257ff3d28ffcdd1a1c5f5e16e19682ecd53bf9ad747ae1f871c9df2d2d5dbc35f71be73b11e4e257e9e2f9ddaa57b38b7c86adfc7db53e9a2b60fdf78178f6f59fabf88efe524cc8f4e67613223fe2f12ce82a35ab322f31c42ea4fe527eb5397765fe0703ef7b39c2c8edeeedd47dcbbb26bf3f33b2eed4f8a554f79f5069d2d95f9f9c5326b8784d8d9ed065d59f22034ae70bb379d14374ef6eacfbd1bce5e7fd60dac7fef3cbd71e37baffedcc72b9287a9530f91fac4cb6a91fb385d8649eeb8b5c8496a9751350177cae7fe67fddf7e2c1d4eee3fd6ee5c35ddf7cbefbbfd814533739b5fabacfea4bbad828f5b07f5683bda44a87fdc674592d70ed3d74d85ddaf7bafd95bda1dbd3aebf2455cbbd33f5cd975e187f359911ded55788b7a047fd8b5a8febc3e7e37aef7bb193fee5649e83566fbeed7fd2aff453f1c1f3fd687d530bffb71b7f613bc58de5f58a8ae28f566893857bafe5349956bcbed7df3e70abf5d32cf940b9a75e54c898fabe199c217deb81a8a38c9aa7fb19f658d38feace061b0cf56f564ba586ebf529d2bc8dc0795f57ca6548813e793cbd58ad588fa53576b9d35f3bdd5d2bf77431c2e579ff6565db4b6d77e2d96f1b942fb315a3df09a7249f5bcff7e8701fbe76ec7f85f9570dfeddf1e21c2fe7924f02ac198e6cbbdc0a86eaa54dbff6e316337c28cd5a0950356ac81e3fd05c8997aeace96f5caf6c73c3b0fa47957760fa9a13b5dea6f01aceee0343f6f07586d9ade22565bc46a2b7d2e898657e0aac48212e9bd9a0d68b36a32dd2cc636d35d79ac3af38b5e8945a1c0fd5e7734a06687e819fa2c3905e2948ae8673f56d66ea2503540d502a47aceb3de3bb0edc67ddc64f14fea480cc9d8c8c6877b6aa0abfcaebcb79a845e3a8983c08db50c19d9a17d0df0f4a9bbab2bf5627321b15ae089e6bbe782c28b76f75ba3eaf9d46840fd577d3e7cea3eefd82ab8cf112f91d65e18102f19a5d3cd62361aaa2b04b968dc8f7ef613ea677f96d6a0c9711f4b4780d7f9627600fb16bdc00d7b232068ea88c702e87bd968a8ce9e8d4ec3b41a2a946d49d4b879df7492680b043b0b8f01058e4151b76d0fe61caa2b4fdc066e382baa776ace1dfaf670cff89581b8420ca0c67d6ffdcc70810bcd2e164982ac517254c60a6af0ec7830dac8fde8c0f298c4a0e389608efbb34465ba2b2c8215eed3a66ff588546c6613262d5da6b33e7a56dd3f759f6575db8ae8f55d0fac4875852ca970d9d1a2fa3be93f2546fc38db9d4b0eefd63067a9499d81b127781608dc7e50204b5ed97137f2f54d352eb71882c23716d5ef1a743d0d9f92fd7b8e86d4ec971e1d4577a9bead1bab8b77f594c89218648d5636b35d7b8c79747dff8c5ffaa66ea77e007307d458afc7433546c6cd389c25fa8eb9655b7584a68791b81f73f2cc869d992e68a6d9efa906ad98555f5663773ff67600e9459df5a08856580c881b06fbf61df527ee731b571456e3c16e8cf6df00bffb877bd2d7f7e7362eabd463422ade7ceb44a9fbe4933e7c7b3ff1877596c6853c7fda9c1c477d3c7099eafd396a0234ae9a8393fed3da4994b51b3e1e3dabfe0ef5dcdb54ed2ec7fa6b3fbcfd5e6fe66236eae3a95bf476e7bcc37b1fc6960888c7577d2064e37a0c72a1cb68dca4dffb3912eb79f030ea63ca819878a1f7ef313e8e40fc38c5e26c3f1f660d2bbd97a2b0b74290508e088a4696f4d65e78cb31c45f3d86b0a52ea4e2f1488e780c58a17ef0591f9f922b853c783a39b624aa92d71a711335077576232f1bf5bb2f1ed35d4d8aa367ad507fb69323d55a21a74732f33a1992234b296d88eb716fc65d1a8be6cc1480390d1f676edcadd6a33a6b46d5cfbbeff2508f43569d69719776633599f4eb3592c296327019ad7a16250fd4bf737cfd4540fccac6cc2fda11fb427b03e2f127f335fbe181faf9c0319d6fda0f8fb7b31fea96ff3de6c3ee9daf311f5e8bb6e6436b3efcffcb7cd8cff2ebec8666fd79a797179d955444abbd8e3cdda47397e14adcef3524a477f645433eaad7f9d7e7c6a48387a0407af5ec6ce68add641a56eb3b59a1f8f16124d6fafeda15cd5575add6032b3ba0b13516120d568ea57ea6970d3550cb73ea752de95193a497d9b0b39077b278523cce74c8312e9393d1505b20bdf726eade66b68ba438f398608de136aadb64f5326469a459e38335b6d4fd7ab2aa9eb97fbf26bbf4b6ee8ba60f839fa37e67358951ea0f35da8bcd6c24d2a47a061a2c6612b5b72d041a5912d7f4c5a975b8d76dd695536ba242bb4335abfab3b62992e8a1eedb58c891b1984975d672504845af5be984276ca2231d07402ec5834f6c21a1f76cd2ff617d4c1fda5ceb93bfdbc7b5fe7185ddf2565fa8cfbdda9dc08d09350d2bbd47d9b80c1779458f752c6d51dbb371b7a8fa0389e6cc81f6cc8d41d51fc40bebf13dab744b93ef1a1f6dd2839db9ddbdc77e7eeedb5fd9cdf577188b87be7a1d0feff56f1664b8bfd9fb10dee94766d6d8c01aed5134f15825404cdd9f0ab2b485cba83bfd4bc85cb1cb22a82667c6de6df59fd849c25f7e96ff51383139affb1c173d50febfc4f8ef3eb234fbd07df8f965c63ffdb3cbfdec720f37a4fc7f9df1fff8b0575558e6e723fdd0e1d8cb0ad0e19d2f2b406f8bb60a50ab00fdbd0ad0f1047f557eec04a4aea8112f911f2a618d4410db16c8aa85af12fabecea56ed10d5d5659bb6177c7eeaed9eb2f5e418718920c89a0b8258b3a2df2e0628892a6cc41523d7e8b3ffd99c5769e3fcd76189aebb0af114a3abfcb9fae9aff7dfe3447b32c4db1ccff167bade54fb7fce9963fddf2a75bfe74cb9fbe6ff9d32d7fbae54fb7fce9963fddf2a75bfe74cb9f6ef9d32d7fbae54fb7fce9963fddf2a75bfe74cb9f6ef9d32d7fbae54fb7fce9963fddf2a75bfe74cb9f6ef9d32d7ffadf0d81b303abfc15bce9e6d1f71e59acb0bff693fc02c9e16dc103d1e1e16f04cf7418f6b1c3761f6f977ce0f1e177c033dd0ecb767e528f2d78a605cfb4e099163cd382675af04c0b9e69c1332d78a605cfb4e099163cd382675af04c0b9e69c1332d78a605cfb4e099163cd382675af04c0b9e69c1332d78a605cfb4e099163cd382675af04c0b9e69c1332d78e62f05cf1c215cfe1e20cd7d55e48fb4380fa8d917da83693a4cf76f891abac3d1746f1733ab6e791b35b40d9ad54a9db3e2e03578164aa4b5abf736b625650e147204396a2492dc13bb05eef79a28e256404dfa3d8263b0c24f8b713fdaff4e2304ed990b85d40d83f9beec347cbd6f6c2c76119447e168d644aad612b0b2d93aeaf60c8b20f7c46d8045b32927d411260fcf1a0d7b81170b39b234e285cd791b929557f4284734675abc0d3c267b132dbbb7b6e394d8ac3ab321178d4461e5ef2264abcc768da126d46deff70a0415e25888a0fe2e626313ddb2ce76802c859aecda3b0a47e12e7af47c34ec150ee4a8b168870604942376a369d8fb6937d1f93bb8cfbdde1fef22570ea970aceefb419e013120a3a144f010146ed8636cb8a591de5b204baa2366bae26666c7e6ccb67a1b572455fb82fdfb2251a06cbd17e0a1563850a20ffdd697672e63cf6cbd3770c52e8d78c0d4df725f4f0ca2d1505b7f8ce0d94bdd04ad1d0614cd3b56efafd15edc99f9c553e842507a8c90207df430ea4b2397c591aff3e168488d6f1b2ced68a0fe76dcc787bf27f075bd847528ea764bd8431bf7ba5dc1da15ec3ac1f09b4120ad1e57c967377c0d02394deccd643e5b294fb78b647be23596fecb2a5cfa7175f047becdcf8bb80fa5f7528e79fc3ba51c7d3b29c77c1e2db29572ad94fb7f5dca7d98f0af82ce1385c21549e0c23a15d4ab2297c8dd67e36925eb9dcded23d91eb52ef7b3fc5f5779168e4a1e8416fb37ba173a147343a9c5b6ee85566cb562eb2ac1f02ab21c486f5c56a246629dad6e7c381e82956369752685fe2cad45d96840cd2cba9bba566fed25da2fab98854d668851da9fa57357144aafe899d53d5a93318276634235192fb8fabcca0825d2a3877e65bf8b1a416193d5c462ea0c7f0b8f01190aa3879dbd5b679278cd40c1e53624abf130efee336b35e5b9c06315e225da3e934493d12cd6022c0aee283e644e082d7d337b6b2b57b6bf03edeabdea2c1316fd387b36a8d988747fd5be13d2fd359a2fc6a37eefedbb34ede847b716e5f5aee259b1bddb77dc59d2dcdf48ade4a89f5df627cbde8e5af9f0791a854fa995dd431a059a657f3efea4ffb748ec9659d9322b5b6665cbac6c99952db3f2be6556b6ccca9659d9322b5b6665cbac6c99952db3b26556b6ccca9659d9322b5b6665cbac6c99952db3b26556b6ccca9659d9322b5b6665cbac6c99952db3b26556b6ccca7f5310522dceff424a653d1dbec5a56438fa6f013bee80339d1b821dab96b760c716ecd8ca99d372e0eb24cafe6c31ebc73520b101f789cada4d34e20fd587117ff89d4edf100f474fffe9a4c9ab0985d96830dac8b727ded45fed3f8b71b313e75ccbb869a5792bcdff4a69feef47b5a99bf5bb1c1beeefe1d8ece4d4c32dd5ce9663d30aaa56509d970827c835ff1e649a0259ca66d2af744e8d7c835453df0f0b29479652da109311a1b277649a73f7d7f54efa4f853c78aade314561ef97c5709510ff65154fdd67fd29b4e86edd1e8b7e0c6b5dfb4ddf4d623a70606731566f2ed8ff53825ab01d86e63a9d36a8452bd35b99fe57c9f4ffc440162f2b6719ad2ea467dc17da0b2deef15bfcc147eae7c34397fb2a7fb05b55d17dd5473bbfcb1fe43eb79b2ff3077f326c25bb1eae915cbb17be4672bd166df9832d7fb0e50fb6fcc1963fd8f2075bfe60cb1f6cf9832d7fb0e50fb6fcc1963fd8f2075bfe60cb1f6cf9832d7fb0e50fb6fcc1963fd8f2075bfe60cb1f6cf9832d7fb0e50fb6fcc1963fd8f2075bfe60cb1ffc7f1d8cb307abfc15dcc1ddb38fd23e9e45cebc2db847cfd0ccf7e0333fa99f0f0ff417d1330f3f1f1e1fd93719137e1b3d439fa19d5c86cfd0f403dbe168f6f11afc4cf3c6d435f899d7a22d7ea6c5cfb4f899163fd3e2675afc4c8b9f69f1332d7ea6c5cfb4f899163fd3e2675afc4c8b9f69f1332d7ea6c5cfb4f899163fd3e2675afc4c8b9f69f1332d7ea6c5cfb4f899163fd3e2675afc4c8b9f69f1332d7ee623c6e56fc2d2dcfff1ea1e3c0babf9e3ad1bb101a2b0d4df13c67507a8616f1749ab6e791b4aab0da5d54a9f8b52e135a8d6a8e80936b34dbda142fa21b7f1e2ee0b820ad50fb9260822db0bb0381b4f1285e0a196ba312e279b34746067dd9f2de6239eacb008325724e37ec8a54804413f5cac1cab57d47f219d35c7b86cca7304f312b12157f6632e9c4065edc628452c286cab0ee2bdf2453aabcb0a28f55810b8fd9e81872072e0e34c65ba1152172b9c287540c37ec8c53654289795384f1428e769311e15bd67939e8d27916658747d8dec9fe7aa8b9749a2b0de53f3d7ddd4e537b6a5cd9dea5cdc2d1ce88dc7215720b818f7437966408141b033c6a250200650934dba7119aa6ee724d10274742c11570481c780be0d9525b69ec69ed8cd274990bb7d8e4196543ab0bbf22829b0999cf69ed202c12db12d854c925ee1b23de2255a8a2cf9d6c1c98e0743bc4e2e2c0e558943d45cfa5b58cbcf1687f360cb9f0f1daacb50afa1cad8df055b329f276cb8026bc9b16ce791a5e8ff2d4b438bb56cb1962dd6b2c55ab658cb166b79df622d5bac658bb56cb1962dd6b2c55ab658cbff1f7bffd9e33aceae89c23fc87847d9923e5a39dbcae19b72ce59bffe85ab56eaeed5fdf4ecbdcf1ccc412d408555658abc79c78be405fa8b6bf9c5b5fce25a7e712dbfb8965f5ccb2faee517d7f28b6bf9c5b5fce25a7e712dbfb8965f5ccb2faee517d7f28b6bf9c5b5fce25afe5fc1766ab7eeff1ce1b2dd3a609fc261f8a46cfc3dabe67ba3efc41af2bf7689d97f8d5843a03804c2bf7c0720fcdf25d690fffb979811f7ef14983b8893c81dfeff0ce5f28b57f3c5abf9e2d57cf16abe78355fbc1ae08b57f3c5abf9e2d57cf16abe78355fbc9a2f5ecd17afe68b57f3c5abf9e2d57cf16abe78355fbc9a2f5ecd17afe68b57f3c5abf9e2d57cf16abe78355fbc9a2f5ecd17afe68b57f3c5abf9bf8557f383eaf2ff06bf0650c32deddccf5f987eef9afe5de6ff57156ee13f736ffee9c5ef7c1c9444a1ff2317a07de3e2e0ff7317a07d8afe376c1ce8fe7505dad715685fc9eb5fe6919f17a429672f8b749feb30b9a79e340470018a8cb8ab4cbcc482d4c4b0b326340586bc9d47c8fbf366f5dd3df73d070c79f2143f1e0e4af8628b3b75a5cbc7f87e44f6187cd85963d8a945c15903de3945c1e80393a2629eabdefd597c53052e7605e69e3bad73c670b345e5e354aa472e7fb47d943fdb88c373ef73b9a4b008b1f3c8e53091c7b684a6a018b6f3842f86f8a4dad03d1a9177501f76f684a686a8a4aa0886f6886f8aa8d51a51488684cfdfed9b9f32da1f728b5cb32526b5f85e9d47b004fa6eb38a3c9bfb6fdd98d416949f7af8291355248f3e97f3b75c8f5ca41fb9c81760223ceeca49220912afbe47153e5c344a4b9ec149cea1ab3551a735f149aaa6ad7156a3718a25aeea8f7e28276a8f2646d43c6e9d23719b3370f5dcefeadcf7a8f73c2adf95e6c0a466df8bf3081173df4dcec07debd9d844be5945213943cf18a2369e4541db82ce407c4f6a3ee6c81b438c1867e84a50c2ffc536ea77f944beb9fed296275791e756919628fba424fb1473bde62cd351e74ffd2592c3162fc7d17307e44cbbe69e0edb70f649bdec92622c10634dc7902c10b34496e445967bba26a59836c62a34d5849ed1079e98075eb1c7ad73c527b5c52535441e3587ae532b9ffab102d7feb3fdf2a025bfcfe18a79a70add60f04f6af65dac4b5cae0b4caa8b90a0895becad973ce69d33729bebc3e73a35f75dacfed4cf31446e037e5ed6875d7fa79f4f59083974a13d422450e4872269d9356a1d50297b9c6e9b25e6c933a1a9d1f78242699bedf77fc786e8c4aa90e7deefcef1898ecf7d78cf798b3b3d0f5b0ef64d0c4af866569a3f5ca087d3f9b027ae3487ae9afbf051bc7de6f3323fcc8b5b6e7fcfd1e049246a8fcd778d262e299ccefb0f3f8d0569485a0e7ceb2be139f0dd47d07ec6b6fd6173ac13b9c4d41d4a371c29736ac7b4c1e665950f52a4c55da9ec552b459cfef4fb4d2edf79e4e3ffa3c81a4dd0725024e8b9e348eaa75f1a5b0263730473f5375d2ebe1734510921df6555daa1884baa8d5b7251686a084a6a8dce4717fc9c8313b77bf7e19bc25b17c110f09f7ef13976bf7dca43ed71dbc0be6734a2a07dd8d2ffc80dd8b7cb16a50f1f305887d71d47753892b5a0e469b1246570a463d77bfe321f652818602ca8ef583e038fda94162a92d6599596db7d57eb0313dbe236dea2cf0b144f056e3605318a10e6ced024ff3abf53fcaea3f733fd8d7e279116bff7b9248854c402d5c425588af49c3b9044d91cc5d90de91a8e649936f97cff5d2cb1d1f7c4f2b97fb70331ca3ff592db6f1bd314189ddf72f95ffaffb81c730f3c090c5de712f96088787b1685a40f5dad1779e8b336f0da16754611ba68ee9b541d21c91af1641170ce197de8fdb38fd4a4c068ff397ee27de49435468cc677f53c82fdcf18e67ffa4a0463cd7fd59696cdb9868d65bfe847b76bf2ad5bdbb41dcb8328ca61f3fca57fefffc7532a2d044725f9d34ef0373b7bc9f9ceb98127aeb1206defcf12be69e253fc1147cad98fdf62e09d9b74df33fab7ce024f6afe839f23a17bcc22ff6ea7bdc7fbc8dfff83f3977547ca6c96b34dfa417e97f1e723ae9117ac0af2638ebff1b97ff629abe596e097baf84347429d277031f8709ec770b125ee517fced3b9deb52ce189fc231777d210f0f65ffce067bceb79e249b3c807ef3af031c64fd9d01ff946d9ff77721a655ad05b3f46e0811865d9ceaf3afb11fb3fc669de7e2dfe92379df25d837fb1051cc14d2df2d03b26fa1fe3f0dc19205ae499759eeebff81ca761ef18884c6c4b3cfded5743d4197354e6a56252ec8f78faa839ef31243070f552b6e65f7207c57fe21ca98861870d3da9f111638bbb3a7f99d41a78716eb4cd1c984511b7c9e55e54f2a7f7add4d3c0c005d7087140a5a3de3283118ff66209e68ea77df894df726f8c53ffd2ff5da4c55c3ea9d2f7b4c6e0dfd8e4f3725aa54d9a84e5ca1826e7c4339acf7c930fef717ff53de52472d3fd1efbff29cea826e59b2b11d45914a48fbc117afa47ad1679ad0f5c6d12f9a615f9e697bc845d1f980d71ae8427973f8ffd47bb52bbef4945e43ae07bec5fdb7eeaef5bec36dfe593f41ff9cdfec88f7fd6f75ff542539aee049cd5909e5d73bacd3aa607fdf041c970b46f315ae3bf8effc38f84b79c0f52640dcea839c7e28ccc6049cfaa8f976e1bd9bbbe3e7ff52fbe69e56f7a757eccf5076ec03ee5c4beebb597ffec9fbff897e9627be219ef1cd3f82ef8ad66fcc416f68f786f7edbfead9bc43de6e75ffb07dfbefad7713f9fffca383f6c60376b2c38e05b7f81cb2dff59177fd4fb2f32ea7fac877fdbcf1b8bfd90c1fe83ffe6c35fe7fe1fe6f8f1de274efa8fb2ff79ae7f88f15f9eef3ef4cf735803d8017feabaee6d4e7abdfdd5e19accaa39cd707ef561c7b4e8fd233fff6edccca4aa8f4ba7e9476fda2497f25a130b1f1760e7c16f7deebbdf3757c23b8bd2925042bf3149b326fcb1cab4b888ac63da35698afc0716fcc851d2f9918ffe658c7d60ab4e2c7f637301fc562b8e3935a9bff3897ff4db7f1d7f7fb29b48b3a4c86350c4ef8328fc8d0dffebf1b1faf0b1c5b0ddffad7f7cceed3718e1f3ef22af1509aff5225d4816f86d6dcdbfd7ea5423ffadae7ecdf7c91a215223d2e8fa13dffcc95ffe82cbfe28cf1f3effd735b45983f3733df12c1f1ff8f9bbbffe26d76f8967bcf5f6595b19308f5a0711d98f3cdf7fd442db18e2d6a9129e3c5313eb02cfa0fc4edb22c10103e7e322f95e36f7ff80c5fee87ba1ebf7a24b42894041c9e7589f71f8c60f2e067eca960f4aeba0a1a781ef9cf25b9dbffd8ee6fe30878f9acc5145dc3aebb7be7bd9c496103686b8fbbbdcff1fe2f0f10fbeff1d4f9bef394bef357f15b74e917cdae19b6c6f7cf7b33e8a74fc6197370e79c7c4b7faf4d6adee7b5213759f7391e9fa432fba2b5d117c4009ef7c606d99ae73f97c94d229fe26d7fe8ff910185d7d2ebed766fc5f6df51b99fe288b609cbfcd29bfac893ff342704630f4c6a0fddb4f15fa8f3ef9bbf8fdfb7c29b1eff5d46f73ddcfb9bf710028338f3fc90be63ecc816ffc2e73461fb724f26dcfe9f7f1fecfbae4e24e7ae3f7fa8f3afdadbd9aef58d4468cc287173b6eb9eaedffbf69fb03c3065e3124747efc09e37eb33d45fed39e47d2924340ff22db875d1dfe9d33ded84ae634f0add3e0a4a0b83dbeafb7e66f79210ff837ce6cd66f5fee30bcd77c6f7dc527f5879a97fe09a38974f1537ed801031783655ad29c1af33cc8b10c477aea36c489659d8b1698479d3347f4a3954aea1fdea3281bd23c0b92d83fbef75b8cf763edf85e9bc72d5644ee079efdb772fdc69fb5def7a4c833dfb85abb12983c8337eef8e91fefb86ea2ceefc51a72ad2679e744cb8692975deba56c6260047ef441c59d54a4bfb73b957846ffce8da1fbae4be4f9f1e51d3ff79cfacfbcfdb127fdce1fc3db972344ecffbe56510febe77af46f30d4bb861bef755013d0ef75feb7f9fd699cd0255791ff9677110d8910a9d63ff6ca9d35e19bea9b9ffc832c9f4fdc3a60e249abc8634d72fef378f27b5ded49abef428d42ffaafbbfc5b67fadf502f8e71cf06b2c7dac8b13d82963b80103f38d253fe4fa91abbeaf57fe148366e072f547eeb0252ce11de6fb3ea72848a57ffda1ede9b71f389af9b9178aad8197fcf85d1692c6efb421e1edf58da7a2e61d9b4e11999febcc5ffafac897d6b79af20367f1c1169f3f64ff6d1b99379a187963cb6fbafd63bf6d847ce2641d2e8aa8c59a88ce07a5334edfc5aea0754ea393b6c82cde739945e6318becb1456dbc5a36e77b5040599cc3fdaecfdf63b40f9dfcf5330194e90e94ff9ffe02951f47496db8a5ddffefdb6fffab0affc325107f6dfefdf819037108fc3f79fe4cfccf9d3f7f93fdef0ea041f4eb04faeb04faeb04fa1fd3c6cf73679b9d198ad21fef74f6783c1ea2fef8f33fe9fdc3b21d5b3721c9aafdedb153bab9c7e2e7c7e28f86ffa22ffbcf7d5936f734ed80b3217db5ecd0a94056deab876e642985d0ac67cab96344e33595bd98cfee52f0a6ac93736df12f0e2617d791f329215ec08e6c448e04be6e640d1f160c7ec987fd683ac398c350e538c14ff4a6c8a39335a714614eabead95eba75ccc91932eeb511bbb56585e8cb559a38c2a247b4958a42162cecddf827bf8a131d77bae84f1a430c5ee4d6e7314b0b3d8dfca29d5afbd4d974677138561b16ed21cc9481141696647504496a6e5dfc84000636b40fbd99772151c3fcad8ae9a1ff2bbdbdfeacb76f6704ff1d5b047fd767e8126bc27393ef4983b2abefbe04faf31dfac7db1ca53c76dd7e7c94c8f727ec5f1d677f3c1e2cc4392cbb9836c6ff38cf819b4de9fee17ceebf31a6a6ff17c744a82d32ff78f62683f322cfb87ae12a04322f47bd69b242f49b9251ea1c232a742ed2c5a2f3b91ab2424f92c52eaa92b3325686ee90464353c40d579835d7b1d45b766a2fd4857d70cfb7e999faf178bc6da7b2dce3f186136ff18bbf4ce8ed200feae37cf3bf616be5fd2342a44e81bf9f9912cca74cf9678bfc7bd37f2113c5fe90e907afe2bb9eff1bb6e3df72f31ffc8ce21b37e5874ffe3c6ffa9772ebbf919b51ff5eee5fcedff496dc12e18d69b9dd72b9e18d6f3fce7f3c71fd3cdf7f3acedcc02c18db9beff2dc2807d423aa7d5a2b77491412ef213efcd5df7d36178ba5ca41de6768788814d758076fad27f692300af356a76e1d17f6cd175e50cff342815ac164229c9cd90c82cb9aac7eec0627496ef874bb4fe0400200e0db3bdb113dff88769c6a14b8b81b31e1ad4ee4367839bc2206327b2f824b4f61fb7bbefbc6da321abdec2ec265794096d768e2830bce20877bc35aa731a70374ec1b4359a9ac6711fb7953d3e591034c7103c7479e9fb88afad2709b9bee156f63d799c35ed49370a66de32e3b8891fd71b32d3da64ae4da504956753d865d1be5064089581d11e18bf1d8ca51fcb0f12c4e7ed15e4543647a6d4f59a52fcb36a80256d22340c0961123529e863d57e54c230eda186f212751a415c541ba6acb28430ce5c73e33f56dbd6f0bd419ed26ebb83547267dc912a21f2301eb7e41f2532f2705d952b6c0f2eaf9e826a83343a2c0914d3390c1d18a97b854f4368460228ed5fa649713be4267e597d93e7a9aa140c5a3d6b3be71beea8b9ba878ea393f45d96b6fbedfe7304ab6e01a35322755c9361090b5ce90c6c601d549fac9f39ca889f78e8d7bd714bb4065f1621145cf5d0c78868b6b0b99d2088e0296da0d2e64201a8dddbdc9a30ba966d0181cbda6e2a4beb895b7e5ad3c425af08405dd4b4a5240d3902ab5bed1ca3a3812540f84eb8c44a7240f625eb9e0a84f43e3e791d5cdaca5cb7e450db1eed9a054ceee416c4d1bb7981cd02bd7d8633edd60cb903b75a8ca79f466ce614bb9215de539db83b3870968bb6787fb3c1feb604085373890c95b53f6adaab67b8e8947e02cb6ddca1c6a9fc2fe42714725ecbdb0b090c578a4523a1dcb5bd3edb19db464f18e71f1940f86472b7d785b12a647fbd9ca8665cd2dc65d4576056144ae7df12e2ff57328105698ee0d2ab8802d591565246c193b57af0bd46adfc2884e0662ab0daf850241e41f49aadb58516bd1e470c643830a3dd6e279c52c0c3eaf0b183838552cf5b4e1162def5179d37d25c4e5a990c596f1a1a0878ae181df138cafbd5df0ecf872c91d908dcc5719c8c117d8a6a0e4562c8de86d991bba2c0a0ae36b82f43001ba5bb214d7037ed61ca2f417c9364ae1184ec4b3142ef10c9b884e2587292faf4dd8c46ba89451d800458c8176095cac766fd6e7083db5bdde6e42bd2b48ddd7a87363d09bf3a2a870e751ec8e972272a826ef24b60c9bc71d7b3a5ee3ede6eb9c19f6f02c97b3d368ba4055ec2e59ada0cdb14bae754bc9ed2b5d140a8d138655c70e69421ee3111e69e7a3d1e0ea1b0b31c1e9e8b571bf8095a49366946ed3ed21657517b54ab095e1a23d291c824115bb53d6c542b8626e4b4bb7de99623b84e92b1b8cf0d4dd0c07619f08389751931467d3900fe19669464562d7adec41702c1ae8e1f34ec1dd2d095a684d45eed488cffef3167620b558eb20195ca5dd91504740a0ca0299174236a9733480a99ecbe6b6bb5139b41178df7459fc405e904081418e909a7e6ee8d418c031a615304c4f6a830ce83ea2d9d18b8c7873d457a385c666dc51604f85d97e5abcdcfa847de9fadb419f509361341ee03dc8f720c7530de06a6055693001245527f56c3c6812a3e76b5910c27094129e7aeb848876b8a10e7737b67e2fda279a1b2fb13f88265d17356c417565cd0d2a1bd4e09d4de8d435d56345a6944154fb7d7cc6d540d7335add1b94b29e2c2407eca077d3e9cf6ee31d60136629bab5cb5c03a2833fb3bbb1d5da084acceccf0e7c8ad51ca6c214e2c7865309d7f77c52e79d7c0a42db155b72d35ba687c0f8062daf0600da6cc3f0dcb7a2d334552a048a99730072f6b09522724765cfba062b1dd53113380cde13fac3d99921f186a139cc6a89b67db2d7176acdde3d5b8087f3aec19509bf2e5ecfedc7837fc8ffae068bffaa061bbcd3fa9e3327eccfbdf9c0136bd5fcf685c19863453661e906756b163fedc4cc0efb0da5ea895b5afac54f6401ca1177c83aa7174e79e3693769bb9727a4d166c26c76b7334e7e4a2fe29105c1493aa2f6109be38c71edbaaeeb15f0118cddc9edb55336a15914af3e4db0813306297109d86faf83315fa441a814134ee842bef243f30c44b65ffc137cb5727e1a0c9eab00aaa0f631124fcb26451637313be88bc01ba88623da6b8e38d3897b1ca9f307fe92512a5e6ba88a83ba721d3651f3273f16e722ae769183fd9309f753ca7347d5747180fa8c7c8542462890aef27a38ce08138528931e2857e301586c6243be5447eee05626f6b6ba4bcc60cddd5ab0fd695199cc44b7651d08501c19417dcd19c454ab6aef7072a408d201cbe4c28b832dd3d4a255343ff18aaed19ba99f773c7bf6a37a1756b400369be5d6c069ccfbd3957c99319ea8b83f03216d52c607aba906cc61739c76e9fcfbb6a2a570326b0438fe54080556e481a98e9b8b4eeda4996613c84fdcf578c39805b557eb331371289a71ed70e1b1876f92e3d3a9fe245ff95cc3151de25232e6a5d9ce3208a90905bb3c387b1dc60bc1346ba04b7464cf6c36ba99f1a62526dd80ca98c5e55eec8b8d2a2b05ae1d6e878606865b8ef0b2853148a5a2303af8ee0b53b1628b877725b50c967759379ca80c5746b4d249a28e56a62d9f2cd7a527800b498dc06ebbc162ab825b4b1f688c028260c3fa66615463c0bad4f08a2d0e41792fb3fd6e0d916a44d5fd556b1f3899f166fd2e9aef70c174f5cf3899fa1d4eb6f77f83934936708322710ff08fdc53e3dbb902f4075e852d485b2a347fddd36fb5d9f7b46b0a8c243a248a13a3ec811bca42e6a5dc9480bb6d8d528e933734b9f528b552efc2a31ca57b62db46535e97c4047d5cbed4b146964560851bfd5267f4214f768ddb36025bf515137702c36a6c06b60bc2e3ec41e155e9ab2c1a38f6e453901bbeb47c477194567a998c96b8706642bfcddcad5e60233502165ea12e16e6344c04d3d55c3426b4097ae5e0f05af04ef77d6d188db3a65fed0b171f5cbe6e792112fbeddceddec39ea630dcba801ecf3240ead888a9eae94be6e5ea339791d7847b0ad4dc0eb6c3f8f1dc43f16edfd9a43a136b2d10be78226111ca1e6dcfcbd425bef04a9bb0c651bdacc510c3b21bbe6e779b6b282c964e3861078fe7668d71d7661bddbe4054275ea751c84516109926112cc5a4594fe4219c635b25e945a0a7fce43959b13170fee0c216413671a0c5a805d81b4899ab0a3fac6898072713ad3311bb72e568cc9d532cc74d0b03a58ca22a5f5b83c8d11ad51982bcb090eee62d0ec70df765b589de525bc2c13d0f452164d73df87ea262bc1b880304768e1322ee2272478aa36b523436dabac7d9550ce744b2d1a2cdec00030b5044cb332fa1352e69ecdea14cb09ebeedd2f368506d59276276f14921d76ed1e2b97a0bb4f6a8395ed82498d2dd9929528fe12fa8c9d06abd70ef89fa0ea222f1943ee3349ef0022f909503e23eb6e2de353ccd9739223979c26f8ff242065cad8bf5c6f8d9ac4b49890756acb7ca4dbd1dcbc77af93c968cceeb7738edd45fd6cbecefd6cbfb5fd7cbdff70c7ee1a782dfcfba8c3ff005bfc74ce3e4824f6d0e9fdd5325eb9e68453f3ba630f4be16e98cd7a76034586979a0844ee537903dbd70a4d8ea452cf5ad16bc3651948a99c6bcf02353cf93a6e1a4d068b6b02e82bac699105c288d24311cc7919ec4b0da8d7c87ce3b63cb782043700020f1d70060f88d631f512a727cd9b36d71201a3f3c5bb53ee46b58ad661aee923159f5e1479d2968aed4da24fa0cce3189e7a338492f67ef2579493bd89ff5f532a644f3cca0c974d079b471dceeeb91aab4162dd54adc9524f6aa1b9e662f92427a9fe9b9aab8add8eb99f251c85f86e586b309571bf398138859af1836bc48b801290cd95224efce531408bb8b4c92df3bc44d9feeae505dd724e8804d0318e32b57d05a5b62bc87b2e37c87413c40aa99e18bd1e99a1105997c42976a639c9c765cfe9e73e5cccac51c52f7b99835e54184a5d16334c5420f0be54b2d37d4e6f21b49baa0b2828324c4b34990aab4d93c7e520c0f647db36b8d7c328dd8358dd864d52bbd9d2014c489802b71d6a9fd101f60dd06232818cbd324e6dbb41fcf53d5ef5e07a3e9a6cf3e7bf0af275126be3426d8e3e84406160b9ed141e551acd9d555efc54fab31aadd6381101295d91e3ebaf83bc363f11abab9711710781d9157795ee21c22aabf1118c498f4285e1cb13b25130314de66547bb02f9431e33ee5c0dc1b1a2b99ce3e5f7a463a254b97a9ea693b06c3ac944bcca21930821b1b88023399b7c10c61e27e8744e9b4808b4a2c7882bad50d08b8642d50f7e009abf6c1237850c4ddc8aac2135f430cc8543ee98487e5d264627a560ab647cc14dc57dbd2c8aef88040a15e42f6e01d7edfefd4bad52887c4342c769716ec9d2f99a946d21a8d152894b3380a3b36b99ecec0807cba70820216766ba28934b6d2d6477c91890de1a20c77d62b8ac52f18c678a961629db9c1b5873fabf50e067833a8a79bb7f18b9906b798a5912b0a81d9a1889fc927c7c94ba0f0f5a62ce11e11777aaf58a6b951e623023a4635ee6661a91110eb684996fb4c1ef7f97c565cb96ad13edd41a87eb92115f8d8c45392ef98e39430f18325d4b39a8c9b1b6b25b6a7bb70d7ce043da0a0bb238dc8976bbe0f4c106f8e04de843e056b947acdf8d8baa1eba0e1ecc1160d4027473e6121a7274a85c8a7d1b9116f95f7d5f2a1868d9e76eb18eace3cf5c3b426eebe78ea309f2f7b763b1eae30badc379953a1843a7299b61c1a9615f1e1a1773bf41a39acf7b9e6bd3c681a968e2fa9f502aea99ff1d858d73dce9fdb4e6f0305cbcb134240febe6c7452c85a3511b540a28fb445db21b1c29dde8ec80ea7965f05e6a5a5c365d8fec6a19e8d9ef2300f601ce786d794a54112dd48e8f10bd2142c7e3e6082b5623d829e2b6eb0a63b3f6fd78aad693a68a9b8f21a413608283b4cb43b1ac4ae0771f42f82009375455d9d391119e4a3e18954d62d882bd96d0462524941023700c24c8e73a633e09f8373a0e3a28b9e06184e23d8d5ea5a29243f387ce54eabd357725ddd00acd5d18f8bc53b53cd7233c127469645f2ab8afb1959b13a70fd8ba1923e156e03192d72d8030f6a47e20ad4d45eb7fb3b141cae128b136c17242cdc0df22ef14e2d0895a9d758b948ad55322f1fddac50d98f3e75bb821a6795af56aa70d3e77a4ae370c9f28e1da420f8109e58fb186b6e1a45fc0d9ff06bcfd540c8cf0c216fc0f37e988ab2ef07a13c87a7cb5f9ee55b6d3a4b1221a0ae6590aef0a263d2d9acc7abf0e686555f8ca2d0eb2b301d49460ac4ec944b2e2c3e98a117b62f673f4f4f865c515a9547e7d9b66474a84e508ebe50c125e9d26d853e5f5a35876ee25a0b1755633a280db6e91afa186e36958e79a5ca1de31dfcab0855d19eb2840dbce7d8a41608e4f11ea6fb9a60661b286dceada9e3bf4a5179307357967b7893f8679982d8adbeecd2751487e4f7027dc91059d98c47c4c8aae68fa8be054415f62e448d10ad6059be6560462d8f16379a5ed8d06ec3da51685fbe8b84703e34d81d0b48fb45af541f18943905884ce90241338041f02fba5ff7e37101dcb5e7201fc3745f6cb70adece71dd50ca801e64263d93d11eb64bd943606f197249cb1b5ff710a917cb7a939243be459b6b8ac3b34a7dccd6988d5e126f74908986250810b9745ecc7a3b1e3e93c53cc16784136b1956de6f6abf6bc00302a4539949d9b89ef646359534cc7752954a280137ee25ade40320eeee0c9b21b06c8f0c60b2ecb9e3c3052bca086e1829919d3529f42c9d18c84c79c6d9778c4e84164f7c6f6cb50b2ae6243f68a7c11355b8855acd324883c1d7861502dd69310b872f9b808f5c692c68e5c2d554965cf7ac0bc10765582ec3506fec001f0b5e54431e10d270ec4b3717aac57476c074da02cfed1dd5673e8566a66f94fe6220e3caf0a5b5d610a804af0dc4254726dd8921c82fd757eeda746a60410c1661e69eaafa7c5dac545650265909cc214e9f7b0ff3e55dcbd52443b39e4360cbe0d8970556a72d6a9f3b7ce84368cbe5500f661cf88a60b2f2c296acd862a67b86b0613c2191971fae308bbb48b6c5ab345e58c06f3e505f503012e869505310c14615038417cbca65e2763b59e36bb3a5b545e4d84fa039c059b9267cace5859569218266aa7c1d1e49c2e923632ef5ed759520081e710b9addfd5e32f4f4349b75597dc4b2626cc837f8c5cf70208b91baf23c13d44fd221abd379dcb1cb603a1a7ff60ac90b42169354d438414dc7fc81d8c6d3bdc30a22480f362746301f056e72bdcb055eda32bc24f29639d61880b1312f62a4a2767082c408dc6ea5a399e3529b4f129af13b4e0ff5592519091cfe53ba9e8d0c742fe6205d1d7d3d63cbcde2c321e811e163d3b91ea010ec9d1a370f90d870399a08fb04721f9bc1c63a53401e8aced62c1b285f637b8a9a7f24cd08745b2ac6767d6980333ea5ad79c89975044b20d8211f9ccf7438a8c47e84871e4db138dcdd10b3fdde0ecd987500612e9dc262f1c61a1fc4cadce1e4b837822db06c2dba91feec57380d6aa85c93b6ed54f7bed02b465558bcdb189749806a18285304e89493ab531d2fbac50c04e91b14ac87fed4a81e0fdd3a629d11793c9f29dad7117f13c59747e3a1b10e5a25c059d458a6826116571be73deaa38d55080f9ba8c982b42b788447aa0b50cd020b71940d0177229519244326f7eac6838f603412b24f37ee814dde6d885f9c4554672aa309d7c115a2dd523d94897bbec192783dac46bac7bb5d6423dd0b2b897810759d574c1748d0c04aaa2b56ef82821c305b71aed12bde60a8c267edbe3a30f144444dcc5c8a2313afc56a8af49926d51c9cc496c5e0f163e446d288e1e5ea69b776eef7fe5af97bcddc6a0ca12abfd1a0c3805ed9cd4f271e44f296a8fcb8003861123b425d143b2d96d4dac9813960868399b203b73e0030e000255b95f0a73f1f0374ebbbfc11de4a2dc90c564440c3f0c51d16976bf6817df57592bc7b202660e6d697004e13474119c00c1d8066073b634701255e85d12a84d49c4f17ef7066340e89cc36341b488f0158524f31a078c49c0f4c8eefc7ca1c5531c3a605ba1dadea2d18a7496d2bc4b9179f72179f7740ae0ab08c04a09348f04e942450c50f663b1a48edce02da82d9d49e23d058536c5e17082a114270abd6009a9d2d86362a84879f2f8f5edabaa92de095bb640b59a97af161db667b1edd5d096d6fa8988a799e9cad5273e9461baeb5bbb48783b4848994083c514ad314eb853a8f7b76a5ac52bd4042636fa53cd20fb9d5fb4b7e8ef56ea5dc4b03f961f31d76f4b4a7c3710e7cae69695e597e5a2192dfad803052c728bcddc770cd30d42672fa93b1ac86d0fc6423eb904608a028083e73ae3b1dddbcfdc43191509213e8e60c433b19a580cae32f64d1abd5b945fb8004c04965678caba79dd431c0c64fe054a8eec005fc05e1e2cc7769243d4b4dae32132e0541c858870f46ea756b8ab678d93e9798ca2cb681516908d864572b241c4b80027be78fc5b9b1b9dbb1c9523c48ee600d350b471f2f2988894fa3254dab6f8d7af49dce93f4a7cf2012872e8f5544e306e69458d40f521d26abe02081a9452271d0dc30ce5ba9f5ce7d7102b9128350ea05314df18596a3d58d6f1dac0dfe692799a297d1782b25610ea26106435eb3c4e95e743ebc85b1abc16675bbc8cbea8eed357b4d0047bcaf45ae4aae41ec128cc1d1c9756f23db8360d0f08fc894238cb69c108467969f6542074dc8aaa1acbf527b620eac4f7d4d8b25102bbc145ed86343efe16cf1403390a42b195b074168d3de4278644fe41c49570a65787dcc1643663c3b5d6d4a881941d88633d2630ab252f8923901edbb702ca2dbcc315c007ad1c67853a3edb89c0109f40457240f90f9aa621d40362955d21dd9facd7429de5c7cac4ecc4eae69ff4695b3dd044e1f53b3d3044b1e9268793e33d95ad8664689e1e5398bf0b40d1bebcafaee28925b2acf4668e5e9c926497f78bdfec25e142bc725c100df78088ce69baff8b13f1ebcefffab7d7bbafe97fbf6bfee357edbab07dde7aee3944ed13c70e7ed7aa0d0c723f6942a7a6ea66c98b4c9dee0be5be42e091a6f828d9dc8c5d8745143922a0d005aa2056e1ab6ee4fbf7fc2a55e147d7c3cce26e68dc3eeda89358a401a4fd6d19291b5945a049582a4b5c0c4387171a8e9e51fd4d116ac871a7a7743b3d72aab389728c0f92a27d337f60eef0f846a2190b1264d1cf1a7228d020200c9a5289ec11dda9eda5e0fd04fd5c487a7c81906b734ac96984b324227ce5f3eb91ea99ecedcc79eae681ce4217fec21a1fb5fb80fbfddd3951fff6a4f578a3a0df4dd63fe858b90b842930b4f07022e68189c763986548dc48d511e11560b4ecec3a65e656cc1db7aed3aa57b6843ae92e113535dfc49cc69d39a6bce8326fd644533e6f998d99e0fddb26645347caea743e7156acf86832b630983295522645b150249e1c2ab8b17234003a992008e6cd00d47900b096e2450840fce53545d6cf2fa9d3926a984e647ba9e4d8947cfca8ab5433ec20b059105b42d93eeb3657df02fffe52f50759f64f7e00a6c847105e7843a97c3668ab416e8f1a48447dc25037273c91e266172449227322213b3b835e71cbb415a979896f97d61e3cbc7e8ea152aca8b1e93593927542ee38567fb9adda50da4da675180932c57cb53d6c6c9a9cbe71d8b7d28382f3460f71e9f8749a60737be4110249ee1ab09c197610b72d2bfb64ea07b3d99c2b8016ce925ad71ff8418391cd44b35623dedccc0031d96332342e64c07d0b456ca8b56b38d721992312ed6278e6b62ae41dda5e545b6ce295b66f34990a70516eb5a9a2abc1accd12cc48eb091b90c0b296ff9b8005587906d76532f97ea65ca45ea92edd63608a40e2d06b8b9647e9f563c341ed6daa67bcd64b3109759d526f8e14bcc03bfe1d33d81a1e54ee2e68a7b4c01ae3bcc528b9de160458766325b2c5b1e0d2d46f3402189049544c24fb2226df7b38fef10b5f8de7c1988f5327236a4587b040d5791ec24abe01d8acd018ac1b14ca2e794c02d964b0e08dc328677e84a65e90d3fc123ae5aff84c764585b67afdb7b404a64ba1c2eaa8f1a29852ad1590de92db4038e26eb608d5fdcb7e1f1726ecdab4b63ce7f9ecf113bfa59cb3bc7ca87010bd59c98f8618e9ac321e589ca12777f1ec68250377934c6c852ccb2f25d2f61449a7ac6739784b0d45c05652f786ace9536d0600ee0b4f99a838363e2d28ee6509301055bd1acb8ad3a9a52d65eaf2ffe754bac82d1912836e4f47e194f99a9fa5ba40a10354d438dde9cc50ce1becf9a43b2cc45bc09c998819aa33601c4c2545a92de2cd01eef59afeed6c55b66a94e40400ce127a77423ed3b40ad2d6f462ce6ef4aed8faf7b74a5878e6b47529687681d736506e7de599754a878e2696d34a988596cc8ad7b5c49b1eead4075d4658c8448e538916ef8f4aa32b45674d4bd0d3c0817f9b9cb328e0ecca1e22c2f96aab8473ac0711c218b83c10814008bad9877f496e2c26cd99e13af165c02b62cf965b03a9e7f9d321e95d58b6c580c61cbd06c979e4ff071a6a9f9e987e1acba1157e33dd90f8edc28051a46427d4f07f7ee12571ccdd3132e0557e75284ed12ba79f6ec00f02f3d5aa579bd423a0a29fdbe2b83ef06707828452715e01597c46d37da3ac193aaa59f816a775390e4889a99d1ea40a46d85e3032a68cacae8471903959e89528c021bcc5e440d34b5d0d523a219d458b94eca550759b06d08f0cfa83a46b4df50b668f9ba0aac1316902e4ac19a7570b242829718315471efa246432ce3a2d8fb458e0c6c768f1d805de542e76d7e86c8987a0ea45256e7a269336e1806cffac5b7f9023c609c0551b489748822bd16037762c2efd3c99a9a33cea30142c491824e7a3f58eeeedc09c76e03fe66f75461010d4674d984d62896a5d1d1a3a54b5cda21c931c75e627f05a5d4520d6a74cc52ec64606b542bc30f87241a8f9af2aba41e1b8d71a4d94255c95c03bc1724546f28256123a8373cc01988c61fe7c9a2c86d19389feae901811f3dbf599148060fb5ba46ef128a968d9640234ec2984c4b6b28e9b81f776d9e865b7d3c89fbb920a0e5c0956a61032aa4da3c7526bc4c1d1c867263759b7570332a39a53e4bda2202c1431eeba44fd6a701ca5221a206781a47b74f28673c81b2cb7aa036faed06c284e76f48e1c5291d0a4106db3d33c7d9cdb4527f4355e721d6bedc56683b580a4943de5415f23d38227b19c56b2e776c5b5ced192cf378cfcf98517ccb1e4fbaaa1f596166cc70679a9a50915b34ab04f1c06362cc1b6c7b44e6549b6050a68e58b522ab1565d4e773369f2e43850f07ca20fcb8317d78a2f00ed475071581e281f193b3e0a20f4bc7521d295beb4d97e3e1d81122765130f16bf878bedc9153ee04add9b21311a35f033b1adbfd51f603b9139e1254e19661a5df02b678f60ced8431d296b7acf5a40d953310b22697dac1e1f4e4e3c683d6ab4f4a8142b00e4d61c762ed09548135467ddd03c0a28b17a3f72bdfbfd1997b3e4c059ff2cba763137604ba4488027f5c7369159402dc35b549b26cea46b2205aa0518de80a9558529d24148b5b3533a901141bee1e804fd2848f0f29d9083786b05e8436cc6b408ae9dd8d5dd60910c7478fa761d71a6a62fb1524aa5d1de1a0ba27570f6bb27299cc2760fa24baf15cdcfbeb0a0c5c404b5bdc3296069cb36bee3e3ceca088477b08c364ad31997298d816853dced97539454e695e5334fac37cea6d7c046e033d76bebdf942dfc3f283e22c3942860746be0433b4bb9eb9b87a2ae46427cd405447d1b14c2fb56d6c493a0e1ccdd111c17122f51d565c092ef30cb3767a1af6cd7dad47ac843e6e0c4e28b303870fd533b0d5fbe6e8858b9ca7296387442b3130f68ab39d51ecda6e059731647722ac6b44f230873486c21bcfe22fbf2f62c3526da534d8d47cd6422295b1c34ce32201acf2985bcc5b072df428816cd9c9ca032d2fbcc44f16197e1e7936c1a35c845d4a8109e9c73c106acfb302d411bf95b1d8834a7b0c6e542a21068a27098110b6c6f4e3762eec39de63f31af242f6a72d70c2b40d5d7c94baf3d4885b22f524e694c093bec6f6ba2e929528911a609b9b65900d79c38fc307bbee8419091b74330fdcdf6fdefa744873f72592eff5e3d88e49311a16ba5377dc062d6f05d54d02f561a8e15985831347e070b756c1d656270cc378d92c04c3cf995b91fe6aea5b00967c824905f81c8e62294bdebf2977b7ce49cbdf90b3f097fbe310e5289baca41e5fde585579b4b011285ac83a0d36de58a3a268eeb89152672a578a0af552d7bc1d72bc5432b7a380994a575bcb62f3aa7319cf33659dd7c491c76919a1ad192d2da77131ed95f463d30b89ececcf96629c273512f4336775c71f5a700a7ab995ba16091b86edc49a81b8ee318b96d27012a9c99d7d45fb14a4510e4ad845cfb648c074b14174b2f2c05a69062fb7c87348795ac217e7364679c3a9c2d88cd6a32c8ccbb51e645d6ccc186f784d6ab069ae81c4509d4406dccc9e5b4cc6edee329874baa09c28e96402d249af5d4c96d4399c0d72863106ea3b3a276c39f0702cd4deeb602f3245898122756dbe8a29b986e3795b04e8b80996d2781b0a3b8caf27576298098ec3140f695dd674343530eb4520357166f7399b05eed9a206a03900645bc0568b5ec7d66282a158f14ca1e74d146fe6e5d17173acb2a70c958fac78d2cfdbe93e7980130b8a8d15a602d7026e1f7d15bd88f93c930a3a4cd14eece294b99c13737d1936717910f7089112ad5f8e055697f6a863a3500c28abb0a7cc9055609b38700b49c335a8077cd70cbf667cb4a67b9fb8dbb1f1f062fb315059e1e5976c134497db7b4b8c9afc6ab8c3bb9b890c6cc9199d414b7831dced720d7acfeb3efbfb00e3587895ddb4a1d0c56cabd0e0b9b0bdf605e3012bac1e8375def3527c6437dfbf6607cb95c554537975b88704ddb2eab161d929c4e9ab81fb473d7b36c38fa275ebd7356795151bd30730f1a4e427b9e155a33aa822eae4be6fb98ccb438ebd84e1b9b8f32dd398f0e97bcf0e6f9c64c760fe52662b64081e074470ada408c60ba703832ce8b7ed418029b0e0bec74588125f55d8244a6a43183fb36e8f5b817b03b17cee431185a26aa5f938ddb5bb3618c6348a01e28858acbf16c8b21dd93c369270123b3564450406fcdea2a5b5f65b3c91af8acaeadbe5c00eb98c6e398d41c948e444380e5edde9715d7731582cd45ac56277d9184a6c2f7d807b75e78ba3da25697d45b0b698777dc0ea5a1ae54543e5965c3d1b69f8772810bd47b1c933236ecdf31e80461faef776236cdb5698a3bba3c58cbd32c5e4d0ab6a517e443114b18dbe9f5202cb1d22ddc972588b21bbdb6d2c731c776c346f4f80f6ecf2bb09e08b99ea1c24dfd07b1863c4f958b115682c556b2f951b81a0949de6944292a699f1e29466e7f8db8c022326d0c5723cafa8501a91c8193f3ee050ad33195fa910a89088e0b5e4b856a01e349c8ba334da6f13145777f82c27d07c6cde9496ce2b2d2dfe35341493892fbd127d322f3c82d3e262c7310b89f16734e5c411070db87a78736748b27046fcf17aed613640185cb3ec79bf64cc4364e51e434b6ded3c5266b768f18a8d8e3cc92e242b2b16e041e20bb16659b1641211644106a28f2c261d05300116cfb884aa3282df6eebfa9a65e1c640217a7fb534c00a19974accbd64cdac0d36e376a6f504b63b060024bd6c16799e80e64c93a943285019287b004a6985dea5f8e1556f17212d920940cee1c2eb8e159b369ee34ccaf8e2f30279e3250f62ccec000f051400435cc2f48e6b9df5bab759a9427403ddf476196788156c3faf20587c292b7717e6e73a3da7ac856ec994e2d044413389de0bb87931b6c24d4896292a1c08c1ed141073332e5d0f52eca1dd475fb485834a81cddf5f6a0a8143e001baaa8ccdf37e6c9cd1bf0e0d7a38f208dc31e9460fb7254d75aa53ee0b891f1b9529011a5ac704c090e4da58d04eab4a5f998bd943386c722c8b4fba8d2d964621d1b0d54956831a921a7bc152cd148cd2ba9908af3a96c70b5aa39bc111e23b195a2dd2e1f6c0ed46b8690406384fb7da4abc6af95486d8159dc47386cef9feb45e2707b90a97ba17e6f04071ef96c441a91950c42d034e5cac4b6cc6d5e006a8de843b5bdfe65123d6ad98392def3b16434f14d1dc9eb85045a5c629c99598d9ea533671bc482166124c882943502de5291a5e4cdf44c9cb1392143af27a3242c7548b744b0718b8e26c78289d576954b69df9b83a4a8204b21b9de1acd78e73f2e62bca6b1ef3a43138a3b4349d48e1922bab08e794d24dea1f9833f7c1b609b9ca259d633b11eb4ead1c40e4e1dc56545e04255642097916bc6015c0d41ca45e85843c42c31ade19651d6413c924faacae8dabeee8683e8982c6775523b2de0a5fb721544f8011e14d63d4d38c5cb4924961cb9a468244e3feb8afde7aefd295d9972d809b3b8a157e00476e667b136f8cac69462f7dda83d0de84f274e8db94a55b0416d77964a02c1996ae689af04011abf463c566230c7fd4db2e49d1919a6e1a63ee5da1d515bf294eb4b5a7486ac523699e51a562c0eda6f3b7ae34ac87c8a437fc4ad1862af1ec36e4b19b9f8ef292ceadaa77a59a9993c86aac3e43dc8d78ca589ef4989d0bec6cd2ca56c5c5654c3879c5596866bf59d97e785c7463fa3b3085d575972a749583888a655a0cea833f600370d77b9e2b2b141c875beb7177db165943d39bb1b837dd74327fbd1396e264bb2b96b03b95d6bea42220b76d04feff293b6b25dcb52c493f900c3199bf98993d3133ebe927eee99aae8a99364e3b7264c9d86bc74a7d9979e95e61620c91170cf269a3a1a21d2fe19c79c6a807875e8526adc5001504987b2af9d950597d1169ace35a2f5b2db02130b4a568abd65929c9a54081517212b9a408cc999b8a1d805d2c7f44882355a00639f747f4d50a599cd038bfcc4757465dee1acd3e335df04626514606bcf8bcb35d608f6a145222508048db7615a6169bda32d662013f2993580da8dff67de2282d18b413bb5b06e4f0dac73b58205ce3ac31d2c3885b14f3479735c326bcab9cbb7fbf96a1fe4a9755feca9346eb19524cffa1c90a3e025b10fc8bad28cf52b8526f53b0974eb61f115a69377a58ca8e59371e99f8fe9452d4cef48afc438529322ea8b4c274cae63b07a47e153663a849364d29edfe406614fd4d87f54d5a0a561788b1e5cf99c67ad639bb238281ba0d888bab08f7652fec4b97ab133694a2b1ec9945e53853aaf4f6a8e5b23c8a9d1444929db921cb60722fb63c463882bb4e5eacce7afa9e56ddb28cf38d5547ebbde849474bf89554ede443e82929f10a15934e146ce81328979c0085a779d4d7f5c3a67bbbbd5b894bf71d70a0b197d06d232349b6193432f4a708f4675556bc9b26eed1cb8001f55993df1e29dd3b26966221e1ea97eb16cfe8b30e9171d52e08843ed6ab9594000be627e3b9c42d2570ee2043f53172617c2bf4d06e0ba52781f573e31a3d615dd496ab24110a784afc2a18e1da66c7ec678be39e52e47c36b80f98a7bce28849903acb16299ed8f309b86b5cfc4f05bd92a967d55eb4f5c1b134395f25314bd945e41875db609bba65bdf9c941b24860604d1058e76a55b1e957a568a319329b7e35b842ac17db218311d6bf6b55c89a1872e86a18f7e61162987be93385b069dba2298cb28593602a1bca06ad6b98b6309e313931756473fc3d7e83abeaf13d48f77206f9e4e9a4b3e049db1acc25d9b2c94d1146f5351356ff59bb365f5a88d5cad180e6f84226ad6251f8e843a6f9b4d30e85f64702ff7526647b52018bfad9bf5ff697fcb9f677fcb9f1ff64361a71389cffc9c656cc11891500229ad0e399d69b73ff896d64ec6290bd63e71afc2865ecc553e9772052e4c2c3d7ef04ec9f83612ed86db26bf00bc3f0d2eb75f0b9646149754e03236491e8f2abac942196f9cd1178e226ac31d707bc215102004053284893e84501866581f55d9b70dbddbbc630b39e7fefac1c9edc30a9bebe396c459d1a30baf2d90ff216a1bd038d3b93b336d89ad6adfb04878c0ee72567e5a5993e82168b4106f0dc9c9bd5cf158a59376e3adf6a10e58a7757f34d33b9e3132c3444125fa2a969d7523e535d74237214e5f2db3264476a921815b7d9f5af60f3797838b49cfad5fb51f9eaa2a8a998d437d62cc270c97271832a8660bb72f5ba95b8e75d124d9f0b77041d5645b78692382d09b52e39fca2034f8c0c0c45e03aa5f2da52d462cc09d8351a8c73f23c20ec5619a7789dcedab292dc8a900def5c2cea0261a75a3800e2071992e4745dce0d3afead9ab2164d848ca97a25e83803c2e17306647b899683fc7cad7e79bc75bc114d2f32ef90748164310e7d6855b1baed9e8846611a9dad05a65be0fb6fc822a3c9054d037468d0daf78adb694bf5154fae3463086199182df3bffb096fea3e38f099f3557c4615a53d9fff7eb57af69f725ba13e680c020d62894bc7ee677a6ed6e94687e9b1bd44ff117a2614bc7ff306d570001ce6bf09a114965f396c85b8fb12490dd8cfe80cb29f0500c3f5a23f801d1e3b823229edd8996dd2b6bdbab53397b47817c0e3740916f5c72bb5bc55dbc72e42fddd429af079215c1d8720dadb700483ed1ce4ebae6064d320f7302138ec4a2b73f9e78358c13b5a2808637b5fc7af0bf0f5b8238e8c4edf6015ed50a6c4815d2f4f4e644f67debbed2e9c48450cad7ac07325fb512e3e09cee076645385026d4666415c31ff2b0b7c14e32c10bcac47579191cfa9508633ac93365d86e7d0696366e868213eb1cac87d4f49d0aa551587316765e8cc20565a8f25bad099a2501ec111694fe0ea0b49d8c1cee3879ce210d9ae714be1c50e3a3bfa22e41d9c279865c18b94c0fe566f5a7a37c763667b7a6e3095e5529b55fc657899cabaae4852deb8f51bf0445797bb2bc3bda7b27b84612b74990575ab42e40a4e53b369e33850a109a172bbb5fe843c9a11f1dd87f2bc758c03a6a8de5f85e7cd5b9a8a6b8128a8943681cefef30d46730a94d81ffd26eb79877022d0317aaee7ea1ef2034bda21a1987562b0c5a0a991ca76787b3cd3bda36cf8e643f614688d3ca39812147b3320f14059b1c6e3bc24591e2f5698cec51450c7fe2e3d382f1c428a9b277fd37bde87ff31aa529c5af75a78f8846986ac8623a8cae6635d163ce02d0b0775f621f279529818d6d846b871dd72dbe3582e1aa53c5025311df73119af3982199ab6f239227b4b776af206971c2d63e662bd1c8e28ac182eb0500c3cf7b6402c9810604662c4fb6db12c5f69724423492433e36c8ed32f41bcf4f0c9d0dd54d7748cd48ed3e291079979c24811cff59e2770deb1b5546b3fbf3f07e82fb12267c024d235d0db0e823a7abdab0fc34efc9b2be2f8a5424c238ccebbd0c1ae8f68ade03a5f8a159b09ea4f1257364e1ca12d668f8a11ddc55086158d5122a1d4e4757b7584620302e98836c7b4f0201451e4370b6b5c49ce0662d06f83693436b1f0bc27cb4d6c0270f1b44f7f873fecaa0174e7624f2bdc03352f489493d0038d604e2c0f37c84eca7314ab2e8056a140001d51bf1ff030ae6c9a989f5a7bd5ec600f7dec47457cf3458bcdfc36e9f2499911b649e8d4ea64ccf87dcd816cb498be280291436bbffac3e372541a13c08c60cc3a216ad4e56e9f1fda33d916090136622618632c6cf89dd5c2af5f3a382b0e89abb09828981a58c7742dee919f3f3cd5d5edcba9b413c5f44247ef4398c5d2ba4ecbd0ba41f411136699af9b4e66958864047bb7924d1b3612a8b8e6d2b5ab24806fbfbc88725ccf2284c3223357adeced3065c3850b1f52794dc4e367383a34dda4325542609e5a42b29b83517509e09400851bf73029f418fb7261d644d6a6ec9efbaf7ef0c1ccb0c83544a220a7d6de866684bfdad1d2bc031cb055d88f1eb32f479758adb0b13451c0d6a111e8bf5fed6527a4f3d5782516a681fa2a44a4828e322cde29f888482ef705f20d42650fc09a0aa5a73b7e0ade0f9d031604499a45b217215b9f846ba57147e0a9c700c4530a2504674ec34be56e6193ab48ab7f8079f15b63bd1771df56cef144f2bce790b4460a626f1f8103bf9f30ca5844e5403d88b9a3478d70158d32345a20d1b1bf8659c57af2c7790f3d4df9d33d40bf6ddd18c24a6c5b73fa199cb4545ea695f62adc08b002395a169e5f632353f48900fa95d6977de5858f9b69065c236ec4bf271e8576ad5d6d9ebb2ab807b4c58e9a2cbbc4b36786ec3e844fbbc6cf9d96481b0ddfb536770e6d179fd2471a19dc2c424908f32c3c6e109f886523412f39ad157a788acc3c7aab106501b44177b606f8f138490ef134fbb0e5d04a734c7db3853af87bae23bca0bc78f6db605e02afcfa0d4efb344157b08bc5543bf017153d6c33cf67733e87d3877654a092ea10e48c9a37b617bda107fa4a5e00e44c845bc62befa4c84184ac35e38acb79b5ba87293bc16905f96e829872352af4e68a35536d35eb5baac0bb9527cac3349cc64b78f0fec56ab1f42a9aeb510c9cf1823648e066b99829480bc096aaa30de726bf2c7776bd60b0fe8189b9faa95bc34468dec9bf4a5858041fa43f1385a81e82fdc74de8ccb32d63dba0c8bdc822294575f34397ec54e715da7b5f11eecfe05b4a9aaee8507f5f8534ea9d6d0d2082fa5f1da96c6305d560a36bbfa6e2e151919dcb93fd5f984325506ccb30adf57e8d657e06e4b1e6c4af1912e1cc32843dbb9480ce71e30e51944461e6c42c5dd6409877a59b0e4f0352954ec62ac1258498b9f8aa9b229bab64b9bb4150f793a7000fb02c0cb052017dd6f55cbb83146e274d5e38be0782d008e43699763c98b0d0663706d5b69a93f8c090f612cdf50ff110ec11cd4069461fd95f1929e5dabe31933e7a4c8692b09185634e552732521320e8577678bea50bcde8df6bd4f4583fa0ac82c3cf42cfbd77255d13d7ab25849080711bea05c4731ce295d59e90f39de96858e6559c32918d83a8589ed81778a06c6b7b4853d019ed9a6ce90ac018cef54757bdcc5d7820768dcf697dd7030856087b63bd471caef47012112d87951557c7a192992fcd4a264d063f5637e03aaec37a938571bd4fab2576c7f8e82477dd14665cd5d4be76421c155ad577cf06b88152d02081d8d1a1953be47f57396a06c14786896c0dea95c5649cee9482b1803026049b4cf9b8022409b18f90814207ee6c0043d177bf3d7a4ecaa44752a5afbbd65aa35174330fae8fd990a2704a5b33714f303dc1a2a4dd09864a9f52731ab45609a559f563974cec7dc25b88eb606c487c13bc8ca093a76bb84fcaaee60826d7e766c1dbc3d6ebfe00d84ccde5842100eb3f2be0da02c9bb0cffa88354d2eb46082f0a1e5f7c9deb2047501f6032b4a2293928e20b023140d2fde95b86a035525ed300b314ad0dc8addf55751f30c5d8b2572b48595ce0a92591db5cf28539469f460a799f1868d6051a5de432bc0d627331cfb566fab73bc811694f85ebfa0669e27be072f0267229b1adeed1e265f90644129ae648f7ad29dc7115eda305db8a86be0b20a0b4cd0ae4127c2c1ccef2305af4ca635456592add0428784b9a1a231172107b42b8f9b3b93d50f6cdad00ca7d0d41a8beb11c5485e3d088f2396d167d9337153fde2eb536741864bd9f06b53771a7991ea3b6d729a690a5493cdf41daa323cba86313c04ceb946c96b5f10d36198fb7eebcfde95568ef630a74c1e333a631a977e419e7f0e59b278204bdd85ae0433ef3d72a1687d2f22997cd0b419a69babcc4633028490646225b2963af3cf351f76d80766cb4951e6673b2d7c292b42fb955d45b8a70e0a388414f30977d2ef9cec9189cd28a35dc76bbdc057cf6c3d276043fe00af72c6e5e6dfabf88a960d51d55e7db96bfc9990a34ceb01d5056fe58f7f958f98ef0a20edf7e334f1effcabc05ff95761a629c486c95163c842654f22b9f744ba8bc387ff93713d0e6df15f39a9ff57d732fc01b67898b7ad4c3f4e9889422d837f1fcdb0621f156664a81cdff032accc6f9a5a5753e7c75122c7b117f84986e0938d471b03e6cfc2f8dcc1072c8d6751bace4f1f93fe4b005299169206eda2e6f0bd947475f3aca2d51db5b8e657c27a77a46cea705a73c128a02518b03f9d17e189111d874152f87cd54867edee33581c526dc45fedf56ede6a765421b395a8795d0a5009ac89d898e148a6f35eadb90b84596a0e6a8a31093d8400ad186e4601fd87d070b4ba5bc91fa4e525331d33311ccede1b1769e0028c57b94fbbc6b2fb6ba860631495f633ad5067c0d2eaf1048ceee7e2cd920e2e10f154c65f7490fd7439f3c6437642a607b4a432f8fbdcf18c844f9da370529f5a10d7606dadd1ad5932cc1b1194fd8911a93ee45e6bbc4ec817f7a3ea8b6abcd407bc9f17e5379535268a77adbb47ddee89c063b41530f3bdd2f162d9ecf62dff4673252b2638f5a09a680135d9e6db789fe4e9d704c7df802c50dd29b8e55b9750d8054adad8072121f070aae9fbbe4593ed9b6dc17aca147c8b89f89262e27b45ca81ccbd36c1a7c8980685006fbd4074923176fc2ebac5a4c5ded54ea4467805bc96d954ee013392e1293c681f5acae91f0effc9f1ca338a56ce9bfffd249bfb3b16f9fe2b16f94ff7092f7c39121cf1f8fc9b47c6e11088288f7e043a85ce506362965dba346637f35de4a3715388f9998a4632ee8b26741df1d9bec461e94b65102511b315cbf8607d5668a4d71f044a549eb2c89941482807221db2e1c99b2887c311a30575245aa0f8b73d388564080080e065f548ad5858703306dbe371d1128b90797abde039ac24908e4e1e5ccf02ea13660ae0ec0458730b1a386a93bf05e1d02284151788611dcff39104ce04be85ac1c8131959c95363dfb31a286aa5c1bcea7e54ddcf9c98386afd66731cf2c69f1a8f649e6fdbcdc8bbca9905ec743e4a0f6ad2c12ebd8a8b0c7683cfb36bc202898f537b3705840582ce6c5e49088b0f969802831dc292c949409f6863b962ca79907065f9249e361ccfaee522f7fd2903dbc147f98dc34c46a094f3415d3a1c663cfc2fab000cea61b674a01b4d66bcdaad7e626d355d3601e6a7f834a2441dbcdbec67be753230b79724daf8ff87c9e71d2abd9f6722474062a3012c9e9aa471b93e576226d19c603058ab10635122ff7b5946f8434d6233b9b18f7d324005971315bb34921e43e00d999584d39ebd829f1f5e70a160697e6653f4e800ceaf0013a6c9ecfbed536974e5d70b3b52047a51808795a200bfa93dce0110c74956f2ddeededb7b16a9c9952532f27f8f03ce3d6d9fadcbab6b84e743da9ae4a07eea21169c8894a43d5feb388a8ada216ac1b166dddf181f161ebad96587e0a16e912b00519edb8660587280311579bb13a35cf94fd9d96f253c818d6f3807b3702d2a933c45544d24e64b1db201ae9bc31f478d0f01601f08d91a891d5315671475175020bb38ddd67a5fc1354152116c8f0f62b18366155eda85051f57d7eaec8e43f89b0cb03742af9eb5828755535e25b5ca01e7657c17fd6823c9cb818e1f75ae8850504aba5be1afd8c7904cbfdc8f810491c7d1b45dadcc207a35d02bb9299c5475f7c199e25085924d82a66f416a260b23ee6edbdafa55905b5ebd89c79a0d4a41789806cd404a28c94c259dec80340a6c8b7344d9645aeb8117918d58cbdc9e1aaadcb0ce6f63344944e6ed562c35c0c1e4dbaf2ead5f9e5c2cfac91db2ccfd498da2d6bb4b6f2ced398cd2af1bca9c805ffc4c264b0d412f87a843f1580bace3d29cb362c12c7af6ebf5046cedbf7f5fa5e80d58a1d85599cb5d6aac6ac5df05b2cdcf14ee5ad6f8bd0cff76e36c77fde2729e2af4142b0f7d774c309c791a2277dc28a8ffd2b641f8da5d086392cb995a0c0db07aaac7c1202170d0ad6ad71ad99ba5e107e1e43803e3f34fdfd2b7b6195723b129c3bdfe50dcf741742f59a55e33b4e5669769acfb25f951f406160ab3d6032418c490b48c48d3946525d4821f2af3d75a08f8e5ca8bd839c7ad18290b15e350fc08971198908114e638273595103a03865ccdac06abc52087b4461eba9aaf747e7f0c6d5670e87a0828b33d60c4a0bbe7a605189256836f154033c88a813b0c61806a847dceb700bb46a9e62a44ed880bdc28f491f0ba201f9c1cb55f28c0347cea9af424b02217fddd26bad6a0eec5b96164b2d3cc8e437390518946c29ebab0a2a584fd569c0cf49752f755159723425791548c248ab8c7ce20f82a8d949ed2ff72bb9523e98446d8bd6769ee1899d1bebfdcf39c7a230fdb2a65c58fbd0d25e8cb0f7c9993a66cc1566e8695497ab916a9f21d367e49d356124b2ac4e371a6f3646a92d33c8c6c070aa234c80bc7abbad2cebaadb012d3bb82520be25bd222fac40ba8b5d2960348646003fcfaa5e8bb237c2782599eea421981fbbb910ea9d4d7408e05c16c3b8d95d8694301169af929e06db3b448daa9cb631cb854cd5a208bdede78635d7fe6a38acc037b8eb082285166876ecee88a04145b710e30f7df451992af1903f7ddd1c6ac1b21f3225644fedd8f225f6cb6bb87da326d94577df25f15b5029987987732c649596eb75026b1a1ac15b76594422f0a59e9ae2ba44c9edfacff3de83707996655dfba9f9e26eb102774304fb6d6b888c3025f2d4b70431d510578e504ee1a2adb822493a5a9e6f8fb308fd0043b0ba2579abf174146d5acf3511be497c80ab41141e110676999f6d46240e7cd234c1afae274d60da870015bac4df16af674d739697a0380a5baa645b357095e22247af3fcda6fd7ec28315e5ae5cf9760fcbe595e41cfcfca2140d2c36470eac3a124953a81503b3d3fd8d55e48f17564609c514f1fc8205edddd532bec0398f707411d5626f961f4d1350c58aa4879eb491d2c8001d6cfd064af2ade8be06ea0753106d9dd5746be89b0233fc82f54963fd7c853d471ac6ab425725dd05746074f13126c84901a0190c7461718244bb5219bc784075809dfd79fac247bb48706ad793835b9519de75eb1658b454f2145d1879e1f540bd4c578b7608660a9424e2fdc8253abd83fa94ea25a44d32def7334058782d3dd31f6c68e3de08cc71714c90c940197b40e9234b8862d4c5afa9d45f2df509311a189bc245b50733878d7bd9597d605a04f81abc2813475afae3360268033d4bdbc5110c060474c02f0542042f977c2ffa2b7e9329ea1bcaf74aaea44aac7c083ac31b967e1c49c1ae39b111f8d1175580e0af5f50b6aa279a051cfacffed3a0f7367d94f4fb712557ffd5fe83fcddfef3af3e8ce03ffbb70c390ef13efb8f1c9f290892f0312251222ce697b1a72aceb61ff973f3937d478419710ae2d5375a2c6d7d6dd7b1a4d695ceea1256b3bf92d8c820b8685dd3a8eea5e70d9217efb1ae12b0d2eb2c15e5c7c75b899b62651e387a9524388016296d24c598327a19e2ed996248b619d78896d8736a6900b4ac7ee42962508d4ac2a5979c4c93c74c956aa6479cb92389031955cd173b94d0187cbfdbcfc53231319d0965cc59f4f40b62ea6035bb7962a227228569716e282d0cb7f546668235af4fb99896694889df786092b52d8e47f69cf55c735c98775a1b9b91d169092486828f799a2d9713fff539314fc3e5790705fb9fe28a55335a911e481d9fab5dc473ba379cc2101518485b95fba30517e724cb48613e618f415795a6a3b8b33f6358c6cdfe686823b5984ebaf11961817aa0815ec67ee13d3623ccf61646baa27d2ba48b246a5c0d0fff83d2aeee76edcbdf8c1b920ec66519802515c35652069d9e8219cfdd681c7521ecb61b8f9ec44d67997e6093317b76f55ba0429d77784fbca24f56825166350f681939f064984d2d77070c1f91c5152172a8136d29bf645cc2f3f265f6b9ab7c40b32c392c773d8cc8a79191d49da8d88b729a9c0e21f2a011733eec4ee4b77ed47a67091a4198f3323e1d347a8cdb67d836e6517ea711262da73c765e7d0453ce3470b33dc1a099103619f3e3de55d47e3bbf724be0288b7a5a29b58e03196277807862dae922881696cd9b208235ec9e6a2bc50d3e70ab8ff1cade73960a0e690e74c57ef36be9635160ca9dc3b97614a091027ea9864932ecdb9bb4e3d5dd980eec69605b47102f7e753a8767b224d225578fe7371e39672cb578db559a2dc8465e30696bc511bbe3ac7c0fffa98b228e9724a7b8b40bf7d7101b391298152df8a7196b71e262faf89e837c6f13e83b2f1fb5371a82240fea815c5486cfc9ea59e6185d4f26150ce919ce19421fd41b87c86d662c798429638bca34d72d6cd67d8c5eb5c17c52a0d8eb2e58a7e14fd73f18a5d40f80b8ef8d3ebfc5752d33f70db602e492d014398d4bb364d6bc95f0bb3087e71e8ff0d66fff0c3409d608b872e04caaecf03774f63b53afd6d491f9cd6829d1c71c637cb124d8eea97e31c4063f6bfcbcfb7504275c650917ed1dfd8c0e95a8edc8dbaaf3bb7eccc9fce4c0c01d4bae0586c3d72ef0eec14375b5c8e866f6178d6235ce0b3d0fba349f2275610a578240038130067e0837011a5826f09ea1a54822a733f4c231eb6ed26f47f05ce87f202ddfd306950bd676b378b86817d1544a0eab2587380b10f0ed443e883b13404e211e8f476abaab70bb58065465cda0b19b0e45594cc53b37983d62f4f701d71c0e2b139dddedbca94498488af60603f598a5a922dc4e25c465a9946f0dc06850d5d0a0572794478748a39b5d7a37e6960ae4ba0e139396338a5f1c50fc54b9073266029996b00a33788ac7dd59300bb49371e728f73110459a9a05a4d7794efac805625230d091d21feaf757815c4c66e7c902d4a77bd6857b2ea6bd9ef7ba315e1a1930470239016fa3c7e718f533a16bff7dab5e5198a3c81eab242b2e8945fe3cd399f759e261ad634dc1cb550c4be4f2b26960f5b1acc84a3df14078278ac5ddd11e923f6941150cd94a1a313d3fa0d7604395a3355319f9d04cb920af08e34bda9da65070d0ba9200874ef798abf8a692570768641037303803641b499116e470b0c9c176164a1b03650d2fe73aace4f11a65e06abf7e432c689c005602c287069ee2cf7d58de4aad9535fffb7111fbfff507fc8ff7e1f777f7e17fb33a5c86e0631a1670feaffe9dffe67612aff29f2310f4121420d985e69067d4553e0a65457257d47c150ae7d970dde5b01f45f951dbac33457cd3e93dd253710b1ea83834e4eca9c9811007aa7afed168616b5a6e597653a24405d003f99d59058238ce223fe1733a51b4d4102d126c78808230e6c5a20d832cbe114df133454f4013a6f183523241ad68d7ef58aedf25005f3d7de0f3d82202732ffa15c3580d32b4ed28888357d8d924085b191741023920c0775cf163346189132cff9b449c28c9d7eb012bc69526ce4e2c24fa8234215fc450f5db055bc1123d56aaad2483f50aeaf02a0d5b1471e5059785fb6dd7645991b79f7d019e425d429f679de73e0567d13e80c74d52d31b7df3a14fd67868eba3051ccce487d588e174152e6365de855849c936404733d08b0d9091f339f2295967dca9acc389b5fe26ea741d09d46cfe46b4bf6a1bbdfd9b409a13798162f8e840178e8affe0ac4083cf33c512d8e0947acae20d6e0607f95c29c4dc89b2437dcdaf87840990cb2b7c2304c34a80e9c644465185126b75e9d8c3605e7651e3eed4019b564172483d725ab76b801c2cf485d4f7ba92673e32048c93c12586a3a39e17fc54dcd564420ff60ebe5650bf7594d6a320973924405cce8bc87db522b7c993be91868130192014cc636638aa52dfe3d1fb1d45a787bff987c47964a3923cce00a2f01088a4e01ef71aaa5f96e7fad4c1898be1ed944ec8c77b6fae2889d9c7e6d6aa9b09767c3a218e609b19eb22373e29772e9e9afea1a51105df1c0d64b3f1d160834d132f71dded2cdfca3987b4217d45fabc6ea60305b761c434bd8b0f93857f4a275aacef29edc2c34dd725ad2d91cc05cfd477d3a2df12ae0fbaf3d4bf3cd525b68ee37adfd38476b63878f4a09f00cea6dac0737d67e4519c9395b1c5b32e39415d46945fea8327f403063a3e77535b561c2f01c3d880d7a7c9e75713ea4f8ed3f4b60d70cf2af9b0f7a0d00c1d3dfcf46970b701e4aa51d1c7e84fde816bddee5257f64a0fb0af0c7da9c4f988de14783a173a50740696b28ba193bb13b5b5260a7f9355e2f44a0d8434a27808f1c28c9d247f17b46c27192bff805ee6c15ee68fa6e7c2558defdf682fbff668fd5af10056e6a941567ccab253564636e197240bbe4932c4f1c23c721715860c6b57ccd4b74c348af8a7da15d3f61e1706bccb2ce4ed8a02acda83c7c943e3f66a5d246c6cf86b98900c5f8f3f630cebf5156d67717b65ce13ced7a94559c3d6f825b5699f8ddbf3bf0c8feacded65ddbfdb1fe8efb02543dcf85bb8eb52d602bc853fb3f4ac79304e6aeef7fbcd7f394bcfffe52c154a31e88ac8b9fead3f07111bed1efcf8f40f95fb16e13d6364c340e4957d7be785758685c67e0695849a68b4ac1a7469785bbd17ada96c3f073fa58b88b8c38967509b1ca9b01230e9d450562b913f66e474805e06943412f75d6effb0ca42d3022773baf83e12fd402303a369e76e29a30cac11d8511d8d64b2a96121dc9ed653a482225113a14bc1517fce731ca7133080202f3de49fac06cb177e63ab6c4a9a79bfd798e8cc3b6635442fd27f2506a469d1015789f1a15262206c68b0d2ad72bd8befb9fdc1113e885072e63dcd2e19326a23bb95d1eebb7006f3c61c683f2a7e3cacdc9e5944b2735582605749319d8a685de9d6a8dda08e6af8dc42761b3983aac87e2d3c199298eaaa9e9729675cc6e956d8e62e447600f1821761f572f5cc0a36df45bc0c98daa192c2f0dd1481a4d13184965516b631d950024361af8911952428d7ba0f03ff7d1ee5865ef98a99d5d98cd7119139354badd843ffd14cedc987e190f8a5e4c1f4e3a1b8bf67f787966b8201be26aca92b23ebfa267a8b884a7cc5a930d1460a278c3ec4594b821ddc1d844a9a5257cb74d2c756dc580eb5cc661c9f2c809c019e921c1a05616c6f9d75bc57dc1cad278d57ef593b68cf08fa2dfe809ac70c49bce07938ec8a7ab0d95aff40aab017a943e9752b6aa0574764c5a29100ca2124bf2e5c1ba2d750bb37831b3cd798f0839b658bf6558c93f8a44a764b318a3de2175531840d368215de0aea849314bdb33ca63707d8ce6a305e3b14429ced9b0af3ccffb62aacbc72207d537669f6588a91e6d7d1e09570864f04de62614762d44c74f3dd8e624e1f09a014ac678ceb3be2f56c58e336eac1d05331ebb7a2b372e5ced6e576957c317c51bb6c15e34e9fe6f6180afdb893d2fa6bf7d9344f97414539b3d17dc6ac956e7f5da8c08e1eac1b236eb2136c90ab841dd1c40d18b668db07f2d7a9e07ea6619b2d69011f19b6ffb87134d7a8f62769dc283c2de1f7a50f24edc5dc7ef155b52100e5a152022c5733f9772e6f68709794cba21a1254c484a15dd3e4e471a9089f496353c26998362e122a59087b21757e7618fa3a624c3c024077814c90868ddecdfba3a0c2221e6065223fd6e5a90d89b6b0a3bb9600847d647a2448592bd8fe2019f42cb473367c3f568e15c6adb177f4111dff93cef1ed833ec0bfcfc5ba96e748b928f7a7355a7dd190b99c2a69e1f6331f0ed451938e68446eedefad3db0624ff4f94de80fe0008dfb5492d80ed596e408197881784a7aacd8798f40f3d77d23c0c239d2b86c19645cf9e29f9fe964f80d71cf30481980bc7217e130acf8a058f578914b13e9ec54838d5ffa2c09b43320e3cca168f2c274f3a1d0d214487719113fc176dbd70a7372227fea9bef878c3d809b8751134f633b0f7ed453190fa5e9bac5378da9aa00053f2e4b940ebf2f2633e6253dab47dcb4c35486bb0c2f0abf1ae3f328a202de5655a24d23166c081b54bf47c345c956e0675fed72be17a813bedfe7a0c0e0c71fad09deccc9181b074adaa71484b140a252dd562e5a245c92c7f20284b184a0c0091dc874f080d89d6702ea693f32e25f185130a06e678e10fc1e277a8670911308754896ef70fc894a41983ad81cb6abe05df0d11d7ff85db176a57b3ad627f2982868130465d901ec0e161fef8e0e5c91a09520daf24b6710477224da624048068517212b8b3c846e7dc6da6a4677f6b0779891e3533e2978a764228f4b17e7edbc990c4bbedf73c9577051616c1b08892695aa45797451d211ee2c8bb05b86c9432649a422ee6f8c6b4186b38c01ded0e8c30766c2d72376d6ce17c7a9cd0815980cdbc3a2f08d5b10a1398f9b44a7647e5a41f292e05866553a8519200caa659d1aaaf10a38f490ea3463e0bae7b7be983f83f920d7984c0ad20e3a3087491d98dbfc76665997d39f6cb9f31aafecaaa6f25a238564863c7fc77bdc7543ee66093ada39a01bf2924d8515e3854b4490d000df6a8d9c339003df1d8eb3016b4d538009e6f0a1d7c38d0b7f3a674fb63200bff04f0cae5f155acf6bc6eed1127591befcb1c5ae79963d5aa29410903c88f8162595f08c05a8ebd0ad92dd760ebc33c2c5718f736bab83dded944f518be4d32ae46fa53baae8dad29c537a89ec1c46b1ae3a89f08d9972614469d466f3834f93fefc475f1e16e5abe2b85793e89c5b3135ca914de8b29bf124c0f6aa4484a05bd9c01121b69e6e3de4a313670164fa10dc614e2f2f4af29519d4316d291da5949f0e2c039d232cb62cf62532c65733f79ccc74d3b386b10c73c31b26271a10ba9111f247ca9f4e9163562a9fb0b34af4cdc0188817e3574f6660ef0ee3169e7dc54db184e9ac1a75e21d3e9d09c59bbe266b79647bbd4342f3934f509e6b2f2fad12a57da6fc4494c6f1a95c7a9647b0cb1b88c21ba4ed702b69fbba2a2665f1b91eb76742bcf95b34aca240a7ab98b6a3f360623be9e6329627be1bb2f71e005a2751fa778f27bd98ca4a11a0d12f237cd856383eed1666363bd6fb90b062c670a7733972d7d8644104da1574e0577bf60c5468bcc97ff8b5a4efcf1df7423348e6fd39850c053f057dbb66f046fc9c1a7d8d2a5a351053cf230911f36909af402f43829bafedd0abe6203c8eba1d3e15e9fc56fd47b9be4246d083023b46896d0948beed647140834e77039c0a29437abf7c685a3305b11f0e52a68511a4e82d0e85f0b0f5ccdee73e4e636f34d66fcc335e8850b024277faee9e7e1c2c98a925b546bf87193eb4efdb27ab5e1be18500fd1054933fcee9195cf8650861586fa96d4d38a0ef7a296d67e1a556d291ae8ac9a87e2b1160abf674a2b893cad66af7c28cf31ae1cfef80ce02d68a0f88a722be5d7b7006701f601dd3c586fb6c3431811295ef8b3d0bb5d62ed3162e70a1690e51b0865da65afc136ab58c82452a4154d5872e958e114f3d0ea074221e3f7c01459d15b8f311429ac970007bfca300aadf6b74cc84ff56947677f26cb8d8bfb09221143277f0e2620ca49d7292b84531f895ef160ef4f2c47594eba392a4339fe161ac60814822bdca1a454179b4be5a981c3b93360002510e0fe30261df6103adedbf5efc7dededf75dc417fc598c4c8f3b71d89ffa397cafa3b2f559789fd6587ca57484a13a30e9721f0118778ef89c399f8c6954dc9904fce7f322e010161a9edd4b48c5db3bb41011fa2db1214f15d0429f26e3e6cb4e928309bdc4acb75939b60543f7b490402baa0b0bc2bcf587b8e66a5f4da0cad0f7d2d95c1a225ab4ab24c20c7f41ba0400bc598504f445682f4f409c9d5d257e32684e8cca4fb50ac4c200e76d851774d8130ad71a32bf3cd5ff14f45b84d1c952d5e604d7c2484e5674e352450e93625c4023a060419e131b9b23f4dca05da363a4207e2e11c76fde7b5adf772fbe0e33c3bb3e26fee9a9f28f2c908862f15350ada3589528b3a1d7202a9e6f4e9534862e7366988bd4e94c04940f5e7bc543bc111386708658dd43440cdc94b9e4ab1bc4e4d1b7c6758e12a7c4ef419bcaa21eca228053b86ffa8707c3466032f74225e481f1148d098294a73b2452687d47a0732968302f09d72ec112a192bd4b23e60830c3b8a4e422e05d9153d1aab6b7c2fb2d6d84efd8d6c40ac17a08591b704805680e5f373dfeae5a71fd0c905f630ecfeb61d474f404efeb6536e08c84fdde1638ba633f5e5268f6d91a293ee20ac290ee19c31c74261088751bab0c6283b670e4df0d2c3f0862e53181207cd78320ed2245e175da57f900d9f384dd6f62e4fe834a9962f2d30d50649b15160ec9a921283f549db4d82a4d17948e969a0fa3b75d662f50d496b3edcb2fa1f73bc796c7c5a50e55b51ec3642245408a4e4e5101a3f5f4dfea6285a8f24e44c2be0e14599007ee96de24f821960a664bfa72f8d0c39c338fb691fe7a22661f3865856b032f2cea43caed25d297f71fcd8163a2f7a1fd363ac92074bb331168c3cdef6be43b7dace2f9bedce13f82aab0f4ea75530ee97dc11b49f06c745b7697ec219dee313378963f0221a2e38f91e5e38e3e51c63befdd9d64f345cd5cd552b28e1a1de524a3c5a9484ac5d75b7ed47878b440622cca42f17dc96960c953a4536549ec7e6ce8c46b0f00aeabc72e88816340030bc6069048db7c610d4155be81bac3c747e53c657998f2abf26d0c44ceac152608a04ba9b7a7be7a8e43d0eb5e02a1ca49cfa4ce1887c78886278e4471995bdb4d3cdaba6b2446a7e9131f67e799b5dff35f3ee441010d0967f3fe19fc75f7075fcdf657cfe997990d0e6a8f3c6a101f99272e562f016e230e490716521dc64a3a3a7213ed8087d16e33feffefd3f750b922d7c0e4190082933ea3e3376bb8ee7b60996355b7e2121c3b6204b292cb10fccfe8e742906d63f3d340ad09b8a320e94161a25030d1839ebca960405b80bf2e9fd1e9944357e9a34c66302e138f59153374cdff53d30015c3fe193ba574b4531d6551c70bd604afcc1104abf0a7cf20c33655d874056c37121d028dec3480c35d91c251e8113ec69fd2246f7653dbfa623b81e5987ba65b09c58382ef012a4ad60c933c650bb9d50c79951121181e128969fef98469afac8ab55f023a13c1c5021ec3094931f2c68a7d3bb8055c1fec42085b237dbb48b00eb2767a7af58c102d839ce4f4fd8700e0d07121680e3db45f6ad612441974db555423862113874ac1275c245b80e87a408ad7b58c7679b851bdef3b1f81012cd597702b959b2dbcda4b56533b25cd1b2b3d4ccb3f79d3a235d8ec656967da28de53c1ff31e03d4d3a6ee4e89e234de1d55a502dbe7e743ec61ba727eb75621441cc64df23a36ec1ec70b8b24d295be4ba9ae2769af312d8610f7a36491f74e22b573bb7f14a136791a21207c36ae5944148df48c32e18cca2cf766f2d3e18009713b9fa92846a798f36eb5e42feb573df02ff3751d8d495ce47a312c2bb33c85df929e34e8f391dec1108f722d13c844c029eaa663395576dbb01095c46cc53722f2f891ce5e3c05129bb39e76a228415a79f4b6f5d72d3dc0296b6aedd607ded33518f8fae57983eaa124af89e936b6e52a042a7d3c654a1755f65fa09f49f7c96b1c3bcde504202b99b88319a2312abaa624916b0c72540a93511c7271ca942477aadf5efec677b830b4620d55d06edee9e0f74051ac31e13d71b8b34edbe70f19bc01d5cc85af490efc212305315574c091e0dad5ddca52c1a5bc66dafd06c80a1b163a0a6ba8e0c5d9999ca4ce586cfc73e0f886f3f61a6d2c402b97df48d17f972b9947e46250983cdb22b5550d83c76896d9d53d7e27e52de288ea57c229c6dbc8110a786d6913c4687b68ff268d4801b22cc0244be0dafaab3d81145e84dea7a8234b54e57243bc8421a8aee7700d4bb050d46663e4d30f38cb0a49be2195b801e8fd699da8360b49b6247e4a41458b2e3409bdb83f3844518a1cd3ac573c2d060043c2b146a4c9fb20be8215964fc34fde95f362292262fa795658a661d2ecaf17786928dab375fd404c86e62e8f0f57a197b49d743907c1466522a4b39b8685c912ef39cc0765c1e7578e92d89f02d65b439fc682520bdecb53bba587dda71999c0b10716a87b00a732d0ec7bb1874b5fc1279aa0a5e87536f6a0831ff137bf8778f276e7d3a7de6a2b6ffd9eb69577cce104770f1c169b5f5704a2532e4e5262c55e030576be003215a7c0e90c55966f906a362918c8eec96f9354a92a66d215113d7a444e08e9ec883807131ea5f800cf9ee08646cbf964f094f8a962c612d99417f06e156cecfefe0f6f7fb144bd969c8ba20fa486989a6266564f30c5ccd2d3dff8575579871ddef72cfb549cae66ccde18233fca4c90c962e7e2859f8e03010c1e2085dffbd4bcd6cc4e577b53b546bf91581d2465fcf22ed7bffb7008682fcce0681610a896b8d764e87cf753e0e6da039e162e22ad50a447f54d766ea3e42720b695a88f23645956d2a9e398e2703849c9ae42a508bd8fe27ca9d9d08e687e03ebcdb7ba7a761fb65025bfbe239bef9b640f3b30fb716d1586eb2d212bb7a31e1172322105fa401ed22ed1ea2892e21d24760d8cc1e938e858ae50defeabb6352bfeb2d2563b0c6360c6dfdb3b49fd0f6adb7fa961b13a95113ce4932bfe247328e4ffd41351f68268df1d133c202d22b2d72acc2209335ab0caabbb98d11881e3f754c40b163e989a3912787a322410a98f625735030eba50b20ae4f160ee5c5745900048c73405c607c5c496eeb80a596b8bf7f33d7bf597ba84b8dea7fbcfd324dd2b27f8a429a59e257d2f0cf15cd442f2390ffd5e42171a4c13d091031aab0c8e73ba37a30a70f9ae35f4e49267d3a7ce53b3f667850051b51a4ef19ba90412206244da38f02e8612e384bc37b9a497187e5f2b38e50eece32c15e1bc2bfe2d9558f17a6304b20ce415cecf42baf3ed181f79377c2707379b8dbe2bdf3acf84cc50e60ab403b956c039f3e947b6b86964280c1d6da8c1790226d1ed6925b614c43090e396c5b6bc3aec45331a9669f80b88d25d77fa0152bd1c81052dd6d58596f421332dabf7b03d3a556352240815e3f3e62baa7e6b0de0cd716c53017c74c3229bfb1629293b4d44c9861a3c32f0758a2e661f4c86f65ffccd3e0e737103c66198f456fe167f33ff27fc0da18f3c12cf5478967c0cf91cc191f4bfec150f06f8afb374a528c3eae06d81184faf5c28b0e6d0185eadb6a96e2af21def293c8c5f19ec39748053cd83ac2c05fbe369bebb27bff18a2a7492ed9c02659cae31a6f45be4f654a74342262a742a251cf7857947a4468fe562d88130b2709dc7a83cec16b0dd589cc56b768dd5e66ee884cc6864a7a104054c3d862c404011b9ede783f7152d4dfdb0e5035e25f66833aa93c4a83994381af95b7b2775acf8b00bbdb3c816708fc1f9dd8eaec28a2ab3eb7eb0d92a87fe1bc4f53120130c1bc0d8e7fa8b11a6837f933898994122f97855d3a2d046374998a1d12910a9b0d4a2554cf6170e87c5d6dfd4856befbb533e0ffa9f59114de4f14e67aa30d02e061ad76d957fdd9c299811c5682e2d299bfb61f61264fe02b1573bca66c890466c8148088278746b28f27099b5f3e404b974f49022ee19e227b5f5ac8bb4b065f3fbd8ebc02ac28e6fe99b0866f8ab9785b65420f0198161f4fdeff5b2f0cefffa5df251f63f6533a630ccc3c78c451bb3c4f72778051b9c61bb4582cb2bbb47863db7cd6ae0dd6c22389960bd519ff852eebd85ab03d09535249ec6e8339ff77c12f0525695d6646038d112008105debf2a026743157deaf07d0759a107f843bf09c700baaa6ef3660f7ace58213952d8b8f73a5f03247dd9d15ed210c39a0ebf64c75bb3371d75f7b30a53532158ffceb284c8043a9801ca9fd1ee023fda794d0512e818634534cd2bd7eb065273b49cc76314eecb935d7b8e78e61b4e2192bdfe8ef49d9cd687d1f3d6caa258da0e9537f1c730bce22841319d7a925c897bdca1ac715483a7a3ab337e713aa699384826f13a8d209d8258cf71ebae9bd03ee932c665ff0e3cf2626907254eb42cc19a4face917de7aebf8037d7ab9de1a0d799b908505f1f469d4d5d0c5155e4efadeb0105fae9e08c46b4a78f9734bb0e6dc39d895f98db02d3181f28936128f2bd8e84c263cc37e5bb66714efa2a271632c73321a90aac722bb54eb599d38f83b3a54c323bbd01f3029cccd62f5e3d255dd2a09aea18cd2762233cef8a887adbded83d792a810de8486ade8fd666e3326f89d75ab29ed714e8908d9061959dee40abc7b7b3c3ff250c032cb2aa2d7710d12176a0f1ba5be4386382bf477affd36b733f674a2498e50da7cf3656a2bb6b2a17616545c34931389c13930df31a46a613c7fad88924dd4f71698b6d5f2dbd9b29cb71663d63d4653baf4a419cbe9dea65385766b77dbbe1329d70a82636f2dd755c60f9e60adf0fc11157e0bdfa16f5335ada1cb887c3194443cba3d92b127278d27ccc2dbb88498f6eb427990dda76eda569c70e6d4cb2db643dd77f198ee573c606fe859d749a9328b570902b28bcc9cd3c3f6b89f7a12a9771026e306874d5a0d5e77311c52aefff34c43a06f1e4264a299895d48cf2e7194a58ea2614005d85e69737588798eefb9e87af2ecdc80b18b3fb797da46174b24a7a95bb2f2c77af5e152324147747ee046bf67042f17ff591bc9c90c806778718f89d17154b09f7406a6102b25b435652dee87974998e30eae51c362228b1769a6a41db6ad5fc60ff183771b3c9afab08bc0dbf6b886fa72c8fc9a39b3d6f97d78c9cbad08843bf2376c376f9506964112c3bf004e6dafcf93d7542515bd177b157992a5948b44b1e4a426146f19ddc396726e89847e05aa4d322811c264034650d15d88a1d07bd2e9a0d41b7cc1819e79096981c9bf624c50badead293ecd82c3331c5065a604418a768d26ea64967e04bb5ab8fa0ade5afe20ac6b5aa950e42e4cbf9eb91f6cd0c887fee4bacae3ce3a2cbd2f12533d56cecbc835e6a6c3af441de3d273486df0117600cb209ef4d641261193cbe828ebe4b1f156f6b0cf8695f06e1cc1a152e5286b29a7c5ef06823bd1a66a57e2426baee72e3072ec6027c9e72da3a01c0c7ddc4e9c0cc0ed221588676fc04f0f60de0aa0c838d3202ecb65cc3c931c9b413f2b349ee0c67408ce332944bf31d8d64a0db0f2799c9d8aa50682de2037549c96a2f38f24fe6518d8e42ec060bf6aa6eb4b3e6a1698861fe775f4e2bbe755b8468ce62e0db41b8d21383eedb746f4bf39e2d86aaf120b2011bb07ca6b9e7f28c2c52edeac05f061ac95ccce320229d6d1e8b8ef4c627b99c8f9d5163043cbd7982a7f11fc5bd0dd2cc3659c7ee4117855b9c1960b7b2f1b571929b7b9eca4848f23cdf5a327625f719827964c7c09949c84144f355b1894b94ffb6a9c156a63147508a49f69fd607467363fc45f1ec64b7b05cf7d992f801d963d4f0f5b9a19e31e91308dec7027a72c349e8dfee94834aff8f8fbc16505feb3862221c9eac21fd8a562fabf5fb7facf353490c4b740c25715c4b194c2d71d87b7405dbf8cd4ffd0d8ff555fbf30cdfdc774059b1875efde5f38c27f3a1dea2d726322a2791c8aaed0183646c5ef4b2e965b95ea17ab830c0524abcaaabe048c15d775b29d317b1025aee0cbf48ca7406e90f2fd15486ea13b70a13763247dcad62a7ba3aa73eebb9a18606420bc7b54c51e22d9b7107d9e418d69a9adbdc3fea49b03a599c88fc0aa3aff5067d2f96a52fd326a4745540a0df3214b8f0afa25ed362a94b358b882ea61fed8c211a718b6490ca27adc6ee38713c113c8e924027c270a983e008a562524e0be6d58dd5a875e771644d2066fe334f557634ae6ac0675e89c1bf9721922caf0e54d86370fbfa83f21a306ba77472fe107c4de9063646229468a62eaeea7b6a284b323eb8b86fb0ad49793aeb2008e36009a25c92a68b1caac6c97e83ba7874049b612a62c79b7ac08069625e46a7a2173402531e00ce3a6bee19e2de1b4c0827e9c3a8f9b285aa81809eb723b25a93ef7a27b0d8ef7cba77d5863748966ff1ca87daf6d39e5437a9741cbbb8e818dc660b6536853fab93c182c53e438df173236823475a7aef7f53e5b9776fb8614436d33e8974a2f189a3e12f6214b2e699ecd51e0a4e8dd8d760da8c7c778c24f499215e898daa11ef894d7f5442d64254d904ad3c095c5aaba1836a8b462a4ff5c52002e7a79bb5ee27acfc8c94195c5b2b4a75f5297152a5fe87a1c31b482aa398da918134c12a48801d627530a1b0475672d2bf9b4b8f1f7c6b966d368fb1c5ea1cb4c0bc9f3553d8c6ef0551c16df2b4ded58d32296c5931f57d76e434be0c4afbf93e9a96d8b0db1c7bc66a78bd60782eec4c82e6a7a5b2430a45a1637c04dcabf98b55558caef3870984aff52cb5777759ae5038f2c11969e6594f1fdbbc2ac2070d4d0541242ea8b8ea297e4392bb79192fa0294e7e63f8b19563d3c80077479ff67391d6cd0330122dc7a8bd40320e2d5d03312849855acde5777c72c1fa4488bc32fc2e2aab8dc78cc97aabab81fbdcbdbe62af5e799e9b2b01a05b5be6de2e5ab89fc83600255f2b6a4a0b8353fdbad1b32c5f8b610dd9cf350abd5b42264f9633fff0ae0760a320cd2fd357f0949f1bf0a9c1049205c2e57643cb6a5d21aac7e865edeff712d23429fec6c6a792046a1b559e2cf71df489f6c9a6ef58ff9a319f822fbc1dc0ca33afbdfe297cedf9b3ffadff14b2789d52f8d95de8952288d55fb1fba05fefdeb3d5bd2f0f01f93158c0a2c5ee488995d141da7125c71d19e57017a9552fbc5d01685f98382a27285273d25bf2a60c080007ac119a0c2b16fa578bf832897b2e64edf8b518bb4beeb41d229456880b73f9a62f089b9b8c4ba31bd0e3dda15b3e0c8cc5ce8863cdeda6929cf215bb2e1d4fd3f0fa83ed41ad9b7a892422a4ed034e193cb49a6dd38f78257502d532be310da3f5573b406b50424d15552a55e54d18b44727e52bd21e8618c2aa065cb7d08a7a6fbc398b59c14ba8dbadc8be91b5c25dd54f313eccd270489eb4d317be913f67fe3d916d0caa22d82a9ae70784d1161349f945fbe37a7e0c2429c1f90faed2ee3c7df6fb05e99b843ee3ed8004bec4408d370555698d846646d9fdebceb070b33c84010bfe171590ec4bd0c58a81672d82e38746909b5c5bca1551b980e05fc2456331d956000232b6e85a254e63a590728784c374f00fdcdc0b861edd3a316f7c548e280f66df23342224ab3938cb6754f618cdac53b8d51dd46c3d5270a5beca95db539df8f4e5be46e0d0ae00891b21f3f17b7ad144ec3a719b9d33a8ed3cb0988f6fa22efac1272311f5a81a03ff136f49dac1f016a2c4d0fdad3e63145bdc0c8fb30afcf69ba5d11f6524aa02284e6047b3f0160e5da83d82a2cbfadce24ff5ed49fdca2cf6b31c89099f4a84f5409fa0755b24c738134b2f81124d89ba18d0a9326260bcc49caf1d4b4275e0594b73dfb3f1c4e3729172e3fcd2326422043b9c79b629cf7f33ba64fb9673c1148c1a76a94a1dc27513e46b31b3a2af0b6000a13bb3a9afd9119d973aac218c3efaf0044b7a3ece44b60b3a27818b5e450b4ed401d7577cbb0accbd5b4e7c7d573cf267f54f8903715d5f12af80ef05735e34ea9cc4ee2e0f79cc5775a9641db37a28fba5ea2d8b5c0e39e52b1492f1059ebd4fb8f5e46e9397215373886e159f6fe3b7963f6afd570ff8f7963c4dc338ffecfb980906d8ac91c8ad6e5d228bd8a3194b258fd4ad18493fe5f38c8f9a7f6649be109fb0252382002bf855ce36aa9724b10e4ba33f70d6769fac30d49ed6e5dc0e44b822269427699dfe6282fc52de856440a3a399a8d72f4a6e146c34f0bd2ddb795ead7f7a368e0076fd3bd75d3009a91170d93e502d21478568cac63611f198589c2da9ce149b86df7daa63c1676b9bc8dcf9cdfbc76acd21da161679547a61fad14fbeb7d5c80ba61df150bf5898660a87666ca6d01d37d820f1d79d52204f51ce340325a358efadd95e0b694328ef53e9b75bfe2fdc828cef70a4eeb2ec8e0aa0b811e190e3fdb40b3d61c6fc432407138a62fe35f170946d9c8de42703aec65b9e8464ffc93630b7ea709164354df3422995ad46642cb7d5d2552fa248feb445224f958372cba0ba2e794b26c80ab06327415cc546e6fd06888d43553440b2a854688a9b7bea10b7ee67546c0f68349f187f9545dbe507d30772d482a789dc211c36295737509ab3fc8e704e15d2de1cd5aabd41f25d404f9b05e57878089b30d3722e33d4c08be044e69abcc2ebeb9e5e376acb54e8c25d8ee3030076be246a030e82675e89cf9a4eac9ee5852ad4f3adc743937d15c78915940c2dbf49ea6b92d119f0a042cc805e478e06baa0a3ffb751be0c75636763c40cfafa5eda4427f8d5436a02b3f113665f60f35e52346d272784462c67cbcfb6d24856fb43673c5af0229c1f3a3823e851a93aac666f3523ef675d5f2dfd2b3331ebb401af0a2e9e964a2b9db7b6a7a4b35b8cb4158b9836da2231eb08cf378d038c4593a1ad38859a799a4159f7a0e50472b25d6bb6cd17d3890cf01b7ae12c356e32b41de707c0f1f4f56439a27965611481ee55da8fb67203821fabd61019bf2fd14c9814a14c1982696fb2e660679732bb625d5829519bfba36bbc45674bf63e52ddcaed6b81055d2690f9f53aa8d126fac97653ec42f0a375ec5153e4f2ec46520d0ca5d86715f9c9dab685740151f1a2223a67d2a0ea2777db394edde3f76c4cf78e9902979013257c536b22cca828d572b0bba9ae74e3d0a1a6fc0167a4b6a98147aaafa30eae6efaa633afd48b9507cb083ea54fab5ade739730393239f73069dca4290f1f8a358da2f7151c8a53130bde8f21342e4a9e7944a178e2a2288a4991f76dbcf04f2afdbfe92d195a4d0079c9514e56b77abf25286cea44c53db27f484ba6c78d13b1e78f85e1fd21a1ebc4bef239890b70d9620440273722719846cf3f627b69b6da524eaf057b45f230e688bf8af69ffbccfcf799b5ac3b4fe2823e60dd1e4871da88ac5363cf7e6c9d2c14dcfde811b1157a1bf5322ae4f578a34e50ed363d67f400b7b6869882bed2724559539053ef7b074f65e4f5d771a56c11c16e95ba611e24e728d6c169e0e6219ce05a35c45943f6db2711e60f2ec9fd98a5db4b70a758cbf2c80bfc551c5ffbdcefb7f38aad91448a8e69339e493b994d280a4e15f73bacef4cf7f62b6294611cad1fff0138e003e6c01120270ccd0520bf725cf9876489d205e7931a4f571a947b58732959b1600e624637448847a4e02011f1bf445117a288327c9897c0ba48499996dba7bb7f7b3b871f49b2a2b37c06a426976646cebc6f6663619fe83007c363e2c41b190ebae19c8bbbde47fb75afeaca7354f7e5bbc36b04e8710d171fb02d90d34d19995af0fafa0d1cdccbb8db2a0b8cde379c16e2601c071d480691e2b26ec60718ed7775625555c86aeecc09af305425e5d8db20db3856aa01bb75c064386e1c64ee377e7ca5cf9422e3b0df82430758bfac5d6f6416f6bf40448315a8bd1dc888ce6570f49e9c3e6a26492c186b643ef21e98786fc8e0f3abf26569ca9aa9a8bc881bd22ab1909c07d0323464b7d4a627add01e8c8db9198e8a80fe814841f67a51a8f7c023f422d71a1b43afba7bf688ebda112e7905a82939f004b21816916c33a04fdc29f75d0350a08bd758ad00739fa1ba7b3b91510472e9dd1a2a9c93f99a546850ca0e00a521989e050e5cdab84c95924e4d74ef1423ccf0671032858487c0edc0e7eb5ea61a6980cecf5bd53d8a646adaf2bd4a0e8870728f62f1599fdac725b7a63acf5c935672d0618fafedd31010252af355e4fa78b446c57f455df3748a11434f543d09659a19b23e5a8cefd00382be727f33ed50f3583be4b0b0b1a7180da6fbd8be0cb0de6bc342b1b91c9943db5eda92f260edacd0e0ebf6d3ba58b7cc125c3c65d391e9069d570357aa7782b577244d6949949542adb7b5b55dd78126b9d1319fe871fdcd58b7dc8da1f08a551c2dfd38cf67fc37d3cce1c2dcf7ff930fffa1ea06e534ac1bf70d51159032a8a41049248ef7cb1c920460725acbe3a92f71d5add4acaeddcbe90314d3d4a1e6720ed7042b766c1e111c601772a64ae73cb597872fbeddd6c4966ed2b45529480359d866c837b051811e8e808ba6eeb57cad62d7c3461c91e4dc7d50596e870a5bfab42b78bb9d98dca47ce98a56338a018a6d56c1e009b475afe6cfa6adf4228daaaae4d1d17456e93979a713fa09b4e918cfc35c89720a319f9a7a79f525acddd949123512f1cb31c5ac32d8c90729149e70b32e7a98ab22680df35f8434da63e284b11e0ebd91497e0e8f651fd1a2904ca70a685121c47893b84f49e90b346a350105e5a97cec29450cf2fe8cee09f91c0c12522372a2ef9284d5054aef99e8c861f7d4b571160ea8ef41ef0ce3027df09a1933ac34bc8b7046592e6b38e589e284a74e8a87f5f2e9eaf97a8d2a64bc9701ca80d9fe65e0c35ac4184167bb99cb1b87a2e04ef3bd2de18ad0677288da27f6c9a5a405e85c716f0a4e528e1c972e214b98e3c1cb15b6c452e0b49fb35f01a7862d8315b1a78dcae17518b3c022b9e70d0ef75e3602d16a2299312657ca2f072b681b222d1dd1f7016a7ecf5e36f9791bb9d4382135ae28e99c7568b906843532785a0274ea2704fb629fea8e01474f1de0ab73f45b8f316f28a338a084c4d5d3b4cd9583ea7a27ac4aff04255d4b7878e3b45bda622534ae6365a63e40b60ef2ce168f3a0060d0ff10be1888cc3020e0e87abbd4290de335812b482c8c3f071a31963cdac31ec5ea6fba78ad7cbf62785bc0fe978766fba594b9c318428ba18efdcca95513764fa102562ffdcdb91741ee445a85072c1b7a40b9893a41c8a7b0e87c690f9615079fa2e5347363bf8da2d23bc4142b77a690085ac352599bb0811ce9c9892bf2ef471782c9493e7881c924e5a187d8b4293c65b0adb71f74f813cf24c2cb179e4d9588638a3347a480582a3739e589e4eb31cc7d99068b1b0ad3ebb33c0d9770f0d61e6ab767aab42b208c3e16bd13ecbd86d51a03ab539781f928245f850b179a1e4dce4ee16226138ef5dddcbd1d06b241c0595d378dd9c053a1eb48a9934078dfb87c87e305a260536f69c84f3d7ad11f2e7db18ecb986ced9cccbb9108b4ce98a325b37bdfd4bc7aeab9c6c68b3b73a71cb8f55fa8d7396cb2a8b51950b25c023ce6dbc0f4a3e9cd9d9681690af117267945748570c07f74229b817897512132e182e46b09b4d5d6a72c4f039e72d8477824227e940bde313db5ca0a6afca8d778a67ebb371884a6898295f069d306a701bd4cd75424050af7a42fab19948c2ce15c1871676ccc05a8e912b08b976f8f7c05add392735c62410b74c75080cc6b7d60cda36a932d08e1ae453782fa5a626de120b17f02dcb0deb8934b174e355fe6e28cffbcdc7a2a8d2e74264f683c40ece7708b9c2ebf5391987d84bdaeff5a765a20704c241b9ef6fa2661d1ac3fccd7fb4c3827c7b527d5a3ee7f80d47d8b15c48f8e93810b911aa2aea901da74bc809d3b1f2b54678e178f453c24b986521d9df35c420b1db0baebf6d46bdf89f88d697fa567c509aecf1b826ef12c1458acc41244d7c65b94136d48e831ef9a97a3d924347a5770cdef11d5e38812f0684c4004b9111347d81b1f40b866bb2f4139e9f1f7cfd7309eaec822cdd7107169ef2763ef8228893a0e9c5b5efc6530029bbe84ff9a155f8adb70fad97f4532015022f4c18ad33fda9736e9400c09ae4748373719e2914353d3987f4449908b9d65cdf66967199cb386e2b6d6501ce0f95bb9eba13f2ab36ed06973e255943d434edea8cb46e006d4c7133aa004403bb7935a8ebf7657b27a57fd07a7114ed8c1d1c95cee920e1a0e68071a9f09073bca96bf66fc77c49639007e8c4e0291cec9b0f33e963dbe2b0a47e964d328c612f920736bcd541cc44ccce5312eca370a8c7dda8b81f5f45087c8182eb315e79146e4482d31165f82903ac9c7110d01bbc48bf460041a996aef0272f37874697f96cfb0f6b362ace429c45fca49bcad0a36817797433331223e8e12b1460acb4b06cfd51474b9e9affa91af67b88c426483b99d4eb17768d99e721c08cf04070592d6726aee1c9c7002aac59ca9c559414ce4397b1e235f7088587838307971dd11ceb9ff7883a3ed0aa3b27e787fa83e46af0bc419dcff3269af1e75a58147270d4bdeae5c306b9229d01055752d9a245d4de0cf322170005ad085c91a855a048cefbbd8dc3d70e3525bff4966c01240370620190208a7e542ea1e87b906a0479cfd7ccdd888d8bb47dcb34e0fd3500ac5e39f843514f641afdf86174ee40e937b0a8f13bf51363dff4de205e36022757418eb985724607b2ea8d005ced73be8deeaffd381d0ab0961eadfea92f9efb9d6d8edd5d53a4da7cc6f34a0f85ef266e06eddd183fc34183f87d086b18e4b4ae6046b1955a4ec601ac3297020c58e3888450f5f80c2ecb45a9cdee4e16e7000f6d43b6a7010b6f2f1a7a4fd79ea35873518a4ec23f31a2031b7a303d10d58fb37acadf15678b396755f67e71920d8a016d652b4dbb4d4487f9040de7dfaa15c1fd9b80e8121c00fdec037caf8b6658d0338164b879ce0da0ec6a1091e26d427f3a06e02ad9fc3d6d55cfc092c477d45e37f7976e2fa4a4e6a7167b338cef3a7f4bb7f7eafff7babd1f0d5f81fce176f45d4ac395f7e29bc22694c4eef01f59fa34ccfdc76445a302213c8bf4613fb9b59edb7a4b38526f4d4714854248349cadb353cf0fe1d3c6034dd3296347bb6d37140be5d7753df9bb19b06d3aa9440678ad750856211cc27bd404289afeb20aa4c02ac86ff6fea50b5bff2c6939f720bff4e4d0d5eae2c6e9d04a7ce6a43894cd23a387377e09e4d58b400a49dce9117a47c972a872c84554bc08aed8ac99a2ad1f9faf945f9f31532795ea8f935c2c3e31477887a5f62087cc85838c3837f1e2cace702709eae3075f9cc3aab4da29b794e208cf13d6a7680d0a393654df3c321ec743401a9da6b15c6cd299ab310611a2065f3915092ba2a7747384968ee0b9116cde6cec605887a936b476ff019e8e82f5493fefa93df98849edaec4dc0fb3a06e59b15a92a4f8d8c1a2c7dfb02c3d1f0a6e9c7ff04ebfcae6b8c6e5c4b734620af8d3b0f7e2f608cf542e7c26837fd4af866582c3cb4ffeed54de12aa446492610e4d87dbdb34bd9a20e4a4ab57681877a714b41d31dd62d6ed1641384c18d0950a742f1be16e121bc49383bf3aeb8a2e3ba2ac9bbbed3c5402896189262c621ec311a219c29a24dd20f2fb1bb57714a329c3c87b076b7237761c5ee65f7aad58da10a64b065798e9d6ecbfad4c2fa672138a34c6eeacea296eeda347abdcc16630e0ca85320f13d61e103d32b50d91e6aff904c12e10e16e03819030b430029769f8d34c2b07ef0021b11a9a87a8d863820c30e329e3a1172e4cd5f49b392ebca90f984b9acc12ba9eacd2409c216b36f63a433e6d996625ec7a0458e87ab8d0f77c891df01036af7a44c7a8fe807269beb3f406b80a0de64ece1b29cba57a9f9fb5916717e93ccb2241a0ff4abe237d057dd5c24bfbc81266cc30bc4eecc7eef58342b18cdc049df9f6ddb6e248e4c30e9993e14ed292ca9d7e0e4dcc677adb4424ff18cc0ef604fc47bfdfcaae2790fda1989e53fcbd77e17f9f17fd3fefc23ff9a613974df11fdf55bf944428f5fed9ff4786611c50bee33a344427d1b004116b3897a33d9c87440d200caef3ccb75a231ecc7bec010c882e5c191aa508072e3ec8c404a618e3dc275e8531e03bb593ae87ea4aa10455eaa905fe7e050014675c116475c6dbcd4594c7498261490ab14b39ca7efed3c055cbee18ccbf6effe7503da97b100b4c0ea516b60862e59ee8ebf8618969b7c1c0ab4560007a988a688aa1ddd2626d8c71bfa90d428687c555b145cee090922cd80142da052eaa552e1625b71d2392e6686f48057fcf5634b6ebc3f2aaf5040fa7649f352a09c4b2526c14b550bf76dde4ceea69ae46a7ae1c154e9ab4dbaac1e3e57dbd0113679fbd1d5b54fde16af1b0e9f497d45e778a0f6478b485c9816ffaf84b2ab587ce93e17c1d858574b573a6b4fd36f790fc6140cd254e60edcadaae3f93946d6fd4b46b432dc330dae37adb843d2f0ae073eff3a936146827cc5bcfc7e7f59dedf6680afa2245cf1e2e56e9a5a8373829b8f1404b4ed5fb793ca3f8d09756c315c320b1afd77cd9b8bc8a09ef6401ff874a856a3432cc0df4eff7ebd5332a75b8dd81973423b75e7562700e92a22941fdad00adb5f99350f58bdb844010fe162bc8ef1bae15d68b549a600b4c680b8bcaf372e10c8a062d409e2c9b9ce9ac397d3da884e67e881e79c033c03124bd36ed6afcdc6d699ba1a86bda4119b6aee46e9961236cc373e3d4f4751f72b6642182e089292c32761f4635c746b1c7518513007fce8d9562d84d6d8468073ff0a6367b59b9272bfc94b70556009c8e37f28523a06bf04c61b28a87f0adab5f91763e47b123bbfbd8a158f5e9649f8d09393315ebb4b357e9863b0ce0fbf067259a1da84da9955629bca02fdf3eeee185d7a2164f5e178af2e3f681bb1f5520610920c538aab5e6bc772954bf9c3f2e78a7f27b8122bc254fc85f746f8c67316f6c8b3aa16d4b831132ceb9f3f21b5e04e05fb38668866ed69963186efa9bde9ff86ff0fefee5fbfff9fd4e62b52925fa3f7af196d0fd3f99a6ec0d8a16aa312608b3613fe36455bc45d2c3d4cad8fe593ddb3f0281d4fa294391126d519093294bd125a1373e10ab66124b70e446150ed29ee4f7194889a43b69942486c7284d83b55277519131b313be2fb9ccedaa59b076b53cbc10277d0419ac452f10f13ebc85dec6a106962fd37de4429509cf11c2246b1cc34fd4c34f871ba6a52d42b333296ec2c933c914494b3984042ca1b41b86df6e5b4042a0db9837cd67703ace45394fd88f0ce1394bf9ea1a8a391b5a4d3bcaf0e0c872ca8d9050250c3a7743f927ea59436fd8835b58c28fc201e29499324d0695c7038d7a0b9dd3faf3b50368cb2f099c679524a697e6c39c9526e67e82476b874476f4d53b6f752f9f93cf29ef59820817dcf2e3b366e889c6cb8ca47c9c03d57ccadaded7bebff4cd70a9480fd4146eb7e9a8fe9507a331e5d28dd9b87cbadfe0183dc965af0a4e8331562e41183c9554bee450ea8e39874838cd750ab49b906fbdc878ffc8e34c36d274be52862542bd9eaa263bc670c7aa5dde2d22acf5801b02a0a99564ea6394eac65ef5c7f6901e6b8e1110af5ec514dd7355eeb09ac96134744c7fbc1fe3045fe630c338f23a0340ddd91bd46eecc828937f276c768c2210eace07d90e84b85a18687366d683f035f0e1611778e4b78350d1388767144a6aaa7c7e344c2fa53e8b66366712e2db531a927e32a2f0ed6ed7621468c83c6919c1c2c61209028ae307097592fc412eba320c08e0347743a79cc773289a0e8b04ce49077b25c4a0bfa1f5ceee0601c69882b78f979a742acc6f0ed453a000c0cae47be85f3f42883e73bc04771460340c769f31fd465d11b3e06a6936cc4c324e2c14191be0396923246919e0b11e463ca9e876b2d9650961ee14556484fc3333f2ac43b0e46db0b9ac369bf8452ad52d667e39fa91b9b252e757b06fb79f9cfc0cb55489ce6f4a000d6850218168b2ee433bdd78a158fcc3f03f911b2fa158e2c13076b8b331e91fdc64e786a632ff6090fa6f6210f7dfc14dfeff6aded6f0876d4310e3543f0bf37ea7640a485399c6cf11166235a2306c02a70e380de917d68af9fce44c54438f63f37fa24d3136518f2af3018c0c070f01256b2be25a782c3405655f8efe7ef8510d1d4e31f1a8914dc2dfe7c62e9bb08693ac152b6a2094fbdbde453d26c921e426c5b7fd533d7607c22d6d01f09d4b7dbe43c4df07cb889c5e477d15d92cd118bb041853fcc69cc9ac2400b23805051241511a2a505da4a997041a4c66d8e2cbbd871e4cab41f73b66a483549a734ddbe9e9fdf126b26c7573b9d8051418e868c92bc00dfa8660252db3c78327879c13b5b973e0cee164b9dd0c903370e66e4dae10421c040ba8488c3a611ce7589b4ec031e15196eeae25a35710d34872b7019b08bff0317243bde8ea075030b89d24c1d6d3d151d92d47d9ba6ecd8af96243a369a5685f65089dcd692080be244734d48eaa99245ddcd6169c3dd95cb48badc3aa25728d36eecc0a138450ef55ab1426531ede115702dc7462162c6d47b29192dcb9db054c5f1cd244de9294c35b793b7e3f9d052320c6299b12b95b7de44648094148312d9f6337ffc7ce176d56636f600486d182bfd7272308ff06bfe69f3c7af8a767fafe132b13a1ff072b072e4307f08a6cd2b9b0ce86b5cee6e99bb355272bc34ef1a86d22986a9d55b6f65edea01fdb6592b3fe2c60ad576a2878aba6da1407a6823fe54321b4f328353451fe90dcfad41187109a9c488a1b05d374b0c5a1306b54cb8d8b9732f29047fdd0396fe5346797fcb08e8c439159dd4879fed91ace094aea7304aa50151aae3a43a57306cd3ed51cb537b427b56c1175b4f2d19acc54b759b3db9d0c61c825541b3d1aa0c450e537f73f8108d52be6686f6b6c8f43719e385b3ef1381d82df29d430bbe6d959514c204da167d6a44ac8422ccb2d589dad38d991d09be18b238b93e9ab52f89872f3f706fbc92d97e48cff8b3263dada4682e34bdc3dbdc0c898dbd063e1458b13c3f55763cdbd675f4365b15f49b71016cad934aaa2cc95150a04e6b90990fad58a36c62843ab653fcb6920a9c676cc50851d9783ce0a6cadb44bcb20b703cc95bf1ae6f0bc73e4b65d82d0587cc6f8242eec1512dc3e4de514897013b69fb501ec269a445d0ea881562e0216b277b669904f3154a05074689e5ef42ad873dfc031ad5fe267452bdbfa58b6ce0d67a43836d57718379a6098e5dd85366d735981ad4a247fd56581f41e70e39622de3a87bff26a3af19c6c8840e11c5f4e45fa42a430c612e979732a71bef2d7561bcefc63719af4ed55951991ef8407cadc4ee258365feb4f1cda354896bd32b9e96b562bcc69926ac4a7d914eb233f19605d6b6b72b18c25e14629316081c0d68c7c263919c248223b191d7e9cd5c8f75460b229f4d62505c508e8cc81a5bd1aff615c41a4fa872943e1539daf8b11bca9fdb749ea097c5ca97e42a050cd54b8162a1c7a50f54154654e7b5dc0485934521964c74f203cca4e4c13f2bff2fbd1c2767ef907d24a89f8ff9d17fb5feef6ff250f110ab02d4042528d19914661aa99541b0d2c9b7103c2266f2c34bab76ac3726b9ee44a343fe6ae7e6cb6493629c8e12ff5cb9958c7d939e93e72c6be2be776a5499931ed0c92a47f14f57df66711174ad3002376fc594f16652a7636e3733b2ea555c38faac69fe1f2e652bfc57a16849b83ae60ad35c96d78587b0dcfa6e888cbdb0acdc1a92d1292258a6b39b25abf1214988fca3ef6aaaedf8952f38a4b2a93e4aa65ae5a6c00f82a1509227ba184408fcaeba9ed641dc1d20a77f706e2b34ff34a034d3f8b59a5032590fb0f579bcb7ae2262f2666a84834635cb8441c2c8ef18b666643ed4244b3a3179f5e3613ad3413d0be85d3d1e082b6187466f25e734d9f816c88e088dadffec2a9a5fc6e88a80a656f072e08bd2622fa78ef3740430cc526a3ad967935342e782ba0ed75d0d2a671e43592f916a8d15ee0cb6369ad79a6019be0512ef9575b930704acf388430b2e7a48bd5cedd20ca3ba9791424cfcddd55db81f890d413175868c2eaa18197f743e996e26ddc99207afba12c979ff5cbbd5f092d8e19fad87baa0b7fd5013ca740f9ca436af54c9402059e965794a5b74f06173b6c7b98b0a9c8e59d8f0d1fba532f5c6377f235ed4f9a63d7d616e905caa5c2e71794e366ecd726336fa24489eca058b1e8a1a44991c1fc69a36c673d67354eb4553aa22535666f484835b28d4fa99ddfb7e867ef2372d7063f655485439fe4c96c0c7b7a3d00f37d674d3969742b1d24eb90e0288b541c8c304bd589d17689738cf2b61a0822d7e7a4bc62ee837249e435af312e1175c552a02b8042f879f52880ab4b1990af6843a694c7b76a3920037d28cff700f4d54942d8e42c71b4bc5397373e31e9bc690ae7de94d1776daf16e38b78fb6cf1274ccbfb8ad49f8d32fa6fe705b95fd5b737459e6dfc06dff7bed8b88fc2f227d87f5c40f420b6b0afdbe4eb277029a0aeabb641306d163458513c53c0b8328e7724bb385c147ac67c45c92f2243ea8f71fc3fcb84996f9858190d44dc66df8c87807a7cfca806ada809b627494ed15a8c4a4dfd86854ce49508f8a62e99d2e004b0a30941bca94f4e14acc0c1376a34d755f7a24123711d60ae3c42b8b733d6a7833842491e3043ad3ac26559c8428f9b60b77c1f12eac0f642e8a41c1f392dcdedaa432330d88581193edf2afd740734f099527d03d04fca27e503e6a94e50a881149a793b80d60fa5d16db2f7eaadc6e6c4880b78f0608b461d901d4257727c0d7d7caaadb38be0372cdaf33728ce99e36b0880a919a28459b44d26ebc2004f16dea3c06a2744197e82e7333aa6a7ed10f8baa6383aa551555b09a5ee4b5470f78ce654d3534eb592c0e7729fa51b8a2ddee24e1d0eaa3f8d7fde4d9df6298772dce8851af9f4abe778a97ee24fb94cdfd38460ce79d8b1dc59d9f64ac44aa77bdcb6389e45fd5b5637a316781a42f2e605bf3d00e20e83aaade3f3eab9c20da29724dc4982f6a7d800e98d59c28b2a4cc17637fe4f3c1412e404770e44c8a795dd23648d5013eb08750eaaa7a1426001fce047cb4a34218eabe78284232a197e47e5373982b5e5d50eb978c749745d1bd0d183111d56d9ccfbd5de6c633d11a598e23afe265fd03f37664295a3cf9576f38f337334aff831974ffb7ba28866786e05789e0ffd281fefb3b43856104fdc1c03cb00c6522b68da2018a29e661c9d5d74fc75c85e366d571358827b11259ac1739310479d19bb8c0c77195b3754080b131366e708a2a8218746cc92a773364d6ac9d7b1b4d87efdb6fd4a041c32a519caa92b296e5a2f54ce16779981b9a812be3e938468f32c21fec46613bf96665f4ef82c36f54b6a2559c114769873755f358a15e39e487fac476717e04ba2a93cd0e726373b59b33a3286850b4147ef1c2ad99f1858a7962f4fad0b7418e46293b971fb33ead67ea56f8ca592009ed098042854cc68ea0406cd258511e8f7e23564b7a3d1196e07edaa6722bdc249bf54d2761a51cd44e7a6887d3a5709dc8f9fdfb965633cd2c86086415163d0bbab6699b089c6c985a746882d6a15fbce287f6aed74fb1701e35852807f2845c6e1dcbe407032f9371102fb69b875a5e261a74e5189c4d0645e30829a7f7158f783aa34b3c836381150d7c9aed830685234f9cba743b2a0daa19d6d4a880f4ae3402caedbbe22042c66ea7a242b258a833819a838219bca04d1aeb8e70f7c4b8e02dcfdc4f3c75862ad24d36043e367e9abe80c179e0970c8e9287d505a8fe5099d6e33e1fb39db6665cb5ee7970a067ebad61389a18bd56af44724ae5145493ff54f3237fd08675d532c0311dbc6ed7d7bb4d8d73e5ae00366424ba7ed7eae5efa74b82a6f164bee16294868f14798985405160e4842ebf12d936bcf4b63f879031f7ee376a616bfb50faed9a4b412e4d53a64d61a26d2b0d9c8ad19c9bb9d684eb5760e939b10aa851f85505f4d55eb3bf6f187addfb6b69cbb750277de878c329e954bccf624b6c9cc509363b0ef00b79d229c8122a74e2c03638596a40e259b37ed735596bbeb171e0ba7cd5477d3e518c41f588d6fb1c22718879705f53ec7b7f9d4a75c610efa2d0e54983cb423013915ca170615a67694c3ae94d8f6e1ef9318f7830019e32680233f805cf33698ce4a09f0c5670ab24b92ed122acbf36f6ff63efbd9a1c55b2b6d1ffd2b7da33c24a62477c1780f04e7873e2c41b38e18d84e78bf7bf9f0055b5a9eabda7c79e9be988aa162a3273e532cf329990ab0fd4af77e1dc6eca539b270ec76593fd77bf73e21d57bed58f1bf14e1b5675c78e8b6d0caba20a9c97731c95505cc6168d9e35ba4a5c710e52130e2471440cf9eb9d9f18b55a8b053fb0a704c85af5a9d924d83d20f969f9b4675315feb0ed6c1ca2677c866d3482cdb83d5767ebe940c8b97f5ae91dba2b70142f3a2e1d6e83171e2e287cec2ff011bba0133ab2f588721c297ac28111299a96644df31d35787a60e579f1bca8b3192488074760f51045eb7c1a3a12f640c665202f38e143c8716908a944132601a2cc8b9f030cc228cb60f6cc65b53386e8baeb9891534092f01070197d6f38695d96e55137f9cdc1ca24a24311a6a043dee0da49adbce41198a0d796a4476b78e488466f4fa81754a7b13625e93c1d102560e03958c5a009e824794c4efebcd74f3cedae53081107aa3d54581149652763c1835432b9d2695ced43d5798a7a6535d6a51682e61229b27483609bb8a353e18b30341903d33686843b957ee4c4b642cd816cc8b3efb1cdcc26aebf32ae4ed9b075207b42cb58894a6db082887081a036e7da2ecba9d1a59ea27f7569679e53c422aeadcbc8370be9bca1f4db5666c5e40131f793a95d1e251c63bce7ce558a182b31f339b6c05d061b80a6f512303cf861a019eaa13d1503ab89b647a759597549858d877174a9b9b09253c6f9c9a542262e2a56f28ab566a79fe22a1e3ce17a82ee0f3f159840a24a0d640540d78c148bc63b69ca6be6c7917ecfd5a654cce3358dd6a786f391e7aae7ca54634be0492dc632d62827bf4daf1426766d123baee06703b0b0f95372738faec85a38959648202d0736a0bca2691c047d1d94838aa34e610750013648552751b91cfce2e4cce3e3a4140b8e52c838458e2b300cd427959d32cdd5b525a7f21c567367065927a93cb807300bdd7a012ca6bc2405a4597e17d9272127cb6811a9327b306163b1a7287f1ed0a75b3ae742f039bcb55b50b189a4ae3ce884a7955927674f3388c6d720cb2ae69a9fd5f6a28712983c659da37a963aa165770dbd637a320ec692f2d76a894ce65863b43d291a8183fe63a421ebc10f9a2cb443f9e03d536386b5a88ee4d2810e89b9255d7b068d357d125dd194bf0bc4dc9eaa6a0657d04d604b8026886c816679869a142df2f51097723b1e5049261f8d6b36cab53928fd13b758a5c57337534d1e75c38702cae30a06759350d8d5036661793c946b947239fe706d30c5bd4b58f044aca60fd4c4457b013929097a4315fd5c00e4b16928043fa438692ed5b81cd25e320a232bd49b00f08bae35ae3d8064be90cf519eaeb73578421c1ff30f0d7591637a45b024d39ca39f0030796a565964a03a66e615006e4127f4426d0d14acdf79d6516e84adcb867475c4f4daf0b6f3040b3838001d7ab72265406d2e524e399e9669ef8437e339cc0edcc9170e136de6cc2c45f3f02ea8d2f00fe07cca90d380d498d5d7a1c0676c5c654ece6817ba494f62561cfd50ab56d648803341c7e1439f22e7a25c939c81040494dc16b927635132d1e00502253a8790f78a08730abb25470e8eae0be9a8cb45c4882a28eb786ddb345346cb6c0fc27146adfbd169933312e5871ae1d3530d30781275386f3d0cf16228eb612ac8a432a1a713a422680c4fba74c6a79f59920c9372c147775a0958aaa1199dbd30a02928d7113c529865a99735e1b4690e3971b5ceb2b3dca92bac038d89ddea43c03862ca047e284a597d11a64731448a29364f3a340fac7e4c34c74a80138543977ae9090a49fcf6c1dbc2314f2809e87a4e923da44578dbec493612976ee82e336bfb540a76dd8579b6e9dac6a6575f8f36c10d47b09a69f51c9b39fb3826daf5ae07898b722d66dfc1c7a89cc2f0140eb486de2583f50fcf3a9c64227d5ca3ead053375766cdd8941eb0410addc512b5e32356c6828a2eddd9a0e4ea345fc6b58bc830ce0fb7a150d305e8dc39b847651630ba5a122b9fd53445648f66140dd9d04ea0dcb849365d42685643026d3aa8754f63a1f794f504dc585414200728e7eee3b1288ed60190bb685894307c4a65c50b8836b297de18d0900192d0affcda60124b1800c57f5e9f3e02d6d5d9caad8b23e74f49a32ee6d3549ed42062ebf3482b75fe2c6844bf126cf554cf87db7d61850706cbc172079e5ac4acbc2c57807f4bd54e11e0e9719ce0277dc693e9382927a7e4602faa0c8f6f4e9a27dfb1e04851fc51511a232779210defc82cc947d4d14399abd9fb413e827402449e7d3a4647553ff2d2f17c935c7d818e2bae3da5fe5e8c278b6183f9f4300ecf8b741e31edbeaa217a729a9ee23423b8161702315c432d74f80afaae07b7d4f45cf883a8a261181ae22d638db92620074890a5916d7fa0c56539b7f4c318346d35189d154b910201bc0a1eb9593952dc4a8be23103a74d6569d9f3753051a55b9c3aaf2368e20e6596c9faddad4b993830cf5213a8015dd2c682496cc11738ad179b5fce33d96407e1a0858e1ef01ef1d49ffab92f4f568b0128720086d87c08d589160a7c0842ffe62e527af2845e022bcd5b619d1f25528886d41089c8703d7b4d59ab8ace475b184ddda9dc6734c752d1e25a23655dd975cbf9e48e96fd3899fab31868ffc9473d3397f113420931466798466201b7db53bf5cac07149625fb8cbbc8abf2055cd092bef574c21549db851d7a0ba3f8969831a42fe7b29de3875a564d3c595c5ef1fa7043a6a827cf696e01223d9b2d859a987548f5c7745a6ad63b1ae7d4486cd4274869e92f31303f0f8ffc4a3091dda542519fdcdc8234bed573f4c0d7180553c72167f0a34d2ba536a2ba726eaf5e90d09780f446940d89baba133c190c4aab5cfb32719ce66c3b8ff844475825f57115d7eca385ce3a769e50fe8809d5cdc5abd5d323f0f138e9d2e596d05e6434ac8155261197692378c0f151a489eeddbdfa24afdd0a45e9e9da154f02245a72b0d6dbd33cd5d9555f8ccc4483635bb6581a0b7d6da3e700d33bf900965021a14d91c6c56c4410681003a94760a6dbc4f1ae8bdea316cdb377ca79a302ebb32096cb3d244d198ed363a565b1c73f57d100c0472e64c574246f8721af8aec1a34596a00ee9a5db82973ce3977e122a93941f083832cfa7a0d843e991704101e717e42b582b0f02790cdc79b5052d850cdba05f6375b86cbe9d15f0af3e450acff3c3533ce11498b8cb44153cbb208049d44a9e4a306e366b06fc87ec6c4e6ea2b6ced73289ca3462f956db03a04a28c2c8c34d311bf8061ad5d71e3a942e1c4e4f74ce0326f8862717643c569f5f40cd2d1d1a09589efbd56bc0b4d2ea62b6d9d18246347307171afcbcfae801972a7b77171eca8c8bfaf075ba4d265b2fdb16d6ff73227100a3cdbe16468882a335ea3b580260fddd53524152bac4b75593447938dc3a29ad5b04aa30206d598817c5c2ad339ab1dec5a34e1720cf200992ada675287e99e96450b7a041ed4a0c5860b5821905af90f7a89fc8518bd4370030de5d6d5dd749c16f0a6b8671094ef2446007370705bff79a4c3ae5583f0397a59351879ae51ddb90ef44ba0e2a705642ef35dbe2165623ac7436801ec53e943ef82699d545c23e2188b34b63205e37697b0998d1b282fd6ed202f6848a0ca8140878ce58e3d6dc8699d7939370227b1c59fb59ddf12e8a4228775429eb23db7a1e2c2b7896c93258b09bc246dff36070267a751808f6aa3d87eba129ee537c3a97e70e6d93774d5d30c8771568e3cfb39565e464143c1ec5a9dbbb824831a6d717f4065eca13f07a11bbafee05a1a137817cc37f2b07a20c5849ae10962c2cbb3888300b5351f1b60c3c6f5c99d14b1d6e03c2a49c364b5fba3edf8d3b3194fa67b0f0a02f761577f96f76b576fe9e1ed89400669cbc9216f821ae0c3299e6a91e0042498f930489f4c35049a443c19288c5c152c65df781e2ea70ef0d4e79858f7ecc92a563c4f3879bf73d173918e5243c8f73009e60296b321b6e71a452b5981af87ab722ba6a28d624d42c81ec7521bbdab27e288e364c815b194648f1b7eba0cae8c280cba666989eb2524804ff9011711619ed9b81961d310651e5360510856d16acae819f6e0d04ff35008ce85a46e7a926016aa9f017690c4b37c73c685a24bce522cf3583f22f5980ef4d8aa0f46450317b2a37b568a412f744b025647b1ba54d405f4d62346128786cceeec8510fd7eb6d1bb70226a32b91ecbd8bacc0ed450915f3f10c98e8701c574167706fc795fbc3ab678a052e7392832b5f3837e7d94890067e39518c3fbfd2c85ba5d53086491c193c04a07cab466245ce568f90df6b8d4d3136285ae652f64e0e98fa87b8080d2a4c2b18458324808e04cc699ad24d70c6c54b2b71b13c6fa8653a12745b341c2d65142b0f39925c609678ed472bc66a4384e3a1e2c34773be141bd08ccc5e60b459f93a5a434716d0abf764522ca32cc58b17a9283560007bab691d96be713dcc5f6c970fa69b81e28050a61988719f88e63016ad4a100288831a16935afccf1ce296c4be6317d8d27e0b670ce6da1d629bb5fdce1312db169177d7d718484c21cc48ea4c3542fe288f8f7cb8daa176f44e23b621fdb90bf8f53744ce8651129736ccfd0702a0cf0365d8f8955cf68bdfa0d9a3be7161b1e75cc1fe3a3ca2b87d4280125d7b8fb94a3ab718a3809444f02188c63cb7aa3c21b271b9107f32cf837f3882b8ab122ed9cfb361b1c3ad01e8e087fec23baba3e408bf04f9632063978b2f9a1b990e043e9e030d6716a1071d01be2946135a444924c84dad49999f314d01e856533d264d764c96fa1398fc0598a1978e69a5b55d6e971ad38788ded19a073923d0ad3a34def52e31f408c9c66fcc0411c72385286654bb65bcf71a9ddca1be01d084339f697e6ec01e412d867ad4aeef41aac56332cf13dd7909bc3e2a133464f3c602934cf22ddd2e114940f3a3b9b947ae4fbf25958f4536f45e138dc6eb105e75e3c118c19f3208daae89d3e39453c3c9ea76b7c2141d29be758068b82ab3d8f35fc9c8faaf502cf4a131437c51ea5f2fa9ccfb560cb3dee018cf2e8a02b71d02e54d54020c8d252a6f0ad3e32dcc3147ad72f5646807beaf26096839597b10a7b4b6ff5a92b4f30c7df8d67978b25586768ce2216a03c1e17831b4f25a890b5bd4ea8d75c425b86e802e2f0119ad5f120a6c67c3ec6de933a5e174cf0164b88733b42837c6141278bbde074f3ee13d90f347de3324717ab3b8dcb48ed4847ef521d739b0a67f53853d6999857e3a0f088254f27314f8fa2214e55b826c3a4f4cb2d70ce173708535d5eaed8c92cd71a666aa40ace7861ddc51e915991e03ae7ac51f6c914aa1aece3d268bd9936c06554169b0fd4735f2dfa092df4bc6d50f51a178fc19d1ee3dccada6af90aa81cac871d3e21571bab65e5eccaeb6dba18ae98a39a2850e5423efb07ae31bb395d7d211a685f31acc7c9400381ec4acb730a01357dd8994543284f09f87874ed73e8fdb2f6cdcbda2e716fd437ac7dd601b3008f27e11cd96871d8b613e6cccb43585182db212b00becf1620634111959196111e775fb3153d1893a0efc086ec1ccb62463e004f5979be270b909f8fb268a87a4543a9dfca0d9a097aec26808b24e021d41b1249f9d63130356f0dcdd65b249af4a913d0beea000d7c14a0dd5865d104f8e51ad0c393e209be362da18fa86b74cc30bc71547d9827fe2972880c9397e2c0de19cae419f3e0949e8c75e8e319266725b28d9b05da810497503209ac348e2e869fc41a2b824cf0203b92889376322f02b31c8590e509fe0ee77316db036490e874bec20724c70f01e8c9807005e456f312817e64119c6884ef38ce49d64b0cad2c68bde6fd635c4a51a52f80a71c8d338e4d6c8e160a7b669f439263253b7617f6cc4d07e88631607e662264412f45aa2f639dc2a01ec276045b0ab900d746edc2122c3c5bb2635ff24a0fae8b762ce974e0b3059cbc55960ef0195bb9c40eca5317ea8ef874f88069038f3b0f8753a6db10263f1463d617842bca7c2cd65ced4ae46c9ae9383e44d91de3e7080782e54e69de12ea13254eb57d38d1cb35d061c99805f07a7c1446f138e997fa204306af46ac7864b02944ef2d605df22babcdb3978b674e1c9efe5a33f0b4c8184b5ccae3ca28394c1d961b13d4ec2144e6db74bcbede8b2447f9f928722a8e938080ffd239acc0dfb17efc5af3b23f9c9bf475bd18b4fdfd3c56ebf09c0371e16e449e530d697ac9240aaa18f8aa4b0c70df28d787160b0f0b30804a5789bae29e049317aeb2f6261c9c99c11159ed7e52c3032f6146c3ebf5720e0fc6b1bb57d51165ecfa1e4361a1632e421ada5d664314c3567854424c3b46f7fa782e83095710eea211b871128dc1019bfee4f534271e6a51cb58ac14002743fc681d0c1923eb484c6b4fb2fb56d7b182bf402465d29c7b93e9bb55ded0a3458a39b81e1f8216aa2a649b0edbe38f12f02c6f5e5d51f15149780c8b7b080c136e6793b95e9f7cf13c51674f4e54fb54c72c5f46d190200c7fb84810b79cee30e96267d50e7cb9a089197e58eacd8bbcc997f9683cf0ebe8f085c37add3d3494d2bb37798340e0bc043235eac00101f5c380f869b390277715451c346d6942b40cbae7e878bd050a69aec8599d3139010f0495de1b837afa80aa695ccc18519251d40aac853d593ed1d331c28f81c69d1fb746934286949727e72e15a9a06347f2b419adb53dc06a87b31ac9ba022cca0fd9168343f3906ec803f1cf519020be2c4699a8e12a860f903cd975a359420279da3a9f395a49154c7666255686ab6866e90d110e591b9f1c156ccfcc9d236c4f6c845bd6987e9ccc5478bc2ea5bce2de6433c40487f994254aa3df04b2eed509901021bdca8cdf6781d08966f8980957d19b852172c70c28757540af79b6b377a17d49cb65cd9310c09f477ca240a02b109ba51aa09085332291b6c7f6f789a4104e23021078aa591937a8701938ce3c39e50509b0b4f26e959703ddb3391875240f4e684f139a2d410eb3079608a72cb312abc89f97acd12c94682fcff1c674e955cd8627c384c76b118c4ff1306762e256ea25b89bca6a8657a0152ea620c5f2dda8a1d525962750394f3446531ff7d73e94f270210f2daa0b201c2e83e695b977362e4476d06c6428759865c8b230c0a61acc1ac14e39939d3824cd42e074cd6f30bd4c67d28edcbcf2fdab76c1c41b6d1dac61112fece1a999f541d20a45ef7d346217c83df858aa7932abe5944da86433f07308deb8e2129a03448215714b8f611e44c8b94be64ce3302095c5603edf5b761697075744560b5904cc8039780bcf1210f44d692755f538d58577574509c0dbaec09f717fced2e3a9336edcca54c1f494081e3ee6c323698b196ee3e97c9f59b799ddd90c614fb3868b5d9f2e39d3686cad334c89e7b6fd602adc05dd83b18eade53da1437c44f503d19130922887587ce2cad15cc553b95ae19c3c020b3b0b86f614b5e7d9cfae2366aa4931ae0905b9eb1db8e1155c0986c7870ea48c6c125d8e40de9103d42cabdd2ff113d59b301cbd69a1bbb938527d5eb9cd193e933538e3834d5d2e3e8d6652c05ecce020d597f478801d939a840867202a728e8ae2fbc7f3f5c8c752dd05741f6bb0e9621568c6e851bb40764eac475224d9b3828222e6abd0b1bc351c5036c948cebd60d58a90b70894dce73a08ae47e0868fd86d8acf53c20038a4a07ccd23b96257e6d94596a02b4b584ed7be84c8b9401be13202a126f617d1a16c445f70af3ba3e2e3a9d86b5e1f4ee12938984325d4322b76cf20d0f182bb008a7339c4da0de699431e1ea8aa2f4136976e67459e0fac0584735e8791064707084df3cb15b0bcb519100bc3c7239ef875a04846444c1ef9d03a244cba2b9ec8b275a63070d03c96e838fe78a06c720a490c262d4470cb756409ff7cc10ed22180af18373b1ac11ecf99b6485267c070e675f3197613037653ffd6cc590a21f35cd3c7121c6e6e48e5297fbac84592b2898f2614c8240280ac1781aee249af19a5795c0fd756010e1d2ae58c28adeb7cb5da47cf8a3dba267ad71c97f2bcaa017af3b37338a6b7838050dcb4e8e42918440d726d95650311f18ef3818b051da9c3debcb49a70be0f5cd870b763f978ce75793b1e43d9a0ce873a5878e140824aea7af730b91316cb65f4e3a0d37d8911b26cc7c344afb7de3eb4d7d36c4a40a7904b4fbbc7a3973cba2b164d8377f4158a2859527fa6973c766dee32f5cc9551ae6bc8a95deed063562e7d5857a765b05a87e643b9be395a5335cd9a1258375cdc255a3b6a1ad4d50af571a8693eeae2f9e450eb642162d80ff185a9db93a35d451b9d04c4caccf1912c4a81f233e1df8c9b45d240e85175490f23d2398f523b18e7f298fa923a9e41e05043e5fa00ac483b057a2be8e58ae20aabf7dcd3bb257dfcb8b2f6c3a70e6972782035969d15054d6532b2b04a8f30cb4db19b9059539524105e56142183ac38caaa7dbbc3560c92366911a7e290d43da6e204ebb5c251bb05c170ebd3bb7b4f5b7dc08ac28243fd764451bfb484733644b33e9a7c5e5be4f298ae8b6d97656866a80627872b74710e4e8d4f66f17471a24b9633786840eb747342d999e9607d6a77662ad75e662bd7bc4d60727c48a0ef0cbad28d4e4b41cf43cf4ec264aa87ab7540e0a28b95faf118e4d27e3cc9b34e1e51cdc21e6b1a58116e8f80539d78e1c41fcad3433e1badddfa0f9e0e2e3edc45bca073f4fdd8b07374d45eb15b46b2b5aa740c8e1327ead762b7d33f1dbb996ffb7dbf9d77697c7dde15f506c11c08bcb40f2d9e92f6597d66a39dd3a643a582aa1568e3c7c4e8eb415f0c1004d9b371cc8c537050842b9fb504353a1e0bd997ee3c00a9eb3a0eec41e77e3e9f9ffb5972e8e120d5096177c2119f9fb2df679d1b8cb46ad90d702769f91cdc694605537f894890c6e64736f2cc6805b997576305096737ee41136070d7c9ee2c7c9511c6a321ec1cd08b1d704e8ee79ed700651d2bf6ea0d0fb6c47c3ff2e2643c11b6012da028914ba85ccea50226348489b25efbb2de70281c19bdac7a47ae2c0b9259cd65e1a4dbe45918a9742e97a63dae0041595f4c41a0a9904e6e73960963a37a44a6affc01f6eb918cbb1abe929cba46910893e9a2a3d1599cb3e9b1b6f37a308eda2c64cca9e18625a15d221579b667c9542975cd322a2108850a3b0d86113e1bee79159528cbe02b455803cdcc437601603e660092a415dd3e9d63b118aa9a59832e7eced7abb2860ad2c0c02927cab0bc3f250999eab8288a6c52903433e96c5ab4ee1c275c43154b7435e1f303e80bdef5da7c5152318f05b084d8e795624eab57b6196c915a5ab8b42c9ebb2132b16118a427275812e2cd8b87b74666e6b0afd4556d9fbd2755c71ced1075868e0c6ad9b99542ad68399a03873ce69af725a4d2538d9268841f23a125ad53483a8a3a5bcf4bc79963507a3e96b157852647dbb6e6ab1cc55570c2f3a1e0b5bc3a490186c909e7180fcd6a2ce8d668cd7cd2d993d1e3851e9bb39d44460a128607245dad50887d710f315fe418072303297108eea655123528fc007b7c40471d49a52e76badb7539e907f7c061447199ba59896ea1183e31cdc989394fec339acc9152bb01369ff361828ee1515e072653e209d7e7ba53b9b666e89577f080bec386389ec568a9843a3e586e4c6b25e301cb5d534e04c1aff99d8844877896d7d089a91635fa62ae96f856b88c86c551ac720a1489255f4e21c30fcf26cc8f33929cce7a0d1edc14cda79369c5575692cec2ed742371f550c70a044b660f0d01b448e5e988bf3005b902a98a85fb236cbfb89f98fb7b3025acb087f70f9c5dd97ab46c2c3c4171c19d4a34ea48f15114cbe9c851bc715dcf859e5606a49693938e69cd37d22a61bed64847a0bdf1e9f982df91c6bd1cf0f9491a8e77ebd5336c95f7b8356a1b1b73e8885f73725d389b2422e1703a71a91125f2ace5793f9fc55870fbb8a381016ca2308e3b9b7b6aa330b521af6a3708cac5ac6c9e54df6548664039d687181a401970a0c35c1d684aeb85907204f09000290cf29898296cab36b6a9931d7f3fdf9bf3953d944f00cf3c13ba34c6e4c2aaf4ac6f595dac057523bdfb784cd7ae0a6ef9c5f5da7036fd472612d6e37c1f673a431237bdf4d000e4b735a772970349b63b9a74d8a5d482b0086f239a706321d435cceaccc4488a9e6cdf7a927909ea2502acc9cccbcff0d4030de275b2142cfe7534f0aa9e0be87832d413a21b73edfa46a7a68cc35cf4a50440203d1f8baeb8b10efa3c30eec2256882216c8132608541440e4468f88034f072c7f9d68c0351203a77a1faa012bdb97b9a2e6b96b315cf722305d29a3a8e737055383e346279ebf9071174a7fc80d64d9404277746b085c2f9e1543ecf33b8ebe919e0fb1449081cc741fcd79ee966ff0e3d356247063c1bdcf475f21c1ef06d6bfd8573c4ca22ec1566a5cc74c4ae6aca91a2472c2d32b6e2a33273b1cd26d322332b4b429ed6bd18938c2c1ebccecdf35931fba579f2847b51898b806805a90e05c745b6181e6f47f63ebaf7f938b2d3f532d18847229ad13aa0334b5cd06983409af721d7bc79959f203ed450dbd4e9856e9ef64aeac5d915d499928755ccfaa6a9fa2e3be5a4901eed53000074d6dfaed20101b856973cdd9149415683bb29cc4fd70b3595160530a5b280f44fd99145dc2b68ac1457d1d7a7505ca8bb4f975577103443d1b30034b033562b8bde1d8ef3723e945620e802498ca036c670852730c5b323d62c76e160ee643c08a531a23b9228cc425dd9d29f542b55ba46093acf54c7c1e728e0288ac29c54f055750fd24502908bb93e1f252433677e8545743af5c7c5060e0b05c006acf0b3a25daf95d6f4ead9af666c4ca5b639ea0729bb3c1df571e76e18eeeb4f9fbc9d2fbd6f07b1e71b983bde9fd8158d5c863ca5be7d7908b23e07c391ebba1b6aa4f5913925f3b00e0419c4f08d159f20914197e6698698d45d86f62006839fd847a52910498f72d13aa7afe7339e70f0e89a62d3d3ea4d4f093c55f19f9c81feedfc72bcf814b8bdf6a583b44551bd6ea28c081222ae7226fe55e7719c5309b18980f9b1f7d66d639a9ff7a0ee67b6c89aa511a2592a5a86c9aa89f25a61191689ca5af9b37edfda265f7bb97dea9794880ffdbedb96aa4f1449efb4eccf46e3df9e8de6be36673edb6b86ab386e9896a9ea206f14eed767a57dfb32440cfd741dbefd391f3ed15b7fa257e8fe88de365850c0b5fb34ac8af731fbef9ecffee97c0c51c309a3d9aed0ed97fc39f6dec5fd37e7f3be1fd8f9b61f3864b05eac8925808932acb5d673e45fe229f19984fb46c38e81bfc637f15317b2447edac3fc6b7d699ffac291eb1fee87feb53ebd4f5d52973feef3bb3dd66f7678fd61bfb62cba47c923b7b8c7c51b1cbf4a3ff62daa44854bbff20c3f194018b09fd3ed10b26b9783096b69586b65f89e37bdcf6ffec16781674ac9a8ed5231af388e2f1fe407e046c7ffcafc34c6aa5cc7ea224a1b2308ed02882e3c872b24fdcfc6bf8a0c78114895c371767f56c6f834be0f88ffccf8265cae1163f53fc47fe0a6db29aa3a16e033d6103165ee3adaf8e7bc22aeb2abdfc20d5419d7c5f1edc3475e85ca3f41eb9b4f7fb735e987773ba42c0b53cf6d9c6bbefd163ed87b8f533433fd42bc01fcfa98a84f070436dd709ce4d809c705fcd39812fb2b310e500e21aca50133ff0d7d24297e19f3e3a60a0cb0e963f999c748f72b3c3618acf6be7b7ee1a7f647d05378062372c2f1654e709cbc7cb2bf5c477ec5fee47dcee5fbf8fc6e837f3ef63cae4075de7c4eb4d9f815f934b6b636bf32b6ea3a5aa33af2ead9601630d6c253f3e84274a731e51ab17cebd6d60fe787fe941e2eba08e8e5484c380e27088e93d3277a827cfa87e8f9d371d98e7449b8d903eba9c0f1abfb695c02507f65dc9fc6d03a430fdedfd6bb136e60e98eb564c2e338be7ed23b4bfe251cb4dee929e431a8bcd683adc575be3f47fae7b67690e25cf1a8cdef74d484e362f2d1d668c9507fc1d6c0af3a48c78c95473fc3b53ff77111fef1dfb5b47ff939a29fe3fce4d13474dc709ede7ee1c74ffc75bd5f1f03a0b3ddd7d932f0b773a49ff3db1fc2447b20148e5f950d68f44f78ca4ef6aff0fb95bf116e2d036145e711fd43dcf4a196298f41ed957fdb2f5fcf81e19bd68e8321f9537e69d6fddf73cef9cff97533b27b494d048e93e7cdf3c9d3277ed9ee3ffa9cf72ff305ff7066e46b6fc08f7a1465ffaa73967f8a571fcf76a38a4f7875a8c27fd5596e7f728ed3cfe5f4f1dc29f5935e33b1ff2b71c29f3f8f4f789bac8ab7da7c2dfd294d67c238c1d8eecff74712f54fd8c62441f29f38fbeae7f4218271d696fd7d7de3e6872cfc936e83e13f4fdfd575e452b7d1d5b3d1d577b436aa2c63f3cf4115fdf49d7d3fd5bf8fef28dedfa9f2a3fe358ef94feb9ffe2bcf92ffdc4685c47f8ed57e59b0efe79afd60a3768afdf3ef8101db109637debdd3488455f40bf49167e00a318ffd0c9170a34ffc449ff3f8d7bda7a6a061d7e1cb9fbf3fede7faa84f824d5f804d1f771bd63edb7094fcf336fca7ef8bfca9eee18fa48c04738b595b55c271ea73ac066fa9d1bff59d733fe719fd505d0076b7cb6acba73fe31e5b66ffba776cbed96df8a7347d7c578afed9670ad9bf4e8e7f3f96dc7ac0446edd26cffdd7c757088a2a3135bf94fffca93cff1e391aebfa00c22de6b95a3bc67dce73c3e2d7e3b23fe2991554bf72a6cf1fc8f5c31e46f993bfa0e3f29fd6b53fc5308e8b23fc34b938ce36ea4fe3204728ff8e987d1fd3a37ec4b23f8f83708c336fceebd2c4f16bf34977c6d32fe58bbbeebcf1bff8a043b75f894d3faecde89fe4c11e9ebf6e67fff09ae14ff92460d0e929f09b79f1c98699e1273e1d45ead7f9f4b37ad6afd14613afb86bc4c90b4ea41c8edf1e6f79eefff93f5f7efbd2facfb8eebffcfe7fbfdc8ae4cbef5fbefcf645f6ab78fbf4bffffbdb97a2f6fb6c8cff1ac5e3b1a8ffd2964392d57fb90f75f8fbb18fabb6f4fbb83b3e06ff590cdd312c9b218ac7b8eebbe35fabb13e4e4fbf6de3e7b1f2c7b8fecbdbd55fdb67d3c6cf3e8bbb6ddcacbe37dbff51dcfb59b97f55bf28f8c356bf7de9b235fef23b045e7efb523551fce5770402f68fffd3677b5b0880c0bf80e05f40c000b1df61e47710f92b743e01e7130a217f01d0df01e0cb6f5fb2ee7fa2ecf9e5f7bb5f76f16f5fba651ffe1a8f5f7e3f212888fef685ab9b2fbf5f9033084018f6db17b9cceae2cbefe06f5fa47d5818062f97dfbe9859f4e5771000c0dfbe30df3e3afff33fad1f015f7e077efba2455ba7c06f5ff46f941365f19a070260a7edb2098beecbef97dfbee07d566d94e871f8e577f0049f500cb8a0c86f5fe46efb06c350103e6318fcbfbf7d91fefcd6af73fedfdfbe90bf7eabf33fff33d44317475f7eff7f80df80df80fff77f377548e3e7cea08d675f8e6953c5c73cae8bacee8e53f32cbad60fe363981ddfd4e62f7596a47db9fc25ccfef2a3f67c50a663d4849b58b9aa6d9efdcdefd31f54f1edafd7267c7d6df8cf24ee5f9fb5a679fb24f97d987ef9bd1ecaf2b72f7aef97f157c1ee575aec774dfdba9769e8acdcf4ef75f76bdcaf97d7b8fdfad988bbfec3dddb571f5a484d346ce3fddf2f6fc4ffb1e1ec9466f597dffbe710fff6afe7e53e3ba989fec5124a9abf564db4776ec5cf2edb3909fe153ced38d1eeb37e07913f9dfc9b4cff25f0f1bfbf7d89fcdefff2fb17ef43d9d372f8ee66a740c412ab925db614710a16f40dfed177c81d5eeee1e522a50cfbb9ebfcea3ec0b7f69755ccdd41fa06ddfdfb129eb42090984bbd5b958358b76d88b75f5dcd3f48531b2cd89f2c155e26313707f9ebd222f8cdb519f820eb0824566d1a26cdbf15ee350abf4ad45fabe8cf21fddb6def180e62a7ff0c889fcea7cb0506907f1d88bf48ff2f8aff17c5ff8be27f0b15be2135b7104c64a3f96b832f31bd07de64d23a9e3de70104961cab8d1c5b8e91c3254165c11c4d83aec33f23474abcda1a5c784f109290e547bfb2f288a404b2d41adf919210a2fb90994b8e2596006a4b175613770b8e19ba0d6a29717562f56db40e18f3fbbe4e1c43545fe9aaa541fbf6b7e1bbfb1ac1c63bb2d61a4fffeefe8c78448e0c702c5f46acb56ce3f88eb6720cbd78b0d57b360a884923708b94180c96bbf694784e5abaf0cb5b910598fa909984b0b5783a01f80c0d700c21b88e9772576ae66899d2213cd9e6e7dbe81a3174173056b1f569319724dc17fed5644b66b72480635e8b81015b24616d0d1c830f220442411d26a163a561d583e1da169ee32562d29a3e636e3c7a256124b1f5bf44ac94f8ac068424b17a0e0f790e976c092bc7d060c46cde466bdfc788201ad83c66b810550073890ba5695045dbf5e865c41ac0d6e242fb1885a723826ebb4908616058c925c7c8a3b78fffb50de07f77cdb1511b3053e256e62eef90a16bd7d14a8f2480602196c846874d9e1c2b9761ed95618624baa326ae3dafc1426c09d3102e44e1d93ce841511b54611232d8129144221bf824dbb8104297c463ac2cb2a37a9f27440f1cc3971c4303d1ee95ad8263ca8a63d0d2b3b7b1914ddf468ee5c12023006f93fd9ff03c62ac3562f0814c9a9c5b8817bf190f0c2a39e12859d2d546d01db50e1762f1ec3db12b83eaeb1c576f9b0fe5594621dfcdc262754b36cdb24c38c61aa2aa5c0208dd758c63bd34accad4ade6524cdac46588d567ac2e2089d585f936645581dbc67088ceb5e592639151acf83484d2c55d882cd609749315c7ca8d67cf1dc7f239c7786dc0983fb663b4d185fa32ccd02d3a7904503a780cb6cb2a629224b63130ccb6b9446d086b4bacb665cc12e3a6a35a69292a88e99a19f126a8e9b6011601243f3d871b7cfb32fa15d60495367a6a5bba503a7224fff7b7d5b9e49623c93dbb0c6e45affe360f7ce3072e9099b4c9808cecb2f39872f0a6cd86d2365c88fcbd28c3313ce8db73112ec44d058ac4b7c1d483ccc4abb085633fda3e22901591b85f7926e761554e11deeef7bcf7c5917bf5e2f3cf42643b2d24f1701d4ed8b1e6eb77782fdaaff6de8e8534e03b5ec99152e2d6561b30eab7ef18be0d2a7ae3f5f7f3d4dfed83dcedbc5c377b7b5b20d9f5f4dddebec7d560c7a8b98b75a20d3222dddbd45aeadb6819262db81f5cf8d6ee9d372ecc976f7699ba15066d76ee3244124269b9d96f08c98bef1000596d7a2fed63ef7cc3775ccc394a2b43661e63fbe732091702f637febef393d9b1aad87432808b2462d2927bd9d48ea91c530e1173495c68064358db70e16fc8e96d7c1dcf3986ee364cd8320a0f8acab0fecaef7d4e6f76fcbd1f6b83dadbecff85e7494b050b3104b0baeb8c0759c0cba7c9e5863b96c54b2e4940aec3b7aecd771be6076ffc0c2b0c8c18330920f7dd8e7ed4b5b21c239da8374cd8e7ccf263e4689bfc518ef1c68099c7e8259fafbcfb232c78d3b536a8bcf1075930b26516d31ff16bfb1bb6fb866b338ad00bf77c065ba36b8348d76412a7368f1cbee34810e248edbccdf7ae132199e18968260957ecfa5406b5da5b6c397946bb65339d6fcbe96b9ed82384b081cb7e68538a665928399571f4247024deeb249ea990d99b6fbe44a9e42e80ad42b42d68f7b9b685b83638058cf9a9cddbb885e7b8830fa1dbb890a7a365ccbcc50f1fc7b6e4c9b365c873f87593b192538344728983370947820547f26787e47bcf9157d78e4a87e44e1c3d653c99c23e83a5815db40ec9630ec9653fea7d6a5a34d17a6af3737b292dddb8824dc46ad39635bed96613c032a0e4c9a45cf191acb6ac124f44c74d78b6b7cc62c65ef325ae0184023b2f2c0d0d19f3e43ac414bc36bf6db63efab5bce9ef3ed78d2fbaad9e24fddbf52ff0f6c5036ae3d16b0c8fb120b1ea07775ff03407cf49d3c021363dffd62f4c942eec95612deff197a423d31bcd5f7978d3d52682d2d1b5c15678c3b57f67165bf975768fbbfeaf8b5f957fab38f9fdad5fb3d913fc9f4c66d17f6132bb51fedf5cf6bfb9ec7f73d95fc1866ff9ec2b2ed0b618e1b4619bf7bed1f7daecb956acef317216c01bce62956bd3ab68b750a083af188fb116a57627314f0679c351a68502e31f6dfbe6c7feacbdf33597eedf63c7ef62cc5394e38342220099fc7b1788aab19efe06c46e777c45560038615fb115837f015bcfc0f97402ff41683dfd0c5aa113f88f40eb8bf43f005708f9d7a2eb6bd6c0afa0ebb75bff8baeff45d7ff7fd175b3f5ef8b84d4b82fa1c07243665222ea40ff6fff519b9ca3e6d685ac2184ace295b0edc93ef1b63493981056456c948695996815060695f696b0e08d6ac98ca013db776598116350ed459331cc883e80f9f22d895e7c9b0723065b38e67d2c3371ed68f1ec57a1305c9084a3e5f255083413a3c04cdd94e9ef0a3185efec27a165d12be1867d476b365a7d474a22085bfcf7429cad15fe1ee8a36940be12bdb0025f346f492ccb971e442f7b21644b1861020dabb2f6593509e068d8931da69cc40c4fac2dd9a46843cbf644ad0c6af9ad5857aedfd1b625b268009b4964a37bd1227ab57b5b4223a4f7b62249d8efc91477e50689c49bedde4dde5cf195379960747b22cc31601aebafa43a72e4f27dbe5e556e8945f9dad5ac26be8decc5cc70e3af8de6de26d7b7c2d48b96af7d0f1c49781bad814da31c83657b91f8ade011b2c59e847f6893b88e2a705393efc51b664fbc4ee282c1111c0e5f970eab7d67c7777cc2a44d864629d3a2c10d12dee4db3c2d1bedb664679343e8586d5859c52b91a7a79d7e88ceb6042b606898db7586aec3ca7a2f0c6eb4c2615502be8dd622becd531ebd5adb771f728cb617df5efab6e9b3356c01c39b4e7f9503b7cbefc3bd0c36700c3dbc64411b1c551a5c4690aa25f3e6322516509a3a8559164938aac5ebaa899aba69191c85e91c25df8c42e32daabc19a59418809ba826ea6d7de940a968e494787609f81b2d8c8584dbdc6129d9f4d5df13cab2f4c80f36c094b967a3aba7bff4fa5d4fc22d8984cacab7a58d4783075baf421d846d89fa5b619828c3ea6de72884ae6f85a3ceb7c136625e059b7093e71ff047dcec84fc0fe08f0e08ff59ac7b2d3173b40cb80e0f70b43571149f468cdc7c2bf6bcf4d4acac39b2cbc5b3d54433517b2f34ef01ef1fd3bbeb0e4908aae5110e90de0cd34c449de802e8bdc8b32f0ea41cd552fa4234fbc2cfa687c96bccf75d7aae3d7d3fa6c02df81fcf89c413c3e0ef3a85c99a8ef76f45f9b78220566d18f25a568f568ef9f6849a47fe38fede8f49db9a89de0d9030cd05ef39763f71b2f79c3dd84f42865e3ff889d7820dedc91c1b359e8dec45ce603f8d96783d2df6d6374712a55885c3de96d14ab7b6eaaff2604a2084accecba61de75e7c7c158b43c802380a24acc2521c00532d5ac2442b7d2d6e2c786fb33c18546d11c1f82962f934a8e5298079e0666b8003cb7bd13e22e7f7051d2cd6e73572e4c9b3d1e2e614dde62fc2ca5ac31540a42b3ebdc950562d8f364accd081527540feca9140e25573eabdf07ef347fba2c3ce6f5bdb175936ec7c6d57401777212adf9ecbddcefe53b6549515477789e8340997699fe790111177ed762c099246e048a2f53222e048b0e248ac8c1869fc8efeefefdd652166f8e8395afebe5523aca4ad8fca573ff6c5152f7dbc0cdffae31247c7cfbbded888f0922fb2d1c91900488befdb426a3ee7b6f118af2593f6d5f742dccc855843c6ca7ddb6bdd85582387d8e5bcf9697eb3938cb8078eb546f4e5b570f65e8066ac769b43981140585be5cba77869c06e38d7e6b11dc1be8d605e457721649ec94a4bc33a6a831cac5c7b5e3da31302bb1c3c387cbf4770217af5743c73596b706db074c90dc791bdf8689b91a39bc843d089af7d472c0f7a3a7e56a626e12890378ac811b22279ef77ffbbd19db7645a63e82582ca61fbbbf7f6f9e6684b649b6f3c93126b8b05480c0c616e0c9832db175617ecb1d9a203a563609b896fbbc976eddbf36b718c24c69d0f75d486fbc20edd052491b9b6fcdcf94462926ff38bebf0a808b4695451a3ce60bda736ef8b3686b7f5cb6a40c84a9bff2fbc4d5e0c36ed4fa1ed455673d8e210119a5bb7e6d3b0deb7efe4224ca7db8f6450b04462777f8f9392c167b53ec05ffd6ff4da0bdec7199ef1544b5805fd86695ce2183feae177ba86702437468ebcec635616e2d9d2e85734e45ad80bdf322252f698cd1a36febee38ae7a4bbfe70df8f650099fba77cb512ee1b0de5a643bfd2a7087ce387bed1a663dc4edbb7be363d7ff551152f395fbb335959ab6b4b1fedfa7bff927134907c3fbf773e865f6d352a835a1b83055c3c7b2edd4d773eb4f9e0b33097d9e5dfbb10367855596ff8e5d77c29da2f1eec459faa10b69f8f982395d86ecf1fb066d3db3df60e21ac8baa2dbe2b071fde7c295e4824d1bb4eb1dbadab6f710afad2c937dfc5c352e2bfeb224de8da0a64fc15cfc857bf49f0161fbec5e5e36b21767e5be020d6d806f73ec3cdfed8a8d97079a7d94e369a55b308dff95804d34b0e012b612e33af1c09761e8967fc36eec2276ffcdafbbbd94419b3c4b2e15dc04a19776d127e411ea281240e990c4239b53c19bdb7d974f6dbfddbfc172e5132bc1617e4c12ff88123379b72c7a0b6bae0fa49e7373a312ed35efc79fbdedb304afd704fb5f9277ec7a66d2c93e659aec2479e99dba0eab2377a5e3ac7687bdeb67d17421b566ff91387b92c017bfba2ea77f18501261e532ec11613e8df78222ec8f0551636fdf474a28d48a28a5e0baa7364d3dd86db9ead6e18f955476e3691efbca580e5ab3e936ec57d37b60ba99b8cd6cd37785bac92719b7de4dce60b98cb86852fdf6b705b9e927cd7d74b3f3369cb5b178e92510f8eda20db6271748db67c8125d288495f9b565e0bbf965194eeae435bce4812d9eb69bb2d5f45d18849f7b1f69c93c1c02deff1f0b6f532bc70e1b2deb0fa079ddf750cf96c17a45bbdc9e0075ec47634b95b5e4b027d64a36dfc81372efe439f9f7080cfdc1776fc803f60b2d1166e713f89f7a2630dbe937c6affa1efab41d18609128445251ffa9625d5920d93a24dfdfab1ef8d9f4922ea201854e586cd850acc8409caaa6a691c57e11f6402b64115c1e286a5b50c6e7cdefb62a5e495cf9503475b8a6e25fba27260d300c7f0e5bec0ac1369506f39d51e6bb65b5e1ec0d6be7165c72452ebb75c285abe8f39769f316c747d8b99f7b8a4e2dfece99bae6fbe20fda49fca424c11a4b62ec9fdd09f5ed0b66afd54c63f602b57e1cd9b4effc0ffeffbfd09ae7e94f5f773dafd93f6b6b96a5f5cdf68df714e6eb81dcbe9fc8dde77bfb9d3bcfb4973f3993218317bdefd2eeb84d3b7fbf8dda78519117299f6791c6b7a611e38353688248ede86821e255c86631cc90fc1f213dfbd6ff8a1dff02f99057d97dd5ee3f83e5ee1187ae55819706db4701dfe959fd3f21830f4b2d99f64e0efbe6befcfd8fa5bc12482d2d6859224acacd4dbf1aeff1e7f038ea41277cfc1b98dafdfdabe61b143a6819311d18edd109edc743c0baacb079ee35f63169e798b17b38fb1ed3ee6ceb33d8eda64b2e15785a65b7ce6fc94ff56c85578f67d4cf113196df89e7be43799ecfd6fb278c74e12ef4d067fc541b6f4ad3fc6dae3d78ff47dd61dbe74ed373fb3c5f3f494f12f3d7a7fdbc22e2387e4939fc530fff4bc5f63ed31d2f73ef6d56e8f6fbfea9d986d3a8765be8dd42efe75fc1f6dee7b3ee99cf0a7f1da0f71d836a7570ef293f8f46a98ea1fc65fc14fe2d89fc45ddfc7b13f608808b58ba763ab4fbee2cfcff1d43e879ca34ad2d0a3f5ada6300619416c78b9e5d1e196276d39711595dfd705de372dbe3610fd2087f5ab0cbecd11fb803fe31e0bc27223427b9cf81e4ffc180fff49fbbdcefd63dbb758e43bfdfcbe7d45c03e53e6fe9b5ebd61d947d9a43ff0d194658dfc987312ef1bece8b0e6c7306f921f707b8f1fd1312289c2b3bd36d86b93f218d67ce9c25a17eb48c65d914adaf3d357fcc1657862ed1b3de921a830e01b3fcde4073df9d60ef11d3591fe58afbef74b3fa3dd71dfea7c4af663adc9b351c877f831a8c032a8d524aae8c5b75ff5d40d3377faf60d594846567b7efde6e7a39b59cc940962926a598a0aa4b4998363b83ff98b159e9da691230d213397316badef4fdb4510b6048cb68ad59c4636baf9de452cbe7dde378db1dab2c56ee1ab76bec5a51b2fc7b02e9210def25a19d86331c65b0208d837bcba90b5860b010730ffdceb539595470cb6c4af4d63afbacadb13821ccb8f01bc6ff2acf63722903f8e1141e5169b0c81e30d1c2b836ef5437f6f1beed0d5b7b572af457fbf89badaf2fc1ffa13fe3ff6deb4c9555c5917fe2b37fa6beddb663065f346dc0f061b0cb6290366dc71e206830b306228636ce35fff86c4e0a18655bd7aedd5f79ca023dcab8044a4a454662af5a46427a0b4b926f504d0119c4f419f78c1c6c1f67417077986b2b882fd0865fbd636b4b2036a7fa9e997936d48b99d8036d69dc079b2d9c45a4c420c3d4287be79d4d93d53c1bd6418ace4365e02ffede8682192cf483fcffdc7eb6e0e24440a09f917a249b856e15cc4abe58e578e0f3a2a86f5f109e4831f97094eb81fea24a66b93b55a977dd5eb22b4b7fbbb315ffb04a8af2d533cfa088c8ae6700b39d6198dc5862f9b1529b021d46d1b9738875e022ec274765ae2d2c932c5dd42be8f21209f6d7e40df7efd387e809e75f38fba7d8ecb68d8f8614af0018fc04de47a7d84a02b87e02a97d44b7b729d435dc7a8106fbbfe126921c869341678e9e82652e8f37a69990a1c0fa1cb9fd05cd886e393b0e0fc17c9379b34b41c5d20106a15e4c2bc7817675b7d503fdb9032b79a44221b625e343978d52435f9612ab05e20569371f35edec5d9526cc1c622a361faab3203eadaf854f6022192336feec70b550c1e7c5456d625cec414518b1e786a75dea668fdff1d0202feeedf29db09337d08dbdf23503c1e8eb31001482b26f44de508e7188e21c17b14ecd77617b97a5d05c5bcdfa79d2579e8454ce225f4a18d692fd15a8a5259c6695103e0a16de10a97a749af62ee00c54d8a5b704d714373d12e51a45e73e4b05a3785b995004ce0a5cc36a43de20bce935a30b4cac496a984680de79f68e36ab5b8894145e2ec2a57cb8a3af8c95db6f7276df95ea69b322371861b1be0bfeab1aeca31bd817672ad36b1dd0f7cf4762cd46bd77250ebaddb6cf8773b83964ec2555d7c258917b73196bfcb874cd0b8cb2ba58880d2a0b41bdb74bb5bc1fb9447eacd3285e29d3cf20013d861b98c1a9f168ee57b9d5dcf7575fb45c76955d199b5ae8bab0f63a27c1e7a40afdc29d6d54d8b757983ebea86fd4529991d9ff7f310d8de2855541511e8d7bb64c72529028f6fd70f868febccf57776c2d131c6c7af76795db1437cb9b33ee0196b78466d1b3dea7b388f847e93aad99bb50a6d673dcf14f803d8aa0c611967dcde1481cd8fbb7ab4eb0222a2416b02c162deed54a77bc929bf6be7b91dba731d08bb22b0a08f6914c1cba5b8999f48a1d5c4236d9e2e6db5d6dd72cc6d149d9ea97a6b87bf9667ef761785aaed835a770b9122e931659ab8cd69b1b8d63038b7c2827acde22339697c97f8511691fff62cb070ae85eafabe4dbb5d03611b20df87beb71be3ef8e85e82ae7d7d8db3b5eaf6dbfb04c11edd8f81867bbc6aefcdc4d94a34fae904fd4b6a79a70958668c45b9fe0da8637c9254b13fa063ef0d91fc572ff46fb376b0fcd5c80473e08f46708bdd1059d6da9efdd7db3d50f930fd65c1a7da64b9c16534c1b537c9d9fded168dd9c41fe302ed2fe9ab640b10324f3ac102cb5f127ed2bdcc625deadad34fd899240966a9d1cb034f58b6d0af407bcdfd030a1474ad0bf8cd76adbd60ca3e192b9c1c559135740fa478826874d85fcc17772f3713b32c0fd40062c12d6f5b7cb409380722703f5bd7f50069ab638b89fb56bf4201f86f56339e025dc4b4e28ceec117a25b06dfbe91b45175f640de75ea28ffa1a47bef9077a287a9403fbb1cd3e5c6ff9757d6819e7a2d6a36268115056c681dfac6dd46b8635eec025fdd2e5e9d0be1f2f37b1b72e7e36453b2b5db01ff9608fbbfaceba6f34fed8354ed325f0f12e290472a377972c7381f36c14776de2f7907f1dca60edef262e291e2c13cea9f5046103116e83aad753ea38e56d7dbed6eb37314619ed98b4a22d5ea26cb25b7fb8aea3743c4cda1866dd2edd5adee47eddf57e7d195ce38e75cce3b3f5e43b595027f5fad8df6af76f7cef8ed7cecf33145d6437b8c4a138fc1c61073e9803bf2ba79dbb064b9541bbab39c619f5cfa6c67098adce56789a7413847b69ecb11ddef9a18fbf079d73f3db0933e9e89a4ceef2d7f95023eff5ce60a78ff95dbc8b978ab91bd5b152ab42b1fd5bf98816f263390f63e6837effd2cfc26a3febba13f2473b8eafbed48df56f156857cc549d987adbbe9ff4d7cfce431e7fedbc4460b15b3ebea3138265342c854ff8bb1f4fb7bfe021ce8962f7f55a850af5bf7412d8c7b1f2353f48f61bec9ac6896b35d6a77a3df660dffdb8efaff6bc8d29ff637367a162b836ce649b2186765135e8f21f8c992caeeb240d0e0f67d40d9673325efbee2866a42aa3b60fd0b8d11451db65877bff5ea4db98d15fb1978d8c7ed5c728ae74875f84768f0d772e41ed2c53796d636c37b838598be985a2495ac76f3bff2072c25529f86ee2185eb450afdfaeb191c287b8028ff4f31a4bdae00ae6ca51e0aef38a0fd6b0af9b39d4989b45bda6d894b9fb3558824fe638d77292c94fad657fcbe6de8df5dae65ed7c76eb004ecfd3afc2d6ee09bf5b9c32c3ce019bee8f387f5ffcf65ec9bf5fd7c8cdce21fb4b978f41310db2a130aac78f1d10efe282fe1d936e44898fb61b3de51d9a65239864eb4d870193b8bf5462bd0cf0a439fad370a80e536b910757e042f1e21af377e189aa3b8095d2ef51bb9bcd998c5ab86dd3892317c6662677113ebafb22eced198eab0b8d27a13dba2524d629915deeb084c92148e5ea91ac59918a72af86ac1025f9575465674f17533e3f44d2c098a2ed068fbafa4cd97e8b607bbdadaf8d1d6e2a1630c176c8df7ebf01190df36895dbcc70cb749ebb54fd1f4e1b774c13762114da27db4d4949677843d443ab1c59398189c631c9406d3b64c70dc9d2bf9c6a063df3803adddd86776b33eb5c1e22df6b93ca1b50d542f65a4e322a3710ca7819b35bc140b3ee8af489c4da2df91ecf8a7f7a3ddd13aaa36e9f1f9191bfdc69cc7d1afcb79ac39ff24e5117fee531efb94c73ee5b119edd7b4479913b98dfa497acb2ffeb131a32a1a764dad32e43acc729faeb771091bf3090409ad436b4dca94c0868c8659799736c5d3a52de7132dd6a53aad00afa1a2045db63b73baa410b8d754aed0264560d787925c96d124d0081d34cb8a2f1b5c11654cabd3fbba721f53dabab4befc0a9140cbe5a1cd2b394a334ab84280ee6ee36ed6fbadd575f7123db54cb109d94b476f0e2ac7f0339f65e0f41578a99439e6a414d87acf2e5997f86bdaa67eb94b416c796cf7aebba682d66e4ab36473934a58085cb7ff49b08a8627810d21eda29183e89af626e42f4d5a659daa886039b847686dddd132b9c0eb438bd04f3e8b964c772e81d2e9423791405be71a02f29856370c040ef18ca0e72e216296014a819fc1fe3b6d5594aaf5988a17fa93bace6dd9682adeee0b44faa45f3dee6a7a6dbb257616654c7fd130ed00ebde94d1d49dd1dde48cd202bd9bd4332b8d836eff9a7adfa4c232bda04e754529b4753a160f4a61ee5728f535f18aaebf6fd2776f778c45b27f97ae7a4df744fdfb400bfbcb32865d3fc9fa2a50f5552420f7186c962c63aaba226c705d13389fd180c86c80222afa2ad8e0422063f48b32039aaad12f5ac5ac95886136206eebbe54356ab6641900dd56c813829d2608067444cbe1265338861e3f8c999b944e34066e64e92e5da8b00c2af50d2eb5552675491b784de811ba97ae012e080e90ae9afdfeceb96b00acde2f88ba7472f4717b7563eb37a5312efe119dd94014b466df45dd9c0472c2d521df76dfa67b79566d93c31d530436cb701b6021389a7769f9ff9934c9fbb1f759ba6453fe757acb62f5fe6e66b3d75b97a637ac506ac9cdfe92025fa74f21d852fb9d6b584393b1f055d1246183d223d1de66985b4d529718a64dba59d9ee6f8642798694b9f5524ca74faca6ddbafd27e7579e9be9082bebca54e56859d6f50d4aebfce85b733f74cc7abf35a8b71c42a7a0ad708903b809310037413ae1f11b6b8d5336b06d3c9eab2c03073eaf575ec59c2c74a8ddad6dacc37d7a0c756908dce8266cd1c05d6ef5a1c06ba55d0dd1fbf51e935e273f8ea95c6ce39c2c6b5dde8d55db948387f0cdc168d34459dcf252bd741285f4a639e6255ce991687f44da9e2baf1e41ef1c42c796ed7e983b9c5ace25dc2311648bdeaa67681b2bdb942eeb4d705a4d278f6df10bd23c1b5bf8bb523d9bf696133d45e9ffc6b910ea3a3570b12604c0fa13b14e9bdfa1d4af6e3a2832fa4c124c4c9faab331d2f9224197e2299fd4e136e66827d65dfff83cc0dc669fbe9bbd5349c7a06297f416ed7371d3b52f70931a7e7a330ea22d2a4fc11af9f9901f283b2d3f8e610542a43f8e0d4ec6c2b5a80ac17a8305424297c23554083e1eb3dae26a17754c6075a41fc43acc82b623f013ae40fb8af27422b0756a6a9d4e22803a8485c294b4c00a91c086a85d84b80e87891afc579f6931301455abe975148e02421477df6ee1f628f433474bd8680f25d86ff675afc29ba5b2dae772090a205e902f348944ad0d0d484b55675eb57805846842afd5492444d0cea1fd17f78ec9a816ce54579fb2868e3536f384d26e1a1dbe649923f49d5a3fd3e5f5d432244a60a9c882bac6a01adf11f5fd1ded32910e367bd537b0df6c33cc3d5286fd57b7b57eeed27c4d92a96c15951b09bc84a0903fa2abebaf0f1d53c2ae7da27bdd78c469589fd222f05880320fc7c58fe882ecd9230eb9c7893b6d2e0236c827503eea7d074f0b3645ba97d380b8d6003ddd600ab7de4cbafed479387e506a0a86d2c85205a07487dbfd2ed13ecee2d15599934b4a17a7b611f06facdb7a60be2a84b90f904ca84ce82674bd6504d4fdcd5ebb6c8cc60eb295eea4f305e8f506a3054ed2645dd404ce66363330937545dc6043383ee8b59ce77654a7d908917e6b7bdfcbcc8cdeab31b2830b3641709fb2f937504cb17249e1f92e6542edf6fd44103ba88f9a7d3c819bdab997d0a56be8a5cf0e837564556d591adfa4a336b60d2dfddd869e6ff6f6adfddb7a7fec7730777e0cf531b2a9c85e21a87db397eee376084d19cd1263eea6120665a43dbcf4f6dd6590d7ed01ed6242576c903d6f88c3a24e8bceeb744ee827a3b178db1eba6725a034eb907e699b21e8da9607a563cadf6d5738cf6974ef18fadfd057212ce39cdbf730f73bbeefcb98d048fe6fda15e9ccffd6fdd0e8b12906e51efa7eb38f653e5bbc244d7bb7ba17412e9b7d67bbbdd46bc83af231a353e0a8145846ed522c9c8749984b8a14d4c308c270b3b77ab307ef11ed87174da27a995828afdf837ee515d26191b00e702cd473f75a97dea724b4e3b4194f251be477fed1474b139d2dc0ba7b808d012fcca8b57e672bde87914555a0d7aa1009bc7f443e9b41c50a0fe77d122627dcc5d6d016218b7a2b0edd5234a98689abfa5461b5fa3ee7377c5c9f8b72f68c20ae33041f9f39a6b050352b50f450d470a487ccfafba2d7a41334fddcd237d0a649beb3d949b90c7251892691a8a36f016187d1428478e878b75a7e63eae8cf6c944ed0e86ff396679ba0bb148bdb3abe24efbefde3b66ff861132986634dd1434ec6e99ac7abec96f64c813ef6cebf690f769723d95378506d121a6b60ca8bbb6d4f3e5c6ed53963a64feb65556d51a794dedd8ba0befaac2f613f6c625a83fda9ea9206f9fea28ec0444bf294e7a4f6619934873e5742d0b423b4f9aa6d70b17cbbfdd6aca13b650bf9c68609b3668ea4dd40f1d355a01814d2310aaf179609803dd3871ecfd5cf831ca5ac2d312b1052fd621b704c1dce02af00970707ef824502ab01a44ba24976e32f7eb0b4a3d7f206ce6f7e8295dd360768cb8d71b3e54c6e6c7468eb295ed5fcd7dbb6d1b8152d685f3e0f112f32f4a5a9b8f1230231aa75b90a6ca95b8ec1e95b3e65ed82812f9f431f7697ffb0bd354cd7aebe756d0fa05caed5075ba09f23c7a0bc1a7e41812daf45ed78d1624ed666ba0adfd776d8d73a443fa1e532f30af1f33e85eebe2bffcce81a355567baba36e8cabe8da135f0ef9b323e3c84bed591ca8c3637f1792d6bcaabae8bab7f14521ee4fc066f6556393a845e7a17ecbc9c227fbf700cfcb2ded4722bab8cb8f9bedc764ba326ff43b8772ecc94b5c0064d5a25e0e15817b55904bfddf1dec02f6bb951d63a46ad36183733715ddd4c31206ac262d1c59e186e3b5780dbc4716bdfe45cb8a41758a68eb904da6eafdd4fff0a59e4dfa5bc3cca46eb234b4d1ac10e6d0f9870c5d5d746b1df3a65875c7510c9da0e37db4975325843f03b3b3fef96cb4f5e42678e21e63ecbec1c5edf39f5dc14ce93e17808bd146dbf8359eaf06e1e23ead7256c35e654519d6437507438461ee058ed7c51ac2159514b7f0bbf6ad619d809b859c65dc8d0a6d4b4390b759371bed877dfebfcf9064a2372da8cd6b5f874e3d3df7fef93feedf8bea67c68bf38b56292ff82769abaa45ed8fc30f5d9da760bac7eafa722edf334993b486fe3775fa176488e90fc6db240d41eda886dd355e245538f934bfa68bd049d15c0e2dd01a7022b24db4adcb2412ca2f44a43dcb93c403ef25a654adbf40e2e21a2d42e8193288f5480ab522fb629973aa1473271cea1dcbfb465a0f843704069a26ce8d6eb41546a6eb267d5945e7ce35c6c4891734d06dbaa41dab5ed15c60dc42a0e9675bce6dbefdf40bce1fbf942654602182e58398ec4b90fac442a1c34afa3a65ea2c79067c7e00aaf9ad0024f01bfc28f5652a7d2b6077a2e630af82cacab82fc5f991481cdeba5cf83d0653fe3fd148895fe0ece2daa5edeb5518a45669089ac2aba9b44c79600c502738bd0659700a53fc34337e152db14fd975dbeb10d09f712806d75a682fe9945d08530c5020343fc7df81c9d9fa063cf2f4029bccbac7aa926b14fe891d5f4d7f20602aaa02d3a617ddec951ba6427e97b3de2e56ddbbeaa37293ad02f7b80f57631af14417ba34eb7dfc2786776ee26e0529fe3f3301ede8f994eb6176d8c6886520a8ef596459daeefe651ff11f852b75ef7f7214cf7db06be8322d1a29a2dd8abad6de221baa5a85a207eeddb0181d5ef62e8a27a8d372a339dd5e13b0826a8054ba386713790b577fafd2720415ffae94274f78d2b142882f57a840269016c0768df145d5437b8b85260bdd8c9b99b0bd67189c5d5cf9791ff89b64f687daefadd5719a367ca063bb7f30e3646f3823a56c54e9226be701f4753f5bb6bb1d912a1d675377312ec206a1cadcad54dfcb5e1b18bddf1f4a55d9f7d8c71dec5d9d853e012d4ce565b193b039be0765b75525a0987a1b95aedabd4b2764bcb523bd7b8c641bf138f84df5e2662e8b3e89cadc245f3f13af6d6fa6f5e22bd7a907ff6fb71ceba5ce9607faf5cc877c4eef28b4380939648327cbf8ba5cc99b0dd62d856af3168d8178fb1746dc6e91a56af1377db2cb2fed18dea98ef07b1fa661dabb3f1473712028fe7d01a501b5f6fbfa3cf7475a381175957383476d9fbf7a02fe6b3137027772a8a55a234f3252604a2a6ab5a4cab50d6959906fed370b73c4bfe3cffe8049596a805bb0dc91bb0dbb70e4ff95b60b7f1af3b3ba5e6bc07bbf560b71eecf6038d70c5baada7f4d0354e819fe8158a69edb0089d01b51b3fb1bb73b7dd83300f2fce26bf5844085c835b75b8881d165dcf206b7d860e368d4e72d666b4b4bcc8e58a1d9eeaaddaeb93973f89790c3d42eee66f123b3c2d7793723b9762216286ae712ebdcb5ffc6633c7daf278e1a6abe7ed5ccadb180ce4c3277d72997a97fafbe36a359d9c9778286d3809cec30f968a376b01d0e60a4f70aeb5e6f1a3cdeb85deb5db10837caea6a7a36bd0b16d9cbb6df5d7f0fbd373ea2534eecd40bc4eea789245e060cdd2d7fb355de8a54a6e27dcce47b4d7b3f4d62c7dffaca6efce425ba3b3d086a7a52ebdc83ab35167b4b66669e2810fd8a727db1431c7d02feba66dd67c9bf2a6574b93297cc3cfdd88ba297b55beb0c3f39aa5774d1a1ef022fce4ced15a7f79959f26ad6b7a6e61e737f4d4c932c5d035740c96bbaee70ae36b1fdef090de6df3fdd4ccbbc79dcca0a3054081624bcdd968b0fe2fa8fdbfa0e9eafbd13795d04b7ce04f87e7e52ef884af8ea6ad67374696497d7ecf32958ebe29ee6c4d475b55419f6c0d744d89b0e19aa5bf47dff279ddfaa944279593627dcc4042e3fe9cc1fdd90fbe918a009db38a7c47eae89bcac93715ce4da423f2272f5d3dcebec1550ea95f3eee7fa15c45c3cb32867338ae58b3f4d7f41dffdd3947a5c79f431f6d638a9516923f3bb448f9e018f253771e6e85b6e944e5d82a1eb904365e92df2ba395916b59d409ad7f2774e5aa543dce583cb7a754ee5654c7ff5d5d52a6b04c05a5062f13bf7249fdb4349ab1f6457d6ee4bf5ac2b6aa28de31a8d09d9e8e9ff0f3415bc1f9bd9e38a6083e1b83687c6b18be6669b45dac9d80ca563f1d87e325c9542ec900a437cc55a3bb14e0a1f9845e5a24902c830a6da23ef6e43a3e6e680800bccb355df3fefdf8e93626b6e6eb36530df9499c1f7ed8aeaf9bd3d126c5a36f32a23dbd4b091d5ffb5781cfe2edb7e440a13fd4936db9b7fa3252463fea1bc8df3bddd6f0e7a3b32ba9532da3e8ccc5fbb6984b3bd8f6eb041cd01884b24048c73bbae909da11b4f5bf6d50bbeda61d8ff7f73b5dfd48af35312484df96dff7ef6ddf4dcfb16da2f92f701389ba6997f1b50fde8d8d7bfbf461df5ce997868dbb29472d8deedcc903da923d552e9ff5cb1a6d49f19eaf4fe5ecce9682e332ede462bc24aef277437fffdd2bfdc123f0d0e5cfd5d6d00e0eaf87ee5cc9fe5fe4d349f5d23165fc0bd91eb7b285ceb97e2f6be325f1219fe30fe5ef612c3bc618da9f8bcfe2a147223d157f53362adb94b0a5c15dd0b9ea863c5e121cb447896548d843fd2f1641c33185cef2863aaebefe784c34bcded7eb2aefe3e6ace0ab5de0cfb84d80f24e97cd1b3dfb30b6ffe278f8b2ef5a5fb6fdfecfe9a70f747c0af54e97bbf0a087db2d3fd13af6d3c35607e3dbd8e4fa7dbafcd826e8d09dbf7baf958ba3659c9e6c422f6d530c7d5e3ba02d39a12e87ef4d3f4cedafcb9c52a96d50c04b38cc56f19d4b2860097d3c12e987d425b8e2037ed05842cf1a9fe90b5a38b68e9671be3c3e5bb33468b60a7edf5e77cfa8db77a10d7d27239fc9cd83ecb75b8f7de4337f3e0e50f9d77e15e787af7deecfe400ea8056e66ef5c4fb7b1fcc3bdab5b50f7c92dde9f8609befede2d55ec65bf26b9fe62bfbda62207c2463ef9e237db13525cc3670b99dd36cf52b2eec769c5f65b7c6bfa17e66a9c225fcb4f6a7dbb518e1a94efdcd2397942ecbe47cb489ee59b9e1e9746370a565f8c0db9d9a2d222838ce8a9ad6cfddc42bdd8ee6231eda7905c233c2febd4bd1856dd2ce61d011139bc77a9f8eed56b35abbae3e07c60daef351b69b6d037c1c8ebb8731ff5ebe6fe4a6d5a54ba21977d739648d31bfdccd83d0bddbb2a15fde9e6fba66e9fc5656d63cb7f37940581f8dc779e7b752efc6318fb6edbe2d171d2b712fcfa763873998c77763028e37c7b4dfc9d49abfa9e355c69af146bdd7271feb80b66e7763bbb50176c2e5ee5c0aed44fb9e3df8b563ea3bb6e13dcd0765dceae48fc6d9a3ad700c0ab30dbf6afafad0fa285fd88bbbf7617d1cc3a6beb411b5ac7fcdd3f4fcd55878d7ee7f659cbde7bd3bcf3e77519e1785b6674076bdc37952f519c22c75839d05f4b2fa90264173ca19947f9d5e9a68bb2aa487ba33841370807a6799a2ed047ec0df3faf0b6fdbfa41e7c55be2564fea705e77bf95c117fdb6241b0c837ed5237ab7f5b8fe6e2c7f5357dee9971ff9504be26b1fec23bfe2eefeed3b506fddfbb39fc6f29a67b773efd0220ea14d686533676de7660fb1156ee710484eb1adc980071bf12e8ed0dd27d0b1a3f5dcb38e3d75b6e13616b50eb2ffe87a57b1f7be5eeb8204ed3a1789b5ab5c043e1c0dc7437c88fffc6257bdeaf0d95a174d921836a4ae87590fdbb52efc793c1afdc45a17e4fe93952eec9385ae67ba5d92c229921c8e490cff9fb2d0f5b8c6f59d9512787588b2f4072b60bf96cb6631eddf7ffcf9c77f75ab69b5ecdc2fa615f0ea7ff9db7c9bfadbd4abfebfff154487b074fff4b2641064ff3b880ef01f3702a01a1ca9dbb5b77fffe181689b1efe0cb23ffef58797a5af5150fffd0a09aae2b04d9aeba609eaab3c0eb67efde77e9b674574c8f6d1b678b853d5d745b63f6cfd62db7ca51d97f757e8ddffba5907fc3764e7b03d1ffef8d71fdbfd3edb17908b045efea87a5f3e1f24dbe4b5f88c0afef37919f5d34171c8f64eb0852565fbea9e3871f6b18bb40e6ca3fd970fe1ffa33480e53cd045072fdc0210c28f42a1827ae35f7f04591e077f46e9a07212f0e791803a2543ff1b44597988c01ffffa231e177f46d9c0c9a3c4f1c228ddee2bf8197863b0df1659b9f7b67f7ca53807b020d83ee9f63028f7b0ccacf8a35e5f1c40a9400b8db09783ed39877f9429d2827547c37f0efb280de03b458524193dfeaf7651f7df7fb8e52be2dbad0edb02c95d92efb74531702f514edcde7885a2717b23b844f9edf505446e2db90707567600a2e2d0dca865c7db57f921ebfe1838f527eb0b2fca43d449cdb57ffbd02f9cebc5d6bbbff4098ac2e9773706517ad8ee53070cb6fec9d9fbc5231900517e88bceb9d30716eaebad7f74eea375dfaf8a828dd03d85e1f243e75bd80efdd5c79c39b8bdb0a14a183df5d11d4f3dd35851337d70f9f3c809b763a53187d7f35c8e3e80cc76dea657e9406377f0e9c22c56faf5da7d83e0fefee44a98386557727c8dcdbcb707b5bf8605720cddc5de768387dae33d6fbec90a52b27027078356cbbd1c12bf7c76df11ddabd13a57996816fd06e9df337a8babe8543a2e9f61fbd9379ee77a8f26d9a07f9f729e10019c4dbeab477fed25bfb24dbff05faade7877f851c044ee27cab59da37dafeffee0b5d1f3820c8f6d1214c7ee6e5ade7fdd46bd791f2dd7773c78bb7df11edf6858288efa9b749b4cf9d22f20641e617834e89165f92410dfb0d8a81b3df3b55a38e3fa73decb78f63ee238a462984db47a17c206e8dd707e6db7b0d3e7d30283c274d1fcdf52dc1218bb7e9178fabfcb11a3fe19a845b906ff7032fdc4387f29bd47906aad70880bfe7f8745459f10da2f72aea2fba50b5abf903a2ab31dc1ea3a2f6bfbf455fbb2d5f91e6a04cdc77e3ed53b281e778e1f6dbc41978d4859f1343970acd2dbf4b9fed13e7f0bd067c7cc98f5e5fffe22b4174888234dbff55fe22ff0c6bf657df4afdedf92fbe93b9bb9ff812d49e3ff35a7c0051faedb73277b7f53e1dc98fd439d4de5e061073f9cfbd35f09cdc7123101daa9f2ca088fcad5b7b91df7a7dbf3dbed7f29f93c3c9d3678af63df561efa4455ecf2bfeda0b837a66fbd7dffb2b52717d2b887ee253e1e1f0ed6ebebed5a9392f4b921f2ac50f0a28b6fbe34f74c1a028c2efcd8cbf397fbec618fef20b033f3bfcb8c9bf9aa8bf2346aec375f2f163d26f68d39ab09b9cff9834d9ee63b03deca31fb5e123f9f71bf3dd9bdf51ba1fbcd408e1ebde49fe32b369e6bf1740b77c7d75403608b7efad4d90d56aca2d5feb3fee09a2c477f651063f113c3cdab9db748b9869620283e88122de1ea3d42df7f1164af8fffdc8b2fea5a8ce7bfe1f29bac64b9cbcf84e88e85b61a46de26efd9f0c387d4c571cfcec91bf4f4253578a62bb0f22f8148e0f344812e7e085390a67de519e9df452c136ffdf4ed0a8ea0c3869f067b60f06e7413bdb06d9e935aa55cf078f3da738509f3d0b1d2f7408ecb3c770c2df0668be26b891f7680bfc4fe8af51a18f9ebe0fe07c4405dd799cc43eab52f16943144538f8aa1de1f36b9c01ddfcbfb91bfbaf5fd0c769764ac3ac99f0dd12c131750db2bd7b74ad2b5a68f88022df67e7eaf141511583ed79eb39eebb77e0a3ab839f16ceeb36dc3a8d1a79242c53147fea02a651fafae711bbbd7372f6699406c5c3ed6b643574504bc37f068e0fb67bb2bd3bf0f65e7d7140b95051529b3cf46fe7fcd7571dc7e8b23103f5a35dbe85e3fa2ef4e380bb5b5e5ede5ebe268726c4dadd4ab787c3de4121ddee5e56a0d8c7edad3c43f3c39be8e2fd2bfbed2bd87a07101dee6e17511a80ed2b8882f0eeab4555780e00a8abb6e9f1a3474d0f74f70fdbe200b2bbda3d74621bca46d3cf9f09697f42064bb94683bea42ab6871fd21c1d10f94eb31af44dca4e697c23ec5e37525207d9e13f03370aae7f2206d1df4da437a963eff09f41528243943b4844d08db7323b6cfd7c1fa507c7452a2745212338001be7b3fd13fdaf95a5ee66db59cd3d38dc5bf3fbb03e90d523b7feab2c5097364b05ef970e90b4dd2d22a03f0645951e50c0f4baa8d0fc35f0eab5a5e6ea1aac3b64090aa7bf7bd234e1bbfb4555dcad55781992e077ab16f09f6bf18d5cb7ab19fffaa34c23af9eb6377f0dcac32bfe7c7f3d469750ccfff8d71fc76dea67fbc10f0cd537a86e4cc457d4e81fa855be4bd7c6e6bf22be35995fd085b55df982e2bd35fc82f8073586a2e8a705fc25dba2a8d5f167849db007251a4c3fa46b2dd55784c42084b3e72fa8223f753e790c2d56adea3f7a8a7cd662eb95fbedc08dfc685f7eda5a8814cdd75eb37df215512ba3b0c0efd0a5b0bcff7ac8c5fc77b362fc7fa1726fd66fef3233ff7da7f0a062cc0ffb5661c097a06bfb5f7deee62fcfdd2cf6de356fb3ce8ffd4f22690609ea922f0f4a81141d9e86fa7d781a1c23706c3c1e12bf105043fd1d40cd784c5238410f7b404d0fa8e901353da0a607d4f4809a1e50d3036a7a404d0fa8e901353da0a607d4f4809a1e50d3036a7a404d0fa8e901353da0a607d4f4809a1e50d3036a7a404d0fa8e901353da0a607d4f4809a1e50d3036a7a40cdef05d4d42097df8daa19ec9ca3f335b40651b4d01a82fc9dd01a9a1ad3cf14de416bc8bf0bad81ecff34b4862028921a0ea9510fade9a1353db4a687d6f4d09a1e5ad3436b7a684d0fade9a1353db4a687d6f4d09a1e5ad3436b7a684d0fade9a1353db4a687d6f4d09a1e5ad3436b7a684d0fade9a1353db4a687d6f4d09a1e5ad3436b7a684d0fadf907a03535d2e51fc1d70c5ac440f135d2e64ad6c26d9e87bf116e838f686a44c34f36701be2efc26d60593f0fb77926486af44c603ddca687dbf4709b1e6ed3c36d7ab84d0fb7e9e1363ddca687dbf4709b1e6ed3c36d7ab84d0fb7e9e1363ddca687dbf4709b1e6ed3c36d7ab84d0fb7e9e1363ddca687dbf4709b1e6ed3c36d7ab84d0fb7e9e1363ddce69f82dbdc005ffe61e0cd806b51043fdef0e69eb485e20c89ee54a92181fd3c08e7d501c53750385487c2c15b140e49e2e3f14fa07010e79fc070c69fc070ae80199aa6707244d3e4ff1418cec0cfbce2118b7395bfe6e957689b2b44a616e60621d3f4ec3d44e616f35253773aaabeaca109f5df773aee7aebe18d5e67fd1e9df5a0333a0df687c7733b87e0525b6512dfa0763e0f8e6eba1ab1419ebb2673f45239708c71e9997ae82507dcab284877deaa140fff7d39fd906eef261ce6983658263a611b14e655d4d4e569dc9ed5d7bfa20c39d573975780b72b166ccae05672cead8ad9b93c77f12a86efea16312336c802819d04f2ccc6dd74b6807f0bf3ee9dbb72d7331af7e70cee4f87819deaa5452ab94b0c3399381f7d43e1fc442ffde95974d39ac631a8936fcab9302fea72d18fd96c4d09b30dac74491d5ba64ce51814e6f2c3aca57f39654147df7e93658ebea9c0e7c15a654adbf4820da963de5cc7163c28e1bfcb44097d7e962d542ab54d45b24de962193e58b0f17d997311f873bd7223e6e3768ba89d97e8a1cf6bb0acc8374061b361fbfdaeac57395bbccad9fff9e31fb07b429a97876f18bd1bbacee23d13bfd3e23dff428b0739ef2d5e6ff17a8bf7d3dae25be6eee41b62e118abc022cea147ae02b556cdc1b6517dde5cccfd84c36c95d9f8733177132f700dfde2c1f236c5828d90aaefca69decf162a33826af3c1ccd426830ddf97a5c6dd37eb7794cc3157e5f5f98416781c78a414da84366abe4bb766cd9beb91cb839dc049989780d2ae9847d3f0507e671a0e2dcdadba7fe09b7009100b7309f8b38e874c231568d2d21bbe1e4d20e6f0e0b24cbae7d0a47dfebd19b3f613bdf21210dbf2a7f5c25cbcfd3b78fc5e659b0aee25c340886b53b9ad8460715befdbdf952f5a8474d59537812d02113fa56235d9d76dfdee97beaadeb51f526cf14f98c797f2f03dfb784b783590cfbfd3408e7ea5817cee0d646f207b03f977f4c5cf59c87632d269de395339a60d2711c1071661f4ce4275131da8bd0fef2d58f7bcb792ff792bd9b4f5bc8804f696e6f62776bcac550fd2ddf4c7642fb0be2756dea7565624b1f45a879c6683fff37b2692ed02e70f9216af64ddf1fbcfbf316991781ee2183d1affbaa445f273d3f8e3a44512c3c9678ca6fae3f7fba4c53e69b14f5aec9316fba4c53e69b14f5aec9316fba4c53e69b14f5aec9316fba4c53e69b14f5aec9316fba4c53e69b14f5aec9316fba4c53e69b14f5aec9316fba4c53e69b14f5aec9316fba4c53e69b14f5aec9316ff11b4d715ccf2dbf315bb4f0f9c3c0791872ce19ff93ecbb7fb43f42314ce27ef5c8fedff3dc98b0d1a87fe754855c4798f54ed91aabdeefabb0ae48a57152a66ea1254e2183eee251ce6187429f076eef2da42a898bd6dc6c15a6508cb38e3b69c9f7d83ab1c52bf2c131b77538e5a26fad0e3e9ca9fe257bc6b70439732a1451c429bd04a7f0e4ef6062f6cc30f2d323e380957b129875ba6b8f7cd55e91178e8f2e76a6b680787d74377ae64cb543cbaa47cf0780e73a6d8b1bdffc3f79273ee277a699bd2656932a1cf07b4cb03c23628e091abc54d92e4c535b8c29d8b94ade2996d7085cf07a597e8a1cd83bbf76feffd0eec25b4f35feb7a44d16a767cfc1bc196e4f01927c7c3eb0911e4df055b42f67f1e6c498ec9e7218e8ffea768f71e6cd9832d7bb0650fb6ecc1963dd872d0832d7bb0650fb6ecc1963dd8b2075bf660cb1e6cd9832d7bb0650fb6ecc1963dd8b2075bf660cb1e6cd9832d7bb0650fb6ecc1963dd8b2075bf660cb1e6cd9832d7bb0e57f17c01282b0fc4e8825fce0e0c7bb7cde6def4990bf0f5a438cc6f87044fd3a600d64fee78135238a7c1e1163ac07d6f4c09a1e58d3036b7a604d0face981353db0a607d6f4c09a1e58d3036b7a604d0face981353db0a607d6f4c09a1e58d3036b7a604d0face981353db0a607d6f4c09a1e58d3036b7a604d0face981353db0a607d6fc03c09ac1fde994bf135d733d29f36b9ccd95ac05db3c63bf0f6c4393a3113ec67fdd918190f99f06db0c098c1ce13831eec1363dd8a607dbf4609b1e6cd3836d7ab04d0fb6e9c1363dd8a607dbf4609b1e6cd3836d7ab04d0fb6e9c1363dd8a607dbf4609b1e6cd3836d7ab04d0fb6e9c1363dd8a607dbf4609b1e6cd3836d7ab04d0fb6e9c136ff14d8e606f6f20fc36e065cf31794923f7fbce1cd7bf2ee6029821cfe8e33036b300ef1eb4e0cac19ef8f0cec8f0cec75d7dfd51dd723033d9edb390497da2a733df22f5d8dd820cf5d93397aa91c38c6b8bc39620fd29db72ab577130e734c1b2c139db00d0af32a6aeaf2346ecfea6b39d573975780b72b168e819f5c52c4041e1c9737c7fdf9bc7ef159eacd37a8dc6729a53d6a5087f7a78fef89c02395d02325dc4bf47809d035d35ebf9cae3cbba4982e9330740da9b24d095bc6d2d14b74c932959dc3eb9577b92d9baeecaae3e1cd3799dce7f56a99702747a560f9c04b95dc25a8cbfb6fe4b89b000cfeebf100b34da1b44c265f020578a47cd78e90779f07bbe67b9965e03b2f41f5bff2555100b6b5cb29c7db6f7df3ddd2259517df38177ac215bea1c1ef4fb4b6ef70c4d3c29beb918bca920acb942ec2ccc6dd4442c745a2766799111b6481c04e0299abdf817f0b73fbe8187280faece69d051b07db534d8f7e331af7e70ceeb3ccd13795936fcac15a9d646ea293c2fd7b393a7ab2bd9e49854beab162dac04d15d6374061a37e902adbe0305b0df26522e28e718e173c05fc8a11dd147e2788545e2f5c7e1c0a519c2f542ab64c255cb0f1888d261d5fb2295d6c5344dff22a2a6cfa9543ed3d5f65421c02973f1f05552804bead0395daa622d9a674b10c1f409e5f9ababeca59dd2e33468332567f8b39f9865838c62af0133ab7590683cf94542f2d12c990e8a60ab0493144632d0a72615e2cbab6631915d2435e7d5304364ba5708c41ba65221de1bb6eaa685b93010b560cbd39533886d49445bf79045d0a517c53deed8f8a5c42a116ac383259f1d0d6c9648567813b756d68b222fd4519996d70b16d0a99904860698058884e81b093ab6fbf634a27db9008db142fe88852f4feac5cb1427edb5f37bfd2e3e90bece765f5398dcf87753ba51266990aee61d2d1e6b56cb59b9c1672f6d13bc13209816528c08b82c822b48363c8d192651ec751b6507fbe6eb6c9e19671d6dc2a8856eaf00465f4b33a38bc1e42995fb0e2ce56f18b4bea95456890a74e2f2c58f1aaab2321ff6eddd091ad48b6f5b36f7085ce8f33e166fc2d9356e6bf2a533cdaf33813121c78a414daef79136ce35cb8d52c5aa8edf8636836c8e9df75cceaa3fd935081ad151436dff09f3f7ea5f3a169ecf7b9d0e42f74a1e9cf01edbd07dd7bd0bd07fd9734c8dff2a29157d0798f31052d38616be0002d72ebfdb231f362994aee27bae81a5c6aeb9f7970edfb576daeea72609b21661b54ec550cdff1557ba6d0636b2cdaf828ccf4a16d48b8cf6b01b4a2c25c0a5d43ab3dbdf92ab0521d7ae0a5c037df5199834b2860f91fd2ea28c2fea5826e62f08d3ec6463f956534869a87a6feea71d9a3670a23a1de6ff4f2f06f9f960df9fff944238a2647c3e133f11dbddc54f93b7af94ada271af589467da2519f68d4271af589467da2519f68d4271af589467da2519f68d4271af589467da2519f68d4271af589467da2519f68d4271af589467da2519f68d4271af589467da2519f68d4271af589467da2519f68d4438d6e602dffc94c223420febc0604bf84d0fc791b38aca1272436fe1dc0c6064183ff3a642362bc4736f6c8c65edd7cae0dae7845a162388b38e7de5c026c449dbc847eb30d0963236ae7f2dcc52399d0e783c53295803f577237f12fcb531e39c6f0c806d94e9881d247d90260c146546ef37ac84659e9984c85fe35f0a2bef62f353d05fc99082c83bab009152d0de9e826766e937a65994aee12c372cbe305a2e5ecdc23f5d065998d3fd763c718073241c7b69c957e2aed5c42813c279621612e29521ecf61ce245b0815b3d6f060b18c958d89a367a02dcf95b3b7652a91dea4fed73d21fa13ca9c81f712ba720c6fb188a8ca36b2051bad828dc111b6315cf83c57d9848e2d4ff9c92530c4e7325542fbee5a042eaf871ea1b39621ed7d73b2f078fab04cc383cb525d36808789a1451c706f9257b6710696298165ca542ec9a00c23db5cfd47b094833f9363fa036b00295a3b40e0bf6fd776e2992689118233d6c680fcbb704ac8fdcfa329698a1c8d2892fe9f620b7a34658fa6ecd1943d9ab24753f668ca418fa6ecd1943d9ab24753f668ca1e4dd9a3297b34658fa6ecd1943d9ab24753f668ca1e4dd9a3297b34658fa6ecd1943d9ab24753f668ca1e4dd9a3297b34658fa6ecd194ff6fc39b9263fa1b2095c9311d9cf64e9ed7208dcf61342d518ba4a1c7bf7167327248e0d47078c555127f174a437f0eabfc0c4a337e6e412f38498f318c1ce3fdc6643d94a687d2f4509a1e4ad343697a284d0fa5e9a1343d94a687d2f4509a1e4ad343697a284d0fa5e9a1343d94a687d2f4509a1e4ad343697a284d0fa5e9a1343d94a687d2f4509a1e4ad343697a284d0fa5e9a134bf0b4ad3815c7e2ba466b0728edbd4a82fa6d929051934ecdf38a7f5ab175b08ce901ee2bf6357b3067d43fcba5dcd6ace3fc1dfe0cffdbe66fdbe66bdb6fa91feb8ee7ab6acb285c066814cd0a7ad29e6361162c25438ada6dec19b8bc023f4d26719cce1b5c025e173505ac629b04c1d7378ba12d08fc37d3e3c7ae9aa64a3c91bfc09b3736e117ae9117a2cccf5d2e6f54a982b99ad320c3a1996d7820d0f76b6415d6cf514e8895e790438bad1a45aee26c102d14ea22b8d80ce985f440ce5925ae01a1c25f0d4d16719dc23d009adb9573189639c81c0eb438bd04f3ecbe46ec4ec5c023fb93c08dd4402c2dccf7d3ea84f74ed78d410df02078ebeca1c2c330e5c42c42c0394023f0b2cd8362a73b4a3ba1dae3c31a13fc9824500f96ace03e743cc9f4f9e97154dfaa4575a26135a440896095dd9155d388604dc54025e45af544de23640e2961ba15c75e530ba9b9c8147ae022fd1cfbe012adb90032b8d03cb64603d76962116b6ca1496e9052e290496e157b601db5939a21369e77ee5984aee265e21cca5a39d2aa4658a00d59157728f542ac710719f7fd737ab963f81079777b43c5d0a3c570aacc86815236a9510c831b751f55551b79f2feab370adeb72a0639caac5dc8b3e039c56316b2d62a61b8c9aa9ba226e306a23cc685e98712f86ca2c558d9a2d590638a692d9a610d86678f212fde255ccd18b98dc3599c231f47859b7cfc636b4c7fe0bec846eeb70f1787de718766e554c611954ea1be814e2d4256de025146c97c0e3f5ca35c005c95cba0a2c838aebf639e7ae01b07a073eeaf259fbd4bc8c178e819f5c52c4043e0ffd6456ba898e2da36cc426e0e0f174e5b3cc9b65dae13201c78fef53b95b513b87e7e0bb85570ddf5e4e372724271c61a914eef3a05882bb5df1466c909f7c432c1c631558c439843253efd047995ec29d601d159e26dde47caccfbc67466c509f61efcdc5dc4f380cb697cf73182cc34eeab1ada13ea75281f35559676445175ff55857350cac37d1841658e1b4dc69a51409cd59f693e3226a4f4e86635f0176c2e1ee5c0e745d5cd572a91c7d822a5c828b9bb63c58a60ddc08275b5e97491e7a119378097d58b24c6e474ce95693d4bed641f792538a64730edbc2ce6dbe968bfadbd9b1395bffe42580b04c05087309f5a5857403d5eca028221950663a2febfa4ae7e8d906f75f36339a51385ad7e253b05627913357306fbe8263b9b24de6b84cf0d04ff472997027cb90325ba58e5ee21ddd7a57c46a4980e392544287e02a47a5dfd7af12da3682bffd27edbb1758a12df3e09362e8cd19e0455824b045a0e322a3710ca701da507471a36af40bbc2f44d49b650ad1cbf504ebb7c5b55d020df631cb606ed5e8f277e5a31d2f4fb629628ea15f04dece5d5e2b84b99f398694093c5edb065e3abaa9123ac630b054267649bf74793ab439bd7251bbd7656c5506734fd7effb26d229a5472ac032e4c025ac7a0cf3575971090afc6c5f6e34ce5034eaf5a67d642da661db6aaaa66f4c9c61f45910ace5b6fcee172d139c7023fada4f44d3cfa65f419d6b9b42e9cdc5237ce6f3007895d08da36595bd356300ea26d932950cb6996d8ae007724e3ac6b91078119d2cee27b5fefe85f55fc8baf8aacd384d652774cbe3f52794ae69974bb2abe30732f7b54c6d12ee60dfd8c5ae8de671e013616e1141e011e1d137ce715d4ffd026d99cf8f03a48b5331b7dbd3d56fe4e03adee5c037c542e06d6807d037aebc0d3b7db33cfd159dc6a81b1cb68f629b18c56c34fdb6cdbab1df7d0740b9166ef46673cafcb52f089700b1c0e3704c64dd7778aeb249c935d538d89e6e648e932838065c953afaa60ce52a7753a570a3205aaaccac1b4fc8e6c06f88986dc8d16253dce80e86affd1c31f4087de69822b048e5e8a571b05699d236bd40494061ab61e825fec5b830fec3fb9bad2961b681952ea963cb94813c632e3fcc84080b7453423265251cf471e29bf29f05560816151359a604141efa26f58eb3cbc407fe8c8b3c822e7c5301b5be0972f8dd5bd95b56e34035dab1ffa371c6802d0f2efe7c55087311e90dc79491ad167829b30d692ff020117870a397a80bf2d948fde2f3f4e1f1dbf7fdca9c2c530c5d43c7e0b76f69ebf66bc62e68f913e54ebf69483f3eb6f7fb76611949d66d6e0368538b39599be9aa897732282abad48cd17874fbfd4e8ee690cf092dcc144e89397dc329afca8c3637f1792d6bca2bb4af2fb7f2c58364d1b4abded5b5f31ba89a4faa6dd76cf1289f37f2a51ad4c93715a8638065608dcdb8fa165a37dec187f4b06d7ce35cbcbc2f1f83b2fafebbf5ef67bed3f581064a6fae63b0fd6c833bfcb82deedbfd8647f9de1e7e5a0ef4c53a1eb43bf90df2f775ff411dd17bb59ff443de1feb7a37c66f7ead0c7d5d87d22674ecdad671a671e21acaabce81d74dcc498a7e2bc3baba614f483f7ff4dd5795d9a19da4d949a66a34b7e525e0cdd1aed681fda1ccb5720f2e3eaf1f96098dfb2cf44940e9f3e772c10a0761a6ab5a4cab028f7c41a4a3c40ae9a36f8e31e45ba542f4419fcfb1c6569c8badca7c26135fcaedb7c7df43bf09ec8c16780a77f9532ecc3fe9c39f1f1fa5459c8f1ea1659fca475db70f7c84fabec04ba1cf4b99c086e2066be6d63c9cab3360f1695bddea7bbf74491108ecb0bcfa370ff2f2ce2fbbe7e7eef9b76d2828edaa9e4fbc4413e43fb7f2fa81ae3ffaa602dbadb6ad532c70139d146648cf67c8166a4aee25facee7e96aab52a96d2a8c954a4777ae63b68e7687cf16eae907bed8bdec39869509068dfb7306f7eb6fd5e310fa0f0685d5bc05f932d1878e296150a77cd8e650ee58eeae0ec826734ce8257ad9949d2d54eae0104aeea59fe9fe1f8cc3c917b2dffad32aacb308e7fc3b2fd143bfee878637e8df5deda3c07aa85fa01f02c744639f60dbca96290237adebb26063d42eb2215e5ce28cfbbc8e7ced051b078b6a128995f081aefd653284b9972c10e0dc8c7fdf571ff074cfcb5ca93ed4293773e25a2fd8954be0d007cda09c2ed97b99fc68fc7eae2fc5199c4f7da8ebae75877e00b6984e1ef8c5028be030e8bf2f3825f3129a6c624e1f8ff7afdb92f35211faeff17d9b7ed85fa0f5453552092de2a07909b783f2ff016de7c3da6698fb6c707ef0719bbe67e8af621e7e42e7367bc31bea579d873a03fa560b4ec2609bda15837bc9b99d6f158d5e086c1efa99a06c4e6cc8e19c0fb697573177366ffbe0a3096c78e59fd031dba088052b4a7a4c9926ae6f145d7c91359c13a238103658e0a67ae1b293448c982fde63180d97cc0d2eceeedffbd0c7ebe68e706eee2554e81ac89ffd2e5f1fc8b39459a6e89a2af4aba58b4fd0950dfd8eab7cc0710ddcd4ca84183736c0873a71a3e1fe5a8be568a152988ba132182f15c3edc7fdcef8a69241dde818d02ed1153a91e31a73ca6abd8d62d2507fe450965d52c83eb755cc64739d8f7ee243411baec07910b05938cf6feaf7f01dc7a04b816ff42e29912e29c6328a95eba5cf835d23275ff052ffbc44c77c532c059e027ef5f5f716705e6d8aa565e060c9deb6fda7beed7b5b3fc71e75c0ed5842f3629fd0238f0098ad425f12f1d5e9aa76bef2300655dbe062a43b3491f2797ddac63985b91859973bdaca4a901f3dbdc642a9d236fdee7a31f781954ab9cf6b25f4a75c00c7a61eba6a3dcfbc290be9cb4d63533a3f8bb78f5ed5f1fe21cd8257804742dfb269dbfb721397acfd6499084337a180cb06f932552acba02e76a2574a2a1e5d3584752984e9a41066e7a39b78e546e32c13b7990da7731f95f9b18f86dae4fdb339b660536cf11f3b15a55b434a9ce336fddfcdd59f3be7071b3dbc276fd79b296c84637f6dc1f9b3ed1ebeb7e24cfeba15e786f7cf969cb1e1af5d73feefb0e943bfe6dcaf397f4f5f5c579ab559316518790215d864329908f2e4f13f11fe6fa3e99aace2e226b68e931323ab274fa81f0b1de137cad21ecbda68dc8baad99c86cbe54673f41d365b9c76135979dd32243b33d545a02beedb651f6542501887905717325dc41b7ecd11f4c1d017c1de1faf0727f2380e48db929557c03be17474599cb5094815a5709c15c7cd2d5f0661e0563375bf25a7d56697cd32f1299d569cb21899893b3b26d18e940f97481d91b3e1d93d46cb251dce08f3897fe14b61cf7aa92c587b693ace4dd788ab73211ed8fd1b7f902a29799167dbd36c44782b301b6638a52e065b627ef04b7d2e8ae029f55ef0c1945024d46eeaf3dc5f39016c8afd44fe56bbad1fdbad5915f83b7d617f56a6638c4b9fe7f69629e6cbd30a963567eb77d8ee6d8e594e4eb2364146113e99bd179cd3643299e19c3e9b1d548de2bb151c021c97e9172b727fe39b92fc93df2499a3abdeafb62db0e2b02846abcb688563d3b5be7a9216cb71765cbe32abc223577875102fb3615195ca62c9eec5cdecb05a06b305153946be7573107a800bd5984b670ce49d3985abc36cc2bdc0ae9fc693c904f6dd6ac64d26d08180ec87ef2a040564c2a015cdbfd1d74bf83f9714d325d1ae928ea7354f414d11b4a4dfe08999753c75488ab69dff46dff1906f1e2132c2068dd2c9e47585e99b7ccb1ff03d5d7dcef7cd8a9b9cd0477f0ebd58eeb431b81c7ab468c5c714ca7a45ff45d70b40cc304f3b5a06cfbd2d6c66e2c6162b45275198fbe6449858a575b26681101e7601c65b5396c8dda5a194b959c6fbd945a418ca2cf538d10dc252d7a39079a92ec341bca4166367af17aa6d5f36fb4df696e6baef3f8df64fcf7b2ca7078381a59d66e938e327ee69c48025113e2bded82c75d700a3285fbb535ccd4c9788cce52c7b0e4e96522653893d9c0c927b0d6c3ababca9a3dcc00a8c1b9979196f3d4e1eb09ea5e4d16e353337e353f5b4da1e26c1601a3e616f9320a846aba125e64f0548d7def12d4dd5fc14c6fb79b54d80713861149d9d9fb48dec311179390ec5c54a963dc2d0865c3e58ba33991488cbd49cedf4a5e50073c32dd6acb963717a7b39be2c56ec65a3294c482cb7679bc492a9e0d28b7d7e0a568b57697c6695b7278713197ae37af6b6940e6f0b7cca589e35dd67497c3a1ef054498e0b79b4295c95bd2c44523ebf8d09d90a697e9f2dfc904e186d3ee357d524dde3a9ea8cc31179941432d7a5702d1c76ec3177305f78db952fb343455c1cbde40f8576ced829832d4da6ace227ce5a59c251589aabaa78111666f2645959400ce9042b5db0e0c49d7fccc7f8a62c7069e6d94c2aca15cf7382243ca7332f335421b557b351781004d3382844418497a3338d14fb1c12627224c2c5c07d534ec6d3e2cdc057aa0d148e2db7c27eb5e64a5e5b1ca3b3c3cecdf961788a187189a98ab85bc54fecb2cc75118ff3b1a1bf8dd3a53f191725679fe34a91f8e26d26abaf091b65e55011e26c6647cb2a9d8c8f20f1126a61b32507b4b760ff446c9445baca7751f166169c3e8b168036962f8596eb27c7c734a34a4716cf7b326633ce13612fe8271065c96a959c024a38dbfa41d3920537d4aaf9693d1ce9abb1760a379433a37872b74c652a485423a34ef466213c539cb70f72c5649799f374f0a7d9302b36aff9a10c3653a314662546908bd8129e1787f8250fc9d97cff0c867363a0899b1da3f8b3c8d32f993c674aedc971593f1f1f63c54c707b2ef0137f2b6b54184bee5ee794898487b2277945496d28a2ba5c0639476c979b55a511c9307a76a327d95a3aa3c53e5c08c9d4c2ed0c0ff3c9e8d9a7f8d83ccd4dcdbb18f469b0505eadd514d74707426370ff293c00c13cbe1a8e311b62f3b7f51e971d7f903ef987f032215e628e5c66177a0696a1aee82e3f6346223f9df982be5b385b7e51020778a5b38c5c070c428fc2b468709949cfa07c79c35fa4537c7c9ac7a7251967f1507f9a0e9ff435c338277e483d8f22813caf545ef7b505a19e9fa917dd04e6495d57c57476363706a76dddfd055b09e965b1dae1475d8bb8c4884423dbc9c23c94b8795ecad459dc9393b7b373dea6d6d0cd0df938c3a776a5cbb1f27c199434eb8337f169ff34115fe3d44d96f631720ed20b33c2096c453d339bcb0c1f2dd5e3216113b3da52279c92cb99fd46ecd3274527672f2456442ef0c30a007a327f7a95941d4d5d9ea20cc3de42804f2c5e0fb9e78d881f5869453e336fa3c27a7972528c396cca5c54b89df44c3a32890d76aff6829f3b333f0e8636c164dc6b91a44f4c801fc7a30ca4afde845ce37306b3039296e4ea38dc0365707edbee06f9fe8539e20afefc367c3d67c25478d2576b2039ca51791e0e4edb79a1bd6cf845628db58b2c43017dc1c12bc58eec5186f119c6f10c181812b6db49c478e0ef52319b79b9244ee5a08cc2f13c3f47e2686b967b52d09ce350e79e9563760a939761a0ac85ec3c06dbf2b072126c55ced4231e81a1c2ebc779ba2ab7b2b75c30cb5c5865a7b7176f97b37131dc3d8321b37999e10b7b96cbe9beb20a0398670c38afdbe1313914f140d0472fafcfca3196de30715a58854e54c2ae70b6f3bd333a1f478ccf6519efc741baa8e6f3240d8ffe939c4c331cf39ef0c31a0c06c9eb911a05d6c6ad5475c53883b0e0f4015d9854c98c037d35abe218dbc943995207678537e7d9593f4d73dfcc7370567707f778da6be57ab829cce7d7c360a2431bbc5389f58597036d32e1278befd960e15b3658e1f5c432f5c29f5da3f1b629c42bb539f797d237ae36dec80af3040ed636155e35273b0e9978cf1d1276cdefe9105bb8dc79217372a8474f3c6bf849ba36e75bf7a812b3d767ed955bbc88ebf1e4d5b62b5a17a48900ce9537922e97cb656df32e413dd3c7f589d1c6d286e1572f2a0688d729198dc4c1e9697d9eaa6b5a19af98a9b31f1ee87570964c855c686bfe055b278ba052a6a36035182e87daf96dfcb2d16861365229cdce42dbcc19c08d934be172aaee6523320e26a3f562c878658cef3c3bde19facc5f052ffc5b581d84520b032c7b993aa74a0c027d25c9428e67aff4da99bf8e97b8bce265e7ad20a7ae339c6ecf432e1ed958781400bd5ee98b944816e353b27b16a7f9a648cb7096551be67531759f0e653ec684b7e97cb52e5ef1e9ae5c6927c23f6f49321d1cf60671d0a9c37e9f0c776ef132dab1f1f04995abe7d1eb4bf6b67a9e97c37070d4665c69eb407d7e31446b31555e86c2e9c59e6fc1766a61bb7d3c50f3a3ae2787d47a3e96c3685e4d4b77a05bfb701e526160ababb7a331dc277b495581bd78191926af28c57c95ade2ea5518e16e3192ce06f196114fa26eb15bf9855e07454cec586724fa6f41a426c502c3573e43183c569829c5cfed7d2161c638a5b3e9511b1e55ef28f92a0bb0e5dbab179dc2d3411b2e4b062bd391e62812e61c03925f6ca829b95b0d89616e196b6a4585472f879674a3cc786366387be675b47c1bee647a1cbbe534895e665cbaad06a3b91f9384911c09215961c7843d0fbde1603ed708f9b8a118a010b208f8a526e476f41cbd9e9e37b9bb52dcddf33a96909f3c350bf95950e170a1e4d5a39fcc7ce4276ba7eff8c9f4cc36ecd037ced83dda54695612f03b248536178fdb39781fc54fa4c232a5cbde567cf72c329ce0be4e46caf24007d1024403e37804cbe86d6fe620d84c22299253e71cbd89cfbea62920ba5cc4a99d79d17af5169387c37c367f62d7ab623859ecb578a46924b1892fdef8794c5131550c8e177ce4bd4e98d12eb256b3a1ad6b7b8bc10d672d05a7e168c82eb305ed1ebc502fc6f253c13dc50742d92af68c28f1d49b175bc79fab86640cbdb1b4c7d70196af0fa354b62c297f53aa985d27eb9130e182f21884c2f8f4549db4cca45ed479fe94daec5b15d964ec291eb37bb144f562c805f74a5ff623738983a7f32ca5f8b7eae408cfdaf3ccdf55fea60c493e7c219dd05998ac561cf6a96fcdd75be0c4a3a11cc5824351af4fa3f2f8ac7180a13cb122fc596ef25c214d8d121cdf8c2c2457ba57eedfe681301b0853e0cf374b959d99028f8fb859b2f43361903196ffb2df784ace59b9416cc634f06cc91b6e06da1163d472454c366e5ee4faabb0a97c218d4a8ea58c624b0523754361e22bc3ec2ca9b45d5d022b3db7837043a64fe641e7b8fcf9506ae36cb34ac6fac83487439c3cc926f15c0d05efa490fac0d682d1581819e422a58537436558ea4d934d4edb794430f6ff7fc6ce1a097735d9b20392212653ccf08b254fcccc1a7dc73d5d155dfdea19670832b622f6fa56665e9ce2f337c823329c71da2ea9584faaa6704f189f9c6fec87dcbe3aecd8f685527d52d1687dd88c646d0089393ebd28c9978ab0bf70e79b32e2a50f1e2aac3b3f32b2b038400d34df4a2b2ff38d6cc8063d45309f732f9f432732634da48a57a2e2f1693f74218dbe39013eaef69f5ab464e2e5bf51070ce039fef4e5f7392aaeeeff89d3cdfe575f16feb7be7cff775ffe3733f80f2315faf7eb96f3ff1982ffcecc10d472cc5e815411a55e4d16d671d6c437ce6fee15ae927e5bb23a827a3018f5636b0012de285d59a1b3a9a3077a391a0b5deff86dad9b38737f75310ca29a3ac395f64dd2f7249f42076bd2344e92243ad338de87591c70f5e45c95045628098234692f204e02a2c064a5224aed2c8ccd839ad2628d46ff68df727ac3b610aab379fd1367932b9ba13afa346625ef5ae4fbd3bc74540b444b7fea0dcd6fffd9ce5698919b0cd50f0a9831cfc7fb7c4a8333b3a33b29422ff2a803c8b2b269169d637e16bb063871db2aa52c953ec70bd3dd45ba8b67f602e6cf2f479c289301b044605fcdb43bb01499f2a7cca5a57b42c3d20a6f9d9da6a1c0167c5ba09c3cc58633c71697224c58770281c804ed765e6ad6601a560ce2eb0d3bba8b0f6a2e0825a216db5dd09a3d6589bdd94d9da1d2d699718e1560c6c3a4d6ac1d63f8e241553fb8ed90a448c96a93d5ae1cae48da74278284d89d46a7de5c270f5d277705e32b81178293bc90493daf26635ef207eac7648564e7b05c6a07b6fbb15ee34744138295d76f8f8547b22daa2d62752d70e699141e511a89ff413ad39cd53775ff949fd1e40d7fc61339a53a777c62ec886f5ec2f3330d6b879051e45c51bb7d3f654f5123be281ce65d6e553e91ba8396cf41961c2b767c041be3dd7c2e45a88e96c12bb677ae8f99575fd5fb696c67f981c3f3271b52bbe226bc1ce60eaa237c155d084fb9643ca159b91dd0615007596061078089589c0d163e12e5f531f4240c4b114ed53591622f39a8b1f5f6a322bc563717ff55adec47d4ce2273771d83162a0c0cc9fd910a8f1448f74db0e7d563229a7388327d66724fb1ea9626cd991cde60702d901812f8f4f9060b0f49e521ca3ad4f8a38b15ea3aaad79c494da50c5488f1e2db9f189edb08824beac0e73f1e40fa88b4ba93801272588c37acc7dce6b7256c7675159b46e66f389376da1245ed4874a9bff423bd338ae0ee4ee0078075990c9c78c321dcc6333230ff612dddde3bfd10fb6b75627b9ad9bd1110dcdb61ca2631be49ac1a07eeba157cce0894f1769b0384b9d9e27779cb84f916d8032713810e8ad49ef5bdf0497e052a04c87309f5186befe43a86691860e91e211e07c2af485b885c731b6bc0b4e54c6126792d717a313c0899e58f8163dcbcf57b5c6f1389233296fdb5fd3d9c24a4c3b9f6be34d1800bf6a935ce0b3844d31526c2083f8d062dedefbd97a23a190681cb3f758c1271e8ad7c1dbc8fc86bebbab96b6111edb060149288e3e28a4633bb8dea651a63ca111b97c24b6fee7a323fdd46e99479db2c97cff1e34bc4221f7bb5655fa03caf9d68685b87a6a695fae5366cea786e31082578f92f83ad93740437dc2de03bf1b32c17b3544ec9a4e80185b480cfeec08485f3a19ed9a628a8384f2cfcf12faa4152b65868e70149de69e120539b41cb2a748130ee8a62b0bd89642dc183adc74f894cd00906d9efced02b618d11c9537cbde977d2e71926506fac71de1cd15b9a5e58c931b50a025a7f5d3eefe889f749187f3c5bcca50c2c747668e90c32ec8de61d641af3cf9f093879423d5736c46f6844261c9a50a5a097e5cefdf5787ba8a3d7f2768c5d5eaadfcf5c8653c3aebb217527db84a575beeaba7c9a76e30f2dcb314c16debde66658669904901bf9ddb591c8f55ba134005ac4e3eafa7d3f946e2d56287d91177b63b9ab2a2563a1e7d0a16c73391d5c1e6337d13e0886cdeb3a77da891ba81adaa0eea47f5ae349c90edbf87dbcf3be593c7d629ca1ad81358e74f61841d2aeb1dc212d1d72638759b6d9ed695884de2166dd5a2efa805f3f136316c067cbb5ee0c6de2a347b29bd450fcad2a8424b2d6a1f420b0ceefb4bccf0277c7441f6bf12c83d86e159de1f7a96def145025ab2d211ce83fbf0d033da0a5bbc16c0da63b9f8fa81c3d8d9ac97a20a1ba740e617685391dafeaab822af66046d21966f9c2a60b1f5779b4e3104d917a1970024f68dfe64e764e1cd6dd1254637f32c5f1a0434936379ff7c37ca0f8dd3524e508373717d021d7bb9e17c63a304357aa55acfe727dfa9d82f7c8d347d902523fc3f4af394e402d1e0dc8aed05516ab2b63dc37f98b3b8a680dd08d43541854c4723fdcfe7a9898af7289922a2ac8cd0a6f09c0986f136460507df59dd69ccff22f76e8d4652768436de102ba445b3d6906a4887047dc143c2ea602f9aab26e72f9105d5fa10ba7557af2369ddbd51787f8adae449fc0b9421ec9228ed6d1fce0662fea870b06b2306420357b8147071cf92ebc91b9c9cc0524b57d0a796a7df0e0534c4f573fea5fe47d28b9e8cbf1398e01080bf21c64d32d7542a9cb731fd3de181e3ff9093f9907b28f04f6dba512def979d0e78f879daf228fd13b53b093a331518e1add7e410ec3717bda75e873a5832739d4a455f81a86657f82da7670a57a0522a2c15c478c6b47dff10dc5329cef92f81ab4ce6d83f7e588f9ef8d3cbf25f5b576e917374f625d7605ed105a411971377c53c4712c589134269477e556e8b1b15bc7c613e98ac1fe839395c25e87dd920c71ba1ca4a25cd33f97f4c7cd5bedcb57cf11d5f2b880f78414b49e8af151924f7e84298eefea73618a42fcadbc7bf480fdb510043df908b91341b43cb759ee701e678c7a5e8e2ff585d8d28e249a9219a724f1496fd101ddbd0143e09fc34f1c69cd3a2dc97295d36c360449cfe5d283fa8e1512888eca2a23d4d40ad5ab2c6e61f485a06d1e8badd24015786b02e5ce7e289981f9c90b512b08006d60baebd1bb160def2441724bff764545834f6ca99f3568e064f30f1dfe30dbcabdb0ca9f80e25654cadde0632039b927231f1888ba482ddb28ff05eb18dfa1c17b4b505b9ac9373d1f6ced757c15337e8a6105a7ab5472bfff4c30582df51a18adf29ee448643f9592d72a97872d7c267d7ed9962b0b11a6b81fcf7eeae64200ca7b1b349e400edeca50274f20c5430cb22f0b42af84d9cf9a4fa44c7ab83d8b719c8c9038b813673b3cbf7d5cac54d0701c8c6f126cabe933e81e9b1b710745e70183fa657e4d7626d3b0cf84604519cb2ab1b9cf244051ec882353e75ccc4e46aa6cf05c1dc73db1775e229bb34bd0a908dfd8cd83cd2f61d2a7fcc9702f8007f5b403854c0a5b39344f174407481093ac4e41cfe52532f816014b6e8b1ed5bda58615e28474a80994bf54a388fa4254e563bc4125f2db6faa959be593462398fdde2fe71a341910bdfce9de1c42b296f057f39e999d5f08dc91bb499c014259a8622a55c88a74118d78cfd2313f946640d2f8713812f9ace24a3b39727c3317f60141ccdf29113d0ff438ca76f160c28f03db1510979b04a1f5487571de80a2bc2913651cba5f3647e9ddf4c23f082f227c3b41d79c8038f840aa6fa8a415efcf0203f3543329d09a45e5080a0a394eacdc88727c7b0cde67fca3692282701977afb905498e7a1ad60177f8014d3fb9793f4b58e56b9c51a7d4e1b5427222f9d57954babab06aa1231e14e85f89830d938b31b805719ceb7bd6e5bc5036d8f58c4674e0a2a98ea39cd751fe6a53fe12a0d635509bc9e0a4d21041b534d8e50c7f3d036c4c6f035fc9ee9ad60a0ede96bbdf07417a8652e2690ea0e9578763ae3a1591af1d71c7d80fbd07da75488fb0571a9f948e6375d71911aad808604aa9d475f18e7a2f9617e784de1d721109712aaeb00a6861ac69ea9e8d050c517da5a07736449902d06a2bc768e36ffe346bed6faf146d1392962b0e843532ad401403e43dcbd6fdaafaf552b426bc8472cac069a23bc649d3718c210be697f7bc8132e3e2a2fb944329b06928a90a3e82cb80e87e495ca1f4e205a7bdc2b149c358b08ba40f3d7edd1900d9bda009f8b2d59b93c6eb177d0e0ab905be3a3b3da44cda30a9ecd25466aad59a5a57b9482bcb72250452b2b23630346363fbb158b8faae8c89d399283454df2817a24041b24048cf1100421d4e4271340c2d3e826354e91a932d0bf3f9eb8cb4ebcda3d3af713045eacf8a795415b18339152c1f1051cf95df431bcbe635222cf3bd421501563bce0bb4e61c104790689d92a4ea2c2b65491e9c969d610e4c88b9c4af5f54faafcd56a055e53dc9961d4a25d35336a29962e44af3d044dc0ef8e8cf9b9ecbdea32141322936b3d0a0cf240f29de11b9e223c6cc8f600472e22773b50ce7bc2085905d90768dfa412eecf570357fa5bff10f3e97b169e62a843751891cc2736144ba7b12382c341daace35c130368c408aacc28bbe2b1daaa9869ccceef1742509db379694525194ef042bb79690a0a6b626cad83ca56b9301bbc88b091465171f6d8379935a0516b0059d689da0fbd7e53f10bdd4522f6ff49a2f376425f788f1be7027ade762806d777f48823967f760488e3aa5b1f6b52acd3b8461c7a8c58e8243b67cc7c7a7b627025d0d5bdd1ae451db2ca128e6279a7f366eb38296b7140ffecb43e0cdd8b573e66618298eff8adb73fd5f72fbff648dff62f55068dd3f92fdb19c041292df2f2cc63079a4779975b99ae372ae0020f3746853910cd1863837552bb91b628eaa7626088ed40802267ede563c5b48fb6b9a397f9877c825e7f1a771139c2651d75708cc62153cbd5720bda13933717151390276b3e3877dc6468830e7370158659f9a418a850ebe76bbb9b1734fe4fca0ec0843bcb799ca4a5ababaca2808169fae478ef89877e94733c859864b2e96223a8e780c8259b847b1c22f297d317d3ee5afdcc53f4c57711efad1fe3024ecfe2ff7e17f65ba1af3574c57cd26138ac367ff0f17a108e5a196ad00063f785982f17896d2c8948bd7990cefe5a09610f7d7554223f9bf3e0cdaf03197daa0530b3742d2a2f67218ddb3962097b304c5cd2529e72f8bf979deae2b4e2cce5c1ad8a9690d22d239479a6ca59ea1d7a95368893451dfd8bc0c2fb44183247ac10089a21f9a0034d8a48c18e9c64f19eafe9f3fc7a6b6f0ce94e73bb46466755e6e3eda937e18841e90efb9dc5c1d2723d9b11d1f70476c5af8880dbe22a44e8a725f6be9b065e608ce64d1222b19d2097d85f48cd008bda28585aee8c61f612f06cfedd0dea7946d4d1c42fec538d7d9a9aedbdc5aecfabb615a9b1f9230f7c2ad5e103b5a4d036d9ad61d9666ae5bd0b71681e7319cbc1f9608f74ceecba6714b9803300c2b6f6a0f29643bbeac15b37d4d3237ff8a2dcd07d0576df5cc670be6b574313ec3c97fe5e426111408a29b519ae806a0698e6add8ca6efb4c752ac79735a24692ab5094f9f5937d5b997425bed2f45bf1ed49c67eb1ac8e9f0cf7050372a64eeb11cb476d5eb0176134a8f15607c213b6b6c88f6ad309d6392a813d62cc8f069d2bd9d64ea30de399677cf57bb9cb7553716e413ab3c4302e44614087c1034e99e64c437d07923027bf81509755cea16bb2708ed33704ab62f2c5aa8704b15d2a6e9ea45bc734ec0ec1147fbe7a09eedd442ca0afe0a39a1aefa45d521379cbb0b9c436b5b64d65620235eab010402152f055c6708dc45bed0937763fc226bb19c6370f72391d02a5d1e4f88fd56935653839abc818e0e2e80565708f0216e886b61ec0018eca9ccc5d87aad157fe6ddaca7c0ab97054f8d9adaa465cf8627a0b58dad8af0b61ee74059405b9d35f374b7ede2302a788563ad7c9f8a145187af61fd832cddbd33170eaa419273ed3d79443e6ffd6c4f4d0dd4f113ab1ae0fc6125ebddfd694b3650780dff43b3dcd14ae2732c8def6620336498ddb6a5c780e07053649eabe1513df75000b9582bc80c8c218105842d5b3ada652e9222cf9e8029bf2acf08120ae6a9b8785580f609903d47c9cd043cbef53e5e6d22fbcae7479a4fd1b68fe23d7be726ef3d799fda1864119963b619a8db5c2830315fd19cf728b313fb392ba5b035499517b9d95d85f5fa0f0b81458290a67e6f4d23b1857f0c529094d650eeec078aa24869cae2f0320b22caa8d4137795a4bc7b7e14e4a787b4a0afa9719b9c41147faf46666d67d38380a3429bbae3314b05b9ee1cbb5b719aee4698893d39d3f3126883de606926f744b98444487d79b66f16d2cae14f2c51612ab8c19a850594ec5f76aafbf9a55c96b23fe2d697384c90f4d19b496da02f6f29e076c6be208b6ee4acc4f0a72d296ad4a8dcec0c60daf7d295811b8ef52a8e6973b0fb558a9a63e085081fd583432f4ffd8a9a0ebb7661508add4337c29882929575cf8acd172634a3d47789f722323a6525d40b01497768622b19cf36c4940d26ea391f2b101fbdf2883b31378884fa87edd76ea5e85a46016cb0de1462e5b05e388eecbf4f1aeb0364105280306cc87e304b47230eddd44612db2bb866b0eeab03c1d4534241493c8248040415f8632201fecc361e38e0d4546d588fe155993d33d686d4673eaa968bc2a7cc5fd2aa233b60cec41fcd4d27bec98e1ac204343544ec567f2dcb5c1c2ed2ee08772dff2dc8ddd0707f61ac8aafd06f9040d1414de9795f01438163116376e616146166e9f232854e18a3fbd6e8939b51c88ec4a45ecad95ccf1c58f5211ec2dcb705e81f8b22de0385bc00e90c0f5f30b934f76d7291639b9034d5066fbabc47dc3135687fbb6a1e0a9830dada1773715a0ea4a98d8239d0eb3cd3bd61a26381ed54cd60efcc17002154145f6813e52597ca4985f833bfe715e07a657c6146c0287dac8d1d362e9e4e7370b4758d46244fe61fabf2eded8d5f47685ac9b1af44fde6bc1e7bfefa725dcf548d5bf10bc10f3d65a040b61b14c59039b5d6037e3199bbf52e94b465a074a322984d9bcdf55eed6fc8b32913c0154c3e003fa72f86dc60df4f7093e811945ba2873473da069e11a8d5d95f3f2d5f9e1ba5f210838ab8471ecb0e57512728cef4b520a3d6b8076f2cf7e7a79d17faa6223de9d2abc2db78047de59d792e4873746c816a8cd40bd32a08f6b690bda1e58db4079020cf9e8b5666517cc24a24f0047f830cf0ccb1f817815033e58733c75d1c035c15be8cab935bfdc55cee2281ccb528d590ccb7b75ec3ea20611a435155dbb4d20d358283e1645faae7aa1114a9d200ddce970ed85c64f88031cd5131b994f420033ce5d994b9ec67422b2511e6a110246810638fe5f8bd89b9f8fd2585e1774fba18e12bf6cb599c62a54905545ad4b4be4748d85fe29032d6faca55091c18bcd340c4c872430a99dd2982d0bdc957fae3e25796cea4e8f7ed9605adfb6dd91a2ffbfb1bf327090798b9a51188e579463486153d2d431706a76dd94dfd69e63fb1df1aadb86937518c55093c372a7d1f3f8a498456770d1468dde8df8de8a18ab475857b37b72df715dae793eb694c3a4b906ac222924b6725be415cc1af09d1f77535fc51393d07d7590fae37cb433fec903687fd49417e265530ee52e6700a480269c773933b9ee1ebad2394aed5cb85dae601bfad870a0a3ab38f78742e661ab1323d0a9b572766dd44455c1c1a623d75b521abd6a453c942051de712989ad6db81c64a026daecc903e3e4b98b57a8a43ca4bc3108c9f39c700ef21bc2b91bbdf52375abc5d499096631a92ab3abdaf4901853ad378d08216f7ade3f77db4a0b20abb20beb86b90904a4e9ca78c70de949bc9170cb80f19df40745a01eddeb14a4bf3ef79ae67d39d41800996207dc88b4ec8b854e8b72c3db21b48f2922892dede29fbe619a4699a1f9787e2e4bb8b273a7f430f24502b15b8da40d6f23447db4a31a013615fd35e7ca16f131f04f3285a566d5ed1af76b4765d9d1d4206291e7a6e8b4f0edeaaeb66b85eb43ab9fa5762727ff4bde4a7a2a4b63cf03408dffd8cd1f384ba9b423e8a5ced2799ca2a919c8672de8eb55e3084b86917f33acc72a105b735b27c60b12bc559b5f00be26584b664d646751ad174e08549e979589c985df1f4415469539bfc2fbbb7a4cc6a48c53f6ef7150ae19a0be68a5302cfce74246d44ada59438953c0260cdea4134e475583da66d9c2ff418ba6f2e7ecd2fb2a74dc475cf44e5d949a5137117de2ba7f3f10e795c7d43482bf4727341f5e5ce29a75bf65dde017dd31c877e37b61742bb48482ef791fd081f5d62d4c2d23f73ff9aadf896c7020e197e00d9d387e8c290808f7fc557386e4192082bc1e6540d13c72efcf951684fbd15b157bb2c5a23e6806600c2be075ebd124d42af1438863756095b80a200ee1771f9f09c5aa42f5d8c9e6431efd71b5a12282a0d2be43adf4167838cccdc6536b5bf6fd1c18fabf885dfbc9a588b4afd3b964b39188ac850b530e7e33910e3189f3e771add81ab0eb7349eee12df254120a59dd0611984309db8e763ace7e69822fcdc61a2dc6716b66aa2fad37c8a9a6aff1ea9d5d4ec417c22c22d34f02adeec4d462aca91e9d67a28b23e628fef0521f1f46ba7edc2e08fbf4e79206bf9b2ef0397402fed98c57b89ba55980a88e36f0ff05a3f5ca3d4ce40645418a83ae6c2ab57ce4b7b4066a6df239f9756c503e6f3ac05fdc4d79201378956e3a276a26e351643c1823a8ebd900f2538f08f347d8f70072a934fad38b22672088a1b47a44fdfbd94a7241254a0b35333846c82094aaa64be2e86824af020e348cc503dffba7428f4d287716917c299f4921080f07a9f530583b3eee4a4bcbc4dc25c1c675b95040d143cffd907ecf981e63e174d05855f3a9aae800b498c58eb9df3956fb4ddb1550f7c0112d0c71ab6db9ab4bc4a6f5410901dc1ade7792bc9e161dea9347728e470e1472503dd1d21354f77abea69678879b8c46fc1fb5e5db5c3c4b4913e231f1da47fa240cd112b145645018345249033a727315e94effb3aff4c04d6ecb85de9ae887ddd88492b8663a8efccf35652781d50e54db7cbd92c15e18fb9268ae2737192bf81a635d5840b92875bfe4458033022cd71ea654efc0407cf30c7cf10573069b56078d594e6387efd447db84509d83170c565ae391eebcb1a7d50a89a8ff307498dbed2c8934dc10ecd28c92c9eef04fbc524c53c2bb31bd8e0bc2390b7dd2097b9a2ad6c03bb6c3dc95e0696af14fbd729315d3711259a797393b887e6a4956d35f5e4c9009d1139103c4d37c14a32b67da7d502e3482f082ff16978846a3a91c347efdd12da56407644cdc56591ea37aa573507c8d0e4419d55d51c954a255552411853e574a0832e28909558b05d454917709ef6aec9000fa718618f1c28c89558aa3cd10a6e35269703bc65bf41e38d8320cd1d9747bf2f6806dbe6fe600cec1c4c7840bdf5d2e8d3e3f4ebaf8f520fd505e1e00991f3c69bcb5cdf75a735f28825990624358279b77aa0478764d0518eb4244873f26c62ac5a03e60618f88dc7bac382ecc77507238aad9f2221efd6b9595b35c240b19524bcb1f04e6344830c36efebe28656956e20899c00af8cba97f3fd7e49893326b1c68a2f3f6c095ef16d1b250c2d4904fe0c7d1d2ce2b94467b61f1366026d05095c05b80538caf2c74e3a71d0e473b1959e60a9f76c2002aba18f27e3761adc5785b8bfa4cba5e59a627163ee091c062b8e6f6c9a91f4b03af8075e9aaeecb41ee0a292117891249bc3cf4d9e94bce9d41bd189f417f176d2cba47030b0c2ee6ac96e944a0d164e6c53de1d7e77c2f2ec5784435d2cc30f0f24b021a6a30830760775e5aac09754fa16df4923014023dac8e09ac73a1b947e54aa6094e2c0e3b98da506c022e52e6b4d512fbec2adce98f5a9c7a6e59c2f7039671dd9f0744b71a29c031435aa0b9a9627fab37879e2bb4305ca0501bfbc5a187d8a3a93adaeb75ecf402fd0440bb337dd7f7d10bc926b67752fe191ba266f56b66e90e962f1551d15bc6a79a9338307fb9c5c975c1b6231057e9009e1366a094c3f017062da21ebb99eaaa8d548b2d780dbf0d0bf2ea5b4155ece94e0f573d15cb452b9b7fb2eb123b0d5b5a886236fc3a4aad94b6d60498d17e415e43279e375b310eb345abeaa615061c52118e28c4e622a4ffe3eae0419080c6fe204c9c2ca8f36c95905d7cdecdf7627a97fc9ed1b70c05695570635dffb5490a63ade4f374d99c150af8d73dd17329c64faeb56d5ec29ddb0ccf190d039e324013dc8aef15568b3618ac1ca3a030701e0270153eb788cc29700f995d8c0b664052c751ed66fa0dbea7b75fdad773bff52558ff76f4a8699c43a87c5add57b20c1a59e42d77c62c5a75bd4bc8de9ce9757dd4f2466003f13e096761fa176d8a925199b6b9c92f48ff4200e189e445deb279c3c4fd8fff209b80ecdc44ac03942e0e706557c1294a707d51d2a2d126ead771fa5026ae3984197e11516c61279c1229f3e9a1ada0932ce5b678c7a70e85568d2da2c504180b5a7b29f0d95dd1791ce39aefd72d5029b224bdbaabeea9d9d927c0a1418a524914b4ac09cb9a9d401d8c5094784387205ea90737f445fad90cd8b8dc3643ebab2da72d768f659e982370a89b20ae0c5e79ded227754a39812810a44fab66b30b5fca82de36c0ef0933289b58062b6ef934679c1a09dd8dd322087f777bc830dc235ce99233d8cb84db17fb8ac1536e15de5fccd302d4bfd159755ff6a268d3632a498fe83c98a3e02db10ccc4769467295c69b725fe964ef93d12b4d26ef470d42fe6dc7864e3fb534b493fd32bf20f0da6c8b8a0d20a33a89fd03920c554d88ca116d934a5bcfb039951f4371df637e929585d20c6958c338df56cf0bf8e0806ea36213eae22dc57bcb02f5dbe4eb8508ec6b267178de72db932daa356caf228765294486ee6872c83c9bdd8f218e109fe3a05a93aebe97b5a6dcb32de375703adf7a2271d3d115652fb251f424f498957a8947492f8833e9172c90950055a407dc3387e74ff6bef56e6d37d071c68ec6574dbc848567e2c1a99c65304c6b3aa2bde4d13ff1865c082c6ac2b6f8f94ee1d134bb19070c5e4862db0c66c40645cb50b02a18ffdea2525c2a2f529782ef34b099c3bc8527d8c5c98d08a3db4ffc4d293c1fab9719d9eb02e6acb559609153c656115cd706db363f6b3c5714f3972be1fb80f98a7bed288c990362b36299dd8f389b86b5e02a3815ec9d6b3f65bf4f5c1b134395f35b14ac545941875db609bba65bd85c941b24864615d1439e76a35a9e957b568a319b29a7e35f942aa979f4306236c7cd7aa923531e4d0d5b0ee2d20c430f7f2678961d3b6455398650b27c15436d40fb4af61dac278c694c43290cdf1f7f80daeaac7f720ddcb191492a793cf42207ff6602dc9964d6e8ab09aaf5bb0f64fedda7c7921563b47039a170a85b48b4515a20f99e6f3977628b43f32f8af4c28bf49036c8af9314cf697feb9fe77feb9f93fb6349a71389cffe9c656ec1149150022bad8e399de5b73ff496d64ee5290bd63e79ac22867dc2550e9772072e4c2c3d7ef04ec9f83692dd86d716bc084617819f53af87cb270a436a78119724874f955562a10c73273049eb805ebecf5016f48940000d0140ad2247a518069db607dd716dc76f7aeb3ec6ce4df3bab87a7346c6aac6f0edb51a705aca17ebf07798bf0b7038d3b93b33efc74bd5bf7090e5903ce4bdece4b2b7d443d96820c10f839b72ac6158bd9306f3adf6a10e58b77d7f24db7f8e3136d3444125fa6a969d75321d35c74237214e5f3db3615476e921895b6d9f5af60f3057838f49c62eafda87c6d51b5544aea1b6b1671b814a5b8410d43b05dbd7ac34edcf32e89a6cfc53b820ebba25b534d9c96845a971c98e8c01333034309b84eb9bcb614b5596b02769d06e39c3c0f08bb35d6295ea7b3b7ac24b722e4c23b978aba40b8a9160f80602053969daecbf9c1c0bf5557d7a2899031d5ae041d67403c7cde847e5ea2e7a0305fab5f1e6f1d6f44d34bec3b245d20dbac431f7a55ac6ebb2792595866f7d303cb2df09d19b2c86c7251d701031af4f6bde276da5263c5932bcd58425c2656cffcef7ec29bba0f1e7ce67c959e514369cf173ea6d6cefe536f3b34069d45a0412a71f9d8fdccc8ad3adde8303db697e83fc2c8c442f06fc1a41a1e80c39c99104ae58495c75688bf2f89d481fd8cce20636c0018ae1765006e787e1194c969c7cd5c93b6edd5ad9db5a4c5bb001e6fc8b0643c5ea9e7add63ebf2234de2da4095f10c3d57108a2bd4d4734b9ce41beee0a462e0d720f1383e357e965ae303e881582a387a238b6f775305d80afc71df16474fa26a7ea873a250eec7a7972227b3a0bdefdebc28954a5d0ae073c57338672f1497406b7239b2a14692bb20ae28a05a62cf0518ab340f4b21e5d255639a7421dceb04eda74199ec3a0cd99a5a385f8a42a23f73d2541bbd6341cc69c95a5339358692396e9c2608b427d4447a23d91af2f24e1865f1e3fe41487c8768d5b0a2fbfa0fb455f84bc83f304b3227a911afcbed59b96decdf198dd9e9e1f2c75b9b46695980c2f53c5305459ce1bb77e0381e8ea727715b8f7346e8f306c852eaba06e4d8c5cd1696a2e6d1c072a7431546fb7369e50403322befb5099b78e75c01435faabf0bc794b53692d101595d32630b87fbec16c4e9192faa3df1423ef105e023ad6c88d5cdb4361e0c85f48a8569d985c31e85aa4711dde1ecf74ef2817bef9903d055a23cf28a504c5dd2c483c5056acf1382f4996c78b1da6733105d4b1bf4b0fce0b8f90d2e629dff49ef7e17faca616a7debd361e3e619a21abe9889abaf95897050f782be2419d7d887c9e1c26a63db6116e5eb7d2f638964b66a90c54494cc77d4ce66b8d6086a6ad728ec8ded29d96bcc1a544cb98b958af84230aaba60b2c140bcffd4f24164c0c303331e3fdb6394ea87425a2912452d871b6c68949102f3d7c327437cdb51c33fdc569f12883c23e61a44ae77acf1338efd85a6ab59fdf9f03f4975491336011e91a186d07411dbdded5876127fecd157130a918d3086b082e7470eb23d92bb8ce976ac75682fa93cc978d1347688bfd46d58cee6228c38ac62889506bf2babd3a42b101810c449f635a7c108a28f29b8375be24671331e9b7c1741a9b3878de93e5263611b804daa7bfc31f76cd04ba73f94d2bdc03b520ca9493d0038d604eac0c37c84dea7314ab218276a142001d510c033cacab5816e6a7f65e353bd8431ff75191d07cd1f263994dbe7c5261c56d123bad3a592b7e5f6b201b3da62f8a4094d0deaffef0f81c95c704b02218b34f881a0da5dbe787f62cae4542808bd809c6581b1b98b35a84f54b0767c5216915170b055313ebd8aec53df2f387a7baba7d39d576a2d85eece87d08b3585ed769195a37883e62c26ceb75d3c9aa12898c60ef56b369c3460295d65cbe768d04f08dc98b28c78d2c42782cb272cdcede0e53375cbcf02155d6443a18d331a0e926d5a91203ebd41392db1c8caa4b00a74428dcf8874da1c7dc970bb327b2b614f7dc99fac1072bc322d79488829cdadf363423fcd58e9ee61de080adca7df4987d39bac45a858da585023f031a81fe636a2f3b2143a8c62bb1311d3456312255745460e94ec1474272a52f906f10abdf00aca9587a86e3a7e0fdd039604390acdb2477118afdc9b85e9a77049e460c4002a5526270e634bc54ee1636b986b4c6075897b035f67b11f76de7bc4024cf7b0e496ba620f6f6113808fb09a3ac4d540ed483983b7ad40857d1a840a30d121dc734ec2ad5933fce7be8e9ea9f6b03f4dbd68d29aec4b635a79fc1494be5655ae9afca8f002792a36de3f935360a459f08605c697dfdaebcf0712bcd806bc4cd9879e2516cd7dad5e7b9ab827b405beca8c9b24bbcdfcc92dd870869d7f8b9d31269a3e3bbdee6cea1efd253fa48a3809b4da809619d85c70fd213715c241a25afb7620f4f9195476f15a21c8036e8ced580301e27c9239efe3b7e4a68a739a6bdd9421dc23dd7115e505e3cfb6d302f81d76750eaf759a2493d04de9a69dc80b4a9eb611dfbbb99f43e9cbb3aa5049f5007a4e6d1bd703d6d4a0c69abb803114a11af98af3d132185f2b0170ee7edd6166afca4ac05e497257a2ae188d4ab13fed02a9b69af5a5dce855c393ed6992466b2dbc70776abd50fa1d4d05b8814668c15334787f54c454a40d9442d55596fb975e513ba35ebc50774cccd4fb54a591ab346f64dfed242c420e3a1041cad4094093743b0e2b28c0d8f2ec322b7a10815b4174d0ea6d829beebf436de83ddbf8036d5b4bdf0a01e7fca29d51b5a1ee1a534df9fadb36c9795e28f5b7d37978b8c0ceedc9fea7c42d92a03e65983ef2b74eb2b70b7250f36b5f848178e6194a57fb9440ce71eb0e51944661e6c62c5df640987465970e4f0352954ec52ac1158494b9f86698a25b93f97b6683b1ef274e001ee0580970f403ebadfaa5670738ca4e9aac717c1f15a041c87d22fc756961f188cc1b56da5ad31181b1ee258bea1c1100ec11ed4069461fd95f1929e5d6be0193be7a4c4eb2b09987634e572732521320e8577678be65082d18dbf7b9f8a06f555905d04e859f6afe5aba27b8c64b193100e227c41f98e629d53beb2d21f72bc2d0b03cbb2865731b0750a0bdb03ef944c4c68691b7b023cfb59064b722630be53d5ed71175f0b1ea071db5fbf868729043bf4dda18e53793f0a0891e097175525a497992209a315258b1eab1f0b1b5065cca4e17c6d52ebcb5df1ef73543cea8b362a6bfe5a3a270b09be6abde2835f53aa680940e868d4c998f23daa9fb304e5a2c043b304f64ef5b24b724e475ac55810004ba27dde049400dac2c847a400e9b30636e8f9d89bbf26e55635aa53c9deef2dd3ecb91882d147efcf527931289dbda15806706ba8b4407352e4d69fa4ac968069d67c5ae3d1391f7397e03bda1e101f06ef202b27e8d87f25e4577507135cc3fc62fb107ee3c6046f2066bf8d2344f1b02aefdb00cafe11bfb33e625d570a3d98207c68857dfa6d5982ba00f78115259349494710d811aa8e17ef4a5cb5896ab27e58851425686ec7eeca54d43c43d7624b3c6d63a5b382645647ed332a1465993dd8e956bc61235854a9f7d02ab0f5c90cc7beddffb439de401b4a7caf5f502bcf13df831791b7904d0bef760f932f48b2a09456b2473df9cee3082f7f305db8a86be28a068b6cd0ae4127c1c12cec2305af6ca637456591add842878cb9a1aab317a104b4ab8c9b3b931503366d68855368e98dcdf7886a26af1184c7112be8b3ec99b4697ef1f5a9b320c3a56ef8b5693b8dbc48f59d3f729a690ad492cdf21daa323dba86313c04ceb946c96b5f10cb61d9fb7eebefb7abad12ed614e59026676e6342efd823cff842c593c90a3eec2508359f01ea550f5be97904c3968da0ad3cd5567b31901424c32a992385b9b85e79a8f5fd80756cbcb51e6673b2d7e292741fb955d45b8a70e0a38841c0b097fd2ef9cec9185cd28ab5fc76bbfc057cf5c3d27604332805739e3720bef557c45cb85a8f65b7da56bfc9950a24cef01cd056ff5cffcaa10b1df15403ac3f0baf477f3abc05fcdafc26c53480d9ba3e69085ea9e444aef497417878ff067abf538b4c5ffdd8cfa6fae65fa036c0bb0f0b333e33861360af50c663e9ae5a43e2aacc8d478a11114589ddf34b5afa6ce8fa3448e632ff0930cc1271b8f36062cc6c684dcc1072c8d6749bececf1893fe4b00529d1692067f45cde37b291bdae6d9456b385a71cdaf8cf5ee48fda8c369ad05a3809660c1fe745e442046741c065915f255279db5bbcf607148ad9198daebddbcd57f5185cc76a2e575294225b0265263852399ce7bb5e62e1066a9356829c626f41002b46aba1905f41f42c3d1ea6ea57090b697cc74ccc670387b6f5ca4810bb05ee53eed1a2b2ed350c1c6aa1aed677aa1cd80add7e309981de3e2cd920e2e100954265c749031869279e3a13821db037a5299c27dee7846c2a7c15338694c2d88ebb0bed6e8d62c19e68d08ca3152446a0fb9d7ba6010cac533547d518d97fa80c778517e535963a178d7ba7bd4ed9e043c665b01b3d0ab9d2095cdfebb1566b456b26283d308aa8916518b6bbe4df049817e2d7064066481ea4ec56ddfbec4e257a0e40ffb2024041e5eb37cdfb769b27db32d584f85826f29915e524a7caf487990bdd726f85405d3a11010ec17884e32c60ee6a25b4c5e7ebbd649d408af80d7b29bc63f6046b2028507ed43cb39cde0f09f3d5e7946d1ea790b0c23fff8bf7391efbf7291ff5c3b11c42f4782231e9fffe723e370084494473f229d4267a8b331c72d5d1a739bf52ecad1b829c43296aa93acfba2095d4742b62f7158fa72194449c46ec5323e589f153ae9f507811295a72e4a661232ca8348876c78f226eae1f0c468431d891628fe6d0f4e211902002078d93d52ab3616dcacc9f5785cb4c422669e512f780eab0964a09307d7b388fa849502383701f6dc82268efe48664178b40861d50562d8c0f37c248133816f312b47604c6567a52deff798514355ee0fcea7e54ddcf9c98346a8d667b1ce2c69f1a8f649f6fdbcdc8bbca9905fc74394a0f6ed2c92ead8acb0c76cbcdf6d7a4150b02b3373705840582ce5c5e49088b8f96980a831dca91c949409f6863b962ca79507a6509249e361ecfaee72af7cf2903d821c7f98d234c46a8b4f3415d3a1c563cfc1c6b000ce6698674a01b4deebcd6ad4d6a6d055d3601efafb068d4882b69b7d5df0cea74616f2e49bde18f1f93ce3a4d7b2ede549e80c34602492d3d58e3626cbed44da328c070a94621d6a6441e96b39df0879ac476eb6309ed165005971295bb34925943e00b999582d25ebb829f18de70a161697e7653f4e800ceaf0013a6c9ecfbed537974e5d70fbe9418eca31100ab44816f427bbc1239ae8aadc7abcff3666e3b438b3e4a65e4ef01104d6adb3f5b90d7d719de87a5243930fdc4523d254128d86aa9db189a8ada216ac1b0e6dddf181f161ebed965818158b0c19d8828c765cab8243948588abcd38839a67eaf79db6caa8640c1b79c0bf1b0119d419e21a22eb27b2fcda201ae9bc318d78d0f11601f08d95a99133304e75474973021bfb99bbcfc9f9276a1a422c90e9ed57306ce2aafda24243b5f7615c89cd1999f89507e854cad77150ea6a5a24b4b8483ddcae81ffd4823c9cf81811f65aecc50504aba5be1ae38c0504cbfdc8fc10591afd1f8ab4b98d0f66bb04bf4a61171f7df165789620e49060abd8d15b8882cdfa58f8ed7d2dcf1aa85fc7e6cc03a525bd440464a3251065a614ce09661e000a45bea565711c72c58d24c0a86eee4d0e576d5d6630bf9f21a2764aab151be662f068d19557af0e938bccff61edbd95b0d7921bc0076240ef427aef3d33da8fdefba7dfba7746238d5655fb4bb5091316331ea0d107ddb07ec86d5567664eed96377a5bfbe769ce569dfafe5416627062513ad85a057c3d229c2a405de79e56551b95a91bd47750aa23efeffb7a7d2fc0e9e58ec21cced96bfdc3ec5d0c5a2cdaf14e13ec6f8bd12ff06faec019ff935589699008ec8335db70c275e5f8c99ea81692e08ab847e728b4610f5b696528f4f781aaea8084c04587c2756b3c7ba6ae17849fc714a12f88ac60ffaa5e5ce5c28945f72e7665c373c38350e3c769c99da4ab3cbbcd673baf260ca03870f51eb2b92825a40da4d2c61e23a92da41807d79eb9d047c71ed4de6141bd68492858af5907e026b882c484046709c17b9ca4035092b1d6cfc47e78ad12ce88c2f653d72f4317f0c6ffce028e40159766ac19d4167c8dd0a6525bd41de2a90778905037e4cc310a519fb8d7e11669cd3aa5589bb0017b4586cd1e1ba201e5c1ab55f6cd0347cea9af235b06a160ddb26bad7f3cd8b71c2d557a74902933b92518565ca518ab06aa584ffdb25098d3fa5e7e656d2bf1941675288b23adb1ca893f08a2e527b5bf3c53f19572b0a9d696ade33ec393b837d6079f7b8e656905d58ff260fd432b6731a33e2067ea98314f9ca1a7d13cfe87d4fb0c5901abec9c0523b16d7786d9f8b339ca6d95430e0646d32fc644c8ff6db79de75d7dbba0ed84b70c24b76cd4e485954877712b058ce6d088e0e7dbf56b53ce4698afacd09d3c84f3e3341742bdb3850e215c28529434bbc792322621ed55d1d3e0f887a453b5db3656b59099569691bf315ef4e35be6074735f886f72f8648b1059a1dbb3b226c50c92ba5e4431f6354a75a3a94cf5837975ab09c41a694eca91d5bbed479051d776ed422bbf8eebb34794b2a0373ff708f85acb36abd4e60cd22337cab2e8f4904beb453573d8fa8f8dd607cff3d084fe038ce739e9f50de2d56e25e8460ccb646c8085392407d4b98500d711508e5961eda4a2b9266a3ed07ce384b100398a2dd2de95b8fa7abead37aaea9f84dd2035c0da20a883870cbfc6c3322f3e09365297e753d6901d33e84a8d8a5c1b6f83d6759b3b284e5513a72ad389a896b141fbbc6efd31d3ae8273c5c51fe2ad46ff7b1425949dec5cf2fced0d0e60ae4c0ea239575955a31303f3d66ace360bcb02a4e29b64ce6172c69ffae97f105ce7984e38ba81767b383789a803a516523f2e58d944716e8609b192839b0e3fb1a2806a620da3eebe9d6d1370366f8057f278df5f315f53c699aaf065db57c97d081d1e5c75a202f87806eb2d085252912ef6a6d0ad201fd42ececcf33103fda43c253bf9e02dceadcf4afdbb0c1b2a5d2a7eca2d88fae07ea15ba5ef443b432a022119f2197f8f40fea53eb979037d97cdfcf0461f1b58ddc78b0a14d7a33b4c6c5b540360715ec01e58fac208ad596e04765c16a6b4f84d1c0d8941eaa3f98356cfccbcdda03d31220fcc08bb270a4a53f7e23803634f2ac5d5cd16441c000824a2424f0f2c8f7a2bf92992cc9d850a1570b355313f543d019deb0ece3490af6ac898bc18fbea81204997e41b9fa37d11ce0d27feb9f06bdb7e9a36486e12bfef747fa07f933fdf3cf048cf0bf266e994a12e17dfe5ff6f84c6198468f194b3261b34cce9d9a343b411ccc0da304ae04b3d214266b60b658d606fa6e60e9cf503bbb4b39ddf92a6223c3f0a20d5da7ba979e374859fcc7be2ac0ceaeb352554648b60ab7a4da3a70f4aa4870006d52de488ab514f432a5dbb7a4886c73be916ca9e7b5ca046845fbc853c2a01f2a8b9751f10a4d1e335569b911f3d68ea42e64d63fa1dca194c6e0fbdd180fcba5d4722794b566c9372e88fd85abd5cd131b3f31294e8b7b4359697aad3fb213acfb7dc627b442436af226039bae6d793c8aefaee75ae0e2bcd3fad88cac41cb2031944222d05cb59c38d317c43c0d97ef1f141c7caa27d5cd68c746287742a175b1c01bfe708a435c62206dd71e438b1ececbb699c142ca1d83a1a94d47f1677f26b0825bfdd1d06666b39d7ce333c201bf81067a0563a27b6c4698eb6d8cf424e756490f49b5a41e1e8181b2eed7edfa57bc393fa41d8c2b0a00cb1a86ada402ba3d05b3beb7d138ea41d8ed343e3d499bc1b1fdc0a563feecdab740a536eff09efa659fae04abce5a11d20a72e0e9305b7ae10d183e228b2741e4f04bf5a5fad27189ce2b50b8e7ae8b01cdf3f4b0bdf530e3804646d270e3722fab69723b8428c2462a84a83b1166fda8f5ce53348630f765033a6c8c0477cea86daca3fa4e334a5b5e7d9ca2fe08b69a69e0e67a824573316a7296e1df55d2995d58f92574d5453bed8c5ac7818cb03b447c29eb0c09444bdb112c10c11a6ecff495e28700b8b5c77c15ff392b15877417ba92a0615afa585498f2e668feb92ad0c8a1b0d4c3249bceed4ffaf11a5e4287ce3470ad2b4a97b0ba9d2bb0791a1bb26724f39b8cbc3b567ab2ed1acd9564a32c98bcb5d288dd495ebd47f0fcca324996b4a0f8ac8bf6d7941a2516d9152d85a7197fd2c427f4f13d07f9de16d0777e31ea6f3c846911fe0672d158a120eb679913743dd94c34e5673867087d507f1c62af99b1f411a79c2b6bcb5ab7a859f7317eb5060b4891e2aebbe4dc4638bde060d5ca3800e2be37fafc16cfb3ad2230b91a502a4257952ca9ac8a5d8b56c6efd21a9e7b3ca2dbb88333d4655827e0da8573b9762266e89c77a65ebdf9c5d637a3954c1f738209e59262bbaf05e59098c2ac0bf31efc6238e56b5bbc68ffe86774a8257d47de569bdff5634f96514213776de527b23cbe76a17f0f3e6a68654e3773b0e814a7f37ee4fbd0a50714698853b412041a8a84390843b489d0c0b1a1ff0c2d4512059da3178ed977937d3b821762cf80b4724f1b542d58dbcdd2e1a15d4c531939acb612e11c40c0b71b0720ee4e00394578321e99e5ade2ed613950573f164dbc6c28ab722adfb9c19c11a3bf0fb8e66858d9f8ec6ef7cd64c24232b43759a8c76c5d93e076aa203ecfe4626b005687ea8606fd5f4af974843486d56577636d9948aeeb30b15935a3f8c50325a3293d90b313c8b6845d5ae1533edece8179a89fac37c745808128d2fc38407edde7a48f42242615035d3963d0a0bf4ae46273a74817e0777ae7aff4cec572d6f35e37d6cf6213e649a020e06df48502a3180bba76e65b8d9ac25c55f139355d71592a8be799cea2cf531f6b5d7b0a5fbe6639a250964d07eb8fe3244eee8907c23b492aef8ef691e2c94aaa64c956d689e961805e874d4d89d75c639543b79492bc624ca8686f9a22d1457fb50cb874b6277c2d34b5b2ba40a380b889c139a0384886b4208f834d01b6b3583918a8e87835ffa25a19af5101aef6eb37c486c609e064207a68e029ffe6c3ea567f7af51318868fb9ff577ec0ffc887df9ff1e1bfbc3a7c8ee063169570f1cfc49d7ff97652bf0e9e23148d0a1421c583e64860b555394a75450a4fd2030d8ae6d9f4bce5701e5565a86d36d832b9e9ec1ee9a9bc451f545d1a72f7cce241880735a3f868b47474bdb06da7a950a206e881fccebc06411ce71046fcdc4e926c2d42cb141b1ea024cc79b169d324cb6f4433fcccd013d0c569fca08c4c513bde8d3b517eef1282af913df0796c31817917fd4a51a28539da7614c4c32bec6e3284adac8720a11212e03baef8315ab0cc8b76f04d124e54e4ebf7809de06a93e42716117d495a502061a8f6eda2a362a991a8f55691e17a85bfe8aa4c479270f505978567b66bb2edd8dfcfbe044ff157419f6f9fe73e8567d93e80cf4f72d39b7df3a14fdef8681ba0251ccee487fd10d3ed6a5cc1aaa28bb08a521c808e67a0971a2027e7731432f297f3a7ba0e27d6069b64d0bf58a4668b19d1fefa39e81ddc04d29cc80b94c347878678d4c207e7251a7ebe2555c00667d453956f78b33828146a29156e9c1fda6b7d3d244e80525dd11b231856016c37a60a8aaa94f4d3968e3b4cf6e5162de94e0370680d2487cc27a775bb06c8c5a240cc02bfab04f62323c03c595c66793aee0531c8a45d4b27f4e0eef06b45ed5b47793d4a72992302c495a28cbd572f0b873ce91b695808530042c57c7686e33a0b7c01bddf51727bf89b192429620795957106105580402403f7a4d751e3b27d2fa00e5e5a4c7fa70c4239de7bf32459ca3faeb057c34ab1e333086904dbdc5c17a50948a5f3f0cc0a0e3d8b29f8e669209fcd8f061b6c9a0499ef6e77f956de3de40de96b32100c2b1b28b88d62b6e93d7c986cfc533bc9e6025f6d17016eba2e6d1d99642f78a6be9b968296f002d09ba7fe15a82e750c1c37fa9e26f4b3c5c1a30783147037cd019eeb3b639fe2ddbc4a6c81f3c809ea72a2fab2003c210618e8e4dc2d7d5971bc024c7303de80261fe647688c9264d9ed98e09ed7cae1ec61a99b067a04d9d3e05e032875a3a18fd99f820bff0ca7cb3cc5af7cc0b972f4a552f7237a4b14e842ec40c91d38ca29874ee94ed4d19b386226bbc2e9951a087944f10812c4193b49e12e69c549734e61805e11c05e118ea6e7a3554b6e667416a63ddae0a7fa00a708d4a0a801653b19a7209bc8a4e9826fb202f182388ffc454511cb39353bf52d1b8f12fe694ecdb6bdcf47a1e0b10b797b92086bcee0f3cad078bdf62b532e3183354a4956f88d8c3946bff5951c77f17a752e523e30a8455da3d664d29fe59c8dd70b4c8ec7bfcdeb1523b85b060c76d856207e6416febad4b5046ff16f2c3d7f0298a43f9e6198f90fb1f4fc5f62a958496157c6eef59ffde730e6e2dd879f806650a56f11c137472e0a2541ddb7775e387758688c31a934d225b3e5b4b0cba2dbeefd78cd14e73984295b24c41b4e3c87daf4c8c4958049f707e53f350ec69c9c0ed0cf818a4692be2b1c06ab6d342b71b2a0cbef23d10f3473309e76fe9673cac41a911bb5d14c27871a16c2eb6923436a28967409ba541c0de6a2c0713a054308f2b34361142d5cbee81b5b7553b3dc675e73a273ff98b508bdc8e0955990a625175c6536802a9985b0a1c12aaf2e8c2eb9e79681637c90a0f42c7a9a5b7264d4476eabe23df0e01c16cc39d4192a797cacda9e5942f27355c370d748299bca785de9d6fc79e12ffec1e71671dbc89b544df66be92b90ccd657fdbc6c35e30a4eb7e2367711b203881fbe086754ab6fd5b0f52ed265c2d40e551486ef9604a48d8121b4a271b08329a61a9a2a774daca4a661b5fefa280cdee7516fe855ae845dddcd7c5d099933abd2cb3d0a1eddd29f62180e59582a01cc3e014afa7bf618b45a530c087471cd3c0559d737355a4452932bc9c489363338658d21c95b12ece0ee2034d292bb9f42a77d62278ded52cb6c25c9c901c819e219c9a3711825ced6d9c77b25cdd1faf278f5bebd83ce8ca0df120ca875cc902c88be8fc39e64849ba3f70fa4897b99b994f16b251df47f315973682c824a0429af07ff4cc96fa8dd9fc10d9e7f98c8c0cdb2c5fb2a2569725215b76518c51dc98b6a18c2851bc1896f0d75e2494afe591dd35b005c673798a01f2a21cdce4d45451e7c5b1dd57e359081a57834772ce5480beb680a6a34c327026f89b823096aa586f56e4739678f0c502ad6b3e6f51dc97a369c799bbfc1343229efb7b2b30bf5ced7e5f6d462310349bf1c0de3cf80e6f7048a82a493b3dfd7eeb3659d1e8b4a4aeea0fb8cd92bdd325da4c2ae11ae1b2b6d8a1b6e90a7461dd1240d18b568db87cad769e07e66519b2f59091f39b633fc385a6bfc0b2679dc283cabe0f7a50f24eba5c279f15573200015a04a066c4fb78477ae6e68f0968ccfe31f246a880543bbae2be9e351313e93e6a646d3306d7c2cd68a18f562e6324e140506624e02024077894c908e8dfe2d04a3a8c1121e6255aa3cf6e56b0d89b6b06b78b608447d6cf92448d92bd8329002fa36dab91bbe1f2bcf89e3d6383bfa486ef0c9e7f8f6611fe2dfe7615d2bf0a45256fbd39aadb1e8c85c4db5bcf0fb590c07ea6a69473412bff6f7d61e58b9a7c6fca6f407f080ce7f1a496c87e6c84a8c0c82483c153dd6dcbcc7a0c574df08707081341e5785395fbdf817e406197d43d2b32c5285a0a0de65340c2b3ea8f66fbcc8a5890d6efa814d50051c09b433a0e0eca1eacac276f3a1d2f214ca7715138ce878ed6b470539918cf616fba1600fe01551dc24d3d8ce4310f7542e4059b66ec94d639a264221c3e7a9dae1f7c5e6e6bc6467fd489b7e58ea7057d145e157637e3e45d4c0db6a6abce9c4820d51831af7687a28d98ac21c685d21f42275c2f7fb1c141832c2d15ae0cd9eacb9f1a0ac7f6a49980b24a9f56d17924dc215792c2f40984b048abcd8816c070f88d3f916a09dcea320c18511250b1a4eee8a21f3b8f133448b9242a84b724287e34f5c89e2d4c1d6b05da5e0818fe106037325fa95edd9f83b91c74241872028db09616fb08564770de08a45bd02d156583a9338d223d51713427228ba08455d9421f27e67a2af567ce70f774739393ed593817746a6cab87449d1ce9bc572e4fb3d9772851715258e8990685a6b7a5cc417251fd1ce7108b7e59832e4b24caad2fe26b81ee638c79ae00d8d017c60167c3d5267ef42799cfa8c50a1c5723d2c89dfb885315a08b845746a1e6435a42c298ee5766d509809c2a056fd3253335f11871e529b660c5cf7e236168b31d90ff2ccc9a220fda0436b98b481bdad6f6797753983c9513abff1abae6e6abf35334861c99339dee3fe35e46e55a0ab9f03ba212fd9d458395eb84c84290d08adde28050bb9f0dde1381772f6348598680d1f7a3dfcb808a77bf664ab00f00b3352783175643faf9578474bfccaec158e2df1acb3ead10aa5c490144024b029b982672c443d976ed5fc760ae09d113e497a9c5f5b03ec6eb77aca9f443ead4a322bdd5165d756d69cd14bec14308a75f549446fc2560b2bc9a33e5b1f7c5af4173cc6f270a85097c7bd5a44e7deaaa553ae624197d38c2701b6572d2104dd2a268e8889fd74eba11c9d348b20db47e00ef346755172a0cea081e94be5aa95f27460151a3c617355b92fb139bebab517646e58be3d8c555498fe30b9f180d08d82900ca97c06458e79a57ee2cea9f1370363285d6c503fb989bd3b8cdb78fe9537c51196bbead48977f874a6946005baa217b1e3f72e09cd4f314145a1bf82bcca94fe59ca13533a2f644ae5db3ec12d6f28896f98b5c3ad66edeb69989c27e77adcbe050916b3e8584d816e57b36d4717e1c475f2cde79c407c37e4ec3d00b46eaaf6ef9e4c463955b52a426350c5f8b0ad70723a2dcc6e4e62f4116127ace94de772149eb929a204b42be8c2affeec39a8d2785330f8b5642fe38d7ba99b24fb326ea94021a3a26fd70cfe889f5363ac714d6b266219452c2352312dd1151a5544f0f3b51d46dd1c84cf53b72b64125ddc5af0a8d7572a087a5060c7aa892303e9b79d1c0ee8d0e96d805b235544ef57004d6bae22cec343eab4b0a21cbfe5a1123eb69ef9fbdcc769ee8dce058d75260b1189b6ec16cf35313e2e9e9c247b65bd461f3f79ded42fabff33bd17037e437c41f20cbf7b6c17b32956518da1812df7b46ac0bda467bf208bebb6924c74d6ac43f5391b85df33a3d5549956ab573f54e0594f89182107041b1a28a1a6bc5a65fa16e06dc039a05b007f9be30a1046c4aa1f31367ab74ba23f66e25ee102724203a16cbbec3fb0cd6b0eb2880c69250b963d3a5179d53af4df03a190c93c3045d6f4d6632c458aeb25c221539b66a9ff822d178b537bdad1dd9fc9f692f27ec258c2d02998c309880bd273ab1ae1b547a6573cdcfb132b508e976f9eca515eb8c586354395e04b6fa828cdc3e64a7d7ec0e1de3930803208f07f7b4c3aec210cbc777e0cc3ddfe9f65dc417fe4314990e74f3312ffc7592afbcf66a9ba5cea2f2752bf52569b0475f91c818f24c27b5f1ace3430af7c4a876272ffabc72524202c73dc1fad60d7ec6d502844e8b6846572976186bc5b009b6d368aeca6b4f272dde4269a35e32ca9484017145577ed9b6bcfd39c9c5d9ba9f751a0670a58b6645dcbb605149871031468a3181b19a9c4c990913d11b9dac66ade84189fb97c1faa9d8bc4c10d3beaad1910653fdcecaa620b56fcd3107e9346754b1658971e19e18499d74c1954bb4d8db0904e005141044ca99d4f970b9176cc8e3080643887dd60fcb6f55f7e1f025ce0664e62e6ae6124494847307aa9b851d1ae49d59f64d0112f925a419f0185a44ee190a6d41b44059c04f4fbdc976a273806e71ca1ec919a06a83905d9d7284e30a86983ef1c2b3d5528883e87572d823d14a560d70c1e0d4e8ec66ae0854ea50be96302091b2b43695eb1c9f4905bff40c66a5001a1538f3d466573855a2e001c90e546c94dc9a524bbb247136d4dee45d11bc7fd7d231712eb05e851ec2f21a09760f530de5bbfc2c4009d52620fcbed6fdbf1f4041424b39d4a434041e60d1f57369d652c37796c8b1c9f7407614d7988e78cb9360a43388cd2a53dc6f939f3688a573e86377495c19034e8e693f3902e0b86e4a9fd836cf8c4eb8abe77454a6769bd7c5989690e484a8d0a63d79456186c4cfa6e11248dce43464f03d5df99bb966b60ca7af3e1b6dd33ecf11689f9e9615d6c65b93b089152119091974be8c27c35c59ba1e86f2421775a011f2fab14082a7f93181966819952829ebe7432e24df3eca77d9ccb1f095b37c471a29d93772e17499ded6ac524c9e3d8e8bc187d428f89461e1ccd2558380a78db072eddeabbb06c8e374fe0abae01389d76c97a5f7ac7d07e9a3c1fdf96f58967748f4fd2a4ae294868b4e0e47bf8d18c57738205cee7d88c647a9a57687658c1c36fcb28e9685112b277cddb36868e16990c2598cd5e3ebc6d3d1d6a6d8a1da83a8fcd9b599de0e0153404f530103d6c006078c1ca0c1b7f4d20a82bb728303965e882a64aaeaa1835614da1899db483a3c00c090d2ff3f7ced5c87b1c7ea2a7f2907a1a338523cae123aae9931f65d6ced24eb7a059ea126bc54526d8fb156d7efd03f3ee541411d0511846fcebf107be3ae1cf767cfe8d7990d816a8fb26910905b27a1552f896d230149079e511dce4a36b64113e38087d96e35feffef33e750bd32d7a0e51940939377f7d6eeece2f99db265cd67c612242811d51913358e61e98638e6c29072e387d340ed19b8a731e94171a25431d1879fbca971405f80b0ae8fd1ed95433195d1e933185709cfac8a91ba6effa1e98002e46fce4eed533494a0c0d073c3f9cd26030c52aa8c3803ca35c5dd72154b4685c08344ef62896225db1465940e0147bdaa04cd07d59cfafe908be47d6e1d7b258412c3c1ffa29d2d6b0ec9b63a4df6e64e0ec284b88c8f21427cc774223cdef28ea550c62b13a5c50259c2852520616f5d3ed3dc0aee160629152dd9b6dda25800bd2b33356ace400ec1ce7a7271cb8808603894ac00d9c32ffd62896a1cba1da3a255ca90c5d3ad1885fcac7b80147a404ad7bf44bce368f36bc1712e921649ab7ef14f2f274779a496fab66e4f8b2e566b99967ff3b0d56be5c9dab6de7441bdb7d3ef63d06a8a72dc39b52d56dfc3bae2b1576ce2f80b8c3f294e26eed528c798c9f94756cb83d49160e49e52b7b974a5b4fd259135a8a209ea11449f04f22730aa77f54f16709344240f86c5eb384a83ae99b55ca9bb555edcd1464c30113d2763e53598e6e3917dd6a2b5fdeaf46185cd6ebb93a9b7ac8f562585ee54506bf153de9d01720bd8b213ee5d916904b805bfe9a8ee335c56ba3525253ab95de982892473e7be914496cce7bda8de3146995d1df56a65b7a8057d7ccdeed0fbca76b30f1f52b8a063522595953cb6b1cdb530954fe04ca922faaeabfd038d3ee53d624719bcb0d414eb67017332573540d5d4d63cf1c94b81227b33c94f2542859e9b4a0bd824de8707168a51f5443bb756743d00365b92684ff24d1ceb96d5f3c64f886543397812ebbf0878c14c4d6f101c7a2e7d477abc8259f09bae5f41ba0a85c541a28aca3a29fe4677a92066b7309e3c2c90d17ed353a5888d69eb09152f02e573a8fc8c5a23079b665e6683a068ff1ac70ab773027e52fd2881a57caabe6db28310af86de510c4e8f868ffa68d44018a22c22447e0facafc7c91145f84dea7b8232b54e30b53bac421acafe7f04c5bb451d4e112e4330e38cf4b59b9218db801e865f44ed29a85245b123fe5b0a6250f9ac45eda1f1ca228554968ce2f9f16038021e53933d6957d905ed18eaaa71126ff2a04a9921029fb7c3baab2286df6d70ffd2c929cd9be181053a0b92b92c353e9256b27432940b0d1d818e99ca6e160b2c27b1e0b40450c8495a7648e51c1dfd6d0a7b9a0d482f7cad46ed9e1f4594ea670e28325ea1dc0a90e34f75edce1d157f8491668abc62f1f7bd0c58fe49bdf433a05a70be8d368f555b099a76d951d7379d1db4397c3e6d79380f854ca939439a9d741919b2f80cca429743b5353941ba49a4d0e07b27b8adb2235aa4ed86c45249f1e9113423a2726cec182473939c0b327f8a1d10b211d7c3579ea84b5252e1344bc5b4507bb3f90c962e7e2854ac78100060f90c2ef7d6a5e6b66a7abbda99f46bf91581f2465547997ebdf7d3804b4176670340b08d44bdc6b3274befb2970f3cf039e162e22ad50a447f54d766ea3a41210db4ad4c711b22c2be9d4714c71389ca46457a15684de4771bed46c684734bf81f5e65b5d3dbb0f5ba893aaefc8e6fb26d9c30ecc7e5c5b85e1df9690b5db518f08399990027d200f699768bf2892e21d24760d8cc1e938e858ae51defe9bdb9a157f5969fb390c6360c69fe54e52ff0b6efb6f1c16ab5319c1433eb96225994321ffdb4c44d90ba27d774cf080b488c85eab308b24cc68c12aafee624663048edf53112f58f8606ae648e0e9c99040a43e8a5dff1870d0859255208f0773e7ba6a8204403aa629303e2826b674c755c89fb67895efd9abbffc4a88eb7dbaff3c4dd2bd72824f9a527eb3a4ef85219e8b5a483ee7a1df4be8428369023a72406395c1714ef766d4012edf3f0d3db9e4d9f4a9f3d4acadac1020ea56c3297e33954002448c481b07dec550629c90f72697f412c3ef7f0a4eb903fb384b4d38ef8a7f4b2dd6bcde18812c03798df3b390ee7c3bc647de0ddfc9c1cd66a3efcab7ce33213394b902ed40ae1570ce7cfa912d6e1a190a43471b6a709e8049747b5a8b2d05310ce4b865b12daf0e7bd18c86651a560151baeb4e3f40aa9723b0a0c5babad0923e64a665bf3d6c8f4ed598140942c5f8bcf98aea6afd0178731cdb54001fddb0c8e6be454aca4e1351b2a1068f0c7c9da28bd90793a1fdb77eb38fc35cdc80711826bd953fd26fe6ff46bf21f49147e2990acf928f219f233892feb75cf16080fffe97ae1465581dbc2d10e3e9950b05d61c1ac3fba96daa9b8a7cc77b0a0fe357067b0e1de0f4e341569682fdf134dfdd936abca21a9d643ba74019a77f1853fa2d727baad3212113153a95128efbc2bc2352a3c77231ec401859b8ce63d41e760bd86e2ccee235bbc66a733774426634b2d3508202a61e431620a088dc56f9e07d454bf37bd8f201af127bb419d54962d41c4a1c8dfcfd792775acf8b00bbdb3c816708fc1f9dd8eaec28a2ab3eb7eb0d92a87fe1bc4bf634026183680b1cff517234c07ff267130338344f2f1aaa745a18d6e923043a353205261a945eb98ec2f1c0e8badbfa90bd7de77a77c1ef43fb3269ac8e39dce5461a05d0c34feb575fe7573a6604614a3b9b4a46cee87d94b90f90bc4decf5136438634620b444210c4a35b439187cbac9d2727c8a5a3871471cf103ff959cfba480b5b36d5c75e075613767c4bdf4430c3dfb32cb4a50281cf080ca3ef7f36cbc23bff675cf251f6dfbc195318e6e163c6a28d59e25b095ec10667d86e91e0f2caee9161cf6db31a78379b084e26586fd427be947b6fe1ea0074650d89a731facce73d9f04bc9475ad3519184eb404406081f7af8ac0d950479f3a7cdf41d6e80156e837e11840d7f56ddeec41cf192b24470a1bf7fecbd700495f76b49734c4b0a6c32fd9f1d6ec4d47ddfdacc2d45408d6bfb32c2132810e6680f267b4bbc08f765e5381043ac658114df3caf55f03a9395acee3310af7e5c9ae3d473cf30da710c95e7f47fa4e4eebc3e8796b65512c6d87ca9bf863185e7194a0984e3d49aec43dee50d638aac1d3d1d519559c8e69260e9249bc4e2348a720fee6b875d74d689f7419e3b27f071e79b1b48312275a9660cd27d6f40b6fbd75fc813ebd5c6f8d86bc4dc8c28278fa34ea7ed0c5155e4efadeb0105fae9e08c46b4a78f9734bb0e6dc39d895f98db02d3181f28936128f2bd8e84c263cc37e5bb66714efa2a271632c73321a90aac722bb54eb599d38f83b3ad4c323bbd05fc5a430378bd58f4b5777ab24b886324adb89cc38e3a31eb6f6b60f5e4ba24278131ab6a2f79bb9cd98e077d6ada6b4c7392522641b646479932bf0eeedf1fcc84301cb2cab885ec735485ca83d6c94fa0e19e2acd0dfbdf6dbdcced8d38926394269f3cd97a9add8ca86da595071d14c4e2406e7c07cc790aa85f1fc1d11259ba8ef2d306dabe5b7b365396f2dc6ac7b8ca674e9493396d3bd4da70aedfedc6dfb4ea45c6b088ebdb55c57193f7882b5c2b3226afc16be43dfa67a5a439711f962288978747b24634f4e1a4f9885b7710931adea427990dde7d7b4ad38e1cca9975b6c87baefe231ddaf78c0ded0b3ae93526716af120464179939a787ed71957a12a9771026e306874d5a0dfeeb6238a45cbff24c43a06f1e4264a299895d48cf2e7194e51745c3800ab0bdd2e6ea10f31cdf73d1f5e4d9b90163177f9d5e6a1b5d2c919ce6d792b53ffe561f2e25137444a70237fa3d2378b9f8cfda484e66003cc38b7b4c8c8ea382fda43330855829a1ad296b713fbc4cc21c77708d1a161359bc483325edb06dfd327e881fbcdbe0d1d4875d04deb6c735d49743a66ae6cc5ae7f7e1252fb72210eec86ad86ede2a0d2c8324867f019cda5e9f27afa94e6a7a2ff63af2244b29178962c9494d28de32ba872de5dc1209fd0a549b64502284c9068ca0a2bb1043a1f7a4d341a937f882033df312d20293ab624c50fab75b537c9a05876738a0ca4c098214ed1a4dd4c92cfd0876bd70bf2b787ff207615dd34a85227761faf5ccfd6083463ef427ffea3ceeacc3d2fb2231d563e5bc8c5c636e3afc5ad4312e3d87d4061f6107b00ce2496f1d641231b98c8eb24e1e1b6f650ffb6c5809efc6111c6a558eb296725afc6e20b8136deae74a5c68cdbfb90b8c1c3bd849f279cb282807431fb713270370bb4805e2d91bf0d30398b7062832ce3488cb721933cf24c766d0cf0a8d27b8311d82f34c0ad16f0cb6b55203ac7d1e67a762f901416f901b2a4e4bd1f9471257190636b90b305855cff4ef928f1f0b4c43c5791dbdf8ee7915ae11a3b94b03ed4663088e4ffbad117d35471c5bef7562012462f74079cd7385225cece2cd5a001fc65ac9ec2c2390621d8d8efbce24b697899c5f6f0133b4fc0f53e52f82ab05ddcd325cc6a9228fc0abcb0db65cd87bd9b8ce48b9cd6527257c1c69ae8a9e887dc5619e5832f125507212523cd56c6150e63eedeb7156a88d51d421902ad3aa607467363fc45f1ec64b7b05cf7d992f801d963d4f0f5b9a19e31e91308dec7027a72c349e8dae74249a577cac2ab8acc17f72281292ac2efc5576a998feff7fdfeadf393490c4b740c25715c4b194c2d71d87b7405dbf8cd47ff5d8ff835fbf30cdfdc774059b1875efde5f38c22b9d0ef516b93111d13c0e4557680c1ba3e6f72517cbad4ef58bd5418602925565555f02c69aeb3ad9ce983d881257f0657ac653203748f9fe0a24b7d01db8d09b31923e657f2a7ba3aa73eebb9a18606420bc7bd4c51e22d9b7107d9e418d69a9adbdc3fea49b03a599484560f52fff5067d2f97a52fd326a4745540a0df3214b8f0afa25ed362a94b358b882ea61fed8c211a718b6490ca27edc6ee38713c113c8e924027c270a983e008a562524e0be6d58dd5a875e771644d2066fe334b5fa614ae6ac0675e89c1bf9721922caf0e54d86370fbfa895905103ddbba397f003626fc83132b11423453175f7f3b3a284b323eb8b86fb0ad49793aeb2008e36009a25c96a68b1caac6c97e83ba7874049b616a62c79b7ac08069625e47a7a2173402531e00ce3a6bee19e2de1b4c0827e9c5f1e3751b4503112fecaed94a4dfb917dd6b70bc5f3eedc31aa34b34fbe740ed7b6dcb291fd2bb0c5ade750c6c3406b39d429bd2cfe5c1609922c7f9be90b111a4a93bbfdfbede67ebd26edf9062a86d06fd52e90543d347c23e64c925cdb3390a9c14bdbbd1ae01bff1319ef0539264053ae6e7500f7ccaeb7aa216b2922648a569e0ca625d5f0c1bd45a31d27f1d52002e7a79bb5ee27acfc8c94195c5b2b4a75f5297152a5fe8df3862680dd5731a5331269824481103ac4fa6143608eace5a56f26971e3ef8d73cda6d1f639bc4297991692e7ab7a18dde0ab382cbe579adab1a6452c8b2715f7fbb90d2d8113bf5627d353db161b628f79cd4e17ad0f04dd89915dd4f4b6486048bd2c6e809b947f316babb094df71e03095fea596afeeea34cb071e59222c3dcb28e3fb778d5941e0a8a1a92484d4171d452fc973d66e2325bf0b509e9bff2c6658f5f0001ed0e5fdca723ad8a0670244b8f516a90740c4aba167240831ab58bdefd71db37c90222d0e5584c57571b9f1982f757d7115bdcbdbe62abfcf33d36561350a6a7ddbc4cb5713f907c104aae46d4941716b7eb65b37648af16d21ba39e7a156ab6945c8f2c77eae0ae0760a320cd2fd35ab84a4f8aa062744120897cb15198f6da9b406ab9fa197f72bae6544e8939d4d2d0fc428b4364bfc39ee1be9934dd3adffb17f34035f643f989b615467ff237de9fcd9fed1ff495f3a49ac7e69acf44e944269acdaffe85be0df7fe0d9928687ff98ac60d460f12247cceca2e838b5e08a8bf6bc0ad0ab94da2f86b628cc5f555054aef0a4a7e457070c1810402f38035438f6ad14ef7710e552feb8d3f762d422adef7a90744a111ae0ed8fa6187c622e2eb16e4cff851eed8a597064662e74431e6fedb494e7902dd970eafe5f00aa0f3f8dec5b5449211527689af0c9e524d36e9c7bc12ba896f929e310da95aa395a835a0292e82aa9522faae845223995f4db10f4304615d0b2e53e8453d3fd61cc5a4e0add465deec5f40dae966eaaa9047bf30941e27a53cc5efa84fd6a3cdb025a59b44530d5150eaf29228ce693f2cbf7e6145c5888f30352bfdd65fcf8ab06eb95893be4ee830db0c44e84300d576585896d44d6f6e9cdfbf76061061908e2373c2ecb81b897010bfd841cb60b0e5d5a426d316f68d506a643013f89d54c472518c0c88a5ba12895f997ac03143ca69b2780fe6660dcb0f6e9518bfb62247140fb36f9192111a5d94946dbbaa73046ede29dc6a86ea3e1ea13852df6d4aeda9cef47a72d72b70605708448d98f9f8bdb560aa7e1d38cdc691dc7e9e504447b7d91775609b9980fad40d09f781bfa4ed68f003596a607ed69f398a25e60e47d98d7e734ddae087b29255011427382bd9f00b0f2cf83d83a2cbfed9749febda895dca2cf6b31c89099f4a84f5409fa0755b24c738134b2f81124d89ba18d0a9326260bcc49caf1d4b4275e0d94b73dfb150ea79b940b979fe611132190a1dce34d31cefbf91dd3a7dc339e08a4e0533dca50ee93281fa3d90d1d35785b008589dd2f9afd9119d973aac318c3efaf0044b7a3ece44b60b3a67818b5e450b4ed401d7577cbb0accbd5b4e7c7d573cf267f54f8903715d5f13af80eb0aa9b71a754662771f07bcee23b2dcba0ed1bd1475d2f51ec5ae0714fa9d8a41788fce9d4fb8f5946e9397215373886e159f6fe13bf31fb7734dcffa7df1831f7cca3ffdd1710b24d319943d1ba5c1aa55731865216ab5f299a70d2ff471de4fcb3f7649be109fb0252382002bf85fcc3d552e59620c87567ee1bced2f4871b929fbb7501932f098aa409d9657e9ba3bc14b7a05b1329e8e46836cad19b861b0d3f2d4877df56aa5fdf8fa2811fbc4df7d64d0368465e344c960b4853e05933b28e857d6414260a6b738627e1b6dd6b9bf258d8e5f2363e737ef3dab14a7784869d551e997eb452ecaff77101ea867d572cfc4e340443b533536e0b98ee137ce8c8eb1621a8e7180792d1ea71d4efae04b7a59471acf7d9acab8af723a338df6b38fd754106d75d08f4c870f8d9069a3fcdf1462c03148763fa32aeba4830ca46f61682d3612fcb45377ae24a8e2df89d26580c517dd388646a519b092df7759548e9933cfe259222c9c7ba61d15d103da79465035c3f204357c14ce5f6068d86485d3345b4a0566884987aeb1bbaa032af3302b60a26c50af3a95ff942bf83b97f82a482d7291c312cd639f72b61b5827c4e10ded512deacb54afd51424d900feb7575089838db702332dec384e04be094b6daece29b5b3e6ec75aebc45882ed0e0373b0266e040a836e5287ce994fea9eec8e25d5faa4c34d977313cd8517990524bc4def699adb12f1a940c0825c408e07bea6baf0b3aadb003fb6b2b1e3017a7e2d6d2715fa6ba4b2015df989b029b32bd4948f1849cbe1118919f3f1aeda480adf686de68aaa0629c1f3a3823e851f26d58dcde6a57cecebaae5d5d2b3331ebb401af0a2e9e964a2b9db7b6a7a4b35b8cb4158b9836da2231eb08cf378d038c4593a1ad388f94b33492b3ef51ca08e564aac77d9a2fb70209f036e5d2586adc75782bce1f81e3e9eac86344f2cad23903ccabb50f7cf407042f47bc30236e5ab14c9814a14c1982696fb2e660679736bb625d5829519bfbe36bbc45674bf63e52ddceea77121aaa4d31e3ea7f4334abcb15e96f910bf28dc781557f83cb9109781402b7719c67d7176aea25d01557c68888c98f6a93988def5cd52b67bffd8113fe3a543a6e405c85c15dbc8b2280b365ead2ce87a9e3bf52868bc015be82da96152e8a9eec3a89bbfeb17d3e947ca85e2831df44ba5aa6d3dcf991b981cf99c33e85416828cc71fc5d2aac4452197c6c0f4a2cb4f0891e737a754ba7054114124cd54d86d3f13c8bf6e5b25a32b49a10f382b29cad7eed6e5a50c9d4999a6b64fe80975d9f0a2773cf0f0bd3ea4353c7897de4730216f1b2c418804e6e44e3208d9e6ed4f6c37db4a49fcc2aa68bf461cd016f15fd3aebccfcf799b5ac3f4f75146cc1ba2c90f3b50178b6d78eecd93a5839b9ebd033722ae427fa744fc3b5d29d2943b4c8f59af8016f6d0d21057da4f48aa2e730a7cee61e9ecfd3775dd6958057358a46f9946883bc935b259783a886538178c72355156da64e33cc0e4d93fbd15bb686f35ea187f5f01fc914615ffef7ddeffd4a8665320a19a4fe6904fe6524a0392867fefe93ad3bfbe89d9a618452847ff759f7004f0610b9010806386965ab82f79c6b443ea04f1ca8b21ad8fcb6f547b2853b96901604e32468744a8e72410f0b1415f14a1873278929cc8b7404a9899d9a6bb777b3f8b1b47bfa9b67203ac27946647e6ffe1ed2b96304692f41e4807311dc52cfd62b88999594fefe8e9e9d9888d5d47af3df6b574ad4a7d90f9e5cfbab1bd994d86ff20009f8d0f8b512ce0ba6b06b26e2ff8f2568bd27a5af3e4b7c56d7debb409111db7cf971d5f13ed59f9fae0f21bdd4cdddb28728adb5c9e177ecd2400388e1a30cd63f9841d2ccef1faceaaa48acbd0951e5873be40c0abab51b441ba500d74e396c360c830dcd8699477a6cc952764b2dd804f0c53b7a85f6cfd3be86d0d1f1fc9476b319a1b91d1ecea212979d84c944cd2dfd076e85d24f9d080dff141e7d7d88a525555331139b05764352306b86f60c470a94f494caedb076d793b62131df5019dfce0e3ac44e3914fe047a8252e945667eff416cdfe6da8c4d9a416e3e427c05240609ac5b03641bff0671d748d02426f9d22f441b6fe46c96c6e39c4914b67b46862f24f6aa9612e0328b882544a223854b9f32a61721a0ad9b553bc10cdb341dc000ae6129f01b78d5fad7a980926037b7def14b6a961ebe90a3528fae102caaf4c44663fabec27bd11d67ae49ab116030c7dffee98000189db1aafabd3792cb62bfaaaefeb2750029afa2168cbacd0cd917054e77c009c16f393ba9fea059a41df8585f98d3840edb7deb9ff6506735e9a958ec864caaedaf6d4171107eda40787dfbf5f42e7d9824bc60f77e46840a655c3d5f09da2ad58c9115913662651a968ef6d5575e389ad758e65f84f3fb8ab97df216b7f40288d12fe9e66b4ff1bdee371666871fee5c3fc75eea34e5348fe5fb8ea08ad0115453f0449a4b7bfc86410a38362565f6dc9fd0ead6e25e5b66f4f4899a61e259733907638a15bb3e0e008229f3b1532d3b9e5cc5db9fdf66eb624b3f6943cce0bc09a4e43fe817b05182168eb08ba6eeb57c8d62d7c3461c92e4d47d50516e87025e555a1dbc5dcec46652367ccd2311c5004d36a3a0fc08f475afe6cfa6adf0228dcaaae4d6c07456e93979a713fa09b4e90942c1be48b91d10cbdd3d54f29a9e66e4ac991a8178e590eade1164648b8d0a4b30599b344455913c0ef1a2c5193a90fca5204f87a36c52138ba7d54af46728132ec69a104db56a20e21dd27e0acd1c8158497d6a5b33025d0b30bba53b83462d8bf44e446c5251ba5090a8b35dbe3d1f0c26fe92a024c9c91de7dde1ee6f83b217452677809f896a04cd27cd611cb6245090f1df5eecbc1b3f51255da7428198e7cb5e193cc8da0863588c0622f87331647cf04ff7d47da1dc3d5e00ea551f48f4d120bc8aae0d87c9eb46c2538594e9c42c796872372f22dcf64216ebf065e7d570c3a664b7c97dbf53c6c914760c513f6fbbd6e6cacc502346112a2884e145eced6575624bcfb034ea384bd4afe7618b9db39c43fa125ea98796cb510093734b113087aa2380cf6789ba28ff24f4117ef2d77fa53843b7721af28a508dfd4d4b5c3948de5332aac47fc0a2e5445bddfd071a7a8d754684af1dc866b847c3eec9e051c6e2ed4a0c1217e011c925190c3fe6173b59b0bd27bfa4b8c561079181e6e3463a4993586ddcb7497aa78bd6c7f52c8fb90b6fbeb4d276d893382104517a39d5bb922ec86541fc258ec9f7b3be2ce85dc10150aceff9664013392940371cfe0c018522ff02b57df65ea48671b5fbb65843748e85637f1a180b5a638751621c4991353b2d7813e0e8f8462726d914392490bc26f5168d2780b613beefec991479e8925328f2c1d8b006794460f285fb075ce158bd36e96e3381b12cd17b6d5676706b8dfdd4343907aea2fb955215e84e1f0b4709f65ecb628509dda0cbc0f49c1427ca8d82c57326e72760b91309c77afeee568e835628e828a69bc6ece026d175ac5549afdc6f983c87e305ac43936f69c84f3d7ad11f2e7fd30d8750c9dfb312fe7402c32252bca6cddf4f62f1d398e72b2c18fbdd5895b4a56e937ce5e2eabc84755ce151f0f39a7713f28fe706667c35940be46c8ec515e215d316cdc0d24ff5e24d68e4d3867b808c16e3671a8c91683e79cb700de090a9da403758f4f6c33819abe2a33de299aadef8743544cc34cf132e8845183d3a04ea6130282bad513d0cf8f0925ec5c117c6861dbf4ade518b99c906b9b7f0facd5ed7352234c0271cb5407df603c6b4da16d932a03eda8413e85f7526a6ae22d317700cfb29ca09e48134b365ee5ef8672dd723e1645953e0722d312123b38db21e40aaed7e3641c622f69bfd7524b4517f0858372de72a2661d1a83eccd4ada6641be3da93e299e73fc8623e8582e20bc641c88cc085415b5c98ed325e484e948f95a23b8703c2c95e012665988f7770d3048ecf69cebef1fa35e7c29a2f5a5be15ef17267b3c8ec93b847f9122731071135d6966900db5e3a04b7eaa5e8fe4d051c91d81777407174ee08b012111c05264084d9f6f2cfd82e19a2c95c2537afed73f97a0ce0ec8d21d7760c1296fe7832f8238099a9e5ffb6e3c3990b08bfe141f5a05df7a7bd07a49a502a9107861c2689d49a9ce995100006b92d30dcef9792650d8f4e41cd0136522e45a737d9b5ac6652ee3b8adb495fa383f54ce7aea76c0afdab41b5cf214640d51d3b4ab33d23a3eb431f9cda802100eece6d6a0aedfd7cf3d29fd83d68ba3687bece0b0b04f1b090635038c4b85878ce34d5dfb953be6491a833c4027fa4f6e63df7c98711ffd2c0e8beb67d924c318f63c7e60c35d6dc48cc5f43c25e177e436f5381b15f5e3ab08be2750703d462b8fc28d48703aa20ca532c0ca19f93ebdc18b543602084ab57405a5bcdc1c1a5ee6b3ed25d66c549406388b78713715814bd10ef2e8666ac486dfc35720c0586161e95a52474b9e9af7a91a563e44fc23c85f3ca95719748d996501c08cf04070692da726aee1f1c7002aac59ca9c569414cc4397b2e235f7088507838dfbd72fa439d63bef11b53da055774ece0eb584e46a70dd419dcff3269ab1742c2c0c3838ec5ef5f260835c91ce80fc2bae7ea245d4ee0cf322e70339ad085c1eab95af48f6fbbd8dcdd73635c565724b3f01247d7062019020f27e542e21ef7b906a0479cfd6d4d9888d0bb57d4b35e02d1b0056af0c2c51d41599463f4a8cce6c28f9061635ca533f31f64dee0de265c3b73315e4985b28667420abdef0c1f577ceb7d1fd633f4e8702aca587ab77ea8beb7c679b6177d7e489369fd1bcd243ee39b193427b3746cf70d0207e1fc21af819ad2b98916f859691910fabcca50003d6d82221543d3e83cb72516ab33b93c5d9c043ffa09fab010bff5b34f49eae3d43b1e6a2149d844b31a4fd1ff460ba2faa1f67f594b72bf61671f6aaecfd62c71b1401daca569a769b880ef3311acce5aae5fe5d4e40780936807ebf037caf8b6658d0358178b879cef1a1f46a1091e27f84fe740cc055b2593e6d55cfc0124777d85e37f70fdd5e4848cd4b2cf66618cfb1ff966eefd6fff7babd170e5f8efcc1ede8bb90862bebc537814d288e9ce15fbdf44990798fc98a460542781aeac37e726b3db7f51673a4de9ab6280ab9106b385ba7a79e1dc2a78d079a2453ca8ebfb6dd502c905fc771e5ef66c0b6e9a40219e0b5d62158857008ef5113a068fa4b2b90022b3fbbd9bb4c16b62e2d6939773fbbf4f8d0d5eae2c6e9d00a7ce6a42890cd23a587377a09e4d5735f0a48dcee117a47c962a832c841543cf7afc8ac99bcad1f8faf94b24f99a9930ab5e424078b4ecc16de61a95dc82633e12043ce89dda8faa5b81dfbf551c21767b32aad76ca2d2538c2f384f5295a8342f60faa6f1e198fe321208d4e9248ce37e9ccd40883085183af8c0a8515d113ba39024b47f0ccf03777367630a883441bda5fff01ae8e82f5493fefa93dd98849edae445c895950b7ac582d495274ec60dee36f5014ae07f937ce3f78a75f45735ce372e25b123239fc69d87b717b88a72a173c93c13fea57c332c1e1c527973b95b5842a11a9649843d3e1bf6d9a5e4d1032d2d12b3488ba53f2db8e986e31ed768b206c26f0e94a05ba970d71278e0ce2c9c0b24ebbbc4b8f30ede66e3b0f95402258a2098b98c760846886b026493788ecfe46ed1dc5704a31f2dec19adc8d1d8797b94cae154b1ac27448ff0a52dd9abdb795e9c5546e4291c6c899553dc1ad7d7469953bd814061c3957e661c2da03a247a6fe41a459369f20fc7244b85b5f20240ccd0ddf611afe3493cac63b4088ad86e6212a72193f05cc684a79e885735335bd668e7277ea7de69226b380ae27ad341067c89a8ddcce90cf9f4cb312763d022c743d9ceb7bb6443678089b5b3da26d547f807269bed3e406b80af5e74ece1a29cda47a9f9fb5916707e95ccb2241a0ff0abe233d057dd5dc4dfad01266cc30dc4eecc7eef5fc5cb18ccc04edf9f69cb6e248e4c30e9993e14ed2e2ca994a9b26e633b97f4428970cf6f3f718fc73de6f65d71348ffa098ae9dffbdbaf07fde2ffa1f75e19f7cd38e8a26ffd7b9ea15920825ee3fe7ffc820887ccab31d9b86e8381c163f640dfbb2b5877391b00184c1b19ff9566bc48579973d8001d1852b45c304e1c0c5039988c014639cfbd8ad30067ca776d2f5405d2994a00a3db1c0b2cc01203fa38a20ab33da6e2ea45c4e120c4b52885dca50f6f39e06ae5a76c760fe75fa3f2ed5933807b1c0e45068418b2056e68a9e8e1f9698741b0cbc5a08faa08ba988a618da2d2dd6c618f79bfc40c870b1a8cab7d01e6c5292859f8f90bf1c17d52a13f382db8e114932b437a49cbf672b1cdbf56179d57afc8753d2cf1a951862592932f25aa8df5fdd64f6ea6a8e46278e1ce67612b7dbaac1e3e57ebd0113679fbe1d9b57fde168d1b0e9f417d76e778a0f64b8b485c9be677af84b2ab58bce93617f1d850574b573a6b4959b7348de30a0e612c5b076a56dd79f71c2b6376afe6a432d8220dca37adb843dcb73e073eef3a936146827cc5dcfc7e3f59dedf670f2fb3c41cf1ece57e9a5a8d73f29b871414b4ed4fb795c23ffd097568315c320b1afd76cd9b8ac8a08f76401af44a55c351a19e606ba2ccb5e3dc34287db1d78493374ea552706fb20299a12d4720568adcd9e98aa5ffc470804e16d918294df70adb09e27d2045b604c5b58589c9703a75038683ef2a4e9644f67cde9eb41c53457227ae802cf004790f4fe6847e3e76e4bda14451df3e71741eb48ce961a3f846d786e9c9abeee03ee27598820b862028bccaf0fc29a63c3c8e5a8dcf6813fee8d9560d84d6d84f8f34bf0a6b6dfb2724f9a7b09ff135801b03bdec8168e80aec13585c9ca1fc2b3ae7e45daf91cc58eecee638722d5a3e37d3626e44c55acd3ce5ea51bee3080efc39f956876a036a5565aa5e082be6cfbb887175e8b5a5c795d28ca8bda07ee4a2a47820240f271546bcd7eef42a8ca8c3f2e78a7b27b8142bc254fc85b74778c66316b7e167542db96f823649c73e76637bc08c05f5943344337ebcc310c37fd4def4ffc37787f7ff9fe7f7cbfe3486d0a89fed72cde1238ffd1d394be7ede4235c6f8413aec6714af8abb487a905829db3fabfbf30e5f20b57e4a51a4405b14e464ca527449e88d0fc4aa99c4621cb9518583b4272e3f03299064278d82c4f008a569b056ea2ecc5366b683f72597b95d350bd6ae968717e2a40f3f85b5f00542de83b7c0dd38d4c0b265ba8f4ca852e1390298648d6328453df874b8615ada22b45f2a454d30b92699204921079080c59476c3f0db6d0b4808741bf1a6f90c76c73928e70afb91223c67295f5d4311f78356f317a6b87fa419e58448a012069d39815c8a7adad01bf6e01616f3a370803865264c9342c5f140a3de42e7b4969e76006df1c5befdac92c4f4d27c98b3d2445c29b8b4764864475fbdfd56f7f2d9d99cf0ae258870ce2d259f36434f346e6ac4c5631fa8e651d6f6bebffb4bde1497f2e4404de1769a8eea5f79301a532e9c888d8aa72b07dbe8492e7d55701a8cb17208c2e0a9b8f2249b5277cc3e44c26eae53a09d987ceb45c6fb471e67b291a6f395522c16eaf55435d936863b527fc5dd22c25a0fb821009a5a49a63e86896eec557f6c0fe9b2e61802d1ea564cde3d57e50cab191f464347f4c77b114ef04506338c2daf3300d4dd6f83da8d1d1965f2ee984d8f510402ddfea09f0d218e16f8da9c9af5207c0d7cb8d8051ed96d235438cec11906929a289f170ed34ba9cfa299cd1907f8f61486a49f8c287cbbd3b518051a324f5a86bfb091448280627b7e4c9d247f908bae0c0302d8cdddd009e7f21c8a26c3228173dcc16e01316839b4eed9dd20c01893fff6d15293768579cd81ba0ae40358117f0f5df62384e833c74b70470146c360f719d16fd8e5110bae96f6839949c689852223033c276d84242d055cd6c58827119d4e36bb3426cc9da2f294904b3325cf3a000bfe073697d5a613bf4885ba454c99a11f99292b757e39fb76fbc9c9cf504b956897530c6840830a314493751ffc928d17f2c53b0cef13b9f112f2251a0c6387bb1f26fdc94d766e682af30f0c52ff4d0ce2fc3bb8c9ff56f3b6863fd836043176555a985b9e9229204d651aa52d2cc46a8441d0f876ed731ad22fac15f1d9c999a8861ec7e695e28f627e443daacc073032ec3f0414afad886bc1b1d014947e195a96f8510d1d4e31d1a8914dccdfe7c62e9bb00693ace52b6a2094536eefa21e9364137293e0dbfea92ebb03c196b400f8ce853edf01e2ed83658476afa39e8a6c96688c5d0c8c097e63f664561200599c8202b1a0280de5ab0ed2d44b0c0d26336cd1e5dc430f26d5a07b1d33d27e22cd99a6edf4f496bc892c5bdd5c0e76013906da5afc0a7083be015849cbecf2e0c921e7446dceec3b7330594e3703e40c9c9953932b841007c1022a12a176104519d62613704c789826bb63c9e8e5473412dfadcfc642193c4666a8175d95000583db49126c3d1d1d95de7298aeebd6ac982736349a548af65586d0fd380d04d097e48886da513595a48bdbda9cfb4d3f2edcc5d666d502b9c61f6ecf0ae30750ef56ab14c45316dc215700dc7462162c6d47bc9192dc39db054c5f14d044d69294cd5b593b7ea5ce822110e1d48f12b95b7de44648084148302d9b2327fb73e78b36ab913b3002c368fedf9b9311847f835ff34f1e3dfcd3337dff899589c0fb032bfb0e43fbf08a6cd2b9b0f686b5f6e6ea9bbd55272bc376fea86d2c986a9d563fedbddc413fb6cb2467fd59c05aafd44070574dfd511c9808de940db9d0cea3d4d044512299f5a9230e2134399114370aa669638b4d61d6a8161b172d45e8228ffaa173d6ca49c62ed9611d298722b3ba91f25cfe349c1394c4e30854a12a345875864ae6149a3daa396a77684f6ad942ea68e5a33599a96ed366ff7532842197506df46880124315dfdc970211a857c4d1eed6fc5c0ec579e26cf9d8e574087ea740c37e35cfce8a620249023db32655421a606966c1ea6c45f18e04ee0c5f1c999f4c5f15c2c7149bb7375829b75c9c315e19a6c6b4b58d044797b8bb7a8e9111b7a1c7c28b1627066b5963cdbda75f43a5915749b710e4cad934aaa2cc95150804e63a319078d58a36c62843abf57b96d340128ded98a10a3a2e03ed15d85a699796416e07982bca1ae6f0acb3e5b65dfcc0583cc6f8242ee81512dc3e4de514897062b69fb501ec269a441d0ea88156ce7d16faed6cd3209f62a840aee8d03cbde895b3e7be816352bf4469852bdb7a58bace0d67243836d57710359a6098c5dd053ffac7a539b62aa1fc559705d2bbcf8d5b82b8eb1c94c5d574e239fd200285337c3915e90b90dc180ba4e7cda9c0f9ca5b5b6d38b38fc569d2fbadaacc887c273c50ea7412c7b2d95a7fe2d0ae7ebcec95c94d5fb35a41469354233ecda6581ff9c900eb585b9389452409374a893e0bf83fcdc8669293218c24d293d1e1c75e8d6c4f04269d02775d12500c81ce1c58daadf112e37222d13f4c19728fea3c5d0ce14dedbf4d524fe0e30af5137c856aa6dcb150e1d0fdaaf7c32ab5dbeb0246caa291ca203b7e02e151b6239a90ffeadf0f17b6f38a3f20ad148bffffbcd8fff4b6ff9b7e8840807f0224c4d598124918249a49b5e1c0b22937206cfc4642a3bbab362cb7e64a8e44f363e6e8c7f633c9260139fca5ca8c89749c9de3ee2367ecbb326e579a841993ce2049baa4a8effb7d1671a1340d3062c79ff56451a6f24b677c6ec7a5b06af851d5e8331cde5cea375fcf9c7032d011acb526b90d0f6ab7e1d9041d71795ba1d93fb54542d258712c5b56eb57827cf351d9e7b7aaeb77a2d4bce292cac4996a99ab161900be4a798cc86e2021d0a3f27af2b3d38e606985bb7b03f1d8a779a581a69fc5ac928112c8bdc4d5e6b29ea8c9f289192a124d19072e101b8b22fca299d950bb00d17ee18b4f2f9b8a56920a68dfc2c968707e9b0f3a33b9afb926cf4036847f846db9bf706229e50d1155aeecedc0f981db84441fedfd066888a1fcc870ab655e0d8c0bde72687b6db4f8d138f21af17c0bd4f85be0cb6569ad79a6019be0512ef8575be30704acf388020bce7b48bd1cedd20ca3ba9791424cfcddd55db81f890d4031b18794ceab08194b3a9b4c2795ee78c9fc575d89f8bc4be7d76a7841ec70f9d3035dd0db7ea80965ba074e529b57aa64c097ace4b25ca5cd3bf8f8713f97731615386d33ffc147ef15cad41bdffc8d785e679bf6f4b9b94172a17299c46519d93835cb8de9e89120792a172cba286a10457c7c186bfe309eb39ea35a2f9a521599b252a3276cdc42a1d64b7fbde7a5e8277fd30237665f054495e1cf64097c74db0afd70634d376d7129142bed94632380581b843c4cd08bd5598e76b1fdbc12062ad8e225b764ec827e43e23924352f115ece558522808bff72f82905a8401b9ba9604fa093c6b4a7372a097023cd7889bb68aca26c7ee43ade582ace999b13f5d8340674ed496fb2b0d38e77c3b97df4ef2c40dbfc07b735096f2a23ea0f6eabb27f2b479765fe0ddcf6bfd6be88d0fb42d2b35957fc2034b7a6c0ebeb387d27a0a9a0be8b3761105d56543851ccd2c00f332eb3b49f307888f58c984352aec4fbf55e324cc94db2cc2f0c84244e3c6ec347463b387d560a54d306dc14a3a36caf4005269563a3511927413d2a8a857b3a002c29c0506c2853d0872331334cfc1a6daafbc22591a809b15618275e59eceb51839b2124891c27d09e6635aea23840c9b75db80b8e76617d2073510c0a9e97f876d72691996940c48a987e0effba0d34f79450b902dd434019f683f251a32c574084483a1d47ad0fd3efb2fcbcbc54e576630302bc3dd447a00d4b0fa02eb83b06bebe5656fd87e33b20d7fc3a23c798ec49038ba810aab192b77128edc60b4210df26f663204ae777b1ee3037a3aae6179658581d1b54adaaa882d5f422ef6f7481e75cd64443d39ec5a26097c292c215ed76260987560fc5bfae94676f8b60deb1382342dd7e2af8dece5fba937ea76ceec73162386f5fec28eefc24630552bdeb5d1c4b289755d78ec9c59c3992bcb8806dcd43db80a0eba87a977c5ad97eb853e41a8b119fd7fa001d30abd9616849a92746dec867838d5c808ee0c819e7f3ba24ad9fa8037c600fa1d455f5288c0f3e9c097868470530d47dd19007644c2ff1fd26e63057bcbaa056198f749786e1bd0d183111d56d9ccfbd5de6c633e11a5ab62dafe265fd89793bb2102d9efcc76c38f3377b94fe071974ffdd7f510cce14c1af02c1ffd281feeb3743054108fd81817960198a586c1b45031453cc8282abaf52c71c85e366d576348827b10259ac1739310479d19bb8c0c77694b3b54180f9616cd4e01495fb1168ff24abd8cd8059d376ee7f68327cdf7ea3060d1a5681e2541517b52ce7ad6b0aa5e5624e60fa8e8c27e3183eca087fb01306ede49995d1bf0b0ebf61d18a567e861ca51dee54cd6385bac5901dea13fdf2f323d055997eec20373fae76326614050d0a97dccb5fb835533e5731570c5f0ffa36c8d62865e7b263d6a7f54c9c0a5f390b24a13d06502897c9c81614888d1b2bcca2d16bc46a49ae27c462dc4bda446e859b64d3bee924ac90fdda4e0eedb0bb04ae6339bbcb6f6935d34c2388405661d153bf6b9bb609c1e907538b0e4dd03af48b9b9768efb8fd1409e751538872204fc065d6b14c9e3ff03219f9d1f273b240cb8a5883ae0c83d3c9a0681c21e5e4bea2114f6674896670ccb1bc814fb37d503fb7e58953976e47a54135839a1a1590de954640b97d576c4448d9ed54544816737526507350308317b449639d11ee9e0817dce599fb89a7ce4045bae90781cf0f3f4d4fc0e0ccf70a0647c9c3ea7c547fa854eb718f8fd84e5b53ae5af7cc3fd0b375d720184d8c5eab572239a5b273aac94ad5fcc812dab0ae5a0638a2fdd7e9fa7aff51e35c392b800d2989aedfb5bad9fbe992a0693c996db81826c123856e6c2150e81b19a1cbaf44b60d2fbd6d691332e6dcfd462d6cfd3b947ebbe642900bd394695398e89f95f876c568f6cd5c6bccf52bb0f49c58f9d42894550e7db5dbecef1b046ef7962d6d79166a270f1d6d38259d8afb596c818db338c166c7015e2e4f3a055942854e1cd8fa274b0d48346b56795d93b5661b1bf98ec3577dd86713c518548f68bdc72112879807f735f9bef7d7a9546704f10e0a5dae34382c043321c9e50a1724759a44a49ddcf4e864a117f1880b13e029832630839fff3c93c64836fac96005b74a9ce9122dc2fafbc3be149afeccc2f9fdaccd796e85614c5ffe7f9d39f1575df90ffd78d62bd10bc68a06dfd03b3fcbd694a45314a1169456ee67b79d5d9be51905b16b05e6184ccf55be526fc91ebffe650099a8a176b13727e4e07d45cc2d48c5241446660dc3f63a8bad24d1102f50bf5cc8910cb608c1c8630b9a0aa92cb4285f973180df99e40085a3e041a1204de1377ec9d3852b0aa7271a20e982281aa6e3a4919d6d093c2649f9bcf6e3673596a0053caeba1e90c4b97368024bb1842419c19cb9a2343962b3735e6798f5bc6907499864bda77f48d417b612bbeffcd57277c671e89929ad58cd8af1bdefbb4e73f78be8a12ec45c470504e866c621ec31a9d7cc879365e012d1618a48f78ef0c6936c24aec9370cf206302b93d027fbf46ccec4ba5eefa8dbaa69639a9dbf738405840518e9be3086dda4b395b35a737445c63e723bda74770ce6809ab46ca60acb347e081ab2157ef7a98e22b7774acbec194c34baa0a22f23ee9fdccc916922cf8f5cc7e927c5ae10a201c01dacd3ca86d084f088b0f98b204ba72c7bdb09572c6c7acac762f43c0d16b0fc124be62fc0f6e41cd2653165bd5e11a9227c875a07b4a4d5247ec606f33ef6513bfa45f716f520c7390ce85cd5f31425617536cba3277639f0fbb13ed7b0516ff5c05878faa0265a25ada911bb95a2ff389e5efcdd25cab13c138d27906a4d1b4dca0c61706059835cc76be8e2aa38dffcdab42cdcaab3e7c1f241be29becd61d422896d72f4ed32d054ce29e956f6863b5d1a5ea0f57da9cb28d6d2f6845eb9db8cb84bc4919b34620874165b147886cd0f6fca2c3ba66c386d068ffa30437a78c6c6a92e8617487b227aae95b0fa97c105ecba8b28d6240939ea316ca4998f43231a934876e247c2bedb18801880db3c9e5e289006aaee112748f72224b48e1b8a5717867695f2399089a2db007c8b8788ecb55461967081ad90ada7314108a619fda92613c763e7d44182a07f26f5b117cacd0db8de4c57110e5920f061e7f3046c080ff0de46e5c7b7f02570a2c5f0b61c9681d3f5129160554fc7d4967358d5c477a4f3eb47907b7738e2e87810a7c413e9f9a80b1e6fd44a639f8518c707fee0b846030db9116e81e677cb1da3784d1e280773b900dc30b9758efdd9e267c03a362690ad85e9e2d6f6553cce570b36af0fcea6b916683e811eed5d578b2f1aa563d638841b26a1f25e654bbb59719fd1c317568c3a3b3c5b4f3b0d32af791630066818ce7fc7eb059ac3f07aafeded9f06a9afebcc7178c25cf772db65defcefcb3644514b7575f018031b1ea3ebd689c0b486508e983f539790a9949e0f827ed9ae1dda149c02ea56aa1c593f36744dcfe023bde167358c36b8473300daf12a28ac130f95c2223aa6199a23ca7fde763e11ba9b9442eba1444a6f3faf09855bb3ba4224d162c4894d74704cb9a6b67239b651273994383784def6609a3be3277b3544b26299afee5d4494c5d79d8468186cc40b56d5573f48c599649aa04740ae267d41477db870978216fccb45f64be9343b66c3547ecbd2b4d615f80ba0810f1e5460b4d4245674c084a90d31411253173ba306aba7539ef50177cfd5a38f6c51d6e8b0776ee2105d5bda0686897266af16956865b2308b922b5312ec6b167fc1a04007814d7db5e2dc4faee85f409ad15b093cea42b34fff26209322bd91b234d78d76a2b47bedcfc2f2f57913731f905db076a2a086088141a8e93d5801abd36555430dec6ac180f64331cc045b3035f40f4e2ef4773f77ea91c35468e07da7a46d69bea5f493890743563941787c449b2cfd4e5ec1dae12b37ab635c59e8b082d7cb22f29cc84fd1c12bc39353609bf2db649b952f46e0107eb129fba56faca8c7693b15e80eb896d6d50b05b5939e608ec4435ddf5e7079d901bfb3b79b17dae327ab8aa1cd24d71ed84f6d275160db75be74cff41c0236e7b86e6f2a471e3b67f179479698b87af710820d8a4bddb2a00e12a22a654a5dbf020032f7e27cad3cdf8c615435ccb964eaf04e3c97a03a4fc774f2a43ad04ec84a377e4b31781ac9a00ba8c8ec36c311287ff3ad4d3875fadb40d19abaad17319767e571b349e057bdb2b6d2a899bd15b43985f4a9a63942e9afb1774b43ef15bcd14d2499fa066f8b8806054d8ad14bd4997012b3a233501054d0b266afe354adc92bec314c108fdcdc5426b9024c10166ba84842022c40db055503247f46ecbe08f831ce661c557f118124670fb17ac04619e4453bd567e73811cd87a0385ec6f7148b79b167f72ecac3699ca08b706faf0ae8369ee7b9a7ff5ad97b261689a01a7b67334c4f517f5f721157ef749ccf935c591f74018698315b3b7f8c8c72315e2b914ec5b98721081ffef4716b7fa3a99b0ae45680a16d4db78aa7c16401691b1c4d38f1b7990394a35fe6459be90dd5977cb8b90534c0c923375313767337973c0622586808c700e82cfd551b0951eb9933cbd35ffc1a0d916887018f4ef2a1ae7a199c569c8da7b3851727e1d7c8c1589060a85dbe1b8df1563ca5d12f8c331bed3eecfb4b12f115842be1bb5b7f8ae9a61687f40ce586e0ac5ee20f2a62a5c6840b71bc54b022f930c85bb917c9d8bdf08b0fe2ef106ba5af973ddff15f5e94bfda2f11f72587e529577b18e7f20e946e54ddf387ddc5c1914d1740baf8f88b80fb740034ee7a13ef2427a047365e1de229cb19ef4195d0b3016bc7b35211ee8dd64f44dc0588a32e6e8703ea440ba8009e9dc480a1680dce85bb16b9f049568b54c625172ee7ec3456acca65a7b558fc31d451349361b4968458d0a371946339c9eb82902e4ddeb80ad2daf88b99f14bdc025e57c235a85f2d268537cb1e3dfa6c3934b39640e0da37b59b54c94498dffe214543f07bbfb130bb7067f0fd369f985ade7dbdd6c733701916ba29b5630a7132a3dddd04e001e90d7cee9bb27fbc02813df6e4dc026edd90052b574fd649f7c984e8546f842752d387b7ca39df44cb061c9db64cd4edd33d085e3baded6f90fb016737f62d9fcd6de341f1d752cadd4664a7504a61cc0482ae0a12883c9f6947fdbc18a4ad6547e04ecf06cc06b50ff8d306813ec7c70de0e3179ae870af07d5fb4424c8e946cc0fa3b0f5825da2270aeffb6aac58178d91e29e14b768ea99692b95fe975af2942a38dae1de610c4bf6452c665d328acd37c850703e393ce36d3692df5257b59ad2266751ea4f9c5bd1e236242c16a0275ab77a248b5e6973a7379f181012d6ca175cc74cb27764acd19eb9bb4bd983bb50a4d50784bad0bc77985ecbf2ab868ec504980cf3db7330db9492d95920c73c773ef60c9bee036aa45e27724c0f786d7f3c3fe3b2e06cbc5a582d07eb26db29a2f97ece5f30eb32ec1ec5546a2269df8240d4dc0206ec6ca14f0a1e31c41ed3557c8bf465af04c87eb067fdf669bfc1fb857f564cc2b05971340b3d19102fe9068af9bed859be5d493b9e5ed739c24e4e994b653643bcb0443d95f9c386da8f40200f2079b38e3ca16867377abe60c15217e94feaa578a7f2f9f17eb0f9063fc07cf19cc52d80c5cf5656c043f4cc666a934eb920425f986d0abb5f8d1036067c37b699e1b3e4568cfe6e6ea9dfb66499810bd3df93694ad8141973d9b315a6cdc726413a9fc4b42a3e997aae9d385e24459fc29169470fd4a53938dcf223b99703974df8c2a4276ed2abbb9dda7eee0710078e9425149d7a5d3eae587fe37e4e20524e6d7d996578e8a4f4897a21e3def16de9938376c5c079beec54ebb2abc4365f841f5759cf32291abbdb50f1fbf4073dfc6d18e271a15903dd9c4d909adfe53de9aca261d9a3e659b349e3993906bb49485ec4363c98a9b70114b14389bd5d7550b59b6c05e573335c5529c5f61aa031b36695d7d9d3a3667b96e133e1f8685a280ff0d6afbffba5281d03e30e866e42bcb2091664182e57fad2a8dbf5c710d4199b9825e15fdb0c8c3b201abc992bda17ac4fcae57ca1bea79b2a6da1ba967d7a300fc5961ff079dccfd96b11c5093fb7aee9007749483e0d9d347fd1f50ae2a00456e083d35ad860738ad762af928d67311216553be8d9a1ed6f0d8fa03e52a340c1c907d21c0bcc5c5bc914aba7c713e29546b01357f3e05006d41321b350a4d38a1961799e38edca4c74325bf5265319a8d0683f4fd6b7f69e66c7b70eb586b617cf5e79559146ee8693802101976d2c3d4448ebcc171b5b6090cef44a4df786c8dabec8149725ee5aec2b0c5973a38103227359cd422457b6a155f32d3cdbdc11ce3e4a1fb362239b20ca592d4f45cdca0f29b3d7cd48a0f0827ccbe9d7ed32d92b2a3f82c9a65793a850ed2df7a9df4170f46feed329d6d9a26d69efa3a7dbcc160d3ec529c49e647908742f43c28b8efbe401c1427214555109ad183ac3bd29d7200bf36ebc199f4f022bc59217ae2b45bebca1dfab44bf57f8eeb6a2e273bddfd20ffb63a222ad16e8080b0b03b8a757bfb0b4a27ec2f42617565658082eb95a5d7701d6e2fbea827f2d247212bd07ff6e1eac83e9c1a72f9df12e2217fa5ca752054bd0562da0f106c8ea1ca5ba3bfcf3884231609cd0e0ecba1639b92cd52342cc3c7d524b7f3ec85896f761cbd3a5a19c013b1c9e20a68247218efc0a076c4a04d695753011aae74c71f06aed685eba8c70ea0c9c9c6523c90e366075ab234b133d1279676222d0ed83cd2d5fbfdd2ff79f0b228d52421f65fe8dc3d480dfa8a05f193e90d87132a8ddebd254c69c0230cddd0f0328888201a0e005a111c6d3530ece6ff84109c07a167850339940dc9b85a433d695f8655f309f6f59750ef68b64268fae62633259c0bbb67003176d601370e5c7176c503d86ad0fc4cd5d740d3c7fbf3240bba4bc59c92f5558c46dbc1289a82fcf7523f892e2602e799ed284fb5e999244f6d24e2dc68f421f6bcefa9f155ec6c06f0f3969a17930092459eb8ef02ce050c23823302c8b466ba98b7b49caea6b479cf69fa4a18740add20b04dd50da68f21ec1d1c4e68d2a6ae56d7ba70ff0d4e29d8c0590b5ae94a75cc4005bdc147e379ecc541e9a88d8230a73218f7d017ae33d2458269b00f22fad256fa0955d58e059f7ca70d4964946fc92eae68e53147f4a1bb9fa58898c894d910126d40876a1903f36f80801c93e9f07582a169837a1770da87bfa3de65f7dded6f1feb288a4e22c6f5cf3e569c21fbe0995266ccc48a60f2afdc04c5967953d221d21247c6d9ce0a31cbc2579440f7e2feb0dd5cc268ff17509bc77bb65c66dbeecd733bed7eb594ce70b520bb680600df30d899d6b7c3f251c932314fb93a723dbc7a1b1d3ba270594d9df9fe64bb5e21453cb0b56c2c3338ddb8720897a0df753347a744f1b881a5ed77dd9ce231da6d4a7bee52d0f6ffad1cb3665d20bad1b1b8172f146f2b26b4f9b74396a59d90f687b483dda176a6558c74d6c91b4b54a9dd072b3abce8e1d9eb93d0a02e95233986807b2aa5fa8234153f76c771491265dcc196f35b78c6b28c66a18c8dd99c31a75893cdaee16cf09dd052b6ef7de35fc1877c881d71e0ee760e8e78ca1f84c3c374165d5c90fb4a310f8026c69668e6cf77c6e75d315cc4439aa07e44a127c55f28168484c7ac7d72daf49ab08bd5f008799810e487d6bb2715d31cd10fa44f759ab254858182ce1103ea5492fa8e5b2caaa15da3d6d199e88c7e137c9a300d63140062726a4f190b93849ad896b5ba0b5c3a6511411a63bd0f818201fdf1debf50eba2d525062811ec9d0b7dce1bd2593f276d61d3dc8d74ec9a47203c88f96e08e940aecc5a9be71df6b6a50d8cdd1b040038b7b217eb6f77c80fb2434c23235922141a77eb906b139d5f685efe4330d0025e94fa9c36c20f6dc8df42d523369c912853c01a27543843657cb7bdc1753faa1bbfaafb3f701237dbfb9ae5537e3abdc2e34d382f86eba85b5379c25a61020c497cf5cd4f01e0de6c1b5f7fa9570a90930114fb50b590725facef16a8102aae365e779924e2715fddcd26f92d0fb356999a506f093ac0e1580f72765930ce4d8f3bb41fecf5c24b3e84850576c86e1208df95b7b58a1ff817ffca7e715fea7bd49fff28be130fdc73ed600d89e4c7f951fdb75c2ccf9497deb9aad67a91db3277acc16bf3aa5b60690078daecd4ea3b2b152d7c7d677f868464a67a4cb4e45d839a01ab437abeef49239e0817b358e202e8553552279efd231c6794e65ca394ed31f7a5939ed80453581e490dd8c852994c3321ea17b6704cf07911ca2a20393eeb4323d6850d46269f19d9e497353a137536284c7e2ba74af520827f8a212ff4cb10a861f0e069cdec11fb86a4e6edb48e847f2c1ac039404c9f3c5ba95e286b69e6f0c649e8f2e8f2ff1fca6f61b21908959db213195b23a14c55963920a5006a2bc448572314dda61969abdc83ee81ad8bfa448eed4548b0b50bf2b52fb484ef62af7ac21a9e66ec610f8793353b85c08c0601738b1b4995f8e883f5d67603f346ecc6991aac32ffe97599cff61a4fdd0660d03acd054b3276c29643b8e524a5e51b782f0415f1fde41ca1e6289a957e628e4fa9b1d239738f3dd94f81d390bbf764e15fde29bc213b57746763839d650dd5ccd50cf8079357ed88aa56491d5586aea45ab3b8c4d332762dee1343b81562389f33da4225a8d459bd16395d6c9eb7edbfc300d689792886c7821a54a61c3449fb55f3bfb69593f420ef2ef607e4c7287127ba37977b7b535bb3f8d9b0efb860c4c6b78534a8f36d376ddcfd7878d2d777e25b68bfc4cb0bf084ee66d79124a4c0da7339dc4c0a0f4b9985b80a1bdc7425998a1ded448cce0c2443eaa9b1330c5613318daec7628675ca34e45f18968a0b08c6ec6e437261db46f33e04d8579467978df78fb661d2a03329bdf6d1bfc2ff6deb54955645b14fd2b27ea6bcdd5f290523ae27c0014041105e4b963c70a5e05c8b304543cb1fffb8d4cf06dd5acd9ddabd7bdf7ac8ea89e0249e6c891e39d6324a19e6cb6e3b85074822ec7dbdd8aaba2891c375b8ef30693c4dd6dc5d7432c8656268fdd776d79d4bc0952cec7da7c1148efeb1c3b5a74bb4532734b0444e450ceb1f6161baf655e4b429da3b8d7368a9d6eecd17a4cc7af8a316c52159f714c9aacd1226bb47c48be6db8f88d1f46b187bc4d362b9c6df723c6f0ad4de63813654c8a2b567fd59b561ccf5eb78a96bf2e9464a9d60ee1cf5acc7a75c848b1a599b2991ab4cc148d70f0d0159f8c3dadc11834a357d1c0dbb8fe7054858758e149249244f7307a2f6707b1fde0135f2f319dc6397483aebcd10271eb2235c22cfb78cb13fb5d161708555609b50dea511c0ddeaaf58a3f7299bbdf2e68011f6c9a8fb04c0e7819ec47ef8799551cac83e6e1b6a23763237f1b6fb84299e52ac7a5d4c6303eb88cb250eb757ddc95babdc55e8301a1bed215830fc3e56b206ea9e5403b8a6fe951f70ee187ab93a3f95ad98aca76e4c4931da9c961b23b8653cc3abe232b2ac3b3f9da163c135bee66a13f1e209b8a69b0a23d1a751b6c09b5f0bc9dbd6fd9ea900ca6f526b38a113e6272f44035c6743c7658225eb8b3b1e6be2ef2713478c54d6dba9ffb14874d7d73b05c3ace60341908c122af5cb60e145cb3c80cd50262a08c3163431f078cc8cc464b02154947c606e9aae091b40877cca19eebf972be298758f87ec85d77324056d48e5ced83d13ee4100a5b12422e0c374b23d346d6b075ab34c5a5e858a718734888623ede219e22d663d19c1a43b5a5ec6a44881fdba571dce4af6fde9bfbaa35d93c976662b5755d954af831b234c7af81b2c205ee75e3bd4eb33a45679bc56ab4940eaf331df10e9bdcf315dc7fc58868339e20ba7d2c9aa14e52bb01153ab9bb5cac7d7a6f331f4a35f4c26a428592a48fa624da28f68cae7861f03a3598bdc79038a30fe7567adccd686734265f17af2e3e21f983a9d0b3c12856dac5a25ae3786c5787116e856bdc8a9c557188236c7838e4ec20459b95e54d3791f0369692309a850e114e512e9c23c3e378ce66c15ecdb965f131799d944be4b522161b4e5c1c8f87895e7ed433b1268ea15a1583361d1d65975839f1c8db45abd7f970caef5b9579731b51c12c439ecd5c71680f0eaf7c305787b9576be352998fde1bde2bf8d520fdd81ef274351878d27a3a7acddd5698bf32e832b2ec772f7ca7f5191fb31faf2a5ba7242d4946d0ecd9e3aa365ecbc9db415b20d592696bd61a0cecf0a39a90febeb107ce724aa73346dd46e34d6019fc785f73136e39397abc5c6d4c7617a76dede5d95bdbe8a5c90a9e94af4ca5c88ae218d164d58cadd63f56d37d231f754fdd35392bf855707833a7c7bd3e14bdba09c65c5ebe99ca443488fd7ca8c7daee236c9709211c6867b55ee90c8b78f6344fd96637accc8f54795d8fd241e42ce4dd08455e732c3d7e20baafbcb96a3957d323412d676acd6fed5558071f9399f1e14c5fa3f0f5639893f168b9242289f17532537d52b72272358ff57d1686189566535a4267e24e928dd53bae072863303afd96bc86794dca143db3cbf94059b96eb3aaa377eb3d2ad5864c121df7d4d580209c549f8fe2c63fa83b4dd8e43ad37eec27ad61a4a9a7c5848287af136c6cbe9a39b5d792ad45d155d88ed0d702d5df56a6279907d63d6e95776e9f1e6b699659da6a8f86838f05ea988dbaac766639c5b6aff56c3fdf6bf2eb447f1de249152cf38f8f464a8d8f2d33529901a1e8e4c73172759f32768899bd09f337e1357dfb9046ebd2289d0f8175c70e5ef9c25ce5d9f741313bf803a5b3dd626696cbcb8aa328fa6dfa3ddbeded4fdb6e5a9fef7bf9dee5fa5cef4ad8cd5c6b682a355e4b2a628c91bc8d77c686d5cc6934979584289c80de39aa5b270d8661c6613d88d76feeeb723e11e2929eee4c7b8619e36ad420916599266e63a3fa301a6de1b7e488d7d7451ed246351f5087ade4d47165b93b56d68d0279675869e4beb39c8c464eeb33284b1e3ee29dc0ed7477636fb25d86cd475650a31ac2519619bfcff08934e46c1623472edb1a2e6f6ea88d6d17489a074be368371fb394741cdf0ec2dd1b6dacb11615174ceb2dc7a37489862c468a929a3b925af004eeaf6b49b6077c9a260c77d4da965facf6b64e32cbcae2a3a8a696889be6636d3e67a71e1bae0e713cdf15b24dc7ea5178c59d7cc704558e4f185e3efabe883351ab12fe483cc4fb8f637938beae07ca611e736f05dfb4216bd19128ccea19132d5355d1d7d9dcf5e619f9d6acd7deb6e0b71371e9c7313e99d27ac37287261e23b8107008c3b04bd5781b0562d264397774ab607b984c96476f392c70e46d43a75efabe5d2c86fb3c489224de2f8751acb1f1be55aa5110f2c53469fd89868f3e903a112cbbdcb4cb48dc047334c566dbc9947b3bda6919e33aa34489c54ae2a86a7c8d6c9a66b1e5e7fa62681f5a9b2ad7b1b6c19d659ee5c6c8de4ef380674d3a8f891d47e8c6468fb052d44dc5c43d81b4b4f7d69b466f39c1103e35f0e725a3bf798cb9940ffa765cf1dace4d6d878c679325cbec0c433f4c243fc8dc376ad32482b2c9de162e494a216fae3f14bdd0b155a114873775f6b6aea9440db48311faeb08a5d7361256f9723a34c6d66b20241b92c7870db3e087941565a15f10f8075a530db15387d1a20acc6a3569dfd457eb9527e964bcaf0e4b7fe589de9654cc0d7dd884c688080ffe32b75cf230da347b6ce00da463c3c5cb604fa987bc92f932e7d8a360522efb8eafc5dd48f4db6c9e07afba15b04acad948fbae2cdf685a386ede695f34e96d3af1cc605a12eb3a39646db04a2c4e21033f90f925e68ba990ee3d4e68b685b7191c86e1db48cdd1572b2236fb374d0f26b3c562345fbdad184a7ecd8325862fb41a6b5cac5da46f03aa9329c30912c9a4074bd8be994fccff8a4cf132f2c3fe03dfae2c6d565ab7023de5ddf769a84c0753c1f70329daf153613d398e1235cad6989ceecd6817e542b1382e4847291603a45c09d1684cbd0f0b6bfc4a1db6ccdab457b53cc2f5f43d28d7b941ee36d8809a6c9863cb1b0cedcf5fdfdef868ed87d241d96ceac3480ce6561d542cd2a085ef054165f05b6537df979e202b2b0cdb88715a6ca775150fe335b6216b8f245c2c465e596f2337ec54a9e7ded49ca3af2112e1a8408af17256ca85a1a94c25bc8fde8bd164f69a6e112ab6356c5cacf7162e2fb6f92ace9363325d31f6fb6e101dabcc5d6dc6965d7a07cdf988455aff18bdef0e6c3c0cad685c630db2591d37d38dc5a3ccac1a68ac5745d376381b0ac65099af661861adb56cc405c38878331c7dcb6c52544d87c8313c08d2d67bab91626857d2c26d9dc96e4d65f921c1066f6bf96da8ae0fb9e5ac2b39e24c6eacb6298222d1689054c96a6612db57ce6af99008c9e12c21383423317a83f884f78129e8f89d124a2d70c5395d59edb47633d13e545bcd9a69e9410f0e52b17017c7c834cd574bc683d7424c57b5f041bbd5dbe695c80b3f74dfacc3906ca794d0bca5dbd10185743a42843a1a8634455128f5bd9aeed92fd0e93a3025c4365040af7bdb1410c7d08fdff88e589a78f5923b4eb568474ee48867449b6ecbe1ae143f326d2396f15ed399588f434f60553b2017eb3868eccada6c0e4bad6e8bad405b63991ecf874ac2c84dc2f3be217a83d560f6beb3de0f83dd6c3f19efd9a1cd0c957569a2e661c1bb95d2cc19edbdd928f6e1286d51aac9b1b2c8a3315b6c8d23a326236b2e1fa6527314e3ba28b2ba8adf36cc3c1a186f2e82b071bd9a2c5e87085faa0b5b3525662ec9eebb363f6c2ddb5364569ca3d1347619e72d1ecc86d6045d1fa77cc64eb6f3643c7d77d834ab5ee7ca7aa9c62eba264764be6cd5ea75706847afa9eeced53943ef506517e01915e25361b6238bd6484cd2daaf3fe865b1f6df87e1926ba79359eaec653d5a56c5d2ad6c4dde350e3f4506a2383f84193e91add7c578810cc7da71fb91621237128eb848ecdfea416b20afed14c1d7f852382c95c924538a5a1e39d981dc458bb218a8af8b78bc35e58f777e45528eba7598d5685c3b861bd8ce9ab476ef5b7242f816c7bc458e31fe984beac16d067c55ad8875940fb8b7f0d01c1b9a71037c3513b7281d63e362ab79e4a21a37e5abe8364e680c9645325ca8fe46d44751579fb1c5dd8faa48009d663d9dd25424534fbe817ef97e39953c186e5d5e3acaead369ad6a0427a2b448c9bc469d699ea27899160b1f397cc0de2a30a6f698830abfd92229ba428b5aba54625292354250127dad3384a4a4cffaeddf0dcfbdac1efa6516f45dbf27de92d5fd9461212cb0369abad446f3e7d7b9477e8d2999a2d69aaec92a2aac13eb5c2bed18e3c6e7d8ad650ae5733c3cc09b3fc03baf3e83b7745b02b18c3af2b2e434667d559ffd743e6b51a1e87501ae08f03fe9d1f686cbfdd3f99cf281cd4b3eb0c791b598d3ad8bd3a9972ba56d4adfc229fd08c23b8001cac0efe14d7ce8425a300f39ccdfeb4b79e88b1a4e3ecd87fe5e9ff64397d3f1e77d5ee558f77c38b9c9d796446bb0b01960f75854415193c56ddfa24c67d4e23b35fc8c8b9108fc4eb7494b9691361aae445eaea4dec96f3acdef70a3b3d0d174194fc1e5529b5014d5dead1f42ad2be13bf353383db34cbdf2a7cacec788cac5d8c436f964a17e35fe44e4d0f19c91798a9ac15a99f5c3f80e22fe99f1353c3dfa9c5edfd87f28a0ed88904d1d7138bdf1b9746399caee6b5cd113c952571e10aa9c655114f8718f2b6ff92760ed75fa89d71637673b44b3193edd8271261bf0fff91dbfd7d494e5f6dfb03790ef8f4938ac4b93fb154531fc6c4f5173ea61ccc5ec3b360e92361eae442e77f8093d3253a1dd6d0680143804d063fa88e361f51d1caf3932b7afea179ef21fcdeebd11ea337b8a6a0f214531e307fedba8c3eff09f04e79c9ec617200f7e3df6617744b211d0393ee0f1c9f0616ce5587c676cd932954236a5a36da0b1cbe9ad303dec2c8cad142e3dfa33a1b472fde6fba14fe1e1fdf19c180fe83d45e1e190a298fd033cee66ff87e0f972dc59c5580c5e40c37a9f50d4c47a189746e4ef8cfbd4865639b6b17f4e776fd49a8ca0ac654281a2a8e303dde9d2b7e4a07e822791766e669736aeb79679fd1de9e7bcf6ba08364b7b0af44e35dd539418def31abb58cbdfe035f44c836cc0e91bff995cfb5ac7f9d4fd7f93d4f8761dd17339bfb759161b0039cf82ff518307fc5af6f7c740d818ea3a43427eee233dc7b7d378a1f2319c52d46409048dfa204f677be33bf8eefc37daca25c4cbd88dcfded84d77b14c69e7e676fa73bd3c19b96b47d3a11cf498a7f852f4f77fcd77ce9fe36bb58edfd3e99ea6286604349fb47fc09761fdd13aef6fe385bafb6664971b704b477efc577d67f9a9bcbaffb6db34799057af99f7577dcbed8bef383d5fa7fbef4ec90f74cd05ce77ec84afebf1691bac55d2c7e6f3c597308de8f51b4e427d0e4b12d507d9c6856ef8777cfbea397cc3f97aa4b4f0bcbe1dd0433af540dba8f7e7e19b58a694aa0671b40de2e8984ae967fa1ae86737f39f9ed9f794feeecf288667aadcd25f616a7f9afed4efd4923fe7d179e86c7719bc4c66a7ef9addf0a811917ffe1c18b4f47009e0ee0423ed65fe37e06346c804e33ee037443c009ff8009ff9f1d79d5393b0b8650ae9f3f3d39ed3a3ba9f1bec1801f408795879e4613ffcf33cfce579914f698ffa08537fae019bb5941714357db4d570e01afd4bcf9c7b8e33f643b610dc029719f0a71fe5de2c8dffba33367bbef5be84e9feac14f55167cee3bf6e1d7f5d96ac6a441bae2ab09ef07ff747088a32bd2fbee5ff7cb99ebfb28eebe3f103f180cd33d1a18c7bf473bde4fb76d96738d3ddec3bdff4f9645def7218a5077dc106e99fa6b52f6518cf073ef5b6b7286a56c84fed20739efe82cd0ec7b4a7b7b2ec6b3b8822796d6576971a454d8a07dad9bd7dcb5f84b4d3e33fb9a3a1d5776cd3fbbd19f5613d66afdbeff3d91fde337c8aa73989bd6de702602f210432d37bc0d3409c7e1f4fcfe259df838da53bbb6b4731638a8e788a5a7df47eeefffedf2f3f5e4a671be4f5cbefffe76595842fbfbfbcfc78919c2c00bffee77f7ebc24b953c7bbe0373fd80d92fc1f65da8471fe8ff726f77e1fd44156a64e1d54838fc6d9264d3588eaba1cfc96edf2c17eeb9465b01d64ce2ec8ffd15ffd566e8b32d8d671508101e3fcbd00fffa41edc429bc9577437ffad68f972a3e062fbf63e8f8c74b56f8c1cbef430c813fff59c7f05d0cc1d07fa0e83f50648d92bfe3c3dfd1e16fd8688c8cdede48e21f08f13b82bcfc7889ab7ffaf1f6e5f77727ad821f2f550b879f04bb97dfdf86044afc78e1f3e2e5777c88a1c47038fcf122a5719ebcfc8efe7859c061711c1d8f7fbc68b1fff23b8a20e88f17eef2d3fce73f4bc7475e7e477ebc283ee814f9f1a25e20a7d3a49bc71021dfc065e125d5cbefe31f2f541d67001235f05e7e47dff0378244c60418bf0277489240f11149e2fff3e365f175d3f39cffe7c70bf3fda6e63fffd9e44d15f82fbfff17f203f981fcf7ff003a88822d4410c0d9cb202ab260b009f224ceabc1bed82655e978c1c08b073dbdfc238fc3a84edb7f78f13f6ec9e68e8a067ee18165e5b3b2d8d62ba78e6e68b07f3a29bceef6dad98641ddfd568aa2ffb5706a2f7af93d6fd2f4c78b5a3b69705e5878a5044e55e45d5bae60e314d05fd7ba1bf77c3909caf3ef7550d577adc1adbb371685df80f1fecf4b0ffce71c03218df397dfeb6d13fcf8eb710967b728fcbf7885c2e2b7acf061e77ab0ad628849f437f40d0a8812cefa243dbe9c7cbfa67f4e6efccf8f17dfa99d97df5fecbb40a76e0ad5ca88107f461f97f11838857bb7257a814f9c846cd329844e292e62f2b9b23c2b0cb47f7f7c143756b3b808ebfab469b7688798b859d4569636625e961e559e95cb1f84a9745bf28bcdc1f15edc688d74de4c442fca6c4d35923ac4c4ac8cbcb0f8d70878654a4d16d3df32ff6b217e697692dae87888ff2d621b1dbd11088e617f9dd8ee40ff8fdcfe8fdcfe8fdcfe541c5c6433dfd29c6f109b2e8997de9f8c6b262c4ddb386c5c0c4df999b2e367e9ce37f9d0cd749c6759d43285ad6f2e423bd71b0b874e40e8cd849d93e91b9f99ce9954291c73117a185b7bdc21e56774eb62656ae17268010398634b375f84964a1f1d83c85d4ebbeeeb8de7e8ec0c57be6894cbb3e6aa5d3137a88ac995c256afdac7f4876f4a083f13527fa6b7601cc7548e3cc7b636aed7b641206258ccf97611ae39726319fbd036a3d4c23bfdc42468e4605ae8e17a6bab34e2702cc273f4dc32ed889f4c0f3c2b4d558c0ac1fc1c8338fa1c5bb99c9e803e756e1c7a70735f0e81c30a0c7d9eeb36fcdc59127ab9def01cd588188ab9b9177aa61e79598d7ac732b14d3b14c35273380de0a873b4181af4dffab345e8cc14c463e8a36d0a986df221704a798e457d0ee817a53c8de1632c0274a4d7d2998bf3a18545919bf9e07a67c7f4d1c5f5d6c2e01889ad0ee7aa61851e46a25e26a53c27ed6c38fef91dc4b9bae6677ee972fbd0ca34b8de1ec7e696a9a43643236e4bb7be4134603df999947ab99d7af130544d39b48cc3d16d69e014355e4b27b621a036e6976ee6851e47b63e4387d29ada4b0635f7b07168737aec1b7e0ee789b10dcf0929cfb1880ff5b09ef05c9af11c91da06187b08e86dc7cf04d48d69c4066bff05ce7d4e3ffa1cd53061b1e15bbac33767a36e2685fc545aa87231574d39f75abab50de8bca56e769ee3d106f399dafa3a91deb5449fa9baa469691af29cdef859daba1801698c9fd99197a591951d52312c438ba38f0ea7572e431f2d5c28bd993ce7c118265d598694f2b3e14ecc84c8c3a2d66ae938506902ac153f930adb3854fc4cd8f09c5dba9c76fb1ea7ec2cac4ebd9800f6c8878b458dcd9170ad7c2e0c038344bd18ccc52f3d5c6903b94c8319bd0334aaa4fa52464955d17c414315d558a3898b495bdbe41bc718ef9c8c2cdc4cd9d972995a58b4e319e1d7df55f970b51986eff1b8b132f6e8807950001fd49c8917600d18df482b9b4b1b7b0f78282abd96de9c022f3c27a08e7148bc965ec948123a061ad99816da19d9f2b37bde1fce998c0ead33cea48d97a57b9f2a619b535f3c0323148f7f2d1d435818fac332f9399435e77b542d1addfb3694852ce29876ca338bd0caf5d2e5e4cb3d4e28dd8c05b8be9ea77ae20f06f2797a04fcd66f82403a3df15b3f6ee56252e4720782e7d286e7a617d999e92d93ebc78ed7200e4ad760735ba5375ea6473ee411367671fb53daebc7687d6338b7383aecf861112a9cbe773992780ea7723ccb807ecedd1a29a9c71d76817a057faf171c83007cb3716780eff416c849309e874529e8c7c3a4d6316984c9000f2e00efc3f1215e3bb98178590a1346bcd35a5cd3cf14f22e94dd004f7e466efa4dfd3993283b9e23763e0364a19003def5818cc67420d3752d3984d77cdae93a88cfd6c575c456a1ccecf890bb8c03e6601824ca737eea33dd9cbd8c447d204bf204d066e572240ed7e7b2c6cdd7b499367636be590b0bd5d535f509be525d5d4fd0c29f297be0b3b850971d0a179790e526dc2f27d48ec924d4cbf6a1685aa130abc17c499eddcf7986aa55868a61300ac82d06d502934e97d03f39005dd2cd132b8f2e368c4fefd80c1507e83e760dfde8616c6eebfb7819d31e1fcb858f453bcb40cbb9be8fdff57dcc83394c49b5831389a1fe9a143b11eb64b3c391477f520c1793702f1ec9da36a5a365f8e94abdea4be5e716aeb72e43d57e4c2501c0c70c09211e29a8c337fc34d274962e6df9cfe009f87ed4133cd1cfe192ff9ab9753afd666efdfaff8b827ed92edfff24a6075a9c3d41047923cfae2089ffcb5d41fc992b88bda17fc415ec60ffc417c486ff7106ffe30cfe5feb0c422ebff603a73b1817c3a5828917a1a822f5bffc0fca50a06bf4c6c3f4e44af7d27dbc2dd43032f3677ee4655aa86424ea664ad4d9795421eb12375769702ff5627ae766d02ede79315dbbb8007d1937575ac710808f04fcb07e2c2db40cbfb58dce17f4da61c8b3526af7b6cb3a21355593d82b5b3b714cf8419bd8ef7c1ddc319502c00a7c401f235be7e46b194ae240db83885c862eddccde7919dac10cf4e14c486d8c6da1ad0b6c229c26806de3cce4d0c5fdc63685a3c3a57b31a6429d8b527ecaae9598ae1c434add5ceafd31608f9d6103b615e1e25ae81b04b44bfdeebd3e2e4a2f4eef8a0c6dc0fe819d34e19b054315a02d586f3e39e3269eaf2be833f01c1a052addb8b81cfa26f04fbaf9da595ad92a9d76c96972e81843e8af42bbc120363658d7def7e86039f7ddf00c6d03585d8325788e8ca12d1bd311582b6f96842e66ddbf135aa63ce7f7c506dae71cd4d36f624be23eee35e778700637e8aef0442ec01aae538915d77cb3a08a0d98a76e1015d0c5601d3c532fbd0cd8c902c17367bb2776392d743916e721cdb0b997e927df0fc08a7b598a00bb4ea4c03ca59d9d2b308984e714e85f75f406e8596f6c4e3ff928e775e0e1faddb5e580edca36dd5ab06b7e9aaef99866645d12b4761fea48aaa95352d719da94754195354253357d0d6c107e2aadd68922e8d374b54e17e11ab14259236cd0978aa44b85d987b691220e8085d3871e983bbe0801bd3a06ba77b914f8d0b73cc0a51bdb208ec0b702ed4e74e2e1746a6169e6180b80a3c6c6f5ce17c348cc3685def7a7532feb138030e208e665338086d1d2e73abbd203ebf9097e44c027ccdf207f5464fef7caba6edf806725c432058467f53d3f15229f938a8b2fd0d1a996e907df485bdb904345230ce8a3e48bb7afe085b4c3d07359b7691389566b4d0b45b5f321fbb818f065227e5a4ed5962e606c0fd061d88d794ab6b08cfdf59873bea53e9f134385ebb5f0ae4e494951a9ba8fbbf4be18990119d2ed95f847e0df9c0a0d6ce6767cd88fc61a8a46bcaf515ad35aaae667f0c361b56d2aa9972f428f638f777aa28bc9b1b6c4cffcc23686d08776e14705e92ee9bfef9b67e854ccbc06becb29a995ebf9793db814f130bdb2e33d94731d1ebb7800f413a728ad27fad24448596717a4a8475dfcaaa56a6326a06e56263e4ebdf93321727369efe202b23214c4c4251897f199c329664706eae1e89bd2de368864652615d0175ea61fbd23325c4ca87dbf8692acdbec3a25d72a92ca262a4c780609edec10d99dbc07faa8f35701be0d05c6d180ececf6a088d66ae9cc310e29e4b3bf8b97b234e3d92a14cd22e463e5710e31edf3930aca12372c806f55da31edf20c9af10c99fadc627705ff755bb816624ced6c53d99cf6dfbc6c01fac81cf9be2f3ee9e871dc5cfae34353a546906e8ce1bc5bdf2180935f23282b9ef6fa7261c383f138bb64c2b2ebbba5575a4b1f3d4edf38865d5a2d7df44d1aae33d0d302e093987e774dfde8b3e32e360ae806d29a5e823978318d78b99e763ac58edc199073e526307cdc3186a49db1958769232653222ff74b778366967138daeb6aee1a6963e3dea9cddcc2d8a3ad52b135d31bcb40538b01721ccc899e189a6faadaf063aed2e7befd9980da2a355aee8b909fa2c23af1cd799c84a77ee1f3753562622a5438b6f5b1b401cfedfef7ca545adfd07a9c2d421dd8020c897a38bf73b93486b1f396fc00bc6862d1ce35b4d031ac105c3bc6a18b7f32f40ee221f74b0fc6eed8ca65e8d832a42dc413432e1c43682d532044a48cfc6cba5339b2b6e5e214975bdba05fe02fcf1640ff2736582f8edcc36202b01e30318cac45ec505ab9107939dc93dd88381b81bfc57a8a2f18f2dd817652d83833a576a9ae7f00afd152751053b1302d693d617b99c687e6fa960eaf686dc833fcce37a5168e99e943db58ec9c8cc52c9dece45b4cfb4b68b3e90dc0ef49aed86604e987bf1e6b8dc4d69778d543fe02430a68e83b7d8ac8051f2a804d257908dba52f40e75d1f59d2adf3a41a31997eb48cc53d5f5feb97986791f07a7e273c7a675ef5533757766e8bb6b671482d403b77efdce92cd2e2e0fad71646367696e6407e39b9908a468703f00e8013fcddcb9c454a427ebe9335806ea1eded6164e567c0be4b1b0707ba944a160c5d5b6602f9d652819d427434d9eb2e015f84ce8916595a558e482c4ca898e9fa0dddde3eecedf25d176b3f009d8bd92a7d0c0c14f6e901fe9bf90590cb1066230430cb5ae29df098b8fb6e1ddcd982b4b8c39167d0ca66a85800e3b642d8e30bf6b732e83498d12d9077ee6c11f3932214dae187b81e86261336f3745f0a8c7f7a07d0eca53d987fcb87cb98cac576f821b4d42bcf009eb2766eae57eee481e6019c241f2b1d7efafb369051f25d9b0ce82701ca263096c60a333ea376027728ddac8a7b783a9ae314e8b7817b1e066435f09f78d29ad1b80de3bb57f6c51a0d6d2e6d5d6013a8179c88edb039af85c16e6d952e7d86ce7ce350052a7df00db60272db36642023cf34b232e80dc4ed1469cff4cc58197f35b685c9608d8e4037d8c0568979c01f1b1ee8026e0c6461a77bd73cf053c2abbe3afa8c17c06f6df9a944d8b85fba31b0c589a30ffc85191df95cd4ed4baad0b7d0d7496a411a023e2343c75dd104f05709c2e7223816f4393912057e8f4d95a51d538985a73990d537340f696cf8c8178c95f56b70838bc0f0f716f06b19a4f60da20cee706351377d3ec80121b63ad971237fd010c0e601bb9fa16ad1d41bc70c1fdebfeb7bb29eb26b0da5697d1adef52d2d645d5a6b53565327f77d037c86a1a8a2a89ba54036273272a0355492655de1f98cba5b13b474331f17812ccd2514e019f6355b849d3f97363cab2f553d847b4daec1223c27a4e0b7add2919b039f0ada9a25f0cb5d5c877b935026314a0d7c21bfbdb639a0ce68005c179b19da2599d0f3d385d6812e881ee873d9d27b1f934b8be16ffa5313d690f5a76b7c235bf98c2a7a9abec1ff75bf4fe4eafd5a5fcf09ea27a5df3fb70ca1b201ec50ce49050f6539bbe9e13de94d0833d4931ad09912ea73d0ef3ead75c8aba09d00759a07f71794c771f47d27f3d07d61a0c3d0544b6faefa211f5324cf088ddb3ed1dd704f97ede55f7898ab70ed608ce3da5ee139f6c8cf24c43288c43285ce3f67a59dcbb12de0bfc59a3ae92ed8df1af47744431f8b4a0b0b432fd3231bcabbfa5afeba3c330d2de883f300af97777b596c32916bc6b40f653746852b958add6c7c8773ea6cb3085c6f2fc6f7b62d1c13e20cda51604d80fcca8808d867e653fceb1e9f51f1b54df1648d807cdfd8cc654d60ff602d4eb293a16a8da33a3bc8585cfae37468bfdec3f7483b426a19bd9e01f63cbb8f858e8e4e45b3708d4c46089fd9307f7adedd58d046bad6b1dd7bd0be3dd39d18039a2363c718e616751eff96e7aef1a4f2f32fedb51b3b0ccca9f3419ed8a793b5267f6a7fb94fecd82776d7b51d7b234344ac6c6d953c3a4c677f3eda53700e1b7e9a326bd53ff631859d1bd3349097c08ff6809f047ce2cc4fafe302a7bc1418e7e36ed6e1785e83cb1cc93bf9b383b6202e152206edc4933d716b0f7ff13e8c73dfbedbdb2257f479fd7e46e30e976e9c9eae7a5976bf36d10d1e354952987b9f933ee550b05e2eecbc4d11dec86d683fc2bdeac436ecd285b14969e7e5426ae14a15a8c3989f0cb305f44f3bfb838fa95087b93c6ce3662472c1a716ded0c9e5bda163cae1e273babad64bcf6037ad3eceb78c6f634db641608e29ecdc0c4ddd5c0efd8c6d1da38ba7029909e19b49a9cf0c632683fe75afe7fd95961ca61a4a2e645d5fca48c46a1b74e7c1022e32b18d28f2cd45e371873498e9c753d1848f91adcb2947313b44be4100dddb8ac9e537dc439f292db0ddbc2e760eec5280cb9d9727a18703bf5642a02dc6d9ad8b2130a7c9c2f4a3d7d2b88b0b5b189fcaf48dcf916da0c2d84b1757e90b3df899b0737198c793c1c256e6760c1f4b816dd2b8a6ddf03309b5b29bfefa3c17e2e8184a0a63d1d7797219f0f36ffa9bdb59dad86c9f4f9c9231f0a7804d3c679230d8dfc441de002d2ec03a02dabed60d27da493b7ba95f97bd6d48a59da5a7587706fc64b38fb598981079980e6cf3f8acf74c05f5b261b8904ff112f0efb91dc9c7f201cae7997f7f7df681f858c101fc7c4c452b15f8225e47779cb2bb935109988f8f411b7c276628e63e9549f419272bb5ebfb22d705a06fb7373cdfd90470ad2d53d8f9309705fa707339d1698d4186cbf502e79908c8b6b58b1d222f4b8ffc64ba1751696f99c2662edfc610a0cd36abe1d8efcfe307f0d9d9ffe8f0b313e3616f8729e11318533793bbfd118c6c1d8c6d5d5c6f6ceae2435d78944f82f37a09241f9624e4054edab99914f99cde58a602f82172b93df4856dc09f9805fc5f48df4cd6b76549a08753af0d4b7e563dc4d9164fe6671b52e1b6542c3011e2c554edb5546e72c39c67bc5068a971ff5e798eb3e5c89c49045a43f477659aaa2be353da0bf9582ebc999fcc5521bcb351195997581351042dbe83e924f3d6d5c9fedfc0bc91bffb6f5f6cf8a93e04f8f730188f077c16b9dc61e7b774e49bca0ef8188e71caf9ba1c067495e7f5584b90959117d3999791f529a62dc2bd14a5b58cfdbccb7104ba858539495e4ba31e06fd16b8d7d3d72d8497ba05e88b9e7381bb3d4716e96453545a598af09c54d886b4edf29bd2e69cefa6d289652a91d8e52ffd3bfee65731a858985ee84a6c89dacf6e8af63ec1e5234df77dc6c21435d6a9ffae27ba2a27e41ae8c995dac7769fd8e8275ee8f6aee5b0935bd7458d0f07bc354ec6b6e7f84a96ccaf632c7f160e19235197531a019743a84b7add745d74fa58c7427c58265f3dd02397223c336cc4b8b769012fdfcaecced7d5eda58e92aaa2d32b5d17164f63a25c1979a9deba13e43c372dd1e535aaab6be62faab339c379eb87007cc3fa1f55803962deb1d889b8907adc69ff6078bfcfdc8db3e1778e31de7d7558df8219a2e2c67a0233d2c30c711bdfcb7be04702bb49d5ecf54a05bab3f33379ae4e0395c62ce380daeb2ab4b9f1791ea77d0101b6817b02e17c763e7048f7b27d7983e7991db9333de5375568011bd3a8c2e5b1baf24fa4c8eae391364736b6dac96e3961d78a4e4e55fda487bfa667efba18b63dad4127bbf95891f484304dd466b544586908f0ad90b0dbb3784627bded92dcd322b4dfde7806f85a70ae8f383d1ffe0470006d1ff2566f8cbfcb0bf185ce2fb1b707582fb89f5ba6000fdeba8fb35d62577ee966cacec717d0263ae153cdd856836d846b9be082c3abfc61d104b6819ffacccf62b97f02fffdde43ef0b70d00601f60ca6f7b2e0ac5bba7b37639ee403f564cfa59767bac46a09419f628aefb3fd431bedec33c84fe322a7bf1e17307600699ee143511b7f825ffe3a2ef1b0b7d2af27cc1f16d52e975434f5a36df2e413d8afdad091874bc0be4c56ea09d734ada192b94685691f5780f2878fa97add427bf0816e9ee3914edd2734d0e7cbfedd34b0f1c11c6e69a0bbf76fa48153eeb0fb195ee33bfa30ac9fd301d7e754ab28ea617acb3327fce96b451796b286b2cbf8d95aa3d0367f2287e27b3ab0ef71f674bfe5af5b43cb38549d1c15220bab608ebcdfef6d747b865dde818bfb8dcb91917dcb2f57b1b773fc6c020fc838223fb3c1ee0f679c9ec7e8edb14b9ce65ca3c1b9381fcabddc1519fa08fc6c1877ede3f7007e1dd06067ef662e2ed496097c6a3d83b981306f83e8f653ba38e5f57cbe96eb573146191e7cb1202d4e226cfcbcff70d94739c3409d62981d5ece7b79d4edbeebedfe727a893b76318fcff6936f6841a5bafdb13f85f76f8c7703ebd9ce33145d60d6a8c4c238fc0ce60e3cf1811ffa39f9aea1a8d2f0901cc738c0f55977391ce649662b1c89bb19cc7be9f5b11dddd8a1f77f7732e7ea6fc34fa59d6bd2a5cb5dfca19edebb035ef6cfe19d3fc44b85d28dbb58a9d5c2d8fe357dc473f9be9f3b9e79b2ee5fda594867675d0eb47c7670ece24bd9d8fd2d42ed9233d5d5ee5ce3f793f5faa37ec8fddfc92fe119e41a8eefc884508c870dff097cb7fc74fd17dec53961ecbedbab5081fc97f63c73cf2b5fc30369bfcf5dd35861a526fa44ef780facddcfd7fea2cf4f31e57f9befccb7347b8a33d96684c0c3f00cb2f937c64ce6977d923e0f0fa5d53552b232dad9ee3066a42aa3d31a40bed11441db14f5ad7d2f90a798d1afe8cb9e46bf5a631857bac95f047a8f89362e466c2c53793fc5d8aef2e2642d21e78a266967784ffe075662ae4a807733c7f0e2b97a19bbcb8de49fe61578b85f76b9a47d5ec14cd9f1ecc5af78b2877da9d7ed726ee6dd9e62dfe7e6afc925f8c4c7b9f493517f682ffb5b3af786d73b9d7bd91fbbca25606ef7e1aff306be399f9b9c85bb7c862fd6fc6effff731afbe67c3fe791ebfc076d26ecfc2c4d6c958e784638faf020665897f0661b72cccffca8dfef686d53691d43c74eb9e1327210ba5a7a60674591cfd0b8631c2ad06f5f0bd1d54770c20ec07a6587411fc5cdc846d4afe8f2aaf6de6b87673e9211746a2207619de8efb22ecc204f9d7371a5d53ab105a5a51299e11f650422490a4b2e548d604d845515743167525f95755a5674e17d3d65f57522f18ace93f04c97ec542f713ef3e5a26b937b5d8b468e319c335dbedf393f02c0cbc7b407684cb8cd190e4db8378c763645bf86df9205df8845f4b599b1a82927d861ee219489a77c1213013e46adf4396d6286a2ee4c29d70699f8c621d54e67374caff6a7d64812209fd313dcdb80f352463a2ad01a4bb35a7ab5879723e193f58a852915ff4beb1b7ff37e76e4cdb9d5a9cef1ed0d19fd9d658e4f0f2afb63658e1de89f5439a26fffa972fc4f95e3ffd5558e90cf2f958e322bb06bf5938a96bff88f496855d1904b3595d19d3e7057a1b776311bf1319805da45d3fa2a299e89680db1ca73a5144736b65c525aa24b5d2501da65876264733a61cdc5f9d0bd546f45362ea476779cfc518ca950c3f4b4df495cae51459011adabe83bf77b5fc576aee42b2f591170873cb239a5849545195b75a717741666778a4e37772fd373cb1492d34908de2c6d1dc32f7c86061e6beae552e19854c333dd492cb22e71974a4dfd7853757882f17422d1a5fab3b34cfa5d9aabeac18a6761f6073c8962110ff73c1381b6f39e0ee24ba51b5f2efb4acaae3a1166e2a01ea69de60e77c6794e1f5a98bef719b84bba7131584117b999949ee6dc657ddc57d20d439e8530c36c73171310cb389feab10fba9326eeabef229feae67cea1b7adfa7d306701ff7dbfbd3e92eb81391832023fa5243b41accbdefa39f3badbbd90156027a57d566569e845d3545ba8119792a5d59a61776d5adb06ab6abc0e2d2869ff92dac76cdbceabcde5715bbd727ff41dabfa950bd5478c2f5bd6b0bd6cb3286e77592f545a8ea8b98871671ba1619da5475855fa3bac6b33eada502bd4e1541d117e11ae543192197ca34d5548d5c6a2dbd52629a5ea7c969eea2aa115391a15360a9029860a66906337f767007dca42bc7d0933b9eb9aae2843c70454b371542956510b9df9dc892bbb89d7a7db4115894ae911e610640bee84f4f3994ae9122dda925c4f14c47cff175e6adbfa97271fe6f91997d5682d69fa6a59b5428676c17e53d9dec714bcfaa6db2a8630aa9cdd0ec3ab560069a773cc1ff472a236f79efb30ac9beff8b47cb20213c65a43b85e6aa326fd8c26a92ab53c378aeab9882994aa7712e910c4d46a2774593f835ac8894e069336e4be52e36ccfb0ab3a6e7d32e7a674885dbedbe9ce589d5e3ed7caad8ec0273ef8130b2ae4c549694655d5fc34ace6763cdfcc831e5eee4256e1a3a984e005de162757a155548dd0cca84fb31561aabac016e3c8e6d2d034d7d0e9ee8b3b7e0e788ae756317e1d313204ba3d48daf22157d86cbb53ce439adb1db217cbf3b39cc3bd38f632a47db38646227cbcfbc6a9b727817b1a98d536528835a5eae374ea6e0dea444bc8c6d3c1c9e7a45da33e5ddc3c88d83e988783ae56c8312e24c423d1c666991817a00bab1b54de9b85a87fbc584bac7c55f50d9d9ebc2bfabbab3c7b79ce939acf8370e15dfcda9cf10ebbd7ec6a784ae527e03abbdce1ea040eb538937117da24ec750e60b18d908fb92ea226cf4ceceac9bf5f1b91481d5f898757d221eee1844e2e2defcf45c589ff19bba5997717ac5077100fb53909e7e9ec20368e7048f6358211febf7bcc1ca48b412543e5cad9190cfc886bf4407d3e73cabcd2f7a5147784687f241e8222bf004023f632b785a1c47663cd355a37615247cda45ad606492e4193ee69908e2854fba0898a0817ff5a996a486a26a5d7b1d46a0523e4ece639f32ec61b4670677ad019f6460ddeccb896057bb639dcde562440a6181b610150bda291a2089aa4ebf6bc922e5638a5ca954ccc740cf0119216d1d93562d946e2f3665972dd6ebcc3dacb4e965b8c8d03b603b9dec4c97d373cb90089e21620bc81a83e86d47b8f6376dc54caa6de6226fc0bad966547ab80cd6afc3b57e3857f69a38ddda2aec37e63909663ffeac5d377f7de89812725913dd3bf3234a82f9341686263ca079c0173f6b17166f1e56971e2b6cb4999032614901fae84ea6dacf991cca5e564b859596929335a2b0ab35755e4f9d03fc03ab51105839962b29ac706068cc328512ea03783aa7b073557aefe2d2d1e97404f88d9c4f1b982d2a7ee6a79026543a7233b23b2502c8fefe04452681bcd39d44479d6d0172b546489e95345917349eb5e9f5349dcaba22ac9121e00f722597a51d7795357cac5febde479a99925b35817a70ce6430c3a7e9ff0d1553685d9c7fbba992e84f25b1fbac3a208ffa530e5337b74b2f231bd7d01b9f1986abd86a4f7d695c5f81daeb36b8db771d6dbe3e090edab7dda9a70f99eddc18c863a853a1be82d9f5fd0989f72720f47df4bb8aa59b4b08a091d367e7aedf15c3b2c307d08b19d93261f1b6c6ea7957095d76159cc04e86bc788d0fddb3b2b431bb287e639b517ac62d97368e297f17afc0cf399e4ec9b30c787a1f661987d2becd6cbf81fbb60f8a84f47f85572833ff3fbd0ebd1c9b2080ee81ed377d4ef3c57c99f5f83ec95e9865d99f10783e21b7cb52873666bc0f1d9548c5f8b4fb0afc3009717181007218662d5c9d98db55cdd83b97037e2f15773bc37c73190fd895972c0e0b077300bcd0f9ee9d2cbdad4238f169cf4f0d139637f6d1b3dd88b32e40cef7522649397e4aacf41b5df1183916549e5ca97ccc73fe0eda6c0691281cf0fb2444ced8a3adc15341e6dde91bbaa568529719aeea1385d1bafbacdfc371792ec8c51bcc6a9dc28cf1a963f27355b342458f040d8572c8ecc617bcbe82a05fe753fb3e9b892a3736433562580a4a4cc5820ec74af90d42f23184e10cbb7582372176fed4861504bdfc36af61b631f25c55713dc765f630f6cf71dfc3c3645202784dd1235646c90ec60bed36f6540136f6c6bfc207b32921ed295cdaae3312e93393e737279d3cdd61d55963aa4fba9d546dde5591dedc8b81bcfa6c2dc13aac135203eba9ea9206e0fe628ea90977e109cfc9ed5accfacf75b67cd8e311e87cd536d844be3e716bdab7db1773f94a87f1d3de47d2aeb2eff345a8180494310aa7579699a6f6541f7a1cdb3d0f4b58a5262256c8e7fad136004fd5079e5352974b6bef88c43ca3a55096c45471652f3ed9cdd13b7a4b0f1f7e8634e7930de0291bfd69a4d3d258eb40d7139caaf9efd7b8d1d805c96b5f3e8f202c32b0a589a4b7234221ee64b99adad279070625afe194b523927ef91cd8b09bf2a7f8d6105dbbd8d69d3e0074b952ef74817e881d83f0ba8c0b220d382d3ef18b96b0b236d555f0beb641be9621fa1eee909997ac3eefd36cdd87fe0fb4ae111375aaab2b836cedeb185a9ff17dd5c7d3cf079f64a43225cd757258c99af2aeebc2e2df9a451e96dc1a3dd1acb27330bdf18ec8419c407bbf720cf4b85a77742babb4b0fe3edd9e77434deea719de253f55563c13f695942907785dd0a63118fb0c7b9f71d9d18db2d21162b146d8a989c213555341e3e7f373ec8966839992ba7d1cb7b34d0e958b7ba165ea888bc113f6a0ed1da857598adc4395cb3d6d9c6c64a9af1cd8c0130133b6bad8da30f6db55e9e08b735664a787fb13a4ce34d865dd9ff5fcecbc43bef732b2700ca1f4197ae370fac6e97c53e027037e88bc1c9eb88358eaf0c68f11f4cbaeb59ab0aaa052c555f639e091bb0cac93bf28745958f1a9fd75c655bfcfc050e9d5ceed5c063aa56b5b3240361987a37d33ded99eefb36704569b92ba96ecaf6cfadbf13e59df33dc972a0fed2faea6a0cabf004f1317d72b9b1be63ed3e96e9ed16fe554ac7d5e197393c5dbdbdd97ec3a484790fed64528687738624e152ac9bc9fc7dec57db85f024f8f66d0f3a7e97886cf8256089830116045a5216c5c2e8536f24aa51bdbf46a1713603517cf4a84872ba9ab124bdb941b1dd363193b9480ee97a73e60fc21ac61652813b9dd7e10919bebe24d35a5a56f1caa352eb0ae4923811ae667dc5e32b753a14d42b18bd77cfbfdabac6ef07e3957e9119f0ee78c9cc4c2cc4fad4caa1ce8d711132fd31300b363b095d75224cf11a9dfa23b2bebaa674f9f62131322f519305705dabf322ea436a7373e97462ef319ecfb5068f5870c6e41f5ca338e722436c3426054c15d673a22a63016585a982ebb58daf85334723336b74dc15f6ecab56d48a897a548a0d32db0cf2c8cacf809121a0884efe9737d96ee6d1d795ba64ae51da7edb2a5121fd363ab5f2ff12aeb5381a77282f93cd0512e3254fe2847bcf284db77f5aa2a07d8657799bce798570eb379e3b36cbfcedc9ddaa59ba5c7eeeb0c77fcf0c83367da9e9f6244535845b0eb4e293acbfab31ff52fc9583aefd7fdf9aca5db93021fb28f48412de6cc45d7f6f110dd52542d14beb6ed529ed16f62e8827a89372a539dd1c13b3033500b45a3cbdceeb3d41ee4fb1fc802fad24ee7e39b312ed93f3198d77df68f16023c00fda6e882ba46858502e6c55087b32fd8c525e6173b5f86f6273c31e1647375efbecb083955d6c8e1e4773009f40bba581543657d7ce1368ea6ea37d7427f0a4227ebae7c12a416349654e5f62afedac3788edd71e4f1b43f7b1fe3bc89b331fbd0c5888dad9e68ec90da18bb0954aab1321681be5a67ab74b476dd962136ae7189837e271e09c6163321f219f8f594ca85fe78177b3bd96f5e26bd7b007ee6fb71ceae5fa9b6bfd72f803b6636e5d1c1d2bd96493278ff1c4b99d1d1e954615bbdc4a0c15adcc7d2b529ab6b48b74f7c3e5991f1776edcc57c9fc4eafb7dacb38edfb9311f7a1c0bf7804ef1f5d338fa5457d75aba94758585bccbdcbe076c319fa1d21bba5361ac1256968b081f0a9aae6a09a9025a57a65afa2fcb702b8becb743967e9de0766a74ca6f1be257f96d7fc317dd88bfee8b6e1de8ffc96ffb4f7edb7ff2db3e930597f4b6d5841cbac63ef433bd8561ac0d122fd4e19edf8c5f99cde17ca8033f8b8eceba3c5a5894ba06bb38a7426cae3f66723213cec9d1f0239cda9494c4a3dc2c98e1be3b90bdfb68e627618ea187c967974d62867b714335c14c4af8981ebac6a1f18ebf3866ef56051c5ab9f9e22d9849e529ec02e0f0711f1773efd88d3f6e1713ea20a291b46625e07ad7968af6e17fa066f957e05ead387467737aa59ff13644009c8bc97ee71a64621b87f3e1f92b30fee4907b19897ad33459655d08c9c2d074c59097fb5dbbc8cb95d2ced88d0fdb5e3e22b462c8db675d7bec3cce660ae72bead252d6e9b53a25b515436277708035dddba68038867e5cf5b85971a7c236bd154dbaf20dbf7463e2aaef45b364868715436efa62bbd48bd1bd3b83dbfbcd857efae2adc9e1945c7ed59e805fb2770d1d01fdae3af7607c59c32b18f29bc3bc5f7b577b7ca619f80181b482e1a4fe637460fe4b88ff2fda9ce7fb6c4c25f2323ff527c383b8093f81ebdce634cf338f8859f7b12f319776be296c6c4d87075201336c95ea9a1223c315437eaffd09cecb014f0dfcc82c2e741f13c848d49fd1a83ffdc918b990c20fe6417391d8f9a6b2f74d85753369074dc8e3791e07df605b07d78fcfd79f6f16f1f02826c06d63ab15437eddfe0cfff9e38f8dc71d221f1e568a3416a43f3bb270b9760cf9f5fc61c3161ec609fbb155347631642ce2dfebe3442397be883ddcf2cec8d655898ecf18b4b42744e9b6c419fe9bb9e47465990a2c001633bf75717d2f1a3daf7d319f2bfa6f4580ab96e01c8388dcc97ef7093c4f70055c7a3d734c21fd8c07217f6b08ba62487828ac9da5adad7eca876311a75b17a7532837cc452fbb94d4832e84de58782a590611d958f771930b7f5cb5c1d2d43b5e8a326fdf4f5eafc3602baec3996ac8afc2acfe295edfd7fb9d8d0b3bdfa4057b7253f839beacaf029e25c1b7e840219fcac953bfd7f23256463f5b1b00df836cebe1f367e9de5e13fb8e4615c2e3b45b5ccca40dc0fd2a4b6bc8838016306977d36eb2077a041ef06f1bc426589ff8f1f6fe5956dfb7d7fab0114cd9961fd7f77aed2687c436a1cb9bba99445ce1657c598307deb8d54f4fd7e6d25e346cd4cd594234eac63295d2cfb41a1ebc9e2bc7cfd665050f9e7884eb533abbd1a5e94ecccf743116b10bfd5db5bf1df7d2bef6303472b9431b185aed707ae4ce94e2ff8d703ab9de38a68c7e41dbe3136dc10f963ed2da58c49ec2397e4a7f77bcec1863a07f8e3e83461e0ee554f24dda686d534244833dc20fe41af258c458a08f32cb9090bbf91f2d8c043c053fca0a645c77fd9c277a586fe775a1f771ffc1c98b5ee00ea88da5cd8d2c9bf572f68eb77f911fbe5cbb932d7b1aff8fc9a727323e0772e75cae7027874f077bc2adebd7bb030dc6d7e1c8d56351fcd8c6c8c89d3dbc77a28b9d65ec5f6d4c6f6c53887c4eabe1c19b409683f7264f0bf8bb3e27446e1b44ea652c62abe8c6c5945404361e0ee543ee626cf5041ec84bf0596f337dd116f0d6ce320ec7fb672b864cfb03811ff175f38cb87e17e8d0071af98c6eee68ff74c0d8339bf9733e80fd5fd65598d55fdbdc9fd1019001279abb96138ff79ef81da7edb42736c966bfbbd3cdb77af1a22f9300ffdaa6f94abf9ed21e7c48630fcfa1bc084c09b10d543ef934817e4905bbe6f30bed76296f709d19a272313fefece9d3f60bffda15f896b18b4b47313bec6cecfcac597364be36d8c632fcd4dbecfb832008c06755d7167ea4ba71cf6d9ec170f22b600a2358df9b425c8093930f033f24b1be9ff77e773a50563b6da5cf52e32a95f39eb6fbc3017c14f0dd1dcf3fd2f715dd9c64a988f57c77f121bbb4f2e38d1f04ef5df70decf2d3478e570c595ed3ca8a63373e9762d6337e9c9ded56e2818f397838f775bff0e311b7f4bcdf9dd30c66c90d4f007e734cfb81a656dcd51c2f34d6f31bf1284f9ecb80d3dc6e78fba403ec8c2ddd9914d999f63d7df0d7f2d47774c3639b277d5ccbe4677c76af2b1c83406cc36ffbb5ae4f36ca17fae2e67d301fc7b0892f754447eb5fc334397cc50b0f78ff153e7b849de83fea42f41fdb26e0210c50af9f533b89fe63e1c455ba6c4a8aedd33619f429a780fe755234e1a154500e9d7841ccd21ac81d31878706fc04be7fbf2cbcc6f59dcc4b02ec5a4eeac0afbb3db0e08b7513f13e6d41bfc811fd7cc0b8fec0cbdf949537f2e5673694887d6d833db32b6eee5fbf03e4d6ad3dfb692caf7f76ed7b4716564736a635bdcf7af2cdee622becc6c1209d228149a7773ae2218e70be8fc18f8b76be67177b3aeb86eb58d42a2cfe355b5cd5d6fb7a7b0b34386d6de1c869630b4387a3e178880ed13fb1bfd56d347cb6bd35c4f0f170885cbe523d3c6d6fa16fe3d1e80f6c6f01f03fd9dc423ed9db7a234fbb504392c047230227ffffb2b775bfadf59dcd117055c745fe934dafbf16ca7effecbf5e7e7bf9eff3065a473bb7fb6715b8fa5f7e5006b91fe45efbfbff0ae33a6adcdfbc221b84c53fc2b806ffb8719ab6831d71bdddf65f2f5e1a0779fd5b58bcfc78f18afc3d0ebbdfefa0415bd541d65ff728e8aeca240cfceee736288b2aae8b6d1c547777daeeba2ab675e057413fca89236fafe0bbff7db5f5f75f009c3a38d42f3f5e82edb6d856008a0c5cfe6c7a5f3e1f6441f65e7dd60afcf3791fddd34155175b270c404fc5b6bd6d9c39dbc485f206e068fbe543f0ff380f413f77ede2da8b82348dc0a080a880dcf8f112166512fe16e783d6c9d2df7618902905fcdf202e9a3a4e5f7ebc24e3eab7b81838659c395e14e7c1b605c3801b836d5015cdd60b5ebe129903d011c04f1ed483660bfa2caa976e4b7100a802ee2d82550e8343097e34391483dd42837fea6d9c87e09daa85940c1ffff7691ff7bf5edce61dc2edb6755041bacbca6d505503f71897d8f58d77401ad737c2635c5e5f1fd3d8ed28b776c06407695cd5fd8d8e76bc6d5bd6c5f9c7c0e986ec2ebcb88ce022f5d7fef543bf722e1781777be9630481920f3706715e07dbdc490781bf77b67e75df2c4de3b28ebdcb9d2873aeaeceaf6f9ddcef97f4fe51d5b8751a5c1e643e71b900ef5d5d79c3ab8beb09549183de5c61c4dbcd35816257d77743d6e9159e0e0442de5e0dca243e00becdbdc28ff3f0eae7c0a972f4fada75aae06d787327ce1dc856e73b61e15e5f46c175e7834d0525f3f9ba84ecf4b9cc586d8bbac8174e9c02f6eac176e3da6bb6bba0fa4edbad13e76551a4df681b38876fb43aaf2d60897ed97ff64ee1b9df695506791996df6f0918649004ed7eebfcd25bdbacd8fe42fbc0f3a35f699e864ee67c0b2da7374eebffdd17ce6be0a461b18deb28fb232f079ef7875ebb70ca77df2d1d2f09be43daa7172a2cb96d1d64f1b674aad81b84855f0dce42b4fab21990b0df683170b65ba7edc5f1e76deb6d70cf73cf5af442210aee89f2aef149793d51dfde7bf8e98341e539797eafaeaf1bd44512e45f3c6ecbfb69fc01d3240ad232d80ebc680b0cca6fb62e8bb47d8fd3f4cf193ee75645f58d468f22ea174da8ced4fc49a38b320c7671d5d9dfdf6adf992d5f352dd326731ff8edd36603cff1a2e0db8d8bf45e167ede189854d0b9fc6efb629b39f5f71078ff921fbfbfffe22b615cc7615e6c7f15bed83f8099fdea5bb91f1c7ef19dc2ddfc819180f4fc23af25751ae7df7eab703781f72927dfb72e81f4f68a140257feb1b7069e533a6e9cc675fb073ba8623f703b2bf25baf6f83dda394ffbc39709e3e13b48fadebad935765e757fcda0b83ceb3fdf5f77e852a2e6f85f11f182aaaeb6f2ff3e5adb398f38a2cfba9507cd241156c777f60090655157dcf33fea6ff7c8931fcf20b03bfa87f8ef2af1cf587c6d074b8381f3f6ffa0d69da353c3be73f6f9a05db240dea6dfc331cde37ff3e321fdefc8ed07df2524f84ef5b27fb6560f3c27f2440b7797f77d26210058fda262c3a31e536efdd8fdb0671e63bdbb8004384778f366e900710983e263088ef5a24c12ecedd669b0480c2fff94cb3fe5254e711fefb1667e4654e597d2744f4ad305290b981ff07034ecfdb55b55fdcc3f74968ead2a20ab6610c9e02fe804c9239b51795309c79d3f2e0e4c716e0fc1f4ed88bea2275f2f0b7621b0e0e8393b79d16fbf7b8133d4f1e7b4e55139f3d8b1c2f7230e4b3c7c0e13f0568be6e7045ef7190fa9fb4bf44859e3d7d0ce03c6b05cc7914473e9b52f52922aa2a1a7c8547f0fc12678037ff59ba89fffe45fb242ff67954f40edf7523c0539720dbc3a3cb5ce146c39316e5b638b4f70faab61a0487c073dc8777c0a38b819f57ce7b10054e2f46ee1b36398c3f9d03a671fefedb0eb9beb377b6799c87d5dded4b64357220a6c13f03c74f832d7eba3bf0b65e7751c3faa738eb541efcf76cfc77576788e165af06ba479bff87bdbfed6e14e716fce1ef725ecf9a0601559517f3c20e98e0cade1c1c812ccd9a752f1baa0d02253995078c3efdbd24c749aaca71d27dd5e53eff1956afea380e602ca4fda4dfdefbf69b59d73f847e56dd0f6f95b70faf7ffd53dd3f85589fdfbafe767fff7d6543bacfefdddcd9d8c7ebb76e6fac7ff82abaf8e329dfbffdd97d2befbbe6fe87b7ef9aeb4df7edcfaed9d43f7ceadd7057aebace3eaa6fd78f87fef4f4049edfbfff7677dfddfcf0ed7e7a88fb50b6753fff4e48fb8dc3cc555ea241478fbafb76ffee318fabaea9564fbb411f3cf259687c20ecbe1b24b50bb29b1f7fac9bcdcb4b7b83f6f553a457ed62efe6c71feaa1bb6f6e57768ad837feebe1e6fe5b75fbbdb9be5fadadc8b9b62123b3009f8ccffd4bfbbffd5c7a7e73ffb09ede33cb7daf7e7fda1fb8d9addcddab873bfb489fb60a7edd3ab0b3ed874d04fbe28fbbe1fade064c5f36159e5efd51eef6969e7e7b09d6dddf281b4effe52f4f43f8cbfb77c3dd0f7b15e58d9dc1bfec5a981f2f977f9ad7fbdd8cfff11f0fd74db973db9f5efdf170ffa7fbe9c7dfbfd85fcd34ff8ffff11f8fdfaeab9bef7fbca3a83e70d42b1571ec68fbc348958f1eb78fcd1f3bf8b5ca3c725cbdd32b478ef8551b1e39f89d6f6ca662757d67fea96f77773b71fcd681cf937df36017d3bbc7ed35d5b103c91fb5f19e8f1cd554d7ab37fe6c34d64ed41ffaabb559efbe950fdfbffdb16eaae6fbc39ba3650fb5feda9f37dfd5b183f673d45cf023c75d9bebfd9f9fd22ffff7d38ef1ffcf08f7a7fddb1f9231fff70f02cf08c6dbfbef7b81614e32a6edff19d3357f5fbae6ddf7f2255573970bfb6f8167fe50f6211ced80628e7846688213223481f3f9ccfbec7dfe8d084df02f203481e77a5f9c4feee711a119119a11a119119a11a119119a11a119119a11a119119a11a119119a11a119119a11a119119a11a119119a11a119119a11a119119a11a119119a11a119119a11a119119a11a119119a11a119119a11a1391142b3a35b4ec6d1fc21578fabe3308d3d620fd310ef9430cd99f988b31798c6fb57611a73fb7f1fa6f9f4c5fbe27dfee28c30cd08d38c30cd08d38c30cd08d38c30cd08d38c30cd08d38c30cd08d38c30cd08d38c30cd08d38c30cd08d38c30cd08d38c30cd08d38c30cd08d38c30cd08d38c30cd08d38c30cd08d38c30cd08d38c30cd29619a1de2725aa2e68f3d2370779cad79396c0fd87cf24f08d87cfafce9cb17cf397b066cc8bf0ad898dbffdb80cd27e793f7e5b343c6864f2360330236236033023623603302362360330236236033023623603302362360330236236033023623603302362360330236236033023623603302362360330236236033023623603302362360330236a7076c5e112fff146af3c76ccf0dbc5fd4e6c743f7f08dfbe599bef189f32f60377faebabb77b91bd779e66edc3d77e379ee972f7f83bbb177fe0678f3e50df0e60591393b0b5ceff3d999f77f0b78f3477553defd4cdfbc4cbca7bf1ee36b5ea098dd2c7e62629e1eec8f50cc6bca6577f4b354dafdba831176af7f906a2f6ffd74c628a5fecd52ea2761f12cb3fea38c67724566d7e26aaa2a16c82aee1ed7d7f0f97c737bbb5e4e1fcbeb6cb3625f1eca655197eade2d87c01cb7fd7615c4e667dadf7c2d2f8a661d773289f18e2f51279170d70a9d153b7b482eeebe9e37934d723e9d2cae8b8732bbd924e793cdf339d1995b5d4cddeafcd5e737f57c7d6ddfbbddfd6c37dffadd79f6dfc5bcab2e8a61dd4c1fc4b2dc50af70ca8bc2f91a770fe6e7a5aaba2a72bbd2c35a90fce6eb55fbf9e91ecece37b767e79bfff5bffee394923ab9be7db8ff80987e75dc733b3ff7d32965b4fbfb64b4bdf351468f327a94d17f5d4c7c4840f7159bdfad186c38d9d6a5079b2b16f4d5327b1696e5c5fcb65233475c4d697531bf5dab72b366852ecdf5e8b3607ebeced3f9375fafa69fffcc6ebeee84edd4e56a7bcb87e99350ae7fbdd6d5cf027a71b35ac2c3cbdf276749fc2c905f09e39f94c10c9d52750f62985e8be502c512356755f7f56d0570bf3f267dfafb81fb266bd2b5c905fea014726f31ac5870fdeabe6e8db27afe8cf3a9b38a3b7da99effbef9cfab439ff70f2894f4e1fe631ae5f5812f2ae5ec942a85fc4e957236aa9451a58c2ae56f098abfa753f6c6f5b36cbc980eaba5a8ab38df1c90a19f7f91e9cf06fee636b9b8ff55e63fff7dd42ba7d72bfb4d9e7712b75e0e7b56229f4e98b8f5f993ef9c11e7f3ef4bdcf2def64d3e90b8e507de99e37dfabf46918c895b63e2d698b835266e8d895b63e2d61f63e2d698b835266e8d895b63e2d698b835266e8d895b63e2d698b835266e8d895b63e2d698b835266e8d895b63e2d698b835266e8d895b63e2d698b835266e8d895b63e2d698b8f5ff0d36ea8562395dced6f367feb1babded9ad2eabeff79fbfde6f6dbf7fbe63deee68d735eda93072721399ff89b2fbf8fe4b4773e929c23c9394aabbf2d395e78ce6498866b12a815abdc52cd768957b1b85dc7f9d764987e17cb76f39f5753c2d9d615d9edb662b361e515fa5209777d3d0b2e55e197f1d95085ee0b0fba7975dcf5b4e6e4be16247fa82eba5e50f74eb0aae65e7bbf52b3e1fc7ae6f2e5fc7bb5848792b8f53ade0edf587ebf8a8b7a7db1b8b9bc9e3faebdecbe8c67ce2a741ef7efbf7b9edade56aa78104bd497cb695dc59bb375dc11c182aef4e0ebaba434bd66b3bbf5c53c1057ee8d60b3bb2ade3c94aaa845dcfd70feebf7fead7ca5d1e5c7a5bb3de22519f78440e517ffb3eb78ce4b46aef7af0295e6f6ff3e50f9c5f3cebc4f2ef9bf459e8f40e508548e40e508548e40e50854fe3102952350390295235039029523503902952350390295235039029523503902952350390295235039029523503902952350390295235039029523503902952350f9df1e51b2ecca49304af3497fbc5fe9f2871297c43b214c73e6798ee3079f7f1f4c636eff6fc3349f89e79d7d76bc11a619619a11a619619a11a619619a11a619619a11a619619a11a619619a11a619619a11a619619a11a619619a11a619619a11a619619a11a619619a11a619619a11a619619a11a619619a11a619619a11a639294cf3c78f3d1a4f42d4bc348a3cced6bc1cb6076c3e3927046c5c87b8ce972fbef7fbfaff99fbfffb84cd27cf771c3f7047c266246c46c266246c46c266246c46c266246c46c266246c46c266246c46c266246c46c266246c46c266246c46c266246c46c266246c46c266246c46c266246c46c266246c46c266246c46c266246c46c2e6e484cd2be4e59f626dfe983dbd32f3e27fbe5fd9e6d7c3f714ce99739afe7f7b00c7ff7d0d00edad8f0d00c70680a3b8fadb52e3a5016019cfe48accaec5d5f4a581df357c3edfdcdeae97d3c7f23adbacd89787570df31cb144e752ddba6bd53997ddbe111fe6e6fdb4ffe93c55e82a9ee9d22b06c1b287dcfc1e3dfffef95c75f7b681e0f9f4b154e5c32a9edd736fde955ef69091b341e46e5dc578239673fdfada6b6f7efd7c0fead62de3ce11cbe4812fa7b797ed4c97a4189ebfcbcf9f715d3cac9699f9d9af968bae6c82ba8cdb87222e7415de7d7d75bcb97767c5e0e9f3ea7acd70b0dfbf7db9af4b556c2b36bb2be22f9ffffab9c1631505ee3ade32db6491de7d3d6fa78b7d03457b4f93dbbe62f33b732d4eb675e9c166715d3c706f71bb26811df7e4e2eeeb7933d924e7d3c9ee9c9b4d723ed954eaec569c4fed337b39c7bff97a35fdbc3b7ef78f7a85535e144e129fb9d5c5d4adce2767c979fd2096e5e6c7f3da07f1eaf7b52abc24ea1eccb95fcfe78960dbbbf510355fafda1fae9f2d518be5dc36982c87a02e3deccaebc5ccccabf505dc246dddade3ed637295dcbddc43702d960b144bd49c55ddd7f3f636ed77dfebcfece6abbd7634b5dfffe9bb3f8fd3e1ef1dccd7d78b4e78f3dace8d66736bc66d7f8fc9f9f4ca1c6feeb55ace3b711e5caf96a233c75d2a7c34e7aeaf17f9b7e5b4fb7a3eafcb8be9dd8ae1d3b5cefeab24670f49d3bebadeeb7f41b3268be0ebf9fcf3f27c7ebfff4ecbf3e45332eb9babb8b85bc7676572ed345fb39b03e74f3697aaee3833f375d37092dfaf58d65c9e4f1a0c930f9f537ad38e7ba22bafd13c3f7b3e5cf9fd91fbeed71e3a5fcf93c723c738abb878f87ade3e94dea2ae2e0a9d91b3565c6d060827b7afe7c1ab7f0f5c9db5dfae36cd9a15bab432c83cfbe7b5f432279a1f9ffb9fd9cdbfb7f9e6cf0214ed95f66234a11f30bd0e9ff2dcb2f3cc39a9f915fc3ef3cbdefa687e8de6d7687efd4bd2e3379a606d6054101179776f54cab319d34e53be5cdc56aa98afd9ec5a140b63567d2d2f8a661d773289f18e2f5127d1fe7ce1ae155a157d55641bb1ac1dc182b61ca6f1f37d75f61a9b6ffd93fa3dfff29844852f18ba559c6faab8ee920bacd7ccbc2e7475011b7e6dcc8aee21899f3ee76a7abf268bee72737bf6efe8a3ac56d7cd9fc6d41d56aa3b2ea57f3cf4593a7ff24e229d8333ffb3ffe5ec3736c7b7773e0ae751388fc2f92d79f02277f97571bb8e175d790d9f8c892ae242f165715785371b236bbf5d05b7ebe1ac597b68cc7bc5d94c5fb25bb2be729b8a7577222e86f49af79772f380c6dd8a6fc99afedd739f64e3b1f397cf3defefd76ae618d7e492cddd15dbb662997caae4e4213df79ddf2953bf3fbcd78ade1eb1979cc1df6b457fe67cfef4f98bfb9793fbce822f679f02f22c3ffd7f35b92ff8577ad17f711cdff13eb9fe47c4e7d357fe88f87c39744cee1b93fbc6e4be31b96f4cee1b93fbc6e4be31b96f4cee1b93fbc6e4be31b96f4cee1b93fbc6e4be31b96f4cee1b93fbc6e4be31b96f4cee1b93fbc6e4be31b96f4cee1b93fbc6e4be31b96f4cee1b93fbc6e4be31b9efff7522c8b22aff8ee43d73e13fcaeee6a1faf6f8edfafe9da2d8af0fdc93335f3e9d929c713f9f059fcf3e7df97d8de7bf7cfa57c819efb3ef7cfafcf9cb48ce8ce4cc48ce8ce4cc48ce8ce4cc48ce8ce4cc48ce8ce4cc48ce8ce4cc48ce8ce4cc48ce8ce4cc48ce8ce4cc48ce8ce4cc48ce8ce4cc48ce8ce4cc48ce8ce4cc48ce8ce4cc48ce8ce4cc48ce8ce4cc48cefc1bc9991f00975350347f9cafbe6f6efe677753b6c7819a57c7ed791aff8be7faa7a9b1b883693e3bbfaf8cd7d3cdbfc1d398d76325afb192d7ffbbd2e7b56078a9e7950cd37c15773a89c5ed3ace37ab256cf8b270d6c4adabb8939c6defbe5d4d2782140f6239afabb86893781e2411d6a5aa1e2f373732893a27b1d7081eabf3e9ad2df9ab169d389faab5976cd66cf650b1d95d1217ed6ab9b85dabf2e1fcfab99ceee63faf26fa7c73bb66deb4e6e4be16a4a896d9ed03676e9784ce26513359c59d7fc9f051c4854c36b7442ce77ac5ce1eecdfe5e40106bf4f36b77aed150327b9b96653aae27ab544a7bc6ebfaf2e164e79019f2e87b3ebd5727153b1e48193b3fb4b6fee965e76bf8e670f623893a59a3962090f2bf6e57ec582562c37cdb9c21bc1f07be915f7bbcf2b7d11463e686c406f741a2f1a41db00e28582986f85dc785ccd14caace78413a019117413a4614450cd94a0590f74a353966db99cf4c07217f5a439578bae8c8b0711170f9c745d394cce92d9ddd7e47cdeac960bb58e67d7e590dc9d3793865f77e63e3770eebb97923797939b4da2845b5d148358c23d276783b8da1d2bae0ba75acebb7270f58a05df93a637d7bc5b937277def5f476ddb87da9cefe4b30749270f280e7fe909eefceafe2b3ef2bf6e5e9d8c5e38a748f97cbc259b1beb99cdc561f7d766b1574dccb9a9f9e7d038ddf5fca49737e8d8fd5722ec5d5e42c399f0f8255b7a5b718be5ddddf54178bbed4378f97a4baade2dae54d20d7c4792caf0b5d9dbb779c05d7970407be5c74e510dcae07f7d6ccc16fe7c9574eea8e937b5d3167f779b4f4d2103c4ea33e0db9163272b98a7c11622d28765c47835033097412a4f65f3ea4ac68414efa34c41a64a5442c3a9099077ab315e1b4e543f255c4452fcc9c61815cb1429befcffa9b5fe7ef6efc6bee2d6ebf9dbb43f534ce9ca1b35a6eee6d1976d5c9fdf3dbbf5f99b573014fcf7ad195aa23a238bb5f7bf3eee99a9d99db6299fc321fecb94f9f63d7c2d3eb757c76fd74aef33496edfa1aeecb8bf963153f3ff3a15aa273c9160fe5e00e62898feb0bd1954d7277de395fcfbbfbf5733dd6c2adce55606b999ab1dedffbd3677ead543194a47b5c37e61927c3a54c1ee03cf95a9233b754b89b33d7f34e904e5717f3e02ba99dea62aad3e6cba3209db3ba281a5b56fceaece99eb6f55a958fdc96272ff4a5ea1e2f5967d6909f6c6ee52a2ee4ca43776de754e2204d8694765d1a963ed0aa163427a821003aed90a20499690c370e27914ee379077a3398f59d8651c025ef81461e68a1b8e6411acecd759c6473db8ae5d4cabcb5c25bb32efff36aba7efdec38396b05db3fbb5fd7c40fef2fe7ce4f73448be59cac18763fbdefac2ee61d678b7e4dceee7efa9b5bc5ddddb3bc50332d28b76b1b2898317f7abf7384dad6c2dbdfdb7c587b8bbb15ddcfa17960c6d5ca842b9f3c7d865c132313f2a763f0b1bce8eec412f5d3df5bb19cdf56aaf873cd5ec921d639abb818f67375adcc7ae81e847b36ecefd3dc4b15e7fb6354b55cb8a52af425c31bce82076165ce87649dfdfefbeb7c8bebba249ba77337fbeb5bb9f2fa355fcef5fe5a3bf95fdff3e5e4e9bcce5993e8e9b5997795cb59d55d2e17afc66f5b7fbbeefeb425dde34efe226b957bbbde8fdbf5b433737e7d9ddd1b99b1265637be2193a30738f7bda7eb0d9c05edfeb560959173f69e8dec10f1fefad8956ad12dc9adb665eb5fbfe715c3daea19332fb3fddf6ef895b37dbaae5ec7b3662f1b56569e4f1ea0f107fc0beb7ecd66b25467faa0cebef2f5c974b64acc9af639c97b88930165550b594b4e8a86ab8c6058b5824e5b94b30e42ee619c1041f916e8c6e5c4e88a3c0025541a6e3cd4f346b08c20cd8fe9ec6dc5ce9cfd5c2abdeec18ce532bbf9cadcfb9e33fc6e5b1914ced7b59add3fe9bc679db0f60ac7c8f15f74e5b93f5ccaf274ba52cd5a906dc019f740732765f95628f0538a1d68d09ca04a43a140971eea7c2b58122033e354ba229c0448230d34f7300622ac6ccd87e3ba72276faa8bf9cb5a504607ecd7e0f6513cc90a3357ccb37e3dafffca1857bfeaa3eda58c1ee0ea64fa688b212a4e6048693498f9076cd1819a4b21cd4fee819cb6a02202310c69c85d50b306c3c84b29f791455bc1f22dd2ae83583440160dc8c4fb883e7a5e97efeb13b9f6a6c13a2ef4b38c7e91b17215cf1ed6aab8fb455e3fdb87f6d9dc1b3fa252cfb68fb326f7b7ebe1e37264671315c3af72c4ca45e774b67fe66238f104151dca72e0241a302c7d8ce735a79c200157843008c6b710769293459bc6992be8b44156345c769d90758db252182f1497659fc647e5c8fed918fdd0f1e1275bf1fa67db01bbf25adc7292fff4be791e5bfd57f4ea6b9bf1959d78ffec0b185d36b8ae78b64903775d9cc9f2a2d00774885e13fc2e96d9f017d6e88bdd73f8b993d33df7498f347140172dd2cd96cba21174a391655b60dc112cd15c6167d626d7752da4f127369e88172a8d67d2f88742d61dcaaa43daba69b819b84a8e3df737d6d2115fed836bc9ca5763770d87e4dfe494f2cf419de894610d7ae3a5b4abb92c1dc172c2695da774d102c32e0d730fc2c8e1725e736df448e258d9181bdfad74cdba139207c0722fa533f92fc8bf377cb1679bf52d7bfc952f8d8f9cdc7755987cdc375e2e6e4a55d4e262fab826fd219daf2f259c4ce78b30e953c67b8cb31ec2c447ba6852365322040f43e841cf8d0fdc40c809d0dc4f77fac8e58a1b9daf516e068cb36dca6612144a88736d7cbcb775fe415ff6888c7acfc6fe450e19bbfefb8a05d74bb27dac9ee31af520d8ac2de3b3c7f55f5a3fdb03f6acf1634f1983326b67137059b5a88100438534ef81442e848b8eab7ccb75d4a7e184a4616bd6c756d096088675ca8c0f9bf782261ac2c99633ac5147ae382e8f8eeba10fc52c0ee8968f8ef9d375fef1d891ca03089341c48544ca09e8790b2cf3525a0682e6c64ede62cc7ba4adc769e273bad1104701d7338944745cd70d481890144d6a8e5589cbaffe8db1a35ffdfb43fefc9b71234eea7aad826e6f07bc114b3cacab5edbea71f770b99c0e6b72db712fdb189bed5226fecf76c207ed024fb003bed160e464723a3949b9032c73388d3c50b927d4ac867043c0e827160d100b85361e5cd45c4e6b2e2b09b20c849cf45ccf5b0c731f49e2a1ce7cd0998724f1b1f9db73e1752c63ffde3d6738ac3df839bef458d9168e1fb2257f3deeadb5fe6257fcf4fe4f72b6f949961e8b5bed8f2345f3f4bdaf05f3f7f7e9f1a3f1f0c331d28371a78ff8340c1f4b951fb593c5757dc39778f34edce7686ce737c6735ed922368e6bee61b38b2124e425b61304af7c33b7547f21aebfac3adeec748220c5c3a1380f9e522fda788550a8cb3ea5a041630771ee712d9450b98bb1b1dbc14dc3799bd289cf69d4639c3b186e3c90d8090644849916e1c4e772e201cdf43b7ad13c4779c9dc9a7bf347785a2be5b278ac5e9e5bb0fe50cc6c717730e6736574dc09e59a4c08c8c916e5c4e17ae3711b139b3522c436a5b5b2fe6cd8d5692c2457890fb4e8d2183b111bb9271427d8089638c61e4ca9b1ed0b25ae9277be7bfdb85b5f33bd62f8fde03c1afc6d7ababd82ada0e071225a64b98732f7385bd418160a753688507429ed24a7b997861b370d8d7f0f2ec8aee5baf4859a29a0b38e939c88183c08138254a863bec99a1546df7ec83f2ebdee810fae53aad9ed8138567f29a307a427b48be22448e3dcc778de70b9905c612bc2d61371b44de9b4e1742a91d635b07903f1a203055ba1160a65d502cd0341a30054d1a2e684b342725a0e704c175e1b5b029efcb82f7bffec6fc55cab8b4570303eddf85b3cd97c9bb72933bef0bc03baf1504f5ba091037226459c6cb96c030c2b33ff5a11a2025d7529853ea573c915d7a84b0234f341d635e8281061a104cbfd63f36d1517c39a75ce259b35abab7d9ca76bf63ab5229d6d0d6de3fe831f7c682c978b474ec4f51bf19aede9f400b65c4e34b0458bbaee406e3cd0b3360dab16a9905cd74aa842611cf94202b1713c053a8d45076ad1a19ef468643fe50312ee739a118ca3e61d9d68ec91037b9c66fc4e368f1abb274db3c0ea3d3995428136fe06d7b903611970397180629b86930048a130c416e8a2b67a50671e841b2d64a538cd3c4ebb0e65bbfdfb7b9caf63f71fdedf6cf8123b94d64fd85ab6e3e9fd6f56164dfa4b993fe0de2e25e2fa9275eac98eea8fee41beb2f35ed9847f637f6e5eaf55f6cbde83f165c472de8a62dfdafa87f7dc526d9feccfa2fdc07ab2e37069e6f7c17da0cdc9e43ba7990b72a680e4c636d2408d4ee39e91595c460ec4f38e4b2022161d869b1e58d2a76c2651571de8a944190518ce544aab56183b4b263e6fdeb109f67bd68764334d4eb8a6128d61b61572aa90243dc8d24fe33cc0b0ee30ac1486b9c749d403e35b11561daa2c000524a5d8701d695030804a7a237b40470e30e881185be0fd678ff2002fb35f13278b35b53dc60b25ccf3a45305045bcee635c85a19bb1a69a5448cad88130f19775256b428238d2127a8458dba96180b2568eea661e9a5e164102a7b4796ce6fab58dc71561d88b54556379f5097a8ddbe9ce8d2183c6473093473399d2ba4a5b10bdb94e65b21375bd0999f865d83611920cb8c3c25a82217e3c8e57ae3a0ca484a23925278effbdfad097ebf64735728eb831fb0f1da93b23340f301684484ca88a05dcbd9a201d96e39cbb7c617005648d0b987e6f9abccc718869472075416a0de04107387cb450d3adba24e0224f95176e68939bce5835b97d7f3fadbd5077ca8ebf963156f6f2f971894bfeae2fe52c283b12b4fb6bf1166ae888b3aa5c6d68081cb6ccbc9a2435a49ae3b63a30da0452de8a2e56ad6a561ddeefcaa8599432ed8719d37c8321fd5ac160cdba3ba983c7328b75cc107fcf817dee7f0bec3e9fc4e88b1811008d7d871b3def4244843b36e2257c40b6367745c170dc8b9c4d8c86308d2106bd4a5c3593208bbdf906b41bb8ed38d8b94fbe2686cf5e9bb5fb9fadbf22f8f9bbb5e4eeb75fce5501cd23b654c3a65e0a6ccf8a7bc073a97a8232d643ed8f72876821afd94075cc256c48b360d735f848b066934a434d128278390a583d2c63cfa94720deff9ebd79d238c5d151fde93c7f313b23d3272b88e7c330e40b23ea59b00c3dc31feb988458da4905c738d947b9c709d861bc22568d0c6568e064e8bc6c66259661950541101e33b1f7ffebb38faa138c5d529f7a5a71dc6665d705fc889161206413327a5767f48a36edd348c7aa12217e2c883105c11d632b571b0d247bae939cb3c4185443dd142cd6bd09bbff9dd4fede3251e84532968a651f31ec359cb49d6730a0312d14238099080037412202d1d20e0ecf6e6377e1a96034a63c3cd15677c0b74d27395f5187eecb9eff9a4c3b1ba13ae7d3af120140da7512068eb7163abe90d11e6f7187a11161da859238c4d1e4e7c11b68108171262330f66b5b071abdc0365e65025316c1d7174af76bf7ff4f4acdff761e4019fd872067842ff05cddc5730a0f9ee4c280c5b8fd3d241157982ce1497d6076e4438f1314c7aa367392d7bae6b05b23032750b8a0fa8375b94f920c2d2c7e11d19b9f74b0fb38fdb9372cf7ae372b5688141802a193835b668327095799c400f2af75125c48c03577c8b71ee099a1bbf8770bd50481732a54636f02d84599f86c9f08eff22852aef578cffe36b84ab99b5df31049dd272c72cc4730921dfa62cd79c98d7d10071d121dd0cc2d85bdae8476c302e1457dc4b69b445326f412d6a0ca7caac91e3cfbe1ed624787c633f649b9e8eb121a8a7b508b9cf75dba7612d4145014aac3933fabf96c66f4f29f7d31815101e60c85d4e7257d0798b31d6968d57790f61eb733a938296fa681cfb550c717d5ddc9b7babe2e2fa657f3970d7574fb1eb3d1bf0630ce58537bef21df8fbf148b98ecf8cfd4d040b9c7270b588ef0ed9b9ce491902c67d94130f956881643ed72841674ecaf8903294696cf795dd34842dd2899386658f32e9212c3dd0138f6ba3e7e6b5a09d32b21e98a88ff335aff7ea9e62664b0cd60aeeab8b79bd5aeef77de775497282e793fe5246c3a57c66065e7cf11fe3707b5eec290ef734e7f7f137b6ed049939e2caadab8bc52f4cff9ebb5f7be8ec9ed93e063dfbf4ad38d3553c7356ece0fc3818635bab99aa9eae512de7fbfd5bb762dd9e95f7044bee4bafd31f9a3b24d0d5ec4cad0ffaded9c3e9f6a2e62aa5469e1a3b2e7351b63d972885ac8dcfad4061cd95dd3ff004e303285123357f2f3a603c0095f448a31e0827222c5acb0aa9dc7b4f7eaf49606497b32468e6c53fbe6e50260e9a75c1222de866e0b4525c275b24e0a661e273ca494ae72d57360ed91819073158b98761eba24cb642564dbae3757a8ca3fedd7d4972f6b822dd01fe74f200347b38ddfe5062d92e11560dc8c807d9355c570dc6738561e9621c05a8eb1a64b6e5ccee73d7480babab523a6fb8911f322282e60e581e6cd1a4343f1ad72f6363c3170fd5b9fbc24cec6571dc9979d2dbfcad3d6ff13c3f823f77cfeeee037ef4abdca1c376927b3a7f221a44cc03945365e32db26b40597f59832c0320a235be8660898b61e271821d9776df2800d97a18563548ee83d1ad72da99e340f377fc09ec2b263abe978987c7e0747cbb2a5ae353a1ac2497456b7c46117287d3cc1152d4224c08cabae5b2ea50e71a42d8da3d368a1da765c015b6188b06c264e09a3bc66ee2c69f7c9b9fb85bb1b9fc883c2e156823dbca4339a457fe7029a3d3f95d61b4452a94b07cf2a2e652d4467f73265a2ea33e65d8019975484b4fd06c30f304e4c6c170d689b86853da35222c3d218d4fd1ba4092ed710e109518dc5bd13ce9dc0fb093222eee04abea2aceeff972e11c8e21270fa7b345e79da05587a4a8215e349c663dea6c4859e603155d1ae73a8d172da7b31a43ee71927918961a753918df8b13631b15b5a0c6d74f02731c90597354865dcc1ff9f0c4c1e93d073573d7de8b2df1cdf264efc9a99f58b203eb34a5add109a7d3870c259224e0a450c0728d342228a71dd2cc01dd0e18e78e9099e62c199089869bb54df280d34241981b59a751969e888b06e38c7009c3713b121fd776dd2dfee464f69c27f91bc7f85610330efff45ec7bc05b268514e5ba0131fe2c84512f5c8660d8430802e3d08b340d0899bd2c8015ab4a0120d96912f7b901b8d54183f5a73626c11b4acfcefdeeb1071a739990de2601edbe494b6c90074de42cc5dd4b9c389f139799052f084cc5c086792eb69b7cb79e20e861bcd75dd82022de8ac4b6932089607822d1a418d2c5d4824d0bf639fb66b62737fefd7ccd8286fecf59c8ebb5082450eb079c3290c226c496af43f8520a5a58734f140e704c2bc47ba68b89eb64245c63677b8ce095736d7341072de012d1dae725b9fe09d3178e6b60fe843724a7d2868e98b70a1c0c8a478d681c6862b2181e69e60992bc2a246e3ab90b904d90e204b0d21b6bb5c28be35320824f8c2c621175d4a33f7bdf8da0b9351fd595e1fc80d38f77dcb989f2c16bfe945cc7b900bc515b89c810f31f7912c9460bc1761a790267dcaa201e95c818a9c94560a097740b60ec6a8844c1c116e06e3bf71063dcaa3b981fb18db661f537b5fc6160f1573eef912ccf7787823c7f8a4f9463667d2ee3b893aa5b31664d45b269019fb7aae767e2c3896250cc14fe3688b7ada818ddd590ea3e60c02cb74c5f346c83cc0a3b6d4de37f9ad1c61b7be167faee3b36b410eed89edf8d513e6a93a484173657c3f34ffa48d13d1aa3576aaa08b0e74dd7035af85dce8948a86d3cd00b4d55c2f2497b306cd3558e6018d1c0c8bd6fa3247f2832c47b9afa5c0dc7abde3cddfc9db3676952bd764fbf8917a22cff5210eef3d0d27b411a4ad1763f71c171dd0a9b2f95561d5a631b8280be31b7a42ce25da7a40898b34f2399d775c67c6de77adef4893008d8e94a2e62aef8fefed1fe4dc7ef08b7edcc37ee2d954f76949cefc15fb507ebc5a5fbf15b33f61dd01c203c10a99525b974781cc7a945d2b18da5c44a0b98b31d622ac641a6e7a41e72da789c369570b95f9693c939c4e7a30be3b9b35693897efed690b7536ac7f66f4fee93d4e5928ae1397d38d2754e408950d10b60e5742713921294ddc34cc0708c11161db736ae6dcb40566ec8c2840923929cd8908c1459a1b3b649bd2e8d83a36bea299ebcfb993c23c6f1638976c975fb262c1f547e651c5f0a6245d7db9bcbd2dcd3a3be87f9ed2464b06415b0fa5f9afebb89a195f52433cb7390a68d9adbae53223c8722765f980b46b389d197bad1336163221422e6a5b234446aed1d547d7ec2ff977c2e5a4d62b16dd7f53ddc0c9d9c313abf4beecbb2ee4ea026ff995fb69b59ccb35f177b1ecc3f5d04ec85f60cbc9ac4ed9ac33bebacd89b7fcf5c6e5d2acd136e034d3182f1ad4d306ed5ed42430eb0b68d541180dc2321985043ad942cc3d4ecb77e266c25d2b74ec773e1c333b2e4bdfcc797bb54742b68f155b7495b1992ee0be248befcf3964af75fdaf39e03fe569bd67933de792bd618b45a78b81ca698724778044beb1cf39cb07a1228d04b6428adaf2f134d90a3a5348e62aa5b993c689236221c1c8211539a0b8c63072902d6afbbed11b1fa973f0d76b3c75dfe24256cbc5e33e47f1d5df76f5453e94b3baa8cbbd3df83772940fe60e1e5e935b3c61ac0de566e094fb5c2601a71b1fd44241983bc8608be6d96a20188a96b34209bae9b98a1cd45dc3c9a213711e609cb99c96bdb56fe4c603961f95756fb0f5afc6196fd7ea237b02bf3cf7c37a83e6a7b347c2ac0765647ed1a671e45b1f4e4e1c2089e57d410a29284ab44c7c36a0ac153736b54c064e328f6b5173960569080ec4f91675d7be6b8f1c9ee7fff85870356b398b08a76d9f325173dd75a8138d2ab3fbd43b2eba52a839c1903b60ede1dc439678c0220fa99129f31665dd0a36539c255e7ad45f7b570e387c894772d13f3edf56ec00cf796a19ac6692eb2c48d9a2132ad15c8293c6dc1761ad80708232dba2ad3d130540619b863911666eeac8b171a4782777312e24c6f376b7fedfcb5d7a1983275ff8bfc138440ed7590fb2f5d1d80764a190ce25d7939e938c8890076958fa767f93e63d28f050e684533337b36d4ae7754adb0054b2e5043b11675b90476ddf97fcb527dbf7756eef25abeb7f43dce017f9f8df60dc5d24f38eb3ace7a450c69f40b56805ad1586dc150cdb940a9952d069180d964fd7e51649a605ad1a1b330ff300eddc2c7baeb3210d930fcfbf2a9ee9d55becfe09e59c8d33a9792764a7b89ed5182f5a11272e574587742653ba090445c5d5bc06c95d949de42ae90535b652d1809e68ae231fe35c8b38d34016f57bbcc12ff52bff793b420996b85c273a8db301493e70c5039bcf138bd6d6015230a4cc7c47ee587b439bb5870d97dc0159ea34cc065ba34ecd15d0769b527ebc469dad3f8d4afc86da0c2fb5ca7e956f3fbf5f92ee61f5eb67bed62df782b97275911cace370c9b6b755bcafafc05f1ff3434d8b1ff6cb06f7c6c885c3f226e84a6fd189e75a10db9a7f2446b6af41f1464ef3e9e4086860091161e9029b75463e0b196d41273d86934184e0089a6d41678195cd614484ac5b9b3765fcef181ccbe72bf051262e67dc85188ed6c9feb65c746b6fdeee58c3f7f47ed5ad5531ac18dcf3e57ce0cbf660ae1d9eb4be60de03cd08aa42725dd7a0a72db04c735929aedb0164d7004d062ee752d0bab375085816804cf46e6cebd6d62254c980143ba4910ff4a8ffe57c33ebf0bab87f9a83cf73664976f7f6011d762d960b5b93764d9c83637829a313e644d4c603955c2edad4f8a9141ba4932dd2a211312a119ab11235c6a053332f694b52060367b98fb4f58dbd60f3d8e8547282b59085e2e4afeec3fc1487bdaeea92b44636049772f2bd2233bdba72f55acdfa92d48fd5b991230559b1c2838fecfd92c229d5ec41c467f76facf313c67f2ac54916a4b47550820b722191260469eb02ad94a073295814a461168091eb34f36d8c28cc09329ba3aeb89c782236765c558b30f1901e5de76f8cf7ad7e8ea5fd52cbc08cb7e55afb4b99bc3ffe4fe7acafdc5d1d68527cc496bb8137181b3c5d8cd31534f340d64a84d18061bbc578d6822cbad4e860926daddfa0f996d38d9732e34f24bd905c7392b868f78b26be90adcbd9bc4969552305f7a8be3edc8be0a1fa3526f34e5ce06335eb7fa9cb7d8d779c253ff427f8b1ceec0fb5c0cdba91fb18f6ebdf2fd94b1cee7ddd51d725a99b529d7987e3daed09eb68ce5b243325e8a2b6b92bd4acb132307616a7933e0d5b9fdbf8dda2e5b292691c39a99d03a0394d025b8f369eb7a8450d32d7222ca40827ce3becc14e37fce3b167d15aae97890624f751a282380f529a3836e662e438c97d90a52b68d1a1b2f5d65c648b06e542091511aeb96b19e1d8d6a1d1a08eca1e77ad3a5befea72899d206eb7beb675281f3f52e3e9a79a2b07ebf6003d5d5e14e86430f342d0d2b3fb4496c5c97a61fc693d97a0f380d3a9029a7840f856c84a419c79299b2b4eb14963a1b802cfd8294844c309b8c7eb7b7f34bfb67e2cbdc5eef7377ca013ee6f48d4b0e51a3ba01317c285b1cd3a1182cb89e840f1ad88cd7c6b07d40b0924d3c8448de186088a0de8592b6446849c90342e1490dcc7e331f16726f6793f6e766674dede96b8357a6ba7cfe021fd80bdf046ff8d9d6e3a1d27e682acba34868033f030ac3a901b17c384a4b4ab539a6f91461e6751c0290f302c6a21f31e15b66099855983146ba425e13af2b8345a2b3a5e9b66af9bac9d10fda29b56cbc523ffe8f8c5b3e1601ec495ef9c94b59258a761d5a0e5f9c11396d94806a1926dcae65284e0a3e23d28ae8dcf646daf381a90720f8c2d100b69d6fb2eae8f12594ed277f2d95617c53d67c12e2febd09ef829eb91d87d8c8963ab3ed3bcb7392f0434ca8d0bf1ace62c7253366b77b1c2b217e1b44be964c0102510f05083c7e9a2b575da63f31a25c647d9966dc53ab91adcaebc9e7f885359b1c5033f28df4f5ab7c6015ad7104744a8599386c916c3d235ab06e342098a92137090410f147775ed98e820449bf32068dd82061759e67292f848a71d27fc684db1359b3966beee6df08a05b7b62e94b5a317b7fb9cac671dca82c752b9f53aee3e7163ef7d68bf74f77dd76cd61fac3dd0f8c30999bf01c38d832ceab9e2beb197533a7140820f7ae3a42ce941c1962b18807672f77ee981323e65e6722d544a4be315d518273eb05927e451fbe3e718b58df5d8ba271f1cbbd25bd4ebebc375852e657bc27cae680b72d109b6ebc192b2c407daf648735fc47c0059d422e69ea00bc9d9ccf8e0bd084b0774bb4d59ee8a5034c677479a68a08b8eeba23b6e7bfcf51c8a153b23821ddc97df5ecad3b1fe5cce1b20458dcacc97a2035aba18965a183f4fe584d3aab3f585c3690b61ee80cc7ad0c996cb8d636c6008f3ad3947a85c733debc0c881a37b6e1fb5d3ba9e93b307a1ba0335ff76fd824ea717cc5c992b23f36c5e0e2dfb944e020c730f481458b656663e107084e42e2733e32f05699c0f4256b5b52ff4cc78c2ae08372e10518bf0a89df6434f8be47ceeadd8a233cfff957fe9ad585097b18dfd68b3be9e6d3823f73fc0fd3cd9280773504f175798b7224c5c08814068e6d5b41574e3733aad85e2841bdd1b4e5ca039010204694444386d84f127e58680de04606ce678dea46cd1a186013590777cccff2a875d6d9ec37b62f9097d808de66aa1b89a4941b18638f781458ef59765a9b9cc02415b0271d2a3ed8dd4124ea32d84d1c0c9bcc5b06b52967836cf86ce1b9436a7fbd8dcf2f812ef2fd9dcc884a79ad7efadc5fbae5441b70e6178bbfe5572cafa571ed289873271b84c020c371a43e3474d1b4ee76d1ace77eb34c6dad8f85c4501e8cdc0955076af2d9c1a9b2480302710438f94f729ad8fd6bffaa14640e3fb3fadc17b7e5ddcaee3ec0363f96b7fb7c335184f571f8bd3762bc28d8f714250dafc38626bbfc8a246d9d59c4e656a79c5cd1658b4055a180fc04f69e40a5af64845c7f5c4d632353e03d036e0efec47fe9c8b7fd8f7395d0eb8a0f39adb1adfa8b8020754a2514f7a21e70a6419a461e688d8d858f35ac4769fa4b39c2c4b6c6e2fd83decdce57ad101ad8dac77f09d3a944f71e4c3b99327dc8f46bd0984b1e5c3560b69ec794e8412d616e04c48a460f93b111aff78a2d390f7c8a22dd7a0c1cc0b997b3b66d8cc1deb13ea0f7cf7871529da4b66fb27de1fb6b96dcdab13ee91558acbae015bcba91d504e7ca059cfe58670c903d0bcc7380984329e4eee83cc060ca7b5b1d34538eb38c91cd4ad6b64b9cd2fa11bdfdadcc7e5c12327f77f5ad972b8a6cb09bfbf79b6899f8613b3fe5ba37f85ad93d73aa885c4d0cc91c8dfd5892807e3d77116795c9af9306f502d5a54854ce944432c1a2127bb7e1a47ec1c4ece7ac12a972fe71fa95b6b59d8c3f522a253eea56ecd3ce1c63ed6992742dbbb500b3aab5366f4511eec6a8089066370308c1cb07e7219800217c21d63951a9b5af381ebc4b375e17e6b3ed676a8ae5cc919de1ce61ca353ea6b0d2c1f30e65bce32dffa0f24ea85addb9ef79cc116081f80608392fb820a8576af1a06eb636863638b1a19da3cc034ce3597c7fb711d942fefcfaf1f62a2877db313ea24251ac1721f2538b6876858b420739f336c30cc7c617c33366b8008296855431c39284b9dd2a2c538337ec960c74acf148433657416be138f7b15673938674ed827c13372d6f63ed0e063c803112e5ae3ab02ad5a903c102af2058b34d268e0ccc8e272c0b092a0a78d08e7ad30c750ee839e0482653da713ff1dbfe099c339d00feaa4f6089711e12a739018fb1f8694661a59ae21ec24d28d83b253824e6c5f3a50592fc299b1e38860d0a734b73575392d6a41e70d84994ec3caf6123ffeecbbfbb799687ec25e58b62fa9c7496e73bcd1c615b04e6d2ea6919985b151b618469ab33c005934226cbdd4d62d881c41a117568719fb6c567306fe7b75d5d6ac7b582d6fff5c7bf5ad88dfaa4974c2b80c6d07a4912f68eb733df1d230f751cda5ad0963d9d5ba16314afe543f0f29b6a8a200e9669b52d1da1e9234f2208e7a60998f71eef0e33da0daf54b0fed1f6281efc9cc37d86672299313eed72e6aa18ccee02e97ed962b3ef0a73ae9c2d8f5713e00c35ab045cd7544ac6f68fba794b6af1deadc4dc39c6058d7826e7a1b1bd4d9c774f28e43ea9ff9835ff3d3f6bcc2e13cabdd79b76b4f3cf7bf5b916258abe20e74f2fa98d7fb773ff616f09e7b14beeacbf49a5f78bdb7973c7ca4afe79a758f97cba23dac0bf829eb94d54219dba00d044b065499031a0694b6c6a46fec6fcb6a2bd8222b6aa1cc31bc4fe3ac073d7190e6bd088b9ad39942190d824ecc3c399ac7b58fcf1ecc7bfd406ccd8c5df58fc749e61d57990fe1c601996d51720d72de621ce9345ed46958f669888d508b56845873bd9040610b1a1cc13217e9c6b5b1745534c61f303a18c3c5d138c91bf3f6e1c758e673dcd2f69a789a9f1aba2f1a9a7dcdecf7ecdbdd3c3f1c3b01ef74720702b0b99ed9165442d270d2839a75d6de65b92f6cfd2ee8cd5cc5b025287317e2599b86f396332069b82142257e4aa39e6b23bfb9cfd90799c01fe5ce6bd9702036fcee78baeb2bf7767d6dfbad1dac330057be73cabe45a050a26c7d4eb9e632776c7f515b5f3533725b8bd0f85a9de4241f90600b0c3c2ea735c6c6479db710d6751a4e34b0b904b9e9812d8ed674fa990fb735462d7fda391fc9a3fde9f8c36bff84759c5216118c93ad60e072b2a88def802a1f52337e3271d250b4693819b8f5abb827e279cbb5f1c3f2811bdb9b561dca42dadaace124486912bc530fd4ade23d4ff281f9b6efa57b68df9fc2297b50f448b320655ca3ce09ca72cb75e4a6e1c615aae8523ad118660ecad64565bd120532d322e43deaaa49a9adc746902c1450be15b224a892a3b56c8ff6c87a6f9e79d3ba5c16dd255b74fcba38bc3f76d23e2e7c306bced8a55c83cff5ac49c3a912b656fec4b7b564d5a2c6785e63881d841b1f695d0b391990250368d1219d045c728261a7accd16e6c7e366d7d3ba54f7b646cf3a3e7ba3974f74ca9ee34484a587a1b12f2743ca16cae85a4e220272e308263a8c733fa59b60578ba6ee404f7c64c6061532a5e5606b1c12334ed1802432b6cc5179b56281aee2d943f5d24b5faedc3323f7f739223f8cd192ec7359de599b6f9c77b80ed209fb87abc8e3b4f441b63a8d730fc3dc43894a501e405829ae6dad1992d2cc3c8b41c82c102af7044db622ce7bd40b33f7b6c6774a69a7b89cd8be8f7f695fffe0b8bff0e0a52adab557ff696c1f4e6677ebe71c1bb75ec7db179bf26fb0766fd44d3dd0172e3a694d3b8c458bbb9ec53d185f5b463ea78916b165e994307a43b6be50dce132b77b0a9c602b64e9a7b4d45c260e275cef3882a2033defde89d3f42be6df9717f3c7952ae4e11a6dd9039cb00f406af361da81cb42226db740bb16e9ac83185bb0f581172d865d2be23c001a0d6998385c451ed052a3ecac8ee1baf54438f1ecbe03c97a71bc4fe54f3962b616fab056b33bdb83fbdc1f3ee2e3fdd43ffb1fafcfc3b5f1c73bc975d4db3c78068e8d6bda7a3df35ac8aa4619b960eb74159d08a71dcac4b7f58e94d11bb5449ba7b0e951198f6751e3b1357e741c5ffa27bf1303f9693eeeece8d28cf37f83b90964de81e41e185b389c36828a3665d9003a213606a2932dd85aa96d2f68e9224b6ccd144eab1a5862e6aa86703220cdb7c0121754749cf1f97d39cc7f655c77b5294fc840a6310448275bd0896bfc68a4931e694eb89c7542651ed87cc3449b7105d92950890734dfa67116a0ee14273040587740458361e2803cdec7f7b7d5433d9c5ffa567edd0999c7c44592109b5bc4a23e0de70af5660bb4ec411bdfd9ea8b210d233367bd94cd5b617389cc98470e9045c34936d87af4b2f5208e3cd4efd4fbf9f858d8dcdb93d93a31f482ce14c83cb0f999b4f4b886dec67b59b6b5f59042d189d8f6257251d60dc8dc435bebb0b4f5a440cfa5b0f5422ccbdde33b4cc64e1714ce8a6ddfaa177e429fa26ed2b0ec8d3c376bc6d811a04493d25d5d6ca0b0c5906f41d70ac2a28570de8930da725d7548c0c598fb699810ce664667c894f16d1abed31bf27ada578d7bb75a2eba343c50abcece81e8943de725ea85445bbb5334a0b201187740160a753e80e4c6c61d806e7cb06c6165f3666cbd60593a5c6f06413317a8e5e67a4e331fdfab7ff5a3ecbe5f99b9723096913f003d1dd32be2b982181cdb5f87650150f090cd3a64a039c97c5ba75a2783d87dff8613ee038b34842d01235b6dbd986c00890a69a7049d76efae871ff3e91fc4121dc1dee29b4f682329f0d37066eb23d8be00143c888158df28ce1d243395d28d0371a1d230dba621785c419086915903dae8254123dfc80c114e25181ffd1d5ee767dd73d84e4c4e177755dcca06ceb867ebb828d8729a07b6ff9a9ab55cb77e1acf1ba4ad8f96bb3063b150c88a0ed9ac463a19c0e899b0e804ddf4a88d8e39da4fe0557e5e7d2b3e625b2f8b5b4eeeeec5723eacbd8363369cd27fe674d64268fb25b746b7723aafb9cc7baef2ada0652028f78066436afc94b09222cebd342e1aa373202c1d5b7bd8f6c45b2894792f62d1c13bfbaae5b2783ca84fed7c399dfce01a5b88930075e68a180611178dcd01b3fb47466ee4bdad492b13b2cb699d100c8d6c15ad50b647719b5a9eab6b8c7c013daff1584ec0011bf81d5bd7d63978a3beef29f35e6b54c916651988300bac6faee6465eca349c68db1f811939523a68632c792fc2ae016dfc77336ed32eb5313c7051252e868b16c2a37927af6b3c6c9e6b3afcbaa7618f5912bce10c6ff8de8f50b307313b7b9dfffd745cfd91de1f3f5ff39fdeaf5318832f98d1d37c40ddc9949646aff5a88c2d9cb8dc56a068f5ae8f0c27665e2299d528bb06e9bc1134773933c7742dd0566338395a5bafbc9892279bd7dff7bdff794c3f38866fc508dd93f64fa1d346c4b90bb225c2e8493a6b20c64ec868e054b410626bb9091d1150d8214906ce2c6fb64539ad856cb5b129d33873205e2854d9f6780db9aaab2ee6f55a2d1ed7bb3a10969579df07b3e7fcb98adfe2bf4fc81a91480335eb9a7b5cb603a79107341a4498079c654e4a6b89cad853452d64468cbf0bdaee71041042802ad3292b6a24914e59465046fa68bed4d3777faeb9f79e1efd35a67a98993e219b8661e281ee3a0c67d2c8490c23479835a4671da74587340b38138dad6b45b1e6baf4b8ccfd94cd25574523682dad0e6689461d3948c4519ef1c77abfefcead4e107bdfbfe6309eb4e753d6233176661280ce03dbdf4af1ada073c56544d0f60f9b3860d6a69e78a0221fc9bc469bbb2d6a08b31e65d1224d5c94a5e60c1c7ca7cede2afe626b39f225de3ed7d4536eb7667853363fd489bf2fbdeea18a67fe47649c6055f7eddcd5df58e070f35d0ff34e27aca5c79d5d2c24f78d5d6b1950657cc385129611c30ea96891a059df2ed0592b18ef8d5d0c7a5623e101377ea48c5c20b9e604fc94bd534bef7ade95e4ecae6a5cb926c1c1feb378d27dc7dcf6a406dd3a224cfa3434f23dead1c60b22874bcb092b908b0e74446c3f3b3d9522346391f4a08dcd3b97208d3d67e4dfbc86f02887fd4b4fc99f6dfc0fac4db7f41672e93dcf9fb71896d3c58729f8826207f14c7229646a6b9ee43e9751c06d3e50e273366f51a28470426c8d59b971c1f84daca881e65b0cb98b217784ca8d4ee88ff61cbbc66ebd14dd47f2ddcbebce7da356fe096b57975b11426ffc66635309cb94cc1a61eb950885c4d661f440465bb47b8bb9cdc306223aa4b3ddf89059c369a291cddb34e63eaaf7f6b751aebd6927bca22ed5c17d99d3b2e8d6ee4f7aae456b640dc4459752e3177022e8bc4d6dcfd8492f8c6f44ab3a8d331749b6e57ad60231fa72a3d370aab84c7aae6635ea5abec7e496a4b8377afe604fb493c6228d8d5d34a9ed890adb34e4c4c6f4154a0cab0e29b8c2f6cd3472a7f439c31664ee8838f280197fb990a0383176bc08bb1ac389f38e4fa40573895826f7bbda20c547fcc75fcff9c7e5f3aea78e88b9ad19c849d4a761ee423cef84141275a277fd67731bdb4ea9ad33ec005b28a409495942d2181b110a2564ad90963da7efe453edfbf9bed15f034e19c367e0219db89ccd3b6ed963f0309e7518965e1a6781085b6deba9d1a24696f5181abb3a19208e7c64e00896f7209301b4f1a75b6367f770d4aedef70778ea29f811db9a1483888b3f455c0caba5f86f316e29e59ad3aaddc52c5b97b3a2e6baaab9b6fb938e90e0706aed42027433a431f72c6fa30b635bb718ce3aa0936d1a762de84d8fc697fb8bb19abfb95ff963ffe8c363494e5817c94b69d7a5662c75a784ed9f266a64e07359dbfece827652d07927a8f93b762027aeed3344a200484e206ccd3cdda64cb429dd0c4296c15126695ff7a879d2ddaffb6aff85f9582de7774f7dd8ba037d08fb4b599e9271e9442c6aa495b19b7d1176126c2dfe696dfc3c41cb0164b68570aa508103247380f000e8440b3a2122ce7c2eb33ea5459db264e032b3fdc58ef63c38d433e8294fa08acfea7dacebdb32ffa58ff97b73741547f77030d6d53ee0e972027dae1752a8c8333e34d28db6794c8c7b42cd1a0c853472d3da1d7a5eeff27c44cbe5b4013ab37da751769d195b1127aea0dc11343ada0b93db5cdbbb7b7e5d28a19e735ddea8f9f953ffe4a7def32b56752ffdb0ce7abe9cb9e2ca6d059bbb1fa9b95192ba3e3cf6fc94bceb80b68ee3c6156a51239df840278e90a59b8625313217c2324843ec385bb4a82222e8c61171a6916544d81ec540807117f424002a14a7d3f61d664baf58f5c0597fbf8acf1e5783fb4a7f1c6239b293ae6fa4b30e35187ddc72bda8b99e4a2428b95ad4402227a58b56a8a807b250c0161d28eea0343a261a907002319094a202c99d34cc5c64c9d1fc928fb2be4fb5b90f334427ec410ad4c65fb40867b5f177b84c7c08275ac8ac1771de735948616bf2261ed0a94a59128818b450a08dbd8c3176b6be7d281a2009419a78efcd97359bddad2f6c4ed481f9c14f590755093a55a02b99da9c0e94c82287534e38cb081ab94e51a25eb49ccda4ad8b1b4e2586d976d72b91bb5c8b0e751b403c6f304c08848bf71847bd563355bd252be8097d3febd3cd5b2030a09c3520a14f63e3cb6c7aae13226ccfb8dc1761e40936af533347e27997d2d24fe9640be14c6118112e332f8dc14b191edf3b538b473eb8724ddc7bc102676f43ecc6c36dc5727e5b7d8863c607ce847bc99eede17f7c2c81e67d1a178a5bde1308a87c00bdd922e1012a6c058dfc9ddecb0354b68fe3366591cf6dbf47d1a5f1ff9fbdbf6d6e14471bc5f1af722a6fefde0908e86e4fd579611b4c702231383c58daba6bcb800308c9f689edd8e8d47ef77f49d88e93384e7a76d67bffcf2f35d5130302c4a5eb59d7c3a882025168431dd9a886c2d1cfe675fe85baeda126d53b75532fd7efdddb422a7976b681a12388ed99c4ce0c28ba00015262ea699062a0f209442408250c87f5168552be611d8612d61e20d26e97fa1b2d4c622bdbe7577b64fe6b395733a4e1c4aa317f2fc6c65bab1afb17ab81e36c212015e258a8fd70e03412c7902dedad08900402421d13f1112776b4c5c0dbf876a0f9b627fc8430048614279101013611205cd9b6677173efd3b21edab97ca287d70c69e446f5d27b27aef6923eb1aed4fbad76bfdc33610835dff574a5c786702375565fdaf0896340101850e495d21b9240f82e61c41e31a26c576c41d58b73509fef2f3c5a6400297f60abf3bff525ef6c811d8c8e79e58bf34771b4bb989e7d1fc9d3639a7c5fa37587ebbf5c43ecc49c4eef155f301e4614060ef10687c186a858f142c33ce650f2080a35940c2bcc871509bd8d1c87922147aa775164c230933631457606088d2954f1bf3df641ccfec7bc58d9bfd1ab7e8f47fe9c5fe0d7b93b3248e2ad2689a591f150e9deedbb3ba7e33b2bd3bae0de8d49b8a3ab1a7f49b021766d127bc009774c0cbc2d0c23d57f0bf108a83d659159aaa780c042da79903b5b2c588d69d0c06444a1ea6f7f766fb0c263c4ee0efda1ffa2b5d8f92b26b3e73cff9d8df72faf55368bd7b9fb5e4d0e677db95e4d5ea3620c558d112890e81ac81ed518045b1c3a8d2f6948d5bc2c34083c416c6c623aaa610237ad9f2ed355fd1a1a5790c74cc52f73b8f948ff9d2627f6c6da7c940bd6fe74b6242c2971878c70cff0550df1b8443466d01d55beeb69087806a488a9186be01958e4dcb7a55c8006e2ce16894cd94750381bdcd64b3e87a72f7a35c1eab0cfa8e2e85a5c8cd793043d11375a4d5df699ba5912a756187496efc4216e2f596f10aa78bac0f443c6a11b57d0461c8a21232acec4d960b5b7e69938cc2c95331f32064500108d004c0885eea02634d248e80162172616313f9fe3b3cfb57beed7f111bc262e1367e2363797ddeb2725523d42031d01acab7af62e34481257c88d745fc1d2117e1873b54747879cd8831ad95d899725093381400090ede850400bf2c8c2e77bee1f7fff6a92e89bcff4abcddd7221f961c63bcd5dc25699bbf9cfc38e9625141276256d6bd20d2a4c1d9d24a88461af26092921ad754849a5f6eb44af8454d22d6c70e26950d40203c471e800c2bd2d0ee1d677cfd685f904fd22eb333d3d72b76c4832a833b7f3743adfa9b8682f1868471b22793d8582d8c1160bc78261d7c4143618c42514520f0e3650a052d9fd8030083c0d7154113bd0a41c4021ab888a65cc4bc207e5591fd92c5e8d01dae49fa907321b2dd2e4bd1ca6e072f1b31c95beebe8d08d39a410289cb3078c24de8624d296c286da07b0f3b2cd0b1b314c47150a1145c988faa1033070b6840716923695b465cfc7a5ff8b36e8bb706beea877c1de6a5d138725c55cd26860f861a4c31036cac6b287350c3190b6939f780db23d819348a0b000900f98ea4b956081b9a361ea0828a0eebb58207156ced21458221f74f85e6f7b91c76d8cca948faaa31e8a7b1d6ddf0f4ac2ed599f3ed3e3ee5f5897f3fafafd257bd5d43a02526e100629e1301c524c490ddd518d00a1486400730f20e018d0c6028643868467f9c980113bd3b0286b62c7150c73a67a0882a821e763f9cef4c87d099bbdacf95598be2ba3da18f40bfa5d62aa727493b8267c5023da6d1080c04fb08eec7a8b01d630f0849457ca9790c494d8a42434d320cd4cdf8580706c628e18b10b8069c9cfc75f9dccf17adb43f49d1cd35ce28d3b3c5a8fcfca33b69e8edff3e77b97dcffd2318d1a487b1cda7185695e9330e710601d026860d1052889b6aa8e35855b243ce0878493705863cab89f408dd865496c56213766aa379308cec6d91fbe5def1cf95b3e81af330648821e3ee00317cc4944350e3315db44c2418928d608cd2c940c2b98601387854112a8419b704c0b0b87dd06855e830106248c541f776277b7880f6a62931a4b5d20f928a667d77bef9d3e1017b48301125d8143cf80a26e7bddd98e5039f261af22e180ab3ed536b488dde35814267207a5cac390b2ca1d712ce9dc8e00a19ea9f216edfa2cdebcd303f164dffa5735ebcae98c3d483996bb8c9ef057bfec39bcaf6b57bda8fbd7f28497352256a9cb3472c87538d41a5c10a07c85f314741eefc6cf6b70d8bf7107d5bf200f150eec7befbfd3cbfc8239986dfd6fdfaeb7840e2ba5e326b841dc69889d3355233d740404aa86b18e5ca4ea964210697e189824714c3f1cd68807c0b7038168609dcf33195a123f556d8f7b137cb64ff571efe9d4ed1cfacfbfaaaba0729e556f837b73bbb75972b7f3d8f6b9fe706d1a9ca045fa6ecde48bea91164ea44e5d523fcc3464d70286038a41d0f8aea3419a73c9cb318d00049141782060322831c7961f065bdfae4d2458ed272369075ac8f54c3ff9641dd0973d7a9fc887f4e3adf73957f98d94a76c4d8e7a997ee4a378ee2ffa6eee95d463cc0bfaca2cc2f116b9d8f25d692b8f2a286580c00db2cb124abd5d0c28e4a48461206d4700690d547f4c1ed788e625a69e85c5882157d5c1daa0f0ac0ebfc4e38535369086c7a3c567e2298ee07ca09d77e4ca057d14aaee8f8554cfe898411ae838ecea084093848586c2418513cfc2cac7386030c1c077230b73a7c174c431573e890d4ea00e29347c1beae47c0f9857f4dfddd74e79858b9f82a7fa5ee25a42e1b8313a2da7c3fa92b559b6180c6a24062574e146f9a3134fd137b1871c53c27c7bc87d9754904726e281bca6635aab183244a56ed22b711297907ba6ea6f973867e3f5f0185929872b09bbc9781f1f76ba7e184954adcd3253f2c562d99b7ec67b79ae7afded78f7cb7e296f780c1facc9bbb5c646f3c9183df7187cc1db953fb9f9947fefc55aef7281de89cfbff07aab982314d6025368c0d031541fde109550d9a89ef0ddb886b4367c9794847b160919f3dd40f86aaf62506210182a463d744ce2e20d06e76bef3dc703ec6466ff9d351cf754aed424c9ceea65cfb59c5ff46dd8e7ab89146c81e4f329c77b7d6b8593ad84fffe192f7cd6a77a56eff49c3a9d4145fbb9fb29d96e491e922727faefcbefbe683e41db57dc0fbb00d97583c39c12459b438ec3112534b250e20128ed0b9b500c481bc7275885c1b0860916d0ee6e60881bd5bf342c2b68e30f6c8fe7bd16cc597dbab732bce05edc9091c433318f1a68b30ad301f543522120edd49c221134d00d1ac4a30d72638ac18062da63241930c43dcbb77b0c8a98639593830ddf76360844e763158f7b6f7ec4239efb72ae536328717431e592679d8a876f69e7727143c31a8581ee875d0b0acf42f6a0f4555c310684764d28863549e2dab7470cf348d59027aade52a4a91a4be1a886a216c4764c4263e6db9126f5c64fd9fdbf063b41925cc5beed7b979ea03de3b2f68eb4db870c8121437cc0207074a2f2756346ec98631ae86ddda15adab63a1248f5e84076ad411e69aa77241830e80e2b123a161699f551cd9923789893d375772eda27cd7711c5b468888db784161b1c620041cca5dd8f542c89ca3b05aa6f9ad4d304dcaabe7c09146aefdb2e00148ca3d013be9d5750200e3fe8c9918f87cbb774e35db8ffa5a343d557a510980e6b2850851242a1886b18160026aa173ec0149a10045b24f92a1f952889b6c8553990956fa35aeaf884124eecc8f0ddb3f96f5cf28eb11137a9bad6a949b2d7a9589df27dbf6dbdcc5d3427e3bd9ed3639287a4b360b5cb1d5136e92fe647e879c24ed661f1fb9784f990a204713f2c6b5ff5dcf234154fecaa7e071b18e61cba518368063045929f6b88161b043040149b38ac0d22614f338142564200357cbe37fceb3a2c2a07f963fde06d0cdf093ab52e19d78512c23018511cb212859e051344a51e4f5cc4111851687b1a0a11274964f8e1a084b4d8100a0d644bfaee5ad08eb96f170de403866c2c247cc907b5c2723010a775837a0dfb2b038fd1e26e8cd678dc1313b7a3495b898cc9828cb3cbede170443118d584c206859146784cb12025069eeeab6f1e96aaae91183248cb0ad925f75da861e1988a7e5dc2481297aacf10cd6bdf8d745503ee2c7ee46506ea93be098963b786babeca80556637689e1a81d44d59ce19cbc505f7607800081fd67ee2187e58347e32aa6132a8a18b28a45d00695e113a60aae63bcd74c41d83d0cc20c988139a5788920a892e402eb6d45e0dcde987f20d0c44aafa975b3501f169fda8328d4bf65c40e1889170502337ae915d0055a3d96ef79948880509830da28c63312831651c7167ab7ae9d87503ed0c1055a3b14751125790d61602e46cbf9077e2aa5fc797eef7aa3ec18f243e6952575f13376769a5ab3d5cf24e6dadcbc2d7132a76829212dad8422ea284c7aa77931f8e6a4ca5dc8c6b984081c3b254bc9e8f6a3f8400534748784357d585a748d5441e547ed83dabbbe359bccadcc1f2e0dbffc88ff0e91ab3f353b0161377d0b4b2fa97d7695767f1741c3c1297eb9b01edc284a1a46307c03010d0250c2691eebb9e09ed1a60e1697e98e990465b55f320cc2b98604078a0648d9f04ba9f781be492ca4fbcadef0eebf3f1692fe0fb1eeeaf3223de646ea7c93fe3ab79c55b0efbe863a46737bda7ec749ffee68e6617ac0f24e58ca7c130d220271c02d5b35083ca366fe30b88ddb5308586ea9f200a40545dd7688b45a4f96164205a08ac7238ba966fe7a51f9ed5713e1f9b559d82e150e2324b0ff1f77f29fe1feefdcfaf4b60486cf6ed4cc512c0b06424090c94380071c491cd2a4463a67296684e31853a721d0327ce16d1ee46e59084718d39a9218d2b648f2ae47ee46751b901ff337ab2abbdbd428392ae456611aa7a156c6138a821701a1c328624fd8b6c83540ebd6761116c8994f976b7f19398f909a991c83904d1c697bce37cccefa11ffd69bcfa0cbdb39a4858f0933d212e9d2f4a61884d3f0c36300c34e2060d4c54af210dd1da54be2aee68883b028240271c9ac88d19169e45126c1157ea9ab0c109b44808b728f400a639fd205e7cbfa7fc0efd5cb0de7e880de2428ba87e69acf413cf44d25e13810e43cf404964c1704021c01ab23d1d85850639dcaade062a631651556bdf56719416b40be3a37eea87fef4a773f32e98d71153df86160eb1815c4289e2c98585c22143612d200d1a92381ab47b25e69105456d419a69d28e8549247c1b6b50ea9849d0f8aeb781ae3caecfd1cea107ff24c426aaf40d6e7479ae4e8d5cdc25f93abfdff3f3164677e3c244ec2740fd77c67e4c6bed7392a13e49b6a7f5ca8bc6e60d551e284962068127903ba0380c0c5ff22f3e52f55c21886b69d3224a18e20180aaa6deb0842ed41085167407dcb73d4be534d1dac2fca3989c434cfd02d102dc8d7bf46e2ccf8d9e7203ae08b04ed4ed527d492e5a3f1d024ff21b00056ea01d344a9f567b81038612c4a00d25bfe684461a4a861483618529d408451509bb96ea81ce3d80134f87896760faa11c7b996b701a372e59bb6c43120830884c15a31546a6aaa70fe4f7473a16854168ade3b054756220871b2c4615b4bb5b483d41a8b445a0406e24308874e24a9df76c3cf29f88ed39c0ccf46df28068b0ca5cb8927446dc8e9135fa2c9dbdd793f772f99e48380d09bd068942f53a42614ea1a4b904d590930ad221c761ce50e2e8c8c65b9c442609039370a7c1c0317c69b7d9434a38dcfa21dcc2b010e4431f015b4bdc38494b17f5017b8d1f4afd3bae50586cb11871123a5b4c7103c3daf25d47276124a0c05ba5ab734ff3a5ad1a3a5b24ca1abaa8967a11e1a444ee88223ea0587c8aafff0a1ebde821fa4eff860be6074716063127c9b0862e34fd50d55c57718f44d2a1d4034426a0aac71ee990abbeee9a6f33aafa18d850c7026f7d5bead858900ffbee9ce8f15b9d9057ad0ffc7f5f7dbb5a4c1ea7b3d5d5effff7ea8fbab8fafdeaeadb159af0a9fcf5cf7f7ebbaa679355f534fd2d9f3e5dd7b3bf2dd8baa8667f7b58cfb2dfaf5753be6093d57479fdb85eaeae33365fe7d3a7e96cb5bcee4f1e8bf96fab3967f2c9d5ec612effe6d3d5a4624bf973d6bee368dcb7ab6525a657bf03607cbbe2f37c7af5bb0934f5f31fab4a8d061ad0ffa6eb7fd3b550effc6e98bfebe66fe04747fbf1fdc74ffd6f9af5bba65d7dbbaa96ffc8abc7abdf1f266c39fd76b56cd40bede9d3d5efdf4d4bb7be5d79b3f9d5efbafea363fde8fcd0bf5d2156cdeaabdff56f5750bdd730f49f3fbf5d45557ef5bbae69fab72bf7f9e7f81fff584c72edea77eddbd528974fd5be5ddd3f4fbdc7eaf6434cadf35d1eceb37a79f5fbcf6f57dd55c5e554eea7d9d5effa77e3bbd5d17e5ae6b72bb494673a9defbaf153fbf1f39fdfaee0f9a1878ffee7b7abfee7878efff18ff56cbd9ce657bfff5dfba67dd3fefb9f728dcbe9a3829004dad57539e7d36b3a9dd5d56c79bd993fd6cbc5249b5e67d5f50e17fe36ab8a72c59abf65d5df5ea2c42b0cb9cee7d9f2eadb95c717f3c7d51f9355f902bf7657ed79d69e0e278fc574d5fe1ecde7bb5f70b2cacaabdf676bc6be5dddaf266c7a585975349a4e96f3593bd69d0f2a365dee47b7ef3d1cdad3c5e177385dae5e8d96a75edd01e7f95abeefff5eed26ff3e35a89956b3abdf578febe9b7bf1e96eaebe03cff8b57a898ffc6e7b97a783c7d5c560a92fa6ffa7745fc0bf5d57bce70f6e3776bfa499ef0cf6f57f96435910c801d59732fbac3123de5e85cd480d42219719976b42bba8161a1b4b3d71c721c2c68ea7674e2c680249626ad6de22e8b3fee7b3fbc9bb75a85576d0ac2e3721745abbca9529bcc5d667a4c2b1e8245898dd162dad70d9278ed7d8d778b13a44dc6c52a9b05bb5d7a69711f6788b7d1695eb158a6207ba9c5f0789db3ce3205f98c8cbdfdb57697bff8dfff3e6efdc7e33c7ba85a4c7f9f571f461d3875e7a28c1afc858cbaf3c5a7bff8f4179f3ecf0d9eb9740ee2caafba4f39e8341303498ecdeec07091561d9e2796e48a4f69f16fd427474ed786ce6f3c3fcfa29e871d69933f2ecaa58cbf549dfcf1c5a7bef8d4179ffa80273c332aafe9dde763a479ce5ecdebb9470cea3606f11283ce8adcf7b4b4e959a911379e6bb17c7f9f7ba476de1c12764a6f309a93fb5e9502b624e3e12675071a091669abee95f9adfbbc79b25301d7d90c3edddef7947a2855401528ef32e1b96cdd67ab223386f40ee8e52431d7d90c15e3fb627d67a006379d154ed8fa6e3614b7f766713f0e6659b30f22cff58cc7b577337a92cfc979e7517ecbc48d0aec9665ca474b92746fc92c5e4bf554aab493c42c12d01319874f1395b8bb6559653519e8e5b77df3a99dc7eedeb127e7bd90cff66e862c337a4fe90cb1f67d4e11399d30ee2e1a321ee844c10b3da5b3513949ac45cab302dff7004eb60bd2ef1501d83ee5c968904bb5d6edaebd017bcaef55f0939eba4191ddc49a77c39ef2b15710371693f19091eea2224959e69c3d65556f91ced082b85191bb6599f77bc57efeb8df7b163c9559dc276681c140907bb9a65191f29891be5ae323b845b759bbf60d19ef1c40635810de690ef37886db529dbbef519c9805717feee7b048ab16de0978b126c531ee1cade53ef85fc1f54ee2a05b32cf1d6cb27ecf9824dba5e7c666e676845ac79b2123f72a90639302b6ce6fe0f77e312fbcfebcc0fd4ee10d46cd2491e6c15078370a27df81498fa78627d72308751479aece72b77c22ddc3b3e624192c73b778ca785caa46f2632470bf17c96f93a653e67616e92c68e1e33ac5f138cf2d194eb6daa4df6b37fe366f9f9bba4cd220cb0c54ece8e7f9bbfa87f92d2763c2521e8bace9edef2d768184b77da6d66085c775918f9184db7a7adf7b22bb35c063524e926d89f9967983556b9275179c2483360943d7e6474ed09dc9663559d3a95380c45d5317b9fb53aefb9270b64cfbed73331e6ff32416f90d2cf038906bff9481e8f6192e2321d7d26b60315226e5f629737596ce82db3e1bcd276358c87ff85eaec97639bdef09926cb94ae068e945e26799ddf496930495ed9a6d8a0cfc2ca64947f75c54a655af2612366e67e3b94cf3dc81e8cf143c8cd48897f2fe745617a9319a4b7331520ecab7cf24f7d64cce15bbbd2203254b5df91ed44cc63dadcf5199f1fcc9735bc7e0e1f866c43223b8c560d010f0b3c866f1bacf7b05eece6f43605149437962ad55f2e10e662f788efcf6e3b571079a676f957355f2c8d4ed509c6c55331d9f161bdfeefe975c5bd25da8674ddcb84c6f4673cfdd39a19b5e99f148adc51f8ad776e57a2e5380ca54ae8d117cf7edae09dfc1eb3faa5e99f2e0f6b3f73ee32efcafbbaa17a5cd9e8e066b6fe742503c51d260b038a2bb8d5c73b5f133198f2cef06e918140596f070919ef16de1b97a39bdef55e4bea76720aefdddda60d05967a0b324c182aaa0efbe0ebcbe5e7bfdfc87d76e084825bc0a78e729bf419637d366de6073ebf5bbabfb7e2ef98c26e775371e59991b7d573cc6dd2e3068932feec042a4c07c710fb9d745e6c6f4102c40e72a8975d8f4b27ed52deea2628641b49a24c177cf76dedcbbdb78f8ee3dc3f5959bc55aa44d568c15dfd1bd2140ec797e239657d663ca079ae401773c3671a26f5237dabda7770e5f14ccfac59c7a4dcf21e3de3235984a98e8178b3803521e2a7e5cb4b2eb99ee32cebeb77242cae35730eaf73679325c4ec668ae686e27f78e36556e55934e77c43277fb34bdef2d14cd35bdd273566b3c1e2d721e159192f74cd2899417edbb9c958e79dca43c5609fd186cf5cc18b18cce6f156ddd485cdf2ebd1b4433ce3679b7c5abe7777557c749f57f24a3270c5652962fd2e6e7cf24eac411ebf4020dfd114756f447b128b0dbddf35025c752a0cbf9b6bcb3afad9ebf8b159edbd9ec6447a5f8d578a449fadecb99118bfd40efdc8fa27c18e9a3fb44ea19890526e3e153ca15ef2b723e6826c9a04add68ed398335e9f716a46a65b2942304c4da5d5f1dcf241fc23c2ab29be1533aee692409d6fd62a1e44f6ac49ad20f5cd2a440933425f2045149cb92571fc1ff599f00e553deb4df16c743e8b944ea10f2f8363bacc7a6c841b9903479c467cbf4063d796ecef27e0f4c1267873bb09824164f4177e9b9d19a3466bb4e0a97d053ea46b7d8889bb4df5de5557745faddd9b419b62e4c3a2fbc7af8941a2331bd1f765ed253679dbbf13aefebda74dc637ef59a67b7cd435ed36066f4187e2ef4fabd0d987d455b09abfdaabb7d73ef2ee8c7af9e690ab7fa1953fad98ddafc7b4ddffbf9d5648cd71360c9f901726fb1a93b5865ee96eddf33ec973b5c656bc27f1677c9cf42f2b0db608783b5d4e95a19e1fd3b379e968fd97917811cb0770e58dff7ae01a09b3fcc9fa66eeaff8287a035d5de751080efa6ae757e6a070701d83b08f4ef3f7ffcf8130e02ebfbbbee01ed1df7c0f7cede90fff9c334b54ec7d4ff5f710fbcf60c7cc6be94472b69a59ef71bfcb5b3dcb920fe7ef5dbd57f1f7c102df2bc74412ce5d1ffcaa78be92c9fceb2e6f7ff5554ab729dfe96cdf97531ff5b51ade49fb462acb97eb28e3d167fbfca58359dad7e2be657dfaeb2f9eca12adadf0f7240b35c4df9ee780782f6685117d3bcfdf9385dcc97d56afe584d97afce34edf172feb89ae6cbe9ee2d7bb27c79a4eefdef23efc9dfe57456d3edeaeadbd5f4f171feb894b3e0f2f0a3cf3b7bfd9a4ff9c3f2bd51f2cffbcf68af5e2f57f3c74931954f9a3f362f07f3c9639d2aa62361f478f6a2fc7f352be4735e8dab56593965ac942f95482519c7b7ab62bea88bdfaad97533e1ecb7272099ca5cfdefba9aaf5715bbfa7655ff5cfe56cdaf278b8a4fb2b29a4d1f1bf91a79e2fa71ba9caf1fb3e9d539be792d1f24e1339baeaed78ff299f3e555eb95b99658a1dc3372958be976217fac678a0fb60b2dffac1eab5921ef59360a93d5e5ffdebbc2fe7e95ae1fd4bcd366355d2abce38bc7e972799d8a6a018e4f3c48d4383e51886a717c2c5895b698bb9ac88fbd66d572b53bd1e24ef6d82c56f3c38feb49fbcaf620ab16a55aa4dd717e7c315f4e9e0fa6d9cbc31c5896de7973e2ba9aada68fb309bb9ee69bc963be7c3d8cb16ab1aab2e733259f1c1d1d6e7f9cccf2dd92bebeb45ca72bb5bfb6bbc073ebf940de777494994707c71fb02c27fa8b23607d7f716ce9e0e8f8d52b57ec084e5b4bebbc3cba5ed4d556d2ed2c9be7d5ac38fa793d59cef4e3e374b29c7e375f9ca9661345568733c53c3d3e2ca7c70fbfa64bc5990fc70b454eeff38c3f1ee7abf90c4e2a26c96b37edb45a65ebc7a7e9f233631f27d56c319fb34f8c9d4eb69f1875585b4912bb65ffe89e79967e66d4623a5b148bcf8f9404725d4f9bcde3e497ee7ae4f3c75f183fcdf2f25786b362c2279f02cbfe8efdfa7ff686c31a4c58317fac5625ff33374fb3ec4fddf64c299fbd7731c9eae967507b7fc312d42f474f79f5b8982cabecba98e7cbeb03135d9e1d2639ec27465c4f1e1f27cd8e1dbf3f76f5387d4d73a746ec9842397d8d94af06ef85d709f19d3d14ef5eb85e6693d9ecb5b83e1eb09ad7d3d999cbcde2f567fc09d5a49cb2c5f4f13a2b1fa542f9c9d18b396b1e2ac6fe35c5e7306abefcc4a0b72cea1755a856d5fc60d0b3309c3e55cb56fffed4f8566d393774c1d63c7d436fef0ebbce265939fdf4e0397bcd0bdf1f2c552a655d7e76fcfc914f569f03e0eb9bf2eae1e1176f29aa5555cce68fbf3abf2adfeea2807ee9ae593eddfee23df394fe893749eef9676eab57ac9a7dfaae794aa7d9bb94fc7af44272ef6cced4e4167feeaeeb6cb298a415ab56cd9f7cc0b2caa769ab457eeaf6c7e9d35b2efffe70693cbdc768df8e5e3d4e66cb456b57fcda0dd7ad65fbebf7fd0a563cdf55547fe255e56af5e9657ebeebc0e6b239e71f32c5130f584e1f9ffec4125c2f97e5e72ce34fdacfcf3e865fbee13a9faf3e06f93943fdcd60a53a3c1b1f1f0ffd04376d071e8cf38f87f2e963cda6abc7ea2318be1efe7960beb9f3334cf7c44d3b247c789cf05f9eec6c9ebf45c074fdf03061f3eb72fa56da14f3964da5eb87f6c7cb0115cf278fd55cbea2787589a6d3d9544d66e713b8ae5e8da8a74fd52c5d3fd65389e1ff3825597fc9abf376feaf471c80c7278be5675c449f72234d793acdffa4c3e9f4b8e52a9fbf9edf3baea9e711cbe96351c9ab923e1491f0c92a2b17ca9df962e47632138d84f9df26c58e55cfd96456fc367f2caeb7d77b6b9bcd370f55cb7a4e5cce26cb95f5deb572929513a0bd77591afc7b07cdf90147f85e4d59fecef867afd0a9ab6f1d38a74649755e37b4f73e69f92e2096cbf2fa1c1ce5f5673f833af98f455ae70f67c6d7b3f96656ce7706dff1204953cf4eb637979ebf556d349c18b1789c6f9bd71796cdf27aba9d6693f4cd3df2d2b3823f5b4e1ea6e574b26323af07ae67caff74709856b387df9eb4e3339bc9e3ac9a15cb57a79f3dabe544415afeb99ee46cfa68eccf5e678f597bb0520949156f459efa7b50fedba3c38cd5e14e0cb497e8622ae9fa85eb67c25e9cca16ebe3c307bedab9580fa766d3d5ea71a25cba8773f3a5f27d1c9f5acc957d78e45d7c79cbe3f4814db315ab562f4e2fab59c1a60fac2aca176f5d36cb6cc2985aaae9ece9d4a5dd0a1cceafa6cb159bbff8ba578bb877652bf3f3cfb8b4df19269ff2ec0d3a3b6a395d7d38e669c2aa7cb2db0dfae4c803d3f884dbbd05126f9decf2cf755a15cf3fd504d5ef9da797b7be77f9e79aafd9aa5a4c148aa813ff673d5f4df3c563355b4d52c57266ca65240970a77cee7faaffed71e97072bf58bb7392dcf7e2f7d5fec0bca5dcf6d77aa99674b755f076eb4061db8b4d04f5e37ad9cc56ca61fabca9b0fb759db57b4bbba36767dd6ace953bfdcd951d08df9c5f36cb177b15d95c61f09b5d0bf9e7f9f13bbcdeef667cbb5acfaaac35db77bfaed7ab07fdfbcbe39fea50a2f9d5b7aba7e92c9f3f5e7f20a83e31ea48449c1badfe48aef2d9717bdffcb9c1c722f3ccb8b2952b6746bc958667067ff0c51215f3d952fee3d3e5b265c7ef0d3c207bb156c4f4e1b8bda43a37105c97d27a3e33aaca6793772e4b89d5b2fa535795ceba9c66ebc7e9755ae5d5e3fa5d68a9a1ca5e7b983ff27383f6382a1ff8997133f9bcff7e15c1fef7dd8ef13f2473dfeddfbe8867fffb0b862719e362f5b86718f226a9dafef757c4fb5f1bf1be7ccc9e63dddb94827f5b14cdce0ff9dbe3f27c3ccdf3b07d544de78779998c9b5d40cd5f98c0ada6fe9570f39570f3c57e3ee40a47d9816d60beca8d1e1b39c374fe5d650c6ee6b777cdcf276f30d4d3aa47f331d2543027e8ac0967b37c3cdc053caa00da0d1e0f35cfedf05dc0e9aba0c85e95276ca902ba37f3a7bbe6a70a1cc520165963aaf7f4ab9f4f774d2f9aa8249be3441e34df05ccab20699cb0b5e70e9669ffec9c5482c234e9e859f522b1e2d5bc5ebcbbc06e4f554bdb1d73f9dd470928730cc8ccafba3c1dc79a77d3c2ea102c1ca1a794930569ea62bafb46afdf2d3c77cbf27eafc6ac53abcee32a37bcb79ac69d1a57c5c27f311671d258351e8fca5b77548dc1a8998c09cb2a8ba66e674dee8bc56db86cd7e5466bffba2ab05f3e63b75ea33949cce300595d05543fc38891fecb249ac96efc4b589d85cd264fbc62d735a520dc3c24b2dc768fbfa70d24f7ab5e9b48d4dfb47394d7fabd3d3cbeef613972071a0eb70eae77df4dcd65fbbeeec2eb6bffe50d862c33e2656e6ff7cf2b76495c0f0a67e962a0baa450f3e51a389dc7db5d52994f17aa6b709e6cb5db7ebdd87d4fa73febe9b8fa97d65cbd2b753b339f2e1629274fde7d5105cf70574956cfc1cc9e5c7b758faaa2cb4765ee3af3fb7d9257bd7bb6987f276eccf1385ee6fd76fd1f821d6d3a2aa1611f785fa40017b94a503aa21f77f71c236e76dd088acc183579825492cd5db1506bb93fe739fb64b2a1bd4b7e3a7c5b7613579eab9219be7b837db5c28d9a4fdb65bae7ec61bb0be0f6544572376ef670f06e96b72d6e90b5e78e18e1033dbd09e6b7f7ddd51fe7c6b738f3c1f5f69faa2a18ce8bc8183593c492ebc133de59ddf687466a0c97a4ef2d54a5c6fd3d37daedfeefc3bf39c0f9ba9ccc72367dfc50373b1a77c887d67e5c281f7aa79dfd95551bd4dcbfd4b32ff5ec4b3dfb9833bcd6cfda8a653e5dec1352bffbf51b3efda33f8b85d4bd54a2e4a06390c4fbeecfa4cc5adeee9eb34c8db84d4c9c8d844f173fdadfc177bf56f267b94fbebeebef64b6d3261792b177b816cce245ea8e58c6f016de68fbf72e53907df7b94a22d99f13643cac49dc26c5a8f7cd864f69dc11a9db26f4ec8ff31b6fe9b90b9102abb3d33d8b7b25d7e2559bb0f726c9779635f29df90237bd39190fd94e869799c1d6b8d5dfe6adbc88e6fd4ac98f3661c69e17a3f6bb97bbf307b8bed245dec89b3faacded4e56dd933192b2ebe7fe59aff5e851dbcdebbf9e659e824d79db1f1ee63135b4ea6e3faf7efda34d18967a44acc9f12a91cad68ab68b5351ecd66b4de4fcee8bc52bf918a64067b78e5acbef7e2d758e4133bd2fc1ed7d5dfc119ac54bf897e036fcb98341fb2f5249d6a52375509f2ec2fc46e92df3bcaa179eadfd579bd4a53f487de1f6062ffe683667deaf92169fefbdc1ebdced3ca446be268994f92feef55360b1f61deabef2f666593c274f1ed668dd560dee750ef74b1cdcc1ad5d8b51bfb537e226a6cee620ff77fae86d7024fbfbd63e1172ded6ad52c9c6f3fdba7b557dac5facf39b7a3f6e4dc665998e7b4ba9cb1dc370afcb79fc6412a75c6f450fde7df9c3eb0f55e260da78dff7eb9dec13d198563cdcd7af9eddd2e36dffe5bcd264b01983b8c9aaf225fdf3b8c978a739e8c6355be76edca47cb08c76850d7678bae8cfb4db7e8552a98fdeb649c48b71b058a5202872b74da8deeb828a9fdc203d73e3c6a7f3ff2369f659afdbebc545abb77f4853bd1fc7dfb8d3e5f738b826e3ec63bd78b7a652176d9f83f6051e1e32c9df66f27b46f98ede8f79445bf460d059a4b39e2e9ff58aa696641c144aff3fa2c7d19e6ff2231d367c71dfee799620e3d1c38e5e2b3cee6d24eded74f1a7b6aed89ef7299caf5afcf6be7bfd6195828e96197525f1606f2f1cd995d28edbc8f91cecafdd1cef9e79dafcf6be5ee3715e4ec6c10b38e33192fc59f3ee4bf59c3bcec418741ea55df4f25d6da7a6b6a844779d279691f1c1e6b65fbfc3874ef2925b89f3b76e47cf6f245cf6fc6420944d34e8b0ec5ed2cc3ef152c2643776b0ac266ebc4cdd9fd5f8be7ec1afd4bfc14fc5db3277b09e24b0bcedbf1cf3f0e771639deae7f122e3b1c8fadd8eb72fe0715f0e76bcfd057efeffed7accf2a78cabaaa387c4dea4d9f3ac61fe9287b7ffc64db7f347d5dbe0c45ae0c679cde73b3b3877f63cdbd3577b9ed548b8295e33d8d964ee404c5572aae42b6c9df3c172928c1e7672707e7bff8a779cf0674d0dc5cb968a0f559b2218f7360fe17b343ed8a8f56cf99fd26726e3d1c3b3dd5ef6b29bee779f5b2c6f8ac5dd6cf8948f47ecb6ef3d4918ed78d726359026d723777fce0fb4795f2feef8c0c009d34ed3b253fc71dfd3c818693e5d44f26fb42f6661cfbf676e47285c9ac5cde4bea8ee1a6f71371b3d8d8d21cbc6b19cef6b1ef412470fdf84cad4dd1e7d53c19fbf7da30a68dcde5b650e068bdc7ef1bc323310cb664179bbc33dd509f52616f25b2763f480c1762165ac9245bcd31ce3ee43b0e8fc5b6b214a2d9a4faad987c6f57ed0deb2fed9011735acffc242636aea5f76f5975dfd65577fc011ce6f7a4c8d67e170d7ef79f9cd681349c6e976d61988969ea3aa8485643c04643cecf89b8572ac93c40263b07d22206759bb19c294137833bf4d934e7d5086c572777ca8d6258d169a8097f34893c12265daedb1735d9dabf6ca34d2883dff3e497e7ef7d9de21be99df86e6413927c9f64929c8adb1c7d2199eefcf8d120bbc7282af0f8acaa0c327c95623e3e1436a7873af35e697c74ef63fc6799971b3924acc24b1544df767e55f09b24d6a0c35bfeae930c46ab3038f4774d2ef89dc95c2275ee774fe3de783e6b63f0c427d1879d5b303fde0b0bfc107a33173074d06a2f9edbda5a7b3bcc1e3ee6ba56290cdbcf9b8698ddcb622d05be3f0aef95904c690e1f188ed36aabc78300abc1b29d408cb76e3ee6f465a36d89d936bc263e3f666fbf39502f8421178a394f6774a99fb7a7d592d95811c0c1a12cebf876e67468034a25e6f4cbc79deab8d89d6787a760aa9f3a7ee6ba4e2465a8561b937c69e9589d1d3ed334e7ef7f95e913d398793cf22203e283b2dec9eabcff97481c878344fc1c84f8d512f75b74f3988ebdbfbfa8de27850a68e9df3c7ffaae72a4f53fde777a984e064b45015c88ced513532d669dbb19d78c6e7e6fcc7a4396168ec8dee1b6d0f9bb56af3d42fe61e751ad4989b3b55e05ac246b5695bdc863f6ff7f8901ac347321e8a5bdb39dc9fcde2f5b331bf53babaff06454945169edf7268630f772ad145ebab18a6d4434ceba01719ff6a7d959fff4a7d958eae9bbaa16be6ff2b6ad1577d95affa2a5ff555beeaab7cd557f9aaaf72fd555fe5abbeca577d95affa2a5ff555beeaab7cd557f9aaaff2555fe5abbeca577d95affa2a5ff555beeaab7cd557f9aaaff2555fe5abbeca577d95affa2a5ff555beeaab7cd557f9aaaff2555fe5abbecaffc8483fc5ccff6d45551429b48defd93cabcfc7ce1c8ddb47d098a60e2e544d65173ef3fdaf0b2bde4dfebdc0e2afc8e2afc8e2ff6ff29b638ef0a277f1be74c92275a35d0fcd584b815ee62ea3b8ed23da25205e1355a624ae3d7768794edbb3f3ae9853cf615adb63d87a52bd6a672396f21123bb7eab693258e7c960e9b9713d198f1629cfd67db64a33774027603023b19ef7db74c9e28ffb6eb5eb65bcc2a053930456fdd9a1ff9cba0efba6b8a3ddaa3fdb9502b9ef76bcfeb02149bec88c5133bd5fa97e7399983fdd817c91bba58e2b8ba6407bca54bf527d89136b7607daf4e4b65fa4be90739ef6bddbb60fec4ae489a6de874459c3b0101078c2b7a149dc21f3c37a435cbc2174c07d3baf708201b27b9450bc453661be5d9b30c400278421bbbbf56d68117b5041bbbb256164c0be774bdc784312ab26894527492c3c5b2b92cdbcf0f87091bb6489935cb4d1a0c36aaae6d9dddcd1688d2a6fd9afba1599c56dbfd946a7a93164bbb13c1f8ff48cc7e26e8c16295f56aa6404df3e91a6bd2f73d9fa6e7ce8335dc0bea9dd51cfdcddafa560b548776373b7f338497eae72b96e7d6fd967daed27d76e9df298e67deff6d0e7b392ebe4352ad2b4efddeefb03caeff666cf3d266fc1735f6b029836b989ab3b8e9ed2fb8e2ae572976ccb94674fd850f828ee387bba4bd89ab8b1e9158bb637b081f454e185b7452233a1c84b18764d441187615ce1b0ac21183008620ac321c709dc42bbb6e43f147a16498206da5d1302a74180d484470db233e1db831aba23ea158b9a8c556f619672b4206358fc71df4b25cc5ee36f0bff369afa6e3cd47670def505d605190fc12441ecd579d5cf35dbad037163555a660cf4a78c47bb67c612b759f6161fd4bdbbe7295ad8fd5ea6206bef9d8d76b01cadb346df64bca31dd6fc66a86746b022ae25eee4f34067a9fa88579bdb7130bf4df4d50627e81127391bc7da6d9bf6a968703ff7f69dc50290f150a8722e728da9b7869529cfef539715ce1cf5397d3cea9b3c9b8c47f33cf1d618745677463ba7d41dac49d3a1191f6864acfa47ae269286c645d5e7bbbebd46bc6adf17e8907a969f442612c5168101432136a0a8b7d08d740860836ca8f9f688e2109a9847c2b73d93b89e09435621daddc2301388138a686d422e9f13547d3e62991b4b7c5b63c0245d76bcc1f278ed680a460cefe07982265e9ccf66c12b1c5111fc0b0ca257e74773d55ff8a6f79482cdab6bb13649b6077e81c78821ba7fee5b7ea2d6dbad9b73fc0583ced304b03d5ed2d4e859a91b8b5fc2c944f25dc9f3f3876cb6a705b2947c179ee06313772061b47cc3cb1274f40ea2e7377143c6f0992fa9e794733c46f33ddeef9faf70aa7ff4bbcdcad83dabe51b6932d8d3c822773be59e5ea49cc893c18cdcebda11fc9678bcb0c606d2f078b4d8af73ea7666bbebab49a2efe1b621524625967697487ce9d4aabfedeeda243157d9cdf069a2f0a2bb95bc11edf9341fac497fff3b9e491c6f6917b18c8ff6cf7f51aae2d5393de35bc99f9e8894dbbb6b13d759c1fbdd73c1b6c4d59ed7b315b9ff3c8f4f9301cd7847bca5f3ee1ade9be26274ce3d0d03c7c420da40d76b10cd4b424b8a415c611e0064e735097b35a203066d6c20d70324c45b18163a06d0c06164414eb86f170612c38a24014061748eceb779d2d1c81e86065bff026f6c3351c6de29bda6b9a3d9c5f41ac80735a4b58513c913b1e627d1967068fa216250408101e2be4d3814998144b4258967a144c229d389ddb550e8081846067221203410c88e1adc9cd56bacb61c832acdb1a33fd5c3fbad8ef20ebe7f16c627f48eed1d75d6f0fe827a878d3806b0f143a791f8079311837c4809957fb10169af86dc01d0858d6f631df241856cc7f0436ca2c4d99224daa29031e8920a825105a9677c46ef38d0e54b7d429bb459479b147496eff2f4cff062256b36fbb559491b21e7317da33f7e928f64bb721e6ff988b396bae925f50564770d12128668d660a9fbd99989dc6189430c10803ab1614312bc8536a3188c6adf0d7412f62a94c415a68c115a9688e61cb9238e69b6f1ddb37ce4acbef079bde085ec3f9699739c586bb25fab77e4e64bb9f573375697bc4327377b996de969dca1d94dbc7f8f48dd4175f80dd0231907bfa2233eebbda7d71d5c6eddbb1b147a1a14718dc2628b695c91b0102809b630c11a493c8139629236b1284b421d93d88541dc11f7dd0125616d115a32447386c25af7eda2c1dc3bb7eeefd0526f91564a17ff3f24419a6777d7a86f36fe2fd85d8abfba6c4d9a53fcaf7b49fea721e1093f41251485e187acc434d34812011c96a51f8e6a9820e6db91016d47c374586221e588a729dee8624168a64bba23145b30890c3f1c7ccaee7a87ff356ff4ee3ddf396f8f1dd94ce8098315cb6dafbaebaa04e234317a2506ab9280381f078bb6fc91d2494eebeca77d19f062329fd8dec64ff006b9c106da9e89c251e527034e6c68201b6ea0189690e615b431806164faad3cd231c752e60b448b06b9c1d64f06147244a11b89f3be8c1153e552e3ceeaa48fe20d8fda96d3197b50e5395c46dfacc15b3eb4c1e3e1a3d4a9c760fbb45fe3dc2d1b920ceacced3cfd8adf2277b727f4594ff2a30bdaad92760a0bd3bc46020298208ec2680381a3437bc4308fb658381bdfee02dfae257d6c49580392a0d24f1c038a6843424f40bbbbc5092a917074729e1f9d9743cfa55f5f9c5732e4201f4ec896cfc27cf79c37b451a9ace40beac391056daf216e4c51880114c31a2681e1879945c248eac95be4e20d0a6b03879e89c34240d7b1b018500408c3a2ac20850d0271e5cbb1dcd3f1fd39dad8f18844d967f473fcea681d38d308df96c4d8af41ab5f2bb9716f82ddf398c447696fbc5e270cca32e5167bb69f0fba9f9824d6e359bdeff3fec4839ef049bdc020c909dba8917cd2bb1c9f0cb1069340c3a163401e19840f4a6817004af994380d7409472ede121a9798f64a4c730a696611dadd6031ac911d99087806128109456020e099a8fad3b870ecc3db9f5be10435a9f1c6bfa82a11ecfd2f1fe8926fc7bd47ebcf7ac5abf3aff86cf58a979ef1691ec681b8da7df78c24e67e9ec6810fcd98e49912aff43b8a77d74fca959daf83ad89de697ec9a6f975ffd2914cd2176912bda3c3295dd6d8dd23f155e2dbcef71237c48d5ed8b8e37da9c5e37346dca46eeb3b224970421751fedca3398c16e98c8183ef791637bfc48f5fadc7099d45bb245fc649d0208e0d24ba1614504020e55b4e11279c8491469221832232210f2c6897250cbb1a0903cdb7b306829861416a64a31ada6505edacb5cbcfd1e24cf232b8d3237feef5c33fe5f351a51fab7774f1ea52baf890438a1b683b00da23eadb790593680393610d4160f92e36891dd77ee29884a30ad3628b92c8c420ae310db684138ac190613aaa088d2c081c8112c2bce2fcb74fdc9f2b0c3a0d1ea30506cb537864dc51c7bc9c5e356050e4947069b367008579495c47430936903dac118f2c69afa030337d3b32a1ebe958448d9f8c28122597f21f26312521a9b1c83690625d62d219bd6a45129d4e6e3e652fa8728177e3518313a6bde353d52fb86fb6c1b436495868980f2be4a24af93bc2bcc6a1634177584217eabeeb6c31f736c48d1a2c069cb8182010b47eabb06e481218889292283dd46bced96faab546b3936b62cfd7067a6a3cfbbaa74a3e7c084b2dbfa9dff1af3a97f327f1c0c2145a525ff7edcc806eb08561d0c004d5980e2a3fac350424fe8d6a08b04020b2a0e4711c5584420309bc4576d1f8ae2360c86a4973242ccee1db9c8c87abc93858e164b8d8cba94932dceb13c624b1caccad8bd6eeac3f034b3d773b94f0ec2d3cefa57eee5c4e0e8051056db8256e60f86ed4f8762660129808043ae288fa2ee124c11a0e4b0e05a138f40016d0243c9272d6807657473662887a86f2d3d95893faf9599938cee93bf6e025f737846f0f18b26b29f72ae8228e05344832a4280c3648b00adac11682c084762d240ca0a441d79172d04076b6f16dc4112025b2f3d24f22e087ce9fb6078ff7d33eefab1c96198800ea9fd3e910278dbe2055bb0f06fbe7f6198fed984eb397cb7f620faec18955bfd837bb3fd6cfe2877da9e3e373f978b8dced6d32f219dd8a0f04b9d7cd937cbd322f2703b9a3a1d0db128a1804c1060a4720d1050a8780b74576af228927101f71124a7c1a54d0662516994142b8c1026ffd30d8125a1bc4c512d71adff5aaf33ce4b0f6aff520c93f2e1acbe34bddd0250c2750872e16188c4acc9dc67709451ceb08905aca394c339dd0c022490060083544b181b863f82ed408270c8591a9e24aec2127fd0f78c8919d7e82873697e5a1782b6535e1918945a6630eb7c88e4b28bf5d487d28b05038e0beed086417a69f781a12b54e6cc94730c061a4e130a6be1d0062630b86d882cd47dfbf7dc260b9c2b3989393fb3cddb57f7fd1b890ada40118124e6cc2fc645412d76bfc70509250eac0704b12285098e972fd895d68587816a24143ecdaf0251fa6a30ab912468e01252d8467e3426624b1a4bd4aef924193f181f509db611fa3b1ca0c767a8fbd319b0bc24c43765c93c4b19094b16258217b40891be90820ea2bdd44f28d0143eea8c24964fa6ea0ec09e24a1c8a3612ae987b3ab10b809301c3e02ccce8735c05abf067f61367c3a7dcdd2ee05b7b6b7347e105ed2d6f8381b7913a08047149dc4840150f185318c63571872506314589d7400e35620f3814b509816320312a311d4afed49010313f894bdf8e74444b7676ef63f7ed77636465bf0cb77895b98365fa76cf48dcd1ec92b17a16169145a45d46bb5bc8a10143c4553c5e9897d29647614e49c82a28063571031385658d5c4f87a167410a81e4c74804a0b5f5bb16a270fb819daa629f5263589f8cc9b837b54beecfc07044615848380862772ddfae351406d22ead09770c92208a28d411cd29a1d0f46d52299f08f7040c872592fc3a2c74629735040ec021dec28fe453ab8b9db297946e76b16f77234dd1052d39b4118762c8901d589006866f43c30f2313863d8ec36883c36c03455cfb2e344932644814ba6ff74a62e70c49bcb111c7dc11fe9ffdf64bdb3634db401731644303d1ae0693112576af84c233080f36d0ae0d2c822db46b1d89406031a2be2be5746122e10114d61ae4a424d4d942a9c3d95ded73ebbe6f87f78e8fea82b40fed6c83f8b08421637e984b5dcdf06dc2a4ed8b45af4649d4e06458fb767703edb2f6a54dec4a9d34ae6132a8a1ebe924cc1a8543006a7e38aacff3cc9d0db25beb8f6d6174c2166c6315fccbc149c3f21b85a721176e09c79a1fe6a5e47938cc194c48d5da7ec31ada8506698f491d17891ef55ddca044f254a721d4337cdb01281cd64814c6073c52daffab49824ff188ed1d752ea9bb19be1d57c40db658d400d3612975514c8715b1738a45b7216101306d63a608953670ce90d4e16d42918b75e4420b724720ea6c90dd3521fdc87ed9dba5ff691a19563851fabb0605b4947f282c4ccce10651c72221a2f2370cbd0d4922ddb7870c73cf50f211781a4948456866c1d031300f1ae23a1a7449fdd1daa7c012f9a0c3d3937a55b0be1cee0fb91f4a5c743684073aa2f5065344092d294c620e392a311fd67ee219d22e95fc1085f27acc60822dc8bd0d0a9d0d0418105bf20cc4118f3ec4fd145892e6b53140d28efd8fef8720ea692809743f7104098b068739c7c2db220075dff64c1c62e087c31a7308884b2a4451095d6862516f90941f54daff79e5b77bdb1be43a1bf2911f6c1f0b7eca0e098335baa05f1a024727765e41ea9890b20a8bbc42ee90233bd391eb58489425a4c11627918edcb844615c22bb2771a7c2d4db40ea0012461a54b113a3ca0fa3ed59bfb42bf95abccefbfaf3fe62f32a665afeded306ebb473fe8cee0d3a9b69b265d929df80e2add1e574907058135a03e86265a3f989d7b43a366c90a805e123866cc4308d344873155f0d958fb56efc30d310701a448b06824105dd588e13a8fa00af8c9e4e785cee7c79efc020b8dcbe7f126ca00b0102a84249b0c1615e233a2a913de248c54b63e0bba30a81c84021dc40e16c891be8d2ce43825518041ae112c78614d1c082e180fa67e3a3b60bcce167748f060bd8103e10a7639bbd4bc6f699307474c409c32032913ba810772c428725e1a30a865d0b834828fa133943f650e249e3db810693b82689b467a4de914b8d4aeaf502d3417956570364769730bedb4fdf7cc27f5293f17091f3f8214d947ff884ecaaad8bee07d1984a5ee5278811b517196d11c51bc98b900d2d48470cb95853f443638ef990111b313f717442bb3ae4230e05361018314c473592369f943b677c28af65d72e46e1afdadfae2749ce32233845b7d6256522b1514d6cbc21b6b39176200af312da7189695740b597d6d5fc24daa0b0de225bca8f6105c5a0243c30a0ed99504480b8430e01a2888f28a65d703e5e2767298f9b490257783c6cf0f8337b69a34526d7819f8097b2412ec7e720751a62f7380aa5cc4415a219f0c35a2080351476b718c00d09b141e888233b30218026b1871482684bc2ba813c667e12d798471a4e3c0d8b9c7e646f92846913f7749c3faaccede5f64022c377038dd001c5625492100acc871c0b474720aea56e85c398118a2a2c3c0b52cf80a22b881d59282c004c24fd79c277092509d448586b28cc3eb0219ef79dc6c6f0a43fd76f63bd2fc7c3dd1187b6a7113ea42819505fea48765e131e73e80616a151036d56421a3592b723bb3608cd39b23d0bd9234a386e901b9890460283018536d6ff621eced259bcba4b06427e47facede016c2eb8174b738a12bc91ba230eeb2db1bd2db41ddd4f624aa4bec4b14ec20145eea88461217c158f946d4838601020e687818925ac13684a598939d6fdf3b966eafdfb7dcc8c77e85da297d8183eedf31bb371fc943fc791596aaff203bdf365f7af53b231bb6cae801d09088615e69e50ffc480e3d03188cd38e49146547eaeb27f4d28ed7e2e757fc782006a18785b4cb1da9f40c2d9223bd0890dc1595c1c8fb4e9fd3e27345ee1c4d28ef68b8f62fee537c787dc78321eae30e82c53e333313d873cd7d37e834bc6d08140e024a628443509a5fd1c59880706b14b8a42ac9344da8fb8c1029b080c2b14465bdf751ac9df502875616f2bf9801f4af9e0019c0cd9f9b8ffd37bf9d8185228861c8f9176223e45d2dd62ca3a4f5397d59fc94525dc02eff8e48ccbf104c4fd246658d45bdf0d84ca61b1b145dc9862ca4a421d1d85238a93c0c0a230a11b35c4751a69abe284d4924760e06ca0ddd5a54e8269d160e17c204fc853c6f5d77108ffe99c1f9d70d8a0c43155ac894b6a48bb96b4cda54d8468dda0b0d021ed0ae40616741d89731b620f18b4a3ad2f6d2dbbd6110f040aa5ed103530accfdae66d7bf992658758f4776cf58ff06816d3c90d5ae07bfdfb642cf5e69371af17cdd58192460596ff5924199638890014bd0a87502734d37cbb30d5de2a8d19b2198334b23077b698c30d49462502c10671ace1b00b94af30094c7856a77d532780e7099a67809577e3c522937851e9623afe8cbd4a740c4a31499cd594b30683ce7ab737797a6fb6b9188e0ae2a21287ac246166401ad7301c52e27a264a3c81956dea6850a818900da601f05db8f1931123b66390b0bb853c30556e87703630ec71049c8f7c883c4f2c9abbf29b4fc6c0accff3d2776b87a85c895ddd8575ce3acb14e4b3e75c8f5d8ec6c7b8bf8b8f7f676dc2cbf9a0a01b19240c040e8b0d0452371f721c4243ea03883b26e1d1164adb39c106e6d842529fa2a39a70b841a1d7e0306808851a0c039db8835af1a3b339e99fca87395d5f27614fe76bee1ce511b80331799b8f70a8d3f2811e7c325fee347f72f40bda51c0b78725a26505292b7dbb6888ca8f0a246d68108c281458437c54928430df96bc2b30fc44d25b5c4bbb89d87189a46dd5c6736e49f8c9bcd977f23532c0d69ff1bbbe59dbd376c5165d4e766e90dd6d08cd80e4d3382c2c1c7a00da81c054c56135882326f55d44338bd81ef05d52223eac201d5262e714f14149ecda8422d890d031fc24f828f6e1252effc761302cb1dab7653551fb989e4076c9551c11451c51acc13032a1884b5fd59e2874c4094722db4a1d0386bd1a27238ec5886131aa544c57e2fc020c5abbea7f021c900b35687b966f4b59836a698b630037d04535e201f0c3c2f0edbac1dcd1a13da448601df1ff1f7b7fdb9cb88ebd8bc35fe554de9e9e1d5bc6e966579d17808d6312c91be207a4a9a9296c13dbb2044c8060ebd47cf7bb2443421242e89e3decdf7dfebce80e36b2b1a5a5f5205deb5a7685b8ad41bfacb15f9a9e3f28608428894625f4dda37e54c3f9267df6ad1fb58fc5aff539fe6fc4a0eff30dff27f4bb9f1644610910235cfaa6a4244ed0227408908cf165dc2f4a014526ed50816962403f2d21080c4c554eae8ce7a56c1a508e21cdea93e56f3cca93c37932e7d5eb34cfa14f0a12615361f6fc51499c5181a201237e506151b6bc281044c6e3be0b908f4d0c0685ca058fb08e29dc40002bcf1a3108462514a8c451f0553cf33ee7ee2ff745080f0b14c11a8abc843465900fb8e78f38e1234e2cd7c074402165f21d39726ce927cab927307701b25c038a4c933e39f10705a1b609fd121cf7455e732d7e2257f774df64a7df7ec16789a3503e437d98b74a5f4ec623e65a0acb0ef6dbbcc9117fbbefb09a48bd7058dfacc918697bb98e4b1c9db4ded29ac8673e283be7dc1f1b5028fa05e24303294cf18022802be8c31a5ac30d94f1ad1368d0879aa77473a742bcc9c143968ce5728a2c58413ea09e856b14f539f2bbc7b92f664c2351bb26ce493c7d1ff1c87ffdbebe0e2d5b4394300c600bfb7043ac7e09816b100e4d485d1353bb86dc95faafa570d93e2b3ddfad61d3b72d628d0a1c497f2810524f79967d942f29bd65721eeaf17fb07f4f40a8299e36a7bdfa2467af42e7c31db70887020357235659111a084c830df4031df311257c28fb0a605ffae532feb54d441985bccf3c2b303db54f0b7524820d0688e208eb84a3e3b8e3036bfaef73cef0182d4e90c9f961dcb6bb46e75b1bd0893f3420cd39b1ec1a5965859c7e0969c83c5feaf9618522db84025758fa5f91ec25774328967dae4b5f1cd34e8bd0529772a870793e3cbe2772300f8aacd35fe2783d9cb7fe86ff50d9fc7c85c79d77ba55e58d3f4fc08bddd8f278bde11295b24ef772a75e8eefa397df3e414fe77902f222e16de3f07a48794e5d5d22d0e7c41fe5c87237c4479cf889e9f9d8c07e67e359650b0358113a2a314da9e7d89aa764000aecbba6ca237406251224577ac7923e6247fbc2e76bf674fef2bd2c522a2c988cb5286eb8719dc0f47c57c382e458040602410bd244277ec810577c163a8a4605a2d20fb201165857b83247fa39b6801c1e8bdff59833b5567d3f468c009dc533c5f3f37c4abc3071c23a8e98761ff58bc9413c87bd867e76beb52ae1d6522e889f189e1f00e2bb358964ec1d6ca0903e406062bfcba1ef1ad246119a72e8a8f50f8e7d54780ee19843038a6e8900293080fa71fec453b142f973628c9ae34f62aa33ee8d502460850562d0efe8d01a512c72462ca8634018e4b8228e94b7b246624421180a14911c5919203e6af23ce81010da019e1372088216a2c931197bb39f84c7233ae9eff9d4b37411f3fe66f2d051f18477c21ed3567f1eb64de7f48f68ca3c079a388206b2520669a623cb059ecf72cf0f2ae4db068e6c13fbd8445698131a6c1047258c704dfc7e817cc56d00b0b00d4ca5d5b28faf097cc0c7bfb54d93f1e8199fda7f5bceddc3f935e7cbb32014e59e9516486140a14164bc26e731772bb52e69c116e278033916caff896cd373ec5af1464b5fc02154ed1b80118352b6a3007c9563f2667ff9d05e657dc6dc473ee2d0ea688a55cf0f360a270da04034d3a1d3cf7164eb5ed42f913fa058241b627599e7776a64210a01349080865a0fb0604d1cf91951e41ce5c0a8d288d149adb36436784e4ed1f3d1688d0fea77f79cfb441af4f31c3a3620bc5f78965b212bd1e5ac414ec815d61e400d4570a372d4c4b0261161d042a567c9f8232fa180bac21201b785fc2ec300b77e662f338dcc85e2fc79d0659fecf81c5e6d68643e275ccf6387dd60e9ef8153b831f6f8ae0fe3b0ce98539ad5c8ca3414d91bcc714bfacb9edfd120852d2832cd8bdc0d5439a3b0863ea3cdf9c4803ce4180c752c08f7fc04204e72e4b82d18f519a147fd8f3c953a0b909dffaaf89c54eee4897d9718a33c9e1dc43b56f7b43c630e805d413a62246a38aebdc86d41bfdc203f681107d790863971b04114eea0cf310836c44a3428caca8b029d58a450eb51be2ba03f625884ecb8ef7100cff1e53c6e834fea779c15d38de9a050f86c2ee52564d04f74642582c8388f072a6f4af1b759dd125a8106e97003855b619a69d207865650c96b080f04167d06a51e38caeb77aa9fc63618b4d784b3d927bc10e79b8b5ccaca804b9d4722c43c3fd9787ec744566040609b84ba1aa10a07aa118a750cfa325e323d27a8094d73e55f88be8c847562653a042427d6513fed0d6770c34d336272fcf7e2cb037c355b1f4eeafd13d667b63ecac1bca5f3ad2b0c4a62b93ab420809694ab6e49fcac85fd6e4e380658da5eaba3433f001040807c1b10ab5b10194fd20c40919950facccea0f0a2114302d64840f0458cf944c683358936026e311b87f990cec7a98844b04102d748712d285e440123b8c1dcae8995d558716be514fb841267907b3e6c413ee02ac672861b8579f13b3aa25d0aad0040ab6c9163b88937bebebbf676dcb080adf1b8bbb88f06fa24aaca13d6a63ed681f8cbe7ab6dc268d8f22c198b6380002a11ed00cc5d5dfaff58da54519a0a27e9f773e8db3ae110785659a148e934a99b379e636b88072614b6e9455f61cede71f31ef21fcec993cb553e704e2c57280cb3c2f4271be8e026bfd5cf34e48ca867c11a47a30272199fbb1b445901f9887bbedd2274a82385e1b65b58ce3d0b7fd5074ab71f9e4be519f7e89296178d72c487260458da2ad0f021da0692f65e0402d2418e9ca18138dc4091016885398ca090632de5040185c993b2937bd2d7155fbf7bcc578cf474e537dd477a7e382e0ece19171b84bb26a6b085236c428a379e656bd0715b88cbd858eadc51e14552d3aafc4865dfb13f6c216758910895c84a4c140d720c5cc58be339587ca15b97d2768d81d42d9fd89673e6438aacf6ac6c23e73f7108477c58a1089ac892b1feb092c79e854de8b806a48906793f47c095f250604a4a62118645b981a2cb31c71b04c2e2683e2440cf89134a7d589fc27da538b90ee84bd46b55675d3f895c13f301431c6a080c75181195cf827d5678fe50f77cac7bfe10603aa2c81a56c81ae4986686e70f28f23b5bdc49b621d28e73698355defb9f99efb04c66c10a833e9d3807f38cab73da6b287d5d3ae230ea975287c208e5d0095ad8ef33e8f4a98c7b214514ab9cc800101a6888120a39d4918095176180fd903679363983c0adbe5adf3ca05fbe96af266e7e5471dde13db833da24c2310f996761811c19730d75e9fb794e9f623ad43c273048d4cf3145322633a40f882c55934c27d6a8f42219bbc9be8215a19d8a489be50fbfd0cb7a9e3a68fe79feecf9d6c411201c8b90221f0acf9271e9502316624d2e870bbc88e49e13e6500455537f6868c87f58483f7058130703c54f68c18d17852574eccd57eb6b2fd884033c8de7f547dc0af14189acb4f422697f4b0d8a9041d131b1085ac8c226e1d2072e2b2c0625748615e6b689784815af8b65eb90db3a8e821ad38e06456610077e35f68af7f913ccd0196ba80c72e997238098ca1f144945fc8ec03ea35e04376abd5fc632feb082a0cf3cdfd5311f9a48308a459a232710d0194a1b26fdb35ce548395fcafd22e6ec660cda2d193b7e6263cec8f76a9b900695e704a6e7c04dc349440a2c08f57c85e76be1684431b0d57e07f603412c9237bc4625204ed05239c1a29b434beadc1143cef1ba0d5b7ee9e5070cdf973af330de1315adfa9c6bac382225a284a3c8356134e090db02735835eb075d06a5ed88c21247b04254c686238a44c7408ae33bd1919fe9880e5b380a5a0d7f14d44eb3c90d3603bee2a93ee47fecf6d43fc963d8eea7b75f79d6f98a25dc64b105eb833c6c1ff849db3b5ef8f5de3ac87e5da5fdf58f5aeaf1afd7945eeb361dd009e09cb6004744fa06a6178505a4a444161490624df1055ac31652f8d501857ec8b0da83261c5a79092db84156a04367a8e3c8ae08c515947a537e7f344f823defd5217b9757f6e3b4be330ef01c9f799d84341c572d2463155587c4ad8935caa1c84bec6706b43281392989331438821a16b6803e14c8094bc54baa6a1b0e1896f180b4c1fe503bba4ef299dcf250dbe17b776b265b8cdf2e1fd248c4e0110ab7e1a8fcdabf6de4fcf0da893823ce4778be0da0e896d01f1488661b680d7295a34b43e639d8446228a08535248626a258477e37272abfa14f11cd5a8893c2b3ca0a3ab0f2fc00784eff449cd45bbdb3af1bdef471dd3a8523749d46fa2336bafa81dc9deadcdcbad00a34cf671c8a4447141b50ea6c3f6b35bce532be1c6ad207423e915e7293270986005a898169a9ea62239a9684da0046d8409414f068bc90b384eb8bb4a7e79897bb9ca713d7dedb1b3ceeebe4412f4934d00ff0df3578e3f3c5a700d251ee5950830e149e032b4cb386e7ca2a379e95b4101d94d81f15d81f0ae277548d021ce10da452bf4240fc60e3452e4074a870db100cf52fd631ded7ce3a84a9a9ceb93faf30b362a8e1086e206525a16e4d1c9423eab69a7dd791aaadee35b9f72de2c38d6785d22700589486aaaf69a5b29f7248d35cd996a3398faf7b7abb9c390c568f6a1e1eaa2fd66fbfe0f0be989b87af3bccfb70462e799223601b9ee5aa3d0585e71258101e00cfef188443955b8f68a9c9b1801c6b5e44180241adea975a8926650faafa57a5a9b88e8ed724d871076e71249d97bacbeffa7d3b6fb739f74ebb353690990094c7cea7b5467fbe9ec1accbe45c8e67c3d56b6dea0336bf9071f339f96b469c58014056bf84968c7db0cabf8760a4d6ea080f6acf774d4fd59d7275b5c60b10250e363cab3420706be4200e856d34fa16d65f71babdabdbf509af9d7bc6fa2c65e559b609556e6d6042df36891554c4ef5262b9b5aac5690d4de28c98e7db1554b508073912b6010536958d01d05479cf026f3c0b95f03836e57d1ec3229e8da42f94c7bd8e5ac785a7f8dcef6b3efdd57c041ccaf8c8c40056d0c21b64f529b2ba39b2646c3aac71840dece30af950f1923498455c7b9694319243306c61116848b82d68118573c1c7f9cd8ff5e36b4df32f62d277f228df4f23e3c11a1fce753db36ca282f82e40a2b381a2b3c13c00c462a5aaf747654c0a6be8cb98dd36a11318c80f0b95230e6c03fbfd42caaabc0ed240870a8b37c8517494f7e54fcbb3fba97e553afa7c35c8919553cf0f36d08735f2b3265fc10a74c4152eb944a25f222b2ca0b04d68b926a18302095b877e5eaaba8c1c51483b2de2db00d3618d2c1790f3d4f63a9c03f5490ec819b9e76be4a745c33d18e650c62c346941df36a005652cd3d80b9a550d8e8015c4090b4c4bd5e7c84225e6a8841471c4651cd4cd9148bee23738bd2f8a33d675e6230a9da022d4d5bd089a90da06025040c7d6b0602554fc0f43a0f2631d5b201fb7307575240280fdd2507684c21a03dc22dc6eea33595fe43136b66057e7f053ae8773e503619a19d091fadcd661e40242071cd352a8ba5e2a875ad5376911dad189d5a989aa790d0d555fcf1f71cfca6ac4fbb9b2198271e8675fe5366c925bbc8a1da6113f3bc0cda364a03a2367728e45a261853b513cd125a47d8e2c572734d1217581f47121b55b9e05018a8606a63927b49f138e0de4c016e481867c5b201a5452763ceb4bcee037bafb3ecaf34feadfe9f7d436cf381f0a42bb1459798145bff4e43b8930277e482140a567f51914490df948bd3fe6887b563f87a26322daa991d501c8ea9690ba82d040ed6510ffcbf9f026e733e6a1489db0fc444f9ed1471a50cfcaaa2687d705aade8de85255e3c7ea3264a539a1650b595d4668a6413f13080ca8e767959c0350da2527a83c0bb7301f6e9a7acc5fe027dedb9ec37e627d465c1a57ba01f43912aee95984c2c8d63d3f3320253971a0e94959a181e95943c3f307aa2f080d19f1c31c4bbb4d3ba6e25a898216b41269638e629cf730cdad89caeffdcab7eeeb93083ddd47619df0f6e13e2bce193fdb15b13a4d0d2c695bb95de3c8d5a13360aa467d1400246c0dd2cc24ced0c060c490c819e6d2e6740ce40c2852fc4289c2514267c489dff9426eb635100fcbcb19f50714c4ea168aeb391a51c8470c73ac432ba59e35947a8341c5c1a7b84a288cf006d1a1a6f8b61d52121e2a7e12cfc12696fa45da56ff2846f4a30ffc95afcbfbeb033c680d9fe1f9d69701f649017d6c78d15053dc2dcea090fa128b6c03c5b0f6a27e0efdcc40965a63d1a1a36a4502286c21fb8df899493814c82705f2871ab13ae2d8bc7a9387fc71ff43d5b81b0334c7119ae39d9f2bdbefad67bdb6cbe909feeffb7b1eced738638d5ba46ac10c5bc8c7d2afa59e9f0824dc0de203a9df74ccb140b41448b6a11890a85f22d0cf1165321e2b881fe838926da46f580a6475bea857da05f751b5489da0858ac37d7a621f2a2ea34ffc8333d6c6eb16c40974484b40386c79326e751023d4aeb14f4a68a1923888626103c81143c0ad714438f28715a25d692f05148aaf47937a4de1ce8ee2e45396de0ef2988f9ee313f2c8b67d3bc707fd6af79c753828f6610515b7635a78fe20877e52417f50229fe5c41a9a9e0301a1594522e96b6201692090c000d37203450988054d12d906f6a1492c0ca08f8ef23bfcac5c9168f43cedb7c5748c288eaae55f5e7792261aa489f0a240830a73596ad01f9544fa1a5198a328d091c572c25d83c8fe047d8a445a203f333147058906cc53be389176c380fed020c7738d8bc978c463a73f4b4e597be2e14c3df7c7f510fdacf507ac8e81fd0c40a9a77cc6300d80e28ae7ca9ee8900f0a286dad3fa0d04a6aec6706e636f0ac40435cd5b391318c0ea9f443508ec510c0a373b03f8f1b6e813c018c7ec2f7b2ad5baf8b69646a787cca9a68c39b7b3f46663c1be5d3833619afe119eb5b103a3491705b6a4fd2c18270c4091dd6c8215c713a8140475cfa6c727e07158c464cc64b9e9f0918d906917622927335102aff4f6426fea2be45c24311830adc47e839e607eb271967ad1de3ab9a6ac2f34725a49d16e2c30df43b3a92bade1f15c847058c64ac1c08e8630d89c0800e2a1bcef38e408231c8610d235748fd87b9bd398ec9d8cb457f596bfbb97c50f59e0e7a7c959fbf3c37b4820acf1a48fd5b200e4dc2dd1af979017d56209a524cf31cf32180006ea0a5fcc0dab364bcd8d1496457c8b735a4f0b2d2ff57d8eba3f52f1210aee43b9fa2fba7e38379d69b73d69241a25f42d1a98835ac3c1f95d082158e0625b11293a85c33243fd7d0b781e7d826f2939a446a1f52874dff18381ae490421df3618bd00c7cb99ff516977e080f714e1fa154f3837629e2434114276f60424e18a284413e34bd081bd0ea32acb8b7ed16b10283587d0aa3a1c08adf17b6a0430a48bb058e6cc373d057b5ba04897470b08ee599eb71c0686890c83549846b2c6ce96f579edfa955ce3408742842eea9fae5fd02893cc76058237f54623fa988050d14c19a506c40da2d151faf35dc1cc582cc108bc7842585bec1e381683870bfb2511faff9abf53314590bfbfd9250578720a4d8efb4901f6c300fb9aa6b49a109a5ddf2530a45c7943a9bd061451cac432ae36adcc26050aa5c5707eb0a4bfa457de6a6a6f9673ac3aecfc75f35605824baaadbc2c31c833e536bb751a02191b488c54acf87b5e71086225b57352e6920207537d8cf742c468cf89d1a52577811a19e2ffdece371f3ae9efbaec6fc09fab5a9111fb6b7f585fe27f49b6b228a72044685e266f4c39c447d8a409f7a7e972131e2508cf2c62fc49567b92d4213933858a048fad6430d4641052dbbe54543e1591d8d58c3e3fdb6cfd72776fc51db75aa2d8e751a9d90533f432ce12336060b7190735df5253e638da6c4f4a2c0446044bd8894380a04e2b68e455e780eaea54c7a11624dfd1b526210d4d00a5a580406f64b417cbcf1142f9d6d12a9e3553de2f2589cb2489d76bef3b3a5eddeeeedaa7ef90979d4135e6d39ef0fafafa3b3f28c8425e1b68e80f49bf3d28b60452c1740c796711e536b8496bd810e06580c85943742cb0a5a88418b94c4ca0b64754c14d926a68302598812ff683ff2d818acc64658c74e536be7853f92332d06f60e5b64a6bbf5afadde3b4146e7f841ab3ea95b7fc61c8b9c220771ec271a8ca0ee59b0266a7f22e5387235a4ea5f86d2efa090f773e29735e2a3023a6e05152f6207785128fbb6c43464888e18f48fe2638ad8694b5fbd4823c25f79e53fabedf1b6965fd376b42040dac16d5c6974f3641cb27b194fccc2d929f23d71ec837d8f8a33cab3da172e4dcf0a39716c1d5a5905ad1147226821815b9eaff27a5a4dbdf721c03e619ea5787274629112fab60e05569c8cd02a2bc4490ebfca6f99a10501661ef7f4790cda4ff7e357fbf13f20f75a8751604021edf18822a74fa1030d0c50411c5b607f682267c4b1df11c451356b6b428740da18e8bb06a17883053621c035a2c316b2021d1faf65f7b29efd95bca8fc89c3b94067dc27c255b3fe226367db505c660a678e38b2ba25f1bb058a1043803048930aaa3d11566281381650facb1a066141a4efc35d81a9f4efbea831b68f8ffccb6bac1106a57f01a049fc9c430075ec8f7244494e2cac2b1e4d000de48c7295c3d0d4ddd4540e9c4005a121453c303cbfdc60ee6a90e20d72beda6b46cf18ac586a1df4e3c559f7da15576da023d1a9a08c7f695e229108686183f07e01e9b0469414886203f98823ae38ed75a54f6850215a022ce344a16abb70cfca4bc48fe2c53ec1d9eee36a7f9efb4e6174f9a8c09ff15516adea8cfbd50cfab620dc0584a292f81d03fb2a874053fead4f189691b69fa9fd46e4f729a69d96aa5f48a1497860608e72e22782d0cc201ccb58821fddaffe054ee0c418956993437f4807d5675d83b0a49f2565c90690661514c316a681f21ba0e84a1fc1247ea7c2b24fac4420e04a3dad130bb6080f4be484a58a156829200d73180d8ff2d91287090cb6bc00c5c1b5bb2dc6aee923e907249c8157ecddee3c5ba74e58c7bcbfdcedffbed4783ad4663cd0e3d948e5c26e653d4f80b6c28aef2c6527e1243f3ed3416e8bf3ad330ea867a539a25d55bf1aabbcb95141d4be7a504331d4554d3c3e6050b6a11d1d73ac13ab4b899f5548c818046a4810ae78ea80ab43273c2aefa7c4752ade78e343bf8d9f7f22f6d3c86dca70b18f17defef6e17ad8f55939d6fc9c633fe444d9ac6ee9f9790923c2b19f534ced0af99909a52ef2b1492c6c48ff90487d4e91f4ab6becf7a9178d0a64b91571a0b407d5f1bd98419e806035ed1de0c4ff0fc6621b1ffe2b01edf5ee9cf2a9fff3b1aad34f792d159eeb8c7c386ea5b87fa2410e0534a09528ee1f62f573e8bb26a25d8a235bf3543d1d54229a17c819565874d5ba08122183ce10a0c8ad491498c4b201165fe17214fefa60cd3d24ce972f8afd3ef31c54621e724c1313fb2c47910d50146c88e3b6301d1a9826350421f3a4cda4294500b7945d1009c0be6d2021fd5128a0df2d70e41eaf13770286fae7715e52a6741a83eaf9403dd266edfe8c186ae21046acccf422bc2191bb81000bb5e6e34080fd6e8ea34189699e23516a8a37260a04b230403eae08871b1c8d38f2470c5255df91a2081fcd4b7fe1241b87da24da9cd25ff3c918edf6d03ea92f7ace5a293650b5abacc0203430916f6b58a48c44ae467c399f3213fad04411c931ed1690931246430d5a522efb0c0968104bd57712509435f1193d5a7ffbcdfbeb8b78dc3da58e9a367198d487756cb8ab49a46f0ed499397bdf798e2d54fd6d076e081f70b556e3870c03bb82ce88116ed79e1fd4880f4ae9a741c7aea19cb76290633a149ee2a22539f409c7b49f43617fc18bf7a7e5406893db01c3d1681383f6018c89bdf67ae78c39871be4771992f2255089ac3e857e59412b2fa0185012d902521b20ab2320b04d68c9582210980e81da33b1a41d0874c5cfceb181409fe3c83e1673ede75f7fe95fa60e5b1df629dd35a4f88c79da79ee39a890b2a6b8cffca08242c50a1bc88715a258c60026a632ee96f112d43d0bd73892b16852a9bae8fea8803e1450042d42a171bcae287a8e67481b03b23e804d14a91c6367a030f2dbb5efadafb1b525aadf5efdc2a6cdce37341f9bf75bfe728cfbfefe873994ce89c30b0ca5ffb89cf3b8821c15880f37c4519827030952608a0dec271b4461057960405a9a380a4b2446d4734625527bca6181a9dbf0ba1ef33b8fd4657ad7373b9df9b37dfa99ae6df261ce57eb83491f07f3a022d188e36808a0e51aaabe2e0d34cfef53424714cb3e95bea19f34fc80bcaff8bd91c85a58104e685e6010969e450acf21c7711bff591d3d0d476689f95e9dac53f572649a9fad03c2b3ae9b8705f2dd1a3a7883a24181c088218085aa4d24520a2dac13dfae3c9f1550d806a4d8449c30c847851761138b51e939fdd2937e441418c88102594739915ede7d0cf6d60dbe96d7f5744c18d6db5fe88173d66c1fe5488c4aeca70c4a7f9e8e3812a58eb95b119ae79e95322c869b868b84e5d07275550b941286fc0e80b45b4219c744a312f151813956f5458ef743fb6912fdf88c03e78cf11c36a085728519f58726f6cb0df46185a96b36b9168421e06ea060aa268367651a8ea41c295bb5210ea198071be4130e694e89956dbce3b5658ba91a934ec35f7abcfed22236087be574eadf4cc3b6b463dae4850b6a6fdd95eb2c8ed07cc7d315bfd6e65bc93e48a391f8b2ae5e9343ba8df3d9ac5917cb9f63b05ced8dc1819a4ebf620f950c1cafc3783e9d5d103fab91e5b63cbfcf2177a5afc6087501f6072552f5603abaf445b01850e4071a5635645c41fca189ac9c61b54e3304c492312f04c82acd5fa8c9b5578bb15deffce40f354cb7fe4d0c76f566de72036cf305b2ad4f51bfadb575c2d8dc4a3f49d5b43f6c4bcfea47b29c3861e139d04462a8793eac54bd59cb6d617f5823a07479817c2c889f72a23080fd82d0d24496dd52356ca3a149543c536a9866e6719eaac3fbce7b9c6aa7d4a5dcab59b6ab21fd65ac5de3082d629eecc6fe2faf3d857dc609b53542cb968cf914a7bac528a2aee639f606524461046bc2ed0a593206c2b5e7638dc8eba22140a05f40ca2872028d38b686fd8e7edc877fc7fd7d820f72a836dc61bb72c658db4f4b68953a8e820a45418dac30875660609133cf1aea309231352b2008198c828a50dc223e2bb03f2890430a2c636bab9b6311c818bc0545c8bf582b7bcb0d626db9400ed4d3fbb23f9bf72de31954329e3a07ed74e59d338f56f1330e0da8f8e6bb25a2798ed5fcee9750ce7d1eb420c7ad86c73603c492df8585e72bec09802af7be9f93c8ae31cd5a90da3a3e8ef3c9a50f8c6b5df6dd62872bf9a40e258b67e1ea3eea0b695fe22d7e7abf7ee2ce9e13c7dc61b09678bc30c706d2f078b438c0dba872b65eb81aa3fe32be7df50552275f24609babfa5eb7cbefc78393d6a9de8cf53687e0137cea99c75b6115744fd5664b9aba288eab4360d73246c554e5e0d59e9fb408ef734c19f3a2a0a5ea6ad1bc80519f122bd1210873e8e725a15d4aa2a37ed9ebbe766333379f8d61e2a0e798930539ee973dbf7c7f3bd0ef23944b1df192e73246cff12d5ea9ba2c2ffe969ec74ef5caf3f976ed753bee8ddfbcfd7eebe78cd649ade6be769a6d7fa947fb9773f9795662128a4d6861cdf3073902a8547353d55a421cf9a58e29dea89abd1c51c21bfc8f170d28e6c38a50b88156a742749013c5a9e86ed017b9321fea5d1dae5d78be1884870cd3bc20bebbf1a24101236822ee1a58281e1143d50bb55c40fc8e46224471840ae8840c4701c0b46c4127104871a0261a521c2c1d43e57a7f2eeb4dbd42273c854bf3681db04fd6b0ce982b3ed4911598d02a1b1eecc836151e5171bc6602f21153b9ba4e58105ffa8403861c68127f944311e8c851ebda25f4738ea2a08514cefda85d785df3f899befb5887f4c0dc4bce1aef6019b72bac4a00701408ec871cfb9941a2b04411299015543822dc53b16d604030ac112d35cf1fd6c41f6e903f14380a360a17e0338a44f955ada0bdfec81787f3e7cf99cbedb6304085670d4a44fbdcb3ba39a258a8fa7a1136142642e5ab910245b60ea34040616bc422391610a0c8dd7816165e847548610b015740f0654d0f3de107f8b08af372ff623fd820008567a102f2a180c0d5150f40a46a7854c44f0ce293028a4c10cbd63dc7ad8963ebc4b7b52677ca6d4130e2241ac968a9447ed23a5e738148ddf128fd922d1f22232fb5a2551dc6e5a1da8489237548b84e7bfa1673ae62d2af6ddc473cd5e1facfe7acf9cd434a1c947b5296685961006b4cf312036c10076e201dea101046fcc484915d7b569743916810a0025ae50645b8e5596eadf254282a64db2f64ada9897e184fbeb933d23c01e52a01669edca2796c0ca5bfcf52ce582aceb70fd1f04b8e3814ae8e7c29538822dea798062df9ce90db0272db803ca83d47c69db885c588423f933258121e3212f573a9a71018b6544dfe2f72f852d017b1b2ff664940b8fe0473689caf6ecca044fe8811bfafb070aa2e314d5a9ea5f2d95b44ad6d0c3788328e455fc68e1c71bbf21c9423abaca19500c249e1f95d8a140f7a692240ca5fa8a92f6566751f0de478cd48d4daedd79cb07ef11e0ba72b3ca7d4077f7dffba025328082539b4b0891ce9218439f251e9f9a352fa5f9087258ca0c07e9e2307b6101f959e0f01a6b690fd0d1dbb42514891636bd22e787ee7785d9e59b84a9cfe323e314e383dd7e910ee501713a75f939330301faeddee1b7d527b5a9c8f97005a590bfad8c4c006d01f0ae8485b1c48fbd3820a47e46a9e9fe8900615129d0df1d3024618103e346184a8170d752f7237c8218517b995e70c4a7414a3f0a67f3f93fd5562849bc469d7e9297b92ef74cb0b3fdb18e9c96df739395cd7b5bea7c9196b880c18a4ae06fd40839c700886aaf6268cb04efc016dea75754c4ca121fd212432401c697f820a8b40f314877aa6f22f08ed98d257f27e9663e9339ed1e2501f0ea42cb3980fff1bf2ff72ed5f3f2e43434ab3672500d39c433f97f18ba170761c7164b102d190a9356f95ff0f75e4a87aec15a29d0d04a4407e58624e4a48c30259a342d5cd3ede1f0be28452e71ee6a8561cb8f07cfe80b08167959a8af99d91e2512456b64116967246a14f7264915c616f22423d4bc678b0f6a2907bd148fa1214f23e55b591149ec935bedc8fdcd544f8cbf96b6cd0e484aa7a1aa6aa19a7b06e5043be5d23112a4e6a2ca42c0c6b5587c31a50a8b8961340281458043a543591ca8de7775a087c516ff365efeef01e9c77b698d4d5b1c88427655d8c38064303fb65cbf3839af8810985ab4169b3adce064703e6f9d0f47cd740163610ed332832802c5b8356584269cfad2e47967d740feeb5466b093c0baf1207aee439e2b48da4d667f12c78b7bfa9b73c8b3c223afca4ed97ba67779f228dd8f2700c7c4eac8a5b130b4abf86a9dc3131ca31b035244a03ab3a10a4803e6244da658a01f14989a85d23853bef5224e35fbf9b139ad59e2f7d536c7ad1807e15976cf9f457131fb750a16f70adcb73656ca4e23e4ad7e927f52ecfcbe78a0aa96f108500d28e06954d6485aa09e18794f81d01296384631d59a18c630acc5d811c2c300f365ea4987f0ac4fb85e29f00ee57eb232ffdf2f99eb8bd46e7930d033a21451c314fd5f0b475cfb27518a19cf82143116c293b14d92de29706917ac8811a9676c8776b856506b68062c420400c452306fde4386fe7cfd7a679e9b3a99581b1c0dafdb84befc7729e8d9e5303ae0830f54f72a4ce884f4a2a19bfca58aea9bd101858f465bc478935e098ba35e1b6417c19930c018cfacc7302cd73480e39ca91600c8b618da586f74b017dbb05c1d7767d5bbffc3027d6f9f836643c2ae32926637a18418df0a082910b20b54d4fc65b51a04301018c424e7c52202bcfa1afeae1b7549e91c518513931a3120b9263004fd2eb3f23476f6a4c7d928378ce756d2f428cf0b090efef59a5e28025ce101027d03dab2fed9fd1701f653a523efb504356666230e28476048a20807e6660e00208c85775000ed4809b1fb2572afeb9fa76b5983c4d67ababdfffefd51f6576f5fbd5d5b72b34e153f9e9dffffe7655ce26abe279fa5b3a7dbe2e677f5bb07556ccfef6b89e25bf5fafa67cc126abe9f2fa69bd5c5de7abd5e2ba3779cae6bfade69cc95b16b3c7b9fc9b4e5793822de5c75973f3bd76dfae9685985efdaeb76ebe5df1793abdfabd0534f5f19fab42b5061ad0ffa6eb7fd3355f6fff6eb47ed75bbf81ef6dedfbcdf71ffadf34f3774dbbfa76552cff99164f57bf3f4ed872faed6a59ab1fb4a6cf57bfdfb44cddfc76e5cee657bfeb46eb46377eb4be7fbb42ac989557bfebdfaea0fa5dc3d07ffcf8761514e9d5efbaa6e9dfae9cd78fe37ffe733149b5abdfb56f57a354de55fb76f5f0fae85d56362fd2d2daea709e94cbabdf7f7cbbeaac0a2e1fe5619a5cfdaedf1837665bfb61b6be5da1a53cd36ecbe7d1befff8f7b72b78bce9cb4bfffbdb55eff4a6e37ffe733d5b2fa7e9d5ef7fd7be69dfb47ffc5b0e6e3e7d523d243bedea3a9ff3e9359dceca62b6bcdecc9fcae562924caf93e27a2b047f9b1559be62f5df92e26f6f65e19d685ca7f36479f5edcae58bf9d3ea8fc92a7f2358db6fad79d29cf6274fd974d57c1ecde7db4f70b24af2abdf676bc6be5d3dac266cfa32b2ea68349d2ce7b3a6ad33ef176cbadcb56e7ef7e5d09a2e5e3efbd3e5ea5d6b79eadd15709eaee5effddfabedc37f3e0dd49316b3abdf574febe9b73fbf2fd5dbc179fa278f5036ff8dcf5375f370fab42c544feabfe9376ad62fd45bef54c2d197df8ee957cae0dfdfaed2c96a22673edbd3dd6f6aac113de64853bafaf3bacc8c384cdbabd9dbd493ca16f1fbb5a1f170916363b498f67483446e1303d7ee1d8e90361967ab6436dc7206b9770aaff1d69f60f18c3ccaf30484f51e274ee566f3fff3e7ebcd3f9ee6c963d1c8dce75af3a5d54e6782f65955e68f3f4f65ca27bf68cc8bc6bc68cc836ae0555fa6202cbca2f39c82763d3190d49dec1e0c1671d1e66964528543f8afe8a491ddb1a0fd1b4f8f2ba5d7662f9e5c5b33ceaa97da7fa22ba79efda2992e9ae9a2990e2b8357d5e4d6dd87748c34d7ce83b0dfc946b3702d5dae18b4ee7a2c65b1839ee328c852e747368dda7a5274d7649c6481da4ee8beaaafa2fb0a797ee8061327c8306f2f6227ac13a7ca5327b88b405fb66d8d1ff2bd6d8ae6dcfd6c20eeeb3253343ab7882533c292a2bb48eaee22ce1631be4535aedb2b1cb1b56c8bfbdafcbe688b84c3e738ea2fe2c2ac93ba5cbb36d30606cc149c93b3593a1e30d2eb6ab1bccf8c3c4f807c979cb94eb7d9f6703a77e4f59db349d4ca22d055f79da834d58a25f2dea09bdef55acf8931a0f720cf633e5a92b1bb4e6670e13a6cedde0e5862749fe31962eeede8d97506cfa993dd8db43070e57d7adda1afa340b51b872c3146e2bee892d808b204e4cf695495ee6d574f7b5d3336c2da75462c01ac26d130c33c9ce33159c4869b4d22534ca211ebcd46733c1e66d869967af09bb168650f512bc3a02fc883bc5f90c53cdcf5038d81c92751aa273cb84b407b451eba0a06abb694c63023bc5dbbb7ec391dbbd95edf2cd5b9872ec5512b23ce0fd98f79daeb2ee2a2abc9f18ec0febdc3cc755ec381f143b6be37d4186edb24aaefeeb3f95da8c6a3bf497a5d6312554bd7095b89d396cfaed2cdc9835a5adac480add35b78d3cbe699db9b67b8d7cedcfea89e44e94c861aeeed684e1eba59b39493bff9fdfb5e97cbfe2311d3264e58bb76da0f7bdde7a4d88e8ba3b3d4c99fc92dbc737b9d7fb94ee779e284797c3b9adf1b2ae57d11f35024a09335cf1baec96df77912999aeb10799fdcbddd6b5777e724ea2f5327cbb6e9ca1fef0baa45cac3351923817bcd9c91e14fe2b417f16cd88c836367b1c300894c961830db5deb3acd32552f5b28198aa3bee9de86b2cff278566631c05b39ef031cb1258e064bf2d08db7a1d3dd2b6d234aef9cd725c6edf7726c9e89d3a649fd63d1c833d163872c6267d3dc774f8e5da7afc9be8f0dc47afcb55f92ba75d72b2075ed114b79b88c8dee8a44a6d6cb16c1c461c255ff6c2963cbf8b6cc12102e49a14bf9d0e43c57b23fee6e6287d12dcc75e9dea2e7b77218021255cf49afbb487bdd3cd92c94bca7a0adc7ce30c39169ba4ebb19f3be5afefb784f275813f9acbc9be15bd9af95fc1d9a70b6493b0b8ac783595c779b65b7d7638d8c91d6e3284f78faecde0ef4385b64d8e9dcf5caf61a83204b66e13ae66c4dea6d9fedc963f3ee6fc6264f7b9d1f6ae9d2927ab17ac6a0bf9c386d915af316b4b2cd1f45378ff9f0aeb957ce705469935e77bbc40b333c1e30351656a5f4ab1ccfd869531c55726c348f661bcffa44ae454bf655d9a3275ebb27bb7f14ad2c747e6481ddf6c35eb7c4e351ae64a6998f7b7a6973871fbaaa54e2643c32dd5ba4639065780c33ec203de155e63a7a3e7de816e4a1ab27202cbd6c7e879daed2e709682fc97041554a454f2fdd5efadde5398b9dead9a56a89f439e155e9ceb499dbdfc8f9b67ae8a54a9ea4dcdd8f4766e204374ad738d502837ea31b1a2ae2ed35dd63efaf9ea597cda95b776d32ee2e6383ed643a4c4090e1668cb366cea0e77836ca2772ee7276d3e862a9dbdffd7eafbb49a3c172324673d7615a73ad9ded2d69dfa9141469139cea79fab095f5ba9bbbf66a2de538e5411680b04e39a3e441e9e4e6b7ec958e7958c73c54298e18547a628c5842e79fc9bb1aafd7dfeaacf66948ff88468a723129cc455cfff81105ed3060edee50437f848119fcb19b03ec758ec64097cfab6c04ee697be9ab2c739df666eb3f14d387ae20e391a6d2a3b6ba7cc4426fa8b71f46413a08f4d1431475ee486482c978f01c739d493d99f27e3d89fa45ec046bd756b676418ac6ee491d4a40a8dd2bbb1acca4fec23cc892dbc1733cee6a241aae1b7d1464b1116ac96d28f5791d032dc30f5d9146884a19973a6aafffc5c469f48bb2dd75f36e6138805b5b208fef9297f1d86429c81752d6a50fe53a288fe55c96bacc4959daeb8249646f65074afbc563d079ab97942ca1e7d809eeb011d671af53deedb7af3babb8eeea09df2c54fbcefceec1e98366feb5f25ef67ffe0be1e5f229391e58ca06bb90d27cd91b007aeb7beb474b6fe9ff415cd938f89f8595e0fb0fbdf5fde625a804bba052bff9f1fdfb2f0495e6e7db03da2721e54dfb25a46c7d6fe937fa0ff0ff4a48f93e9a3c252691472b19d91c8f35ffdca7dc86ad7fbffaedea1f2f716b233a6fc3d6a53cfa5fe974319da5d35952fffebfb26295afe3df9239bfcee67fcb8a95fc13178cd5d7cfe67e94fbf7ab8415d3d9eab76c7ef5ed2a99cf1e8bacf9fc281bd4cbd5946f8fb75dd01c2dca6c9a361f9fa68bf9b258cd9f8ae9f2dd99ba395ece9f56d37439ddfeca6e36be3d52d7fe632fe2febb7c9cd5b45a5d7dbb9a3e3dcd9f64a4ffc8e5e157af77f4fb6b3ee58fcbcf5ac93f9fdfa3f9f67ab99a3f4db2a9bcd3fca97edb984f9eca58e91ad9474f47bf94ff17b34cdee75dbb6295e453c672f9a352a8a4daf87695cd1765f65b31bbae279cfdf60ca44a99abffae8bf97a55b0ab6f57e58fe56fc5fc7ab228f824c98bd9f4a9963f234f5c3f4d97f3f55332bd3aa62eafe58d64ffcca6abebf593bce77c79d544f2d7522a54482f47399b560bf9613d535ab01968f967f554cc3279cdb25692acbefec76ef9e4ef57f1fa513d775cafa64b25777cf1345d2eaf63512cc0fe8947291afb2732512cf68f052be246725713f9b2d7ac58aeb6271ad9499eeac56afef2e17ad2fc647390148b5c0dd2f638ddff325d4e5e0fa6c9dbc31498a6defe70e2ba98ada64fb309bb9ea69bc953ba7cdf8cb162b12a92d733399fec1dbd5cfe3499a5db217dffd5721dafd42eccf60b9e9aaf07f2babda3a4b577b0ff02cb7ca2bf3902e6cd9b6353077bc7ef7e72c5f6faa932b5f6dba3eb45595472dece92795accb2bd8fd793e54cdf3f8e27cbe94debcd99623651d3eae54c368ff70ff3e9fecdafe95269e697e3859a4e9feb8c3f9ee6abf90c4e0a26a7d7f6b1e36295ac9f9ea7cb53da3e4d8ad9623e6727b49d4eaa135abd8cad9c12db61ffea9a79129fd26a319d2db2c5e92de504b92ea7f5e669f253573df1f9d34fb49f2669fe33cd5936e19393ba6577c56efc4fbde0650c262c9b3f15ab9cffcac5d324f9a5cb5e67caa9d72e2649393d45b477172c41f9b6f594174f8bc9b248aeb379babc7e51a2cba3cda4863da1c5f5e4e969526fd5f1e76d574fd3f773ee508bad52c8a7ef85f25de39df13a60be93c7ecd32fae97c964367b6faef71bace6e57476e4eb7af1fe357ec135c9a76c317dba4ef227e9509ed87a3167f563c1d87fe6f8bcb49a2f4f68f45145fda40bd5b89a5f347a3586d3e762d9f8df27b56fdc96634d176ccde30ff3edd366d7c924c9a727379eb3f7baf0f3c6d2a552b1e5a9ede74f7cb23aad03df5f94168f8f3f794956ac8a6c367ffad9e72bd26a8b15f9a9ab66e9b4fac96be631fd855f92daf3572e2b57ac989d7cd53ca6d3e4d399fcbef5426aef64ced4c32d7eedaaeb64b298c4052b56f52fde6059a4d3b8f1224fbafc69fafc51cb7fde5c064f9f29da8fad574f93d972d1c4153f77c17513d9fefc753f2315af5765c52ffc54be5a9d3cccaf57bda8b964cef9974af1c00d96d3a7e75f1882ebe5323f2d323e317e7e5d63f8e90baed3f9eaeb2e3f16a87f68ac5c87d7e0e3eba62768d3a6e14b70fe75533e7d2ad974f5547cd587ef9b9fde991fae3c45e91eb8682b848f4f13fed30f3b9ba71f05305e3f3e4ed8fc3a9f7eb436d9bc5153f1fab1f9f0b641c1d3c95331973f91bdfb8ac6d3d9543dcc764de0ba78d7a29c3e17b378fd544ea584fff39065fda9559d8fcfffbec54be7f1c96279ca12d149cb48531e4fd35f5c703adc6eb94ae7ef9fef93a5a9d716cbe95356c86fe5fc5093844f5649be50cb996f5a569399a8659fff6d926d55f59c4d66d96ff3a7ecbabade45db6cbe792c1ad573e0eb64b25c999f7d974f927c02b4cfbe9601ff6e81e678833d792fa62cfda4fdebaad0a16f3f2ee01c6a25dd79ddd03e7ba5e5a71db15ce6d7c7fa517effbacea04efe731197e9e391f6e56cbe99e5f36dc0b7df48cea9d745b60f5fbdbeabda6838d062f134afeaf75f2cebe5f5b49a2693f8c335f2ab57077fb69c3c4ef3e964ab46de375ccfd4fad3cb8269317bfced59db3fb3993ccd8a59b67c77fa7565359fa89e967fae27299b3e19bbb3d7c953d21cac540249c11b93a7febe38ffcdd1cb13abc3ad1968bea28ba99cd76f967e26eccda964b1de3f7ce4abed12ebcba9d974b57a9aa825dd9773f3a55afbd83fb598abf8706f75f1ed254fd347364d56ac58bd39bd2c66199b3eb222cbdffceab25e2613c6d4504d67cf87beda8ec0cbf9d574b962f3376ff76e10774bd92afcfc9525ed4f9ac9bbbcae061d6db59caebe6cf33c61453ad9ee069dd8f245699cb0ecde74126f16d9e59febb8c85e3faa07549fb72bbdbc597b977faef99aad8ac54489883af1aff57c354d174fc56c358995ca99a925233901b7cee7eea3fa6f274b2f277783b53d27a7fbcefcbedb1f983733b7f9b45eaa21dd6e157cdc3a50d2f66613417db85ed6b3955a307ddd54d87eba4e9abda5edd1eb62dd6aced572fa876fb65df8e1fcb25ebed9ab48e64a823fec5ac83fafb7dfcaf56e37e3dbd57a56244dd8befd74bd5e3dea376f8f7fa84329e657dfae9ea7b374fe74fd85a13aa1d59e8938d65afd915ae5d476bbb5f9638df74de691767963578eb4f8680d8f34fee28da528a6b3a5fcc7a7cb65a38e3f6bf822ecd95a4da62fdbed2cd5b186e03a97d1f39156453a9b7cf2b5b4588daa3ff4adf25997d364fd34bd8e8bb4785a7fda5baaa98ad71ee74ffc58a39d8cca1b9ed26e26eff78f77a8e7bf6f778cff2995fb76fff60d06faef6f149e548c8bd5d34e61c88ba46bfb8f0b4afa4f42492f9f92577c74833ffff35133db95c7df9e96c7f133afcd76289af60fed2c79190d80e64f4cb0550f7e49cab824655cd4cde7ca602f676c8c98eb6c13268c94613abf5179649bf9dd7dfde3d9ed0ff4b8e8d2748c3405567c4d78d8f2da2a80e8068f079aebb4f916509927b7dde52442bb360da8d9616bb2993fdfd73f143012835024754bfd4eaff8f17c5f77b780ed3d00b3e2a90c97a4d77d016cbb4e7f19f78e3e9302e16f1349f69347de3dd79bdfceb0d3555c17db632edf7b2f89618e0199794587c7e350736f9bbe7a01c3063b8ef0329b6edfd1ed7532d7a958daeb9698b54b55fb77ec667f3c7457d3b05de2225b786fda224e6a53019bef9c51310623556f35294c1a3bed3579c81677feb219975badf9eb2810a6bcc776bc467312b5f601a0ba020cbf4d5479938831d9b67fdb5747fb6693466e86c7c88c39cc086f6d9321b279f37d47bd4fc2c3ca2bba6e7a3bda043cacd22814696fd33ca77cdf5e77d72737bbfe1c397d0dfb958dcbedbbd3d6727bcf85dbd3feb76bab24820732469b1898823c74bfefffe6c3ed484bfaaf49321e5d78b1a600d22c9e0de777c3a6bf1f870bf50ef2d9f7fbe64e8e81986703aeeb69af6b90c8bdf1984a145a60105adba492857bab122de4f83e1331bf69c0b1f6dc2db7726084750330de5d1b1472ec3e8cb3bd4bf219ecee7de3f11123bcafc7b7c3f9dd43f9bd37d3eeb6fdde8d8b2e9b3afd55e2546c6fbeedcbf89eccf67773484b66215589180fad3b575f95643c58a43c980f41f51cf36031def647628cea3452895aef9f4bca7533aeb761e13a8a4bedc6ed232d69920fee1e87f3bba61e5bd72611c9d3a8da25adb83832cbd809ebe1b6af5ffb8fac5d67ff7d3bab3f8eb56fe4e68bef9b7f8aebc59f6781315263e1d1054f787b75d71b18b13158929ebb509c27bb6b6eb5bbdddfc7e17f234f566ae17c324bd9f4e94b9f6cafdd4bb6acd10267f4cafec41cfee6c92f6ed9c52dbbb8654714c27bbface1cff4e882bed886f2835efede9b3509798ac3a4df6e6cd6ace1e8f4e80291f1681e83e152d9d862f36a235562dd70f9c1a68eb5dd3d973190f688ad09fff1bd9749dbd91dc4e3ee92444d52cc47bf2115ca2602465d27672af953d98bbe98aa841fa9ef9b64d2bbdb014bfcf9c7e7d9d55b117395a8ebd1852d6de51f1f6dd2ffded98bad8f2112a7bd96fecece56bdd8e5d9f2c615edb65b6c945ff26a8b195749860fe66adb4fd206b5ff78e8eefaedc62b5512e7f75ef16a5b0ef8197f4cea6c71cf07cfe4b69c13deaee3a8afb90f59f1e084cbd8f9914d0d2d1f3bade2bed77d494e6df8c8ca4573ef6edb75c2e5fef3ab7fefc7c79fdff86039bf7b308b188ccc3b4771ede769cf9ebb6c34c791f994d4ddef8f0ffd242edcd7feac4dc5a173f750eedb39e90f50c29379ea48ff8ca53dae3f935e937828efb37d36e5472646b891fe9a57ccdf9c6f123af3c7ed787dc7bc5d4efdf9cd50fe7dd8642ae1b0b7c9d46fdc6adf9be4dace1bffebae5766f77eebcb317fe70b34f25e8ef2d4b16f3c6eb2b4ce3ff8071e5d943b9fe4aef7dadfbbe770f5d56efed4a935bf51cfd9dffa036f643765692f5bbc7b8625190f955cb996d6bca335bf09d53d5ee4fac6e3cdb5f7b3d1f3b8e1db7b4c5efc62150bbc8e791337483f7d23efb9f3af65fb3df991fee11a8fd37c321ebe914f3c46828c07da188495fb90abfbdccf54ed293d9172ba4b40a40b3f75fa5a3a46560c94aef9e3a12e8fdc2bfbe0670d4a25f3371e57096d5fc87ea74841bb8e9d6171f7502ef77fa7914939a73a6b253f0f723ef5c5d8183052c87e0bd7a931c8935eb6d8bfee652edf4a3f599da32f2400c640f3e842c9f27838dfbdcf4bdc92386df1cbe339eb3e2786d417a616eb6dd59ff259b7dfcf5f9eebed3d45d2ebb4dfe8c087cdfe1c90ef6ce088696fe5a12f54a25fcf9e37f73045336e50fefe22d1db2f4984f21e07afedb759f260cf3ff4798ff4a41e79f18fbfd2277bfef3ddc3e6833c6c9fafd14d3d299f48ca39979fd3c83412dedfdcf5cafdeb5e9ef771b868ffd79208aff9a4987de978ef1aedbcee1f37e75c0afd13096ad4835f7cee8bcf7df1b93f5304c71742a746e3300fc7ddcd7def8393b9739c7d321e00321eb4bdcd4239432432c1184827386549b340ca62a73df336f3bb386a97af0eee727bfcc2f4221da33de3d53c87629e61daddbee16ad868b26651ec1669c49adf4ca21f371e9306345ca6d6667ee7b75e1c4912350b556436788ec3368b6778be3b378a4cf0ce4192c689e371b84cfb6d3e892a8d8c078fb1e1cedd261890c67b3d89ccc5d671b9db735a36b134ba4557873e568b9daaf85caf2b52473a41e13aa5f39b94f7ebbbde60e8eb83c02dca770e6ffbe9ee162f5c4bbe1b5e274ebf4e40200d9d1ecfd21a8f3bf3b786a7db4f66ee7c5c97d91f7e2bf3ac4e0bf6363ba7e0c5d9bcaf7f644363c06450b55d3873c3fe68f8c204b46dd738f7db73b2ff7968dcdd563fde3909dde4b6b37538df3a24cdbfada173de8f252b89ec27d0af9523bf258e3ceca0beb9dfbbc5e817c776fffca1ebead80835f29015f7b5bbdc2db41210aa714e9d1ff3170622aa1632a5a3b9b81bcedfdda7b34e785b4f9d60ee163f6410b30d34f79ca03a9fef1c6f8f2eb6051f0ebecbee993e380fcd3f778f3d64f5e815794da27ea9182e0cf4638fa966f1d814123b708fedf3ed39dd778703a9b78b805b87641720ecfae19e0f16311fceef7a6e0569a20a28dd535bf68392f7bb87f27afb1c6b45c007c23aa9b3eae5fad94097f375d766ebb4fff90b8d7c322b1ea7cbd56ff5e42b6ae5b74d5f39f9ce4415aab5cd1fed1bd3f83329f92e5ca1178fe7e2f17ca60d5edd1d3c0b17b13362c90cde4895f462eead794600aa15bfbfd1cd2720d4e27acb057fabea0e887b30d027515592b17b83795f10a9e29c419e80e0c67552da90f6b437385ab1d4f9b1dafe96e2724eeaf6762f38ac3daeaeb97315a95cb5f48aee0c1bee7a12fd784e9cfe13198f9eefa3e6b7541d1f033ebf3c375da86b7ad9e2cdb379ca846b1971da54aae037ef01d0731ce97acc9936ddd635f83363cde5e2a99865b19a3947d96a5edbbd90d6fcf815d29a1fbaf6fda66d829f24ad691bdfbfeb3f5a2f6ab7f51f93d6fcf84f486b7eb45a7adb68992768dddd0b9fa075f79a5e486b2ea43517d29a0b69cd85b4e6425a7321adb990d65c486b2ea43517d29a0b69cd85b4e6425a7321adb990d65c486b2ea43517d29a0b69cd85b4e6425a7321adb990d65c486b2ea43517d29a0b69cd85b4e6425a7321adb990d6fc7f1d48b48757f96f30d6bcdefe3a61f3753a7d9ece565f11d6ec357cc12db6dabf04a2d1b4ef373f6e6e7e1244a37fbf313503dcfc79281af5fc3f09a3f9aebd005eb416002d609c82a2d9bef129289ad7a61714cd05457341d15c50341714cd05457341d15c50341714cd05457341d15c50341714cd05457341d15c50341714cd05457341d15c50341714cd05457341d15c50341714cd05457341d15c50341714cd05457341d15c50341714cd4198cbf91035d7bf4dd362357fda064e47f1356f9bbed61f384ff9812db6e64fac0aa59efc420c762106bb68a213d5c32b5558c2dbcf69afd3766f47751a05773db6fcd778d8b03bc6b3d163628cccd809b23f1eba2271fa94ec7f07d80d79e8b45dcbbdc320cf931962cdbd428d145aab371bd593487f4c6f07f924aa16314f1f53902f52276cee25af75481edf22d6e36cbda5b1e693c8cce37e7b4dc6e9721299ccb5b48cf0fe3201c1dd9f4fe7f5b69b5eb75a8eabd0fd2d9946ef186df39cfaf34facdfa29efca23f2ffaf3a23f4f510cafcaf3c10e61d03357a4b3d0f0783023e3e173afb0d7f198acef8db4c6e3ee868cdde738ea0312b556aabec16d972585f92f3c76efdc87f9bfee0d54e3babdc2115bdfd7f27894278ad6f6c7fef7aac6c1fbef7b05a46eddf5c33eccdc1ad25e61e6c9ede89180704d54bdbcb0eca9fa727d9118dd3c75b2bb7b4e726c8c9e9319dbe0f168de2bcc4dc2dbff2211d27a8529c878a44d2273966ce6ebc4e8aada5a431ee6f10cdeddcf909688e10a833e9d38c1eef707aafe9a532d1e8aee6064875db707a9bb99af27d188e1e1fc5ff79c19c946fd5dc51df5779364f33bf9ccae6db2d41e301c99627bdd73cc072fcf742f9f614cf2d4099e7b457b8d79c31979bf993f138709d90ff7c02c5e3ed7e61a17fa2ce1fd3296d7bcb6cfef8af973620ce83dd0f349d47a96c70de7a41ab77fdd156d9170f8dcd44af9218f1bfec9d7be8e82baab6a69ecde319d212a8fef377f1ed5ef6732c89f675f9825d962679080fe2b88f94fcdd271c43cb8691be0bb42ac3756c9f84f11f3f2f17f19306fdeb480696adaff2b36e90298bf00e62f80f90b60fe0298bf00e6af2f80f90b60fe0298bf00e62f80f90b60fe0298bf00e62f80f90b60fe0298bf00e62f80f90b60fe0298bf00e62f80f90b60fe0298bf00e62f80f90b60fe0298bf00e62f80f90b60feff5f6056fc797656d43c7f9e5d6f9e268b4503dcf81c5ab36bb443d7b47fa9a8eb2fa26b8c16d0cd56cb7c41d780ff145dd3fef9aaae3f6e5e8030ff3ff6de63c9715d5b1b7c2045fff42239e881e83d456f66f4de7b3e7d87b26ad77675ced9ffbd376e4f2a2394912981c0c25adf3200be802098009f4f18fe45aff945aff945aff945aff945aff945aff945aff945aff945aff945aff945aff945aff945aff945aff945aff945aff945aff945aff945aff945aff945aff945aff945aff945aff945aff945aff945aff945aff945aff945aff945aff945aff945aff9dfa7d7fca0bbfcff44b301d468cf7aefdb3fcc70f4edf049f6ffa78ef6e8df5370fedd83bfd1725012fddfb9c6f23b25e7f93f770ddb37d1ff0529077afeba88edd7456cbf42d83f0f25bf5fd3a65c832cd24361c0e491f9d218c2252832e2a132c99a08529bc0ee96d21418f14e11239fcfdb2df08e22f05d30e2c94bfc7a7150ca977bd2ab1b5dbda6cf4b64cf3180dd2d81dd4614dc2de4dd4b14cc21b4282ae1bfae482b6cbead430fbb43eb28dccebd12b8dde3ea7529f5ab90bfdabeaadfdb88a37e0c855c51588c3845ec7198c8637b4a5350023b45ca976372515de49dadc8bb6800bb474a53635c51750c4347ccb765dc69ad28a463ca179ff6edef323a5f728b5cbba716b5067e53c4b004065ebb893c5b041fdd58d41e56dff4f0bb4c5499be86422e3e72bd0a917e15225f82a940dd7a45ec2992224ac71d81a70da185ed4997ecf16fcffaea6eb32d633a986d5ae067ce1f3b7cd9c2f5b025f4b55bfce8df77c7a4731b91973091e78e84ffc8cc55f1c71e3c877cd77f9f746e1bd214185f5f734692aefdbaaa4ea1a93b86433085b92b34bef4d744be06265d5ba5bef979068a3bb34dfe3eb78f3effda768f2baa8cab5765b86a61b96a25b212e580adadbcbefaf62dd7146dc875442ea59c56a2ecd6944c572d6c482c0c90d44db6752c87d49d8b7a9b1545d96d535860ab9bf451845e0b461f9cf02efa853d442d62442c22efcb7e6d48a35ffa7160b7fd8e2535f2b436eeb556e4c3fdb7392408d50670db459efad1d116226e19c24e11c2241cfad2f6d18b28506dd241638268630c63b7f869f76d0e4be44163ca7360e4915b72fd2bfd7cc9b2d35dbb263c79a53435057e582a1dd6a6343ae9c738c63eb527bd51441d07071636c6d74fdfdf228fd802b82ce30e6b6341dde47a91bfe68c48a0c88f65dab15bea9b634c6346d29147e84b60e4b9b77e0c7222b8d5075322af2dc107332c54a69dbbb9bf5da7d8987b0a634b0c734de88b45767c30f62a44e1c7d58145829865fad54738c61db788dc97cdb7f0a27ca7e10c87752d1f0a39a7d5241b448bb7f5aa541a85943aa83e3ef9e94fb9868fdf7ffd2d57141b7a61997a272872ae657fc3651323e916f36419fe164f7e7ef56311f6d21e5b4711794111774421c1bfcfc1f5a545babeb079241d09479ef91d175f634fca777912411ad38e03438bbabfd9522dc2ee5bec7210f3ebea46913539b3e15c9b337393257dbb39df8663e6ae2ba922031662f7bb2f279d7bc417b6067ed8c615567e8f615b8c48bd027fd3b95a91637c9160e0ad65d2353fb9da92a87ed3d1979efe857ee5eb55fdd6a7e2ffb82a7315abd72c72a965b89461ba52ee36aee580eddbfebc4f8b5bd47197582ff2f73176b91a7ee845e4beaeb82c529ef816fbf8bff5bf2582b427bc7ba57cdbfe164b159a4222bead239a5a232f1d52fa134fb11fb131e44924eece3df04c37e98ee2471f42f319ebf7f105f72ba6c4bd06861ed7883cd97df7e1e607567872fbe657ff155b4294dbb8ba0ffdae1f8793de1fddba6ccb39106918ae298a0cf85bffbfbf2a6c4d3b74ffdd4ee4773b4348d27d62ae7b293d75c508d526bd3986befac1fdf77e88e913ffbffd3d14ce47be2f9db95768fd7b9ca770bbc434557de6f519ef5bfcfe9f9bbfd570960f5194cb16c5db188abfccbb523a088e2bf2f739fe1d73ff1e532c56c69e53c470f00d53c20f1d61a2900e91a70da2a00d31e22ee1b77942dfea017317f9af587c7dfcf7ef38f8dddf45c1bd629aea3e79e0db18bfcbf67bbc21fe6f629ae134e4473f8ee792bae140dc1f75f6c3f7fbdfc6913eb8feddde020505dd3906d7efb6483b720c69eaeb9a5af9f771caa44b6f0f02475158fe8039cacefc8f0f805b8cb8e00757918781318f0e620516e6effef4c9399f31ae94771bb16af03fc60eb36b97d0a2aac0d75a936fafd0d3c01891b08fec71e722221b8e31ef0c812ff509b41cbef5e7e71da4bd53de5d958e84521a3b3e32a7fcb9c9b4b88a9c7b7f618a97ca4f6d15fea17fbd7a5522bd1441c7dda1637e6a933ae5c92bb3b03ef44d2ae8b53d165c3074bfe2cd207fc62dfe883d6217d9f637dfff4f7e56847e392688792b34757d8b1b2df895ab69aa8e78b78e2e6a0c2b6afc635c4a2eaa14790d4a10738f8dbf8c2dfcc9ae45c27357e0416dfa19fb8f727ed3df77dfc5fcdfe4737ec4b796ffaa35ffaaefbfe9e5286c87f34c07cb5d48a21c8ee29c96fc8141cb71edef3e3afe964bbf5ebfe308fac8f9b628d67442ca754ec707cdb70b62aa0d72ac0fb996cdfc095f635895dff4dafe98eb8fba2173bee4dc7ed3ab4c377fc1e71ff0e5b45b22b8e027c6841eb7fe96337ed416edeffefed3f61fddf4ee12337fef3f1524ec67e37eaba1ff0be3fcb0812bc53d05a55ffa73cbd8fa8fbaf8b3defff072fe9c0fff653f9f5aec870cdc9ff03bc8f6fff51c3fcf7daf93fe93ec7f9deb9f7dfc0f98f80d43ff760e4a97b6e9eff26332475936f4c1ab19fa2046d98efb470cbb4e732cdfe2f34fc615c022803930808b4266dbb7e99775e8535f35b5c83b3fc5dc77dc630962b6b185eda96f7c6a9231eecd25ae8a4ab13ee34a6fa7a2be72c3578ca293af78f40f7decabb6922ef12736a7c8df72452c349f3af9a798f8b7b8fdc7fef757bbbdcab7456da9772eb245fd0b1bfed7fd43e9b42546b456fe999dfef0caff5e237c7bdfa2eac037eb887e0d96437219afb589608e318c16a1f5af75f58778dfc71d7985d66b532af4e7ba13fe5e97fd499e3f7dfe8f73e81877c9b7f5843d145ff5f36f78fd59ac475cf0a3b76fb9f5458a3cd6a617f515e7e5af5ce8b2912fb5dfae886fb6107641c393ee183ea194778dc03707996e96ff508bfd197b7cdbc934b7a7be79a4bef935d6773f2c93ceddd2ef7945b6b036e3db3b15d44f4efd89ce3fb82bca3fcfe12b271b812fb571ffad6f996eb6d85b9bc897fe65ecff0f7ef86fb0ff5b3d0d16a62b599f357f80486de07fb3c36fb289fc1ff3e3abffb20b4f42a94041dfe7fba55b87e7aed0c3becfa518bff4c2725502934bea9bedb75abb183ffe2f5649f5b358fb3f85a194279e222d7ed66c7fb7d54f64fab32c1498f43fb5d9ef6be26fb98b4f3a72fdd4a0f2174e8fbf60f227fefb6fe2a5f9b59efa69acfb31f74f1d90d2c5f117794991d7ca94d706912e9d4890f6f4fb9ed3cffdfd3fe8d297ae4ffd1efe59a73fb557687daf45390d0c3c6d7605a90c60e7a779f4f71ad64523df18d4bfe8e737dbe7c6bfd9f310c23df28c3fcaf66557f313335cd7b2e9d24e3f3afd60c09796dfd65b0afd2d2e88bcd926c8673edff68be4cf9aefa32f442dfe94f384bfd668afe177f9d34ffdb9a55551d96ea8bb10e93aa06bd90da79996388a34fb894550cc1f855405c5bf79ce305ccd7641d232e93f3df7533fffb176fcaccd7d69fbd4c19f3ae69fcaf5135cd511cf5d1e047eeaea3b41d23de98c4fddf13bde60170c3d0c966949731bccffc44407d27c1b9258b16ab69427994f1f862f5d81dffcd4eec6d7deb3bb7dec17f8e69e7cfb6a8e1f7b4ef2b7b84da5be397ce247e47db04c5e32fdaf7395c1febe1efd1735d4917424f85907859ef159e77f9f9ff99771da3daea8ef7157bb5398bc42f66b7ffc1383c74f4df485937f23cb37ac4a6dfa890115b5857ef21fc62b3febea2beeb835b48e3feafe5fd6b67fcff514f9d718f0473d7cad8b85b40d7a6d4cbf7de7d5975c3f62d58ff5ca5fd6999d5b86fc2776b874e69badf1db3e274d5d41a7fea96dd249f5077fc61ff6423f35f5efcf9448e84977e49badf2a9a73cece39b6de081dfd6997f5d1f3bdf73ca8f3a8bea6244fd21fbcfdb944de86b60e461df75fbe77ec38efc5627b3da1078d8167ac727378349c76d091cb649135e310c0e9fb928f4eb50684a8d61ac571a88f238d2339cd335ad9ff5f9f31aedab9fbf7d469174319274f1fffe6f7cadca8f13a52edab3fefff9fedfffa9a3ff702bc4df9bff76108d813804fe6f9e44ff0f7ea1e277d9ffd5513488fe3a8bfe7516fdeb2cfa3f458edf4fa01d766128ca787d02deebf57a89c6ebaf3fd2e797edb88e614192dd04fbeba00ceb48c46f1f8b3f1afe83be9cbff6653b9c6e3921e740c6663b915b83ac7cd42fc3cc330aa159df920bd78ca77bae06b158bcb5e42dd92097c6e6df1c4cae9e2b17734abc8103d989020903c3cc5b3e2a19fc964fe7d5f6a6b94491ca7142901a6d59c4176bcd19c25c763db083f4e8998b3365dcef6276efaa1a31d6bbb2708445cf78af14852c59d87ff03abf89339df48618cc1a438c7eec35d7b9482b3d4ffcaa5d5aa71b6c76b0389ca82d8b0e1066c940060b6bbab98224b58f3ed12180814ded4b6fd65348d5a8f8a8627e19ff486fefbfeaedfba9c67fc716e1bfea33f2882de5b939f0a55139d44f5f02fded19fac7d31ca5bc0ec3797d25cacf27ecdf8173bc5e2f16e25c965d2d07e37f9c70c0edaef46619c1dc15593f39edf96f8ca919ffc531116a8fbf563fbfefc8c9e0b2ca0baedeb80a81ccdb551f9aac10c3aee494ba24880a5dab74b3e8726da6acd0b364b3abaa14ac8c55913766f1d89649cb9556c3f52cf5919d3a4a75655f9cfe313dd3bc5eaf8fed54967bbd3ec5c647fcf26f13fa00e4457db117fe1bb6563ebfbe9d96fec68820986f3215df5a14bf35fd073251ec0f99029f2a03b86c7fe8f9bf613bfe23374f5ee145fe76c2fb03937f38c5fd67721b3f919b51ffb5dc7ff85244a323f754f854a4dc617bdc18b71a18f81218fae216c0679920baeb2e2dcc8289b3071ecf4d7248bde226a0b5ea904421f55fe22bd88223600bb15ceb02e4038686c758f1cc6df4b766666f09a3307f739bcef5e0c07ae325a55f370a340a2613d1ec2e5618def66c0f533fba69fac0e7c7730647120080c039d89e18f8577ce054abc0e5d34c087f7363afc5abf11d339035f8315cf90a3b3c8b2330b78ed1e8f5f0102e2f42b2ba270b1f3d700139dc1fb7264b3803a093c01cab5a657d9b38ae879aadaf0260ca0738bd8ae2c2553490c6c7d2f6ef649ffade1a8fb299852beb5a6f3d408c1cce87631b095521f78e4ab26a1809ec392837024acc1a8808df8ccfd6ae1244ad6f73f29bf66b1a22b37bd76595be6dc7a44a58c9ce10013b468c49791e8f4295738d3869737a449c4491769c84d9a6ad930c31549004cc3c74cdb1af506f76bb6ce0f6125bf42d4b88714e046c0425c9cf839c9664473902cbabd7ab9fa1de8a88124776cd4446572bdfe25ad3fb1881a938d59bceae177c47eec6af8b730e3443818a4f6d57f3e00235107751f1d56bd145d9ef1e413014304a76e016b73227d5e93e1290bd2d90c62621d54bc6c5f39ca889cf9e4d06cf12fb5065f1721545df5b4d7881cb7b8f98ca0ccf1296ba1d2e65209eccc37bc89307a956d89a1cbd65e2acbeb98d77e4bd3a235af085153d2a4a5240cb946ab579d0ca36ba12d48c84e74e44afa42f62d9b8f06c2e53e3978935acbca3ab61434db119d8b052aefe45ec6d9774981cd21bd73a53313f60db947b75acab65f217ce652bb9253d455f9cd13da21474bcabc7039e4f0c30a4a2071ccae4a3ad864e55bba3c0c4337457c7e9640e752ee178a3b8ab12ce51da58c4623c522bbd81159de50dd841dab2f8c4b8642e46d3a795217aac2933a0c362e7e3ba1536e36d22bb8130223781f894d7461f4b8415e6678b0a1ee048764d99295b25ee3d1802b5398f28a6d391d81bd3efa05010f9579a190e56365a3cbb9cf9d2a0d248b464d9301b83affb06460ece145bbd1cb843ab675c3d8c408970792e65b16302281ca0727ce1cf14e31bff107c27b93df20064330f540672f1157628287d946b2bfa7bee451e8b82c2f49e21234a81fe91aee5fd82f5864394e126d956295dd38d7996c2259e6153d1ade528e3e5ad8dda648b942a8e5aa04c30d0a9809bd59eeda64f90ae1dcdfe109a43419aa141dd07833edc374545078f624fbc129153b578377564d83a9f98eefaad7f58ef6b61d8d3b73dcec9e2f90655b1bf65b58676d7a9b8ceab246fa80d5128354e1837033ba519794d6774667d80c6a367ec2cc484976b34e6f30636924edb497acc8f9794377ddc29e15e45aba6533804832af6a4ec9b8570c5dad78eeefc2bc30e083336369ce0b97f982ec2ea08b854719b9657db922fe1916b664d62f7a31a40702a5be815f06ec93d6d095a694d459ed4842f81fe887a905aed6d944caed69e4864202050e7a1cc0b119b36051ac2d4c0e54bd73fa802da097c68fb3c79216f48a0c0b04048cdb876746e4de09cb21a18679dda21137a4e687e0e22233e5cf5dd6a91b99b4f1438326171749b97bb80706ec3f8005487da1ca3f1101f407e00399e6a014f03eb5a830920ad7b696093519318a3d8aa9210c6b392f0ccdf664474a21d75b9a7b90f47d9e96861bec5e124da6c5bd5a803d58db576a86a51937777a157b7cc4814995246511d8e494fea916e16b47eb62865eb2c2487ec68f4f3152c5eeb9f601be519ba77ebd200a28bebf9d3dc1b6d022566091617bec47a8932618ef073c7a9941b063e6d8a5ebe04a1ebcb3d7d181d334060f280d6770b005dbe637811d8f165592a1501e5c2b900b9f8d8461185abb257d380b5811a98059c26ef0bc3e91ecc98fae3d89e56bdc6fb313bdb1bb517ff99afc0cbfde4e0da82df376f14ceebc5bfe47f9683c57f94834ddeed02df5d52f64f0cba46b5be7f6930e6dab143d886493dda35c87a3177a26147a966e6d68e7ef333598272cc9db2c119a55b3d78da4bbbfeed0b59bc5b309b3f9d9c9375e94dbcf230bc4857d45e627b5e09aeddf77dbf433e86b127b9bf0fca21349be255dd025b3867900a9780e3f13e19eb4d9a844a31d18caee4bb3835df4464e7cdebe0bb938bcb64f04205500575ce89d06d871459dcc29c7028437fa45a8ee8ee25e62c371970a4295ef85b46a9646ba03a099bda73d9542d747e2aaf55dc9cb200079d898e4b2a0a57d50c7184869c7c47424e2890a1f246342d08134728939d28d7e02158ee624bbe5557eee14e268eae7e4acc682ffd56b2c36553b9ccc48f751b09509c18417d2f39c4d49bea1c707a6608d203ebecc1ab8badf3dca175bce8784d37e8c332ae279eebc3a43e850d2d81dd61b92d745beba97b522033a68e8a871e0a599b310158cf0d608dbbeb766b1f3cf70dad848bd962c00de65228b1b2082d75da3d74ee66cdb2da50d671cfe74d7311d4416dae5cc4a178c1b5d383a7017e486e4067864ebe8ba5816b3ac2a5742a2aab5b641052530af67870f17b8c17c279d1408fe8c981d91d74b7925d4b2dba0595294faaa33c560755360adc7adc894c0d8cf602e1651b63905a4561740cbc37a662e59e8c9f4c6a9b2cefb15e345339ae4c686d9044136f4c57e92cd76717800b6983c05eb7c362a7827b479f68820282e0c0c66e63546bc286d4f28a238e61f5acf2e3698fb16ac6f5f3dd685f7532e32fc653b43eee8219ea5feb64ea6775b273fc933a99fcb123ff675693f9fd3400fa13fbc011a43d13dabfedda2bdd3766eb1c9a697c4a1427c6f90b3795952c2ab9ad006fdf5ba59a667f6c0bfb556995d147673549cfd471ccb6ba6f890987a47aab5383acabc00a0ffaad2ee84b9e9d06771c04b69b3b219e048635d802ec378427f98bc2eb2a505934749d39a0202f7a6bc581e228ad0c3219af49e92e84f158b847b3c26666862cbc417d222c59940a96a77968426833f42ec0f1bde2bd1104da38995743bfbb372ebeb862db8b52248ec77538838fe996303efa909eae2a449ac44ca85a0f24ebf68c85cbc97bc67d056a1f27db63fc741d91f8749e6c5a5fa9bd95085fea485446b24f3bcb3af76920bcb3366a70d4a81a31c2b0fc816ffbd3e15a0a4ba40b4ed9d1e7b94563bcaddd276f2811d54db679120a910544a64d055bb168d6177908e7d84e49071118a820d5673b31472e183dd826c83609b504b5016707296b53e1971d8fcbe8e6a27da5625f6d1c8d794b8615b86563a09453541d685b18bb5aabba63589436d23ffcd5e5b8f1b96e0e31d86a47b8b8efa328841c860f3f2f544c0e137181d0297042c43d44ee4971f22c8ac626c7f039a74ee08248775a7498036060018a6979e125b4c1258d3d7a9409b72b703c7a994caaab9a54cc6f3e2de5c62b3bbc501fa1d69d0dc70bbb045386b73065e633fc0db5395a6f37eeeb68e0222a92cc999e64c98c9778896c1c900c899d0c9ee96b81cc11e9c5134177563732e26a536e0f26c817434a2b3cb413a3531eeae35cbfd6cbd7b9e674d17cdce9a0feb65e667fb65e3efebe5efe6dcfe00f8c4dd06cc38e8362c1647f9c247fdeffee33ad5b0801b5bb7cfecc94bcd7d19ad67ba6348da111e99c37e6703259697da18441150f90bdfc68a2d8fa4daccda311fc2e55949a99a7a20c62cb28d2b6e5a4c86cf7a829c3a6c199085c298d24311cc79181c4b0c68b03972e7a73cf792047700020f1f70860f883635f7126727c35b05d79221a3fea9dda9cf23d6e763b8f4fc99cede60ce2de12344fea1c12d5c36b4a93e52c2fd22fd86745ded2010e5773bfcd39d57c2b6c7303745f5d9274c776662aadc56bbd114f254dfcfa8167f99ba490216006ae2e1f1bf6d6333e8ef8dbb4bd68b1e07a675e4b0a31db9dc0a61f0b0f208321478ae5c3d5458170fad822f9a347bc4cf70e85eafb3645476c1ec104dfb892d6ba0ae37d949d96270ce221522f0c5f4e6edf4e28c81433bad63be316b4ebf1cf82ab16562e97887a2ee5a2292f22aacc01a329167ad9285f6985a9b677d04ad20d55351ca6119ecf825467edeef3b362fa201b587d6716b365269e652616abded9e302a13049055c49f25e1dc6e4049b2e9c40c15c758b581ef371ea976a3cfd1e46b3dd5802f6e4df3a51a58134a5d8ebec4506164b9e3140e5556ef9ddd79fc54fa731aa3360a11011b5d59d01ba0607c363c9167985f91410789b907775dde212216ab01318c458f424de1c71b815930014dee55477b26f94b19221e3c0c21f5b3b9dafa1580746ba24db90a95a775c936136ca2316d10a19c14b4c448199dcdf6186b0f0a047e26c5ec15525563c45bdfa01845cba95a877f284dd04e019be28e269e675e98bef310164aa980dc2c70a69b63023af04c727160a1eea7d6d654f7c41a0d0ac117bf22e7f1c4f6adb1b9443121a16fb5b0b8f3e90ac4c23698dc64a142a581c855d87dc2e7764403e5b3941014ba7b3d0549a3a691f62beccc596f05086bb9a0dc592370c63bcd43289c13ce0c6c7f57a7b8221de8eeae5155df266e6d12b1769e2ca52600e28e61752e738790d15bed995353a62e2491f35cbb40fca7ac540cfa8e6d32a6d35061203adc8ea58c8f3b95c7acd559b161ff313849ab717516180cd3c2505ae35cd2993bc5842bdead97c788956614776084fed4ad1130afb27d28a7cb515c7c884c9ee4ae0431832b041a9f7824f9d17792e1a2d3e6cd3007471a40e0b053d532a44ea66efc5bc5d3d373b805a36d69dce35d583d18dd3b267eeb9faeab85c6f67f17a1eae31ba3a769953a1943a0b99b65d1a9615f1e5a34f27f25b396a8ea5e1fd226c5b964e6ea9f343ae6df4646aedfb9914fa7ed0fb48c1f2aa4308c83fd79d4e4b59ab67a21148f495756837a67674d0fb193bd1dcf19bc0bcb56cbc4d27d839d477d04b1e97114c92c2f4dbaa3249a29f082379439a8225fa0b26583b316248df7093b5bc457fdc1bb665d9a865e2c66b04d922a0ec32f1e16a10bb9dc439bc09024cb70df50ce64264908f471da9ed4798d4b2d70ac4ac928204ee0084591ce7ce57c8eba37ba2d36a88be06986e2b38f5e6d91924bf387ce32ebb373672dbbc106cd42948cad5bf32cdf67221202696458abb4e8605d9b026f4829ba1d221131e2319af7234002fea40921ad4d4c1708627149e9e928833ec94242c3c4df229f16e2308b5653458b54a9d5d31ef00dded4839ce21f3fa929a1695af37aaf4327dbba469bc65f9c04e521002084fed634a342f8b63fe81cff87d146a2814578e900f407f9e96a21cc74928faa87bfceddb81dd658b241102ead926e9096f3a21dddd7ebd4b7f6959f5cd280abdbd43cb9564a444ac5eb9e5d2e6c3057a63c77a0dcbac33e486d2aa3cb97ad791f1a9ba613505420d57a4477735aabfb57a89bcd4b3572eaea76c545a6c3734f4353e1c2a9b8a5a957bc63ff97719a9a233e7291bfafad466360814c91165c7966256172a5dc16d991bbc2b5179314b5f5547f49078bdca40ecd1dc4ee5b98a4bf24789be6588ac1dc6271264538b57dc3c42a28e060fa2268856b0bcd87330a7d657879bed20ec68bf63dd2474efc04322b8185bec8985a4f3a6376a084dca9a4344a60c81a019c024f8373d6cc7f9ba01ee3e0a904f607a28f7470defd7b4ed2865422f3297f47472c6fd568e08383a865cb3eac13703441ae5ba3da4f4941ff1ee59e2a8d75980391ab3d36bea4f2e32d3b0040122972dabd5ece72b60f28427f89c70132dc7aae7431d0e0d78418074290b299bb7eeec545b4be3f22455a9825270e7ded246be00e2e92db01501ebfeca0126cff5031f6f58512670c74889eced59a117e9c240662e72ce7962742a74781af853a7dd50b9a4c549bb2d9eaac223d21a96415a0cbe77ac14e85e4b58387a3b047c164a6b431b176d96b216866fdf083e2ae37a9ba6fa6047f85cf1b21e8b9090c6f358fba5546da67742a6d75678e99ea8b1f019b43043ab0c370399778eaf9dbd45402df85d28ae05321b6e024141b5bd0bcfa133130b13b08c72ef5255fd7db3525543b964a73087b843e1bfacb77faf779b8eed768da12383d35095589375a8731df0698c91235763335a49182882c5ca2b5bb1628759de15c1a6a943222fbf3c61110f91ecca7765beb190df03a0b9a17022d0cba4e63086cd3a01083f9195dbc29d6eb6a7f7ee485b87c84990424b88b372430458c70b1bd34104cdd4c536bed2943326c65a9bc7fbae40103c930eb4fae7b362e859b7da6ddd02c4b6136c2c76f8cd2f70288bb1baf13c13363ae992f5e5be9ed86d323d8deb8342f28290272415b76ed8d0097f228ea97b4f584104e9c516c4041693c0cd9e7f7bc05b5bc7b7443e72d79e42303197558c55d4092f909880c7a372356b5a1b4b27a1057fe2f4d85c759a93c019e8d2adb732d0bf9993f40cf4ad27b69727a74bd013c227967bbf40213c7a35695f20b1e3723c13ce051401b680ad7d65803c96bda3d90e50bda7ee12b5e04cdb09e8f74c4c9ce6d60077d2a5bd7dc9b97d866b2838111f5e7a369e54eabca2d388e7441c9f5e8439c1e04456c2ba80b0546e69b3786b4f2f62639e707a3e5bc11158b611bdd8d0870dcec206aab6b4eb7ad57baef4865135961c0ec6e512a09a26ca94213a17e4e6d6e79bee3013418616059b71b8346ac023af895977425eba9ea14313f30f517cfb341e99dba8d5029cc7ad6d291866738d793de321de5985f0b1999a6d48bbc35774668600352cb01267d512702f52b9493264faac1f3cf80a273325876ce75ed8ec3fc6e4cdd9447d65329a723d5c23da2333229978163b2c89f7cb6ea5677238653ed183b091880f51f775277489842dac6486620f1e28c821b397d716bf931d866a7cd19e9b0b133a226a62ee511c99fa1dd65064c0b499e6e224b6ae268f9f1337916602aff7407b8dfb7c0ef7c63f1be6d160085507ad069d26f4ce1f4136f3205274441d2425c009b3d813eaaa3859b966f6418ecc09331ccc543db80f218001272839aa84ebc1728ed063e88b57f4a8b434375911014d33100f585cef25008e2d3048f2e983988059fb5001384d9c2565020b74029a131e8c138794789766a710527be91edee3cc649e1299ef683e923e03b0a4916140f94ab80098dd20489425ae1386cd4a743f3bd55f314e93ba4e480a3fb9e43eb99e805c9760150b402f91e093a848a04e5ecc7eb690da5f25b4878ba5e913d0da7362dd37082a3142709bd6029a93afa63629848f5f6f9f5ebba66d6ce05d786407d9997af351d7e547113f3d09ed1ea8988945915e9dd270d94e9b9e7d78b48f83b484899408e828a5698afd46ddd733bf3356a9df20a1b18f4a9ee897dc19c32deb5373d819f7d6407edc03979d7c4d7739ce85af2dabac3b2f2e3b428aa71d1266e69aa57f0418ae99a6dac6ee7031b6dd125a90ee6413d108019425c1e7eefda4e3877f5c3826124a7a01fd9263682fa31450fbfc8dac46bdb98ff8189110b8a8fc4a70f572d22601d844072e85ea4f5cc0df102e2e7c9fc5925e69729d5b70250842ceba7c3851ef475b76e5db09b8d45216b10bcd5a43c036bf3b21e5580214d8277faeee832dbc9e4dd7f24572276baa7934057845414c72991d69d943673653e0f6be64e80183481cbabe36114d5a985312d13849759ced928304a61189d4450bd3bc1e9536b8cfd50de55a0c236910c42cc3575a8e372f79f4b036069793e68a51c5d3a39284258cc7058c78cd16e767d907f01e259e065bf5e3266fbb3ff7f7e2b7211cf381167b2ab9858947302647a7f7b38b1d1f82413338634b8e31da7623105e587e910903b420bb81f2e1ce9c9939b1210b342d9140acf4337865cf1d7d468bcd03ed48929e64ee3d04a16df788e089bd906b223d2992e1edb5d80c99f3ec7c771921e604e198ee444f19c84ad15be60474e8a3a98c1f0bc77021e8c73be3cfad76e0720ea4900e6e481122cb5d270680ec52a66407b20fbbe551bcb50658935abddcd0c183aa16a70ddd21a116b70dd72222d1ead273d95ed9764189f1edbbaba03ba683f555f37415c9ab14bd153a79d6d9341d4e7f30ded89b62e5a42218e03b0f81d102eb9dbc8ed78b0f827fb46f4f37ff70dffe8f7b8ddff7ea414f3f0c9c32289a079ebcd38c14fa7a25be52c7fa6ec9a6455bec031efa55eed3b0f567d83c88424c2c0f3525a9d600a0233ae0a161dba107830e5746590ec9f9bada84374fa7ef66d62c4369ba58574b27d6561a11544a92d6420be3c4d5a5e67770526757b23e6a1afd03cddf9bace25caa00d7bb9aadc03c7a7c3811aa8340c69e3571c275459a040400d25b517c933bb52373fc01a075d5c2475de44c935b5b564bad359da00be7ef80dcceccc816ee6b4f57344ff294bff690d0e36fdc879feee9caaf7fb4a72bc5bd0606deb9fc818b907a425b08ba0b0137348e6eb79e63a6c6e2ce28af186b04b7e061cba873b6e41da3f1dcca3bb5b150c948c7540fd789256b3b6b2b78d0a27556b4129e4f985d7f19b6bd28a21970031db9ef48d35b0eaecd350ae74c89917d530824834bbf29df8c008da44a0238b2430f1c416e247c904019bd385f510db12d9a4fe498a50a5a5ed976b5151eebb59d68a77c46370a222be8d8163de4ebf6e2dfc13b58a1fa39cbdec995d804e30ace094d2147ed1c6b1d30e069054fb84786e4ee91034cc2e484a43a322133b37a0de79e8749dab79855c57365933bc0e8fa1d29ca9b9ed245b96654ae92956787863da41da43abd2cc15996eb5597b569769b4a7f62490085d78d86ec31e0cb38cbf4e8250f0882c42b7ab711f8361d414e87f7de0bf460a47394b48023bda52d19748891a351bd553331b2de0a7dd065392b2664ce72014deba4a2ec34c7acd6319d9272d3715c130b0dea6fad28f36dc9d82a5f2e82bc6cb0dcb6ca52e1cd64ce76250e848dad755c49792fa615a87b84ecf2877a7bd420531ed2546cbf756128f56839c2ed2df3c7bce191f9b2b72e3b1a265f84a4caeb2ec5cf40625ef8039f9f290cad4f12b736dc674a703b60965a9d1c076b3ab2d2c566d9ea6c69315e460a4925a822527e9615697f5e43f284a835f097db44ecb759b011c53a13687a8ae4a4790d1f50628d50024e551aeb730a775821b920f0c819dea56b95a577fc02cfa4ee820b9ed271ebdca3e99e212991d97a7aa83169a414a9446fb7a4bfd22e3859ac8bb541f9dcc7d7db7db4ef3e4bb840bff4093b87452b7ad72ec6118bd48298f97189dbd325e599ca53efd04f7345a8873c99536c2b5655079e9f32224de9c9d2a7112cb57749392b9e594bad8d345800386dbd97f0e498a472e225d26440c136342f1f9b8166947d34db9b7f3f52bb640c244e4c397bdea62e33f5f0885501a2e6796cd087bb5a113c0c797b4ab6b58a0f219d725073d536845898ca2ad25f04dae77dfbdd3ffa64cf6dd50d09882182f4921ea4f304a8ade3ad98c582436982e9fd8cefec3470ed4cabea14ed73a9adf03a7afb964a154f7dad8b6715b1ca1d79f4af3b2db7a313a89ebacd8910a90227b21d9fdf758e368a817a8f9107e1b2b80e59c6d19139559ce5c54a158fd800388e2364713419810260b1138b9ede335c586cc77793cd862bc091a5a00a37d70fee4bc6e3aa7e932d8b216c1559dd3af0293e2d34b5e841142daa17730d3e90c3e8caad52a2512c34cf6cf49e1e7127f132eb7025780697216c9fd2ad3eb023c0bf8d789396ed8ee838a28ce7a18c8117c2d1a994bd54827752118fc3ec9a144feb8ed643d5e9e7302d1035b7e2cd8548c78ea61754d2949dd3af2a016a2317a504057698bd8906681ba16f264433a9a9f6dc8cab4fb264bb08e0f5b83e2774d851b6ecf8a60eed0b16903ecec0867571b246c2b7183354f9ece356436cf3a6d8e74d4e0c6cf5af03803de546977dd12364ca7c175229bbf7d0ac9d760c8317e3e6bb62055e30ce8228dac60644917e87810731e3cff9622dcd9d96c90421e2cc40377b9e2cf7749f84eb7421ff7006aab4811623fa7c461b14cbb3f81cd0ca236eed94e484636f71b8c34aeaa816357b662d0f327434aa93e1974b12ad4fcdc55d51af9dc638d2eaa0ba62ee113e4a126a769492b009345a1ee04c44e3cfeb6251e4b18e5c400df488c0af81dfed5824c3975adf937f0b65c7c66ba8111761ce96adb594743ecfa7b6cce3a33975e279ad0868bb70addad8880a99b6ccbd05af730f4791dcdafd6e9fdc824a6e652c92b68a40f892a7261dd24d3741592a45d4042ff3ec8f19e54c1da8fa7c001a73d81f204cf8c18e947e92d19110e6b033304b923f2c3b0b7654755f6213c85d8d76a3ad9034e4cf75293fc33376d649bc97eac0f6d5d3f4705da66771258c12d8ce74d175f3ca4b2b67c627d336848a3ce2452588179e1053d162fb2bb6e6c602c32a73c5ba1359adace2a158f2e5f2182a7ab9500ee1e78319a20b850fa0697aa80c151f4c74ce86cb21aa5c5b75a57c6b76434ec6f34088c443c13468e0537f7b13a73c095a73643726a6a0010e347186b31a46f2207c25aca33dc7aaa0031cf11a18da8d12a4ab1e79e74b3b2ae72064cf1e7580e3e5cbe78307edf790560285603d9ac1aecd3a33a8025b8206860f80659face610d441f0a073ef7a590a3e1777402716ec0a74851025feba97ca2e2905786a6a9be6f9dc4f64497440ab9af11d2989a4ba6924968f7a6132132877dc3b8180a489001f33b2151e0c61bf096d5cb69014b3a79778ac1b226e809ebae9341a6a61c71da6aa539fd1a87a17d78c5bba71b9cca760a613fd74addef37d87262ea09523ee394b03eed5b7cf001e0f50c4e3238261b2d1985c392d6c8fa301e79ca69a63b7b2ee399e8271b98c2e3943af855e07df3d02611860f94571b61c23e30b23df821539fdc0dc5c3397727a905628aa93e8da969f390eb6a63d074ed6e48ae03493c6012b9e0457458ed9073d8fc7eebdb73351a20037473792d991c3c75a0f1df5b9bb46e921d765c9d829d14a024c83e2ee579c788e57c3550239bd081b1a91beac314ba0e8c1b3f83b18cac4b45547a94c36b3f44648a52a7199795a2580555e4b87f9dba8453e25901d3bdb45a815a59f06e92ac3fa59e4333cc965d46714989241c20391a65f35a04ef8a34ac40154ba73f4e24a893050bc480884b02da15f8f6b65afe99958f758947230efa11b655de4e193d45f97463c52692031b70274fa9ebafbbe4956a2446a841d6e914136e2cd20895eec7610562cecd0c33af1e078f89bee92d61148243f18e7b99fb362b62cf4a49eb803dafe06aabb041ae3d8c08b0a87178ec0d1616f82a36d6e1445c9badb08865f0bb721c3dd368f10acf814934a501fcf72ad2a3e78284faf29483bd891ab0cd6e7eb14e5389fedb499defe54d745bcb23128dac8368f0ededa93a268deb493526f2977860acdda34bc1371bc54318fb38499da503bdb668bbaf718dfb76483d7c489c76919a1ed05ad6cb7f530ed9d0e533b08a9ec1e7a4731ae4e4d04ad17ace1066307cee1207752df2151cbb0bdd83010d7bf16d1565a4e2235b977eef898c32c2e4009bbe9c51109982e77884e371ed86acde4e50ed1c78ca7257c751f535cb49c2a4ced64bfaad2bc3dfb4536e5ce4cc98e37a4065bd6164a0cd54b64c82decb52764d21d1e83499707caa992cd16205df4d62764455de3d522579460a071a04bca56230f2742e3bf4ff62633941829d2d096bb9cd37b3cf5c72a40e743b095d6df51d8650223bd53d34a711ca67848ebf3b6a7a991d96e0269882b7f2ef922707a879a80e6029063037b23fa3ddb88298662a59e41fa43141fd6edd3497b6eb2af8c75806c783a2cfbe5e93cc08925c5260a53835b0977afa18edfc4725d690d9d96e8a44e79c95cc18985b18ebbb8be88678c48a936ace70aab6b773689592a2694d7982e33641d3a160e3c22d2f44cea053f35336898006de821209e4e62befcc4798d545efac52d3b04d117ced1119326bf5beef49f562a037b7ac557d8117e02f787dc80be7e3f97e018611c8beeaa9f7714ba997d135abc10f6f7b1623c6047f56bb4af675189affc1104f7e26285b25a6a266f2ef792a0475ebf762cbf84247bb7f0f06a16df61f849b41fc3b615acb26153f602669e9482b430fd7a52475544dd22086c8ff178c875d628ba566f79e41a13e981aff778eba60706f3b7b2d81143f03820825b2dc5305eba3d18e6e1b0ef2f02cc80150f7c2e4694e4aea336553207c2f885f506dc0ebd078815cb10892814d71bcd27d9a13db5d134e7490c1157c412e3bd42b6e3cad6b993849b3a99292b2230e2cf0eadec6dd893997cd754de3c6e1776c975f2aa790a2b462267c275f1fa494fdb7688e16aa3f6269687c72650eaf8d90b3cea275f9ef52149db3b86b5d57a1a23d634d224af1a2a77e4e63b48cb7f5c81187c8a4df59c78b4fa3304cd21da9edd4e388ea33067ff44cb057be78ac5a177dda1fc846228e298c330670456b8447690d5b89563fe74ba44e638eedc69de99014def8ba705e0ab95191c243fd0679460c4f5dab00d686d55eb6e959b80b092ddf6922292a699e9e694f6e0f8c782021326d0e57aea775c2aad48144c909c70a436b98c6f5404d4484cf05a7ade1bd08c1ace2571161f8f194aea277c553368bd767fce2af79d5536ff1e5b8ac9c5b7518b0159943ec1694979e0988d24b81ecf057126610b6e3ede3e19922cdd097fbddf47948f1006372c7b3d6f19f311597926d0dad8078f54f9235efd72a7635f724ac9cecb157891f84a6c795eaeb94484799883e82b4f4857012c80c5732ea5ea9ce0f7c7b6bd1759783050843edf1d0db042ce6512f3ac582befc2dd7c5c593383dd81010049afbb4d5e17a0b9f36c19100ad426ca9e8052d9917f2b417437fb4d48ab6401907b7af07660e5ae4dd7b49032be06bc403e78c987182b3fc1530105c014d7287be25a6fbf9f5d5ea910dd420fa35ba705620527286a0816dfcac63d8545df667dce3be891ce190ecd14b490e8b384db37e328dc8ce4b9a2c2a1103e2e01b176f3368c30c35eda730a444738a90cd883e3ad661038863e60a8cad4eacf73e7cce17d6ad0cb9527e089490f7a7cac596650bdf25c49fcdca95c09d1c83e67008624cfc1c26ede54face3dcc19a371971359d4e92eb1591a8544d35167590d1b486a9d15cb344b302bfb6121bceada3e2f68ad618567841f646477488f3b237798d1ae1118e0ea5ebd5778ddf1990cb11b3a8bd7025dcb53b7df1707790a977937e6f240f9ecd7d445a90550c43d072e5c6c2a6cc1d5f001a8fe8cbbfbd015712b369d98bb1d1fb83643cf14d13e745ca8e34ae394f44ead7c0b288738dfa490302926249429a8b6a28ba69fd00f51f28b9424859ebc7546e8997a951ed9080377928f2fa5f76b8dcaf7ab983657499150f6e22b5a8cc6752fde7ac745c363be3485579c55961b2b5c7ae735e15e52b64bc30b739721dc77a150b9b4771d3766bdb99343883cddc786caaba0244a24217ac90b7609cced491a7544c813346ed19351b651b6905ca2affadeb9fa894e964e94347ea81a910f76f47e8c917a018c08ef1aa35e56eca1b54c0a7bdeb612249acfd773f3b7679f6dccb1ee21dc3e51ac0c4238f672c79f7973622d2b7e1bf31146ce2e54974b3fe63cdb63b0bcaf330765c9b40d45d384178ad85590280e1b63f8abd90f498acfccf2b204f39e0aad6ef84371e3bdbb44522b5f69abc7b58a018f87c13ffacab45f22933df03b435baac2f3c758245e71b9ca5bbaf6ba39947a612e226fb0e68a702fe62973d5e929bf56d8dda58dadcb9bcb9968f6cbabd4ac61b7f3e3f4b9f8c10c4f608eeafb29d5e826873195c8b41836277fc226e06dcfa25036283c4faf3192feb1afb286660f73f51e86e5e6c1f6246cc5cd0f4fac606faeec63cd4440eeba18dc553bd551ea99a4147c2b9d2623352b608cbe05880d79768e84d59b7ae4e0435f22c189dbfcdda4be429bd6ff47d9596be1aa454bfa8108700b7fdcdd33dcdd79fa1e675f3ba3fb06bb1312228235d7a8c95755d6cb560b6c080c6d29daaa75564a72295060949c442e290273e6a662076017cb1f11e24815a841cefd117db542162734ce2ff3d1955197bb46b3cf4c17bc91499491012f3eef6c17d8a31a8594081420d2b65d85a9c5a6b68cb558c04fca245603eab77d9f384a0b06edc4ee960139bcf6f10e1608d7386b8cf430e216c5fcd9cb9a6113de55ceddbf5fcb507fb59755feca9346eb19524cffdac90a3e025b10fc8bad28cf52b8526f53b0974eb61f115a69377a58ca8e59371e99f8fe9452d4cef48afc438529322ea8b4c274cae63b07a47e153663a849364d29edfe406614fd4d87f54d5a0a561788b1e5cf99c67ad639bb238281ba0d888bab08f7652fec4b97ab133694a2b1ec9945e53853aaf4f6a8e5b23c8a9d1444929db921cb60722fb63c463882bb4e5eacce7afa9e56ddb28cf38d5547ebbde849474bf89554ede443e82929f10a15934e146ce81328979c0085a779d4d7f5c3a67bbbbd5b894bf71d70a0b197d06d232349b6193432f4a708f4675556bc9b26eed1cb8001f55993df1e29dd3b26966221e1ea97eb16cfe8b30e9171d52e08843ed6ab9594000be627e3b9c42d2570ee2043f53172617c2bf4d06e0ba52781f573e31a3d615dd496ab24110a784afc2a18e1da66c7ec678be39e52e47c36b80f98a7bce28849903acb16299ed8f309b86b5cfc4f05bd92a967d55eb4f5c1b134395f25314bd945e41875db609bba65bdf9c941b24860604d1058e76a55b1e957a568a319329b7e35b842ac17db218311d6bf6b55c89a1872e86a18f7e61162987be93385b069dba2298cb28593602a1bca06ad6b98b6309e313931756473fc3d7e83abeaf13d48f77206f9e4e9a4b3e049db1acc25d9b2c94d1146f5351356ff915d9b2f2dc46ae56840737c219356b1287cf421d37cda698742fb2381ff7926647b52018bfad9bf5ff697fcb9f677fcb9f17fa5b01971389cff66632be688c40a00114de8f14cebcdb9ffc436327631c8deb1730d7e9432f6e2a9f43b102972e1e1eb7702f6cfc13017ec36d935f8856178e9f53af85cb2b0a43aa78111b24874f95556ca10cbfce6083c7113d698eb03de90280100a02914a449f4a200c3b2c0faae4db8edee5d639859cfbf77560e4f6e98545fdf1cb6a24e0d185df9ec07798bd0de81c69dc9591b6c4debd67d82434687f392b3f2d24c1f418bc52003786ececdeae70ac5ac1b379d6f358872c5bbabf9a699dcf109161a22892fd1d4b46b299fa92eba11398a72f96d19b22335498c8adbecfa57b0f93c3c1c5a4efdeafda87c7551d4544cea1b6b1661b864b9b8411543b05db97add4adcf32e89a6cf853b820eaba25b43499c96845a971c7ed1812746068622709d52796d296a31e604ec1a0dc639791e1076ab8c53bc4e676d59496e45c886772e167581b0532d1c00f1830c4972ba2ee7061dff564d598b2642c654bd12749c01e1f03903b2bd44cb417ebe56bf3cde3ade88a617997748ba40b218873eb4aa58dd764f44a3308dced602d32df0fd376491d1e482a6013a3468ed7bc5edb4a5fa8a27579a3184b04c8c96f9dffd8437751f1cf8ccf92a3ea38ad29ecf7fbf5a3dfb4fb9ad501f34068106b1c4a563f7333d37eb74a3c3f4d85ea2ff083d130adebf79836a38000ef3df84500acbaf1cb642dc7d89a406ec677406d9cf0280e17ad11fc00e8f1d41999476eccc3669db5eddda994b5abc0be071ba048bfae3955adeaaed6317a1fe6e214df8bc10ae8e4310ed6d3882c1760ef2755730b269907b98101c76a595b9fcf341ace01d2d1484b1bdafe3d705f87adc114746a76fb08a762853e2c0ae972727b2a733efdd76174ea42286563de0b992fd28179f0467703bb2a942813623b320ae98ff95053e8a7116085ed6a3abc8c8e75428c319d6499b2ec373e8b4313374b4109f5865e4bea72468d5aa8ac398b3327466102badc7125de84c51288fe088b42770f58524ec60e7f1434e71886cd7b8a5f062079d1d7d11f20ece13ccb2e0454a607fab372dbd9be331b33d3d3798ca72a9cd2afe32bc4c655d5724296fdcfa0d78a2abcbdd95e1de53d93dc2b015bacc82ba55217205a7a9d9b4711ca8d08450b9dd5a7f421ecd88f8ee4379de3ac6015354efafc2f3e62d4dc5b54014544a9b4067fff906a339054aec8f7e93f5bc433811e8183dd773750ff98125ed9050cc3a31d862d0d448653bbc3d9ee9de51367cf3217b0ab4469e514c098abd199078a0ac58e3715e922c8f172b4ce7620aa8637f971e9c170e21c5cd93bfe93defc3ff1855294ead7b2d3c7cc2344356c3115465f3b12e0b1ef09685833afb10f93c294c0c6b6c23dcb86eb9ed712c178d521ea892988efb988cd71cc10c4d5bf91c91bda53b3579834b8e963173b15e0e4714560c175828069e7b5b20164c08302331e2fdb65896af3439a2912492997136c7e997205e7af864e86eaa6b3a466ac769f1c883cc3c61a488e77acf1338efd85aaab59fdf9f03f4975891336012e91ae86d07411dbdded5876127fecd1571fc5221a61146e75de860d747b456709d2fc58acd04f527892b1b278ed016b347c588ee6228c38ac62891506af2babd3a42b1018174449b635a78108a28f29b8535ae24670331e8b7c1341a9b5878de93e5263601b878daa7bfc31f76d500ba73b1a715ee819a1724ca49e88146302796871b6427e5398a551740ab5020808ea8df0f781857364dcc4fadbd6a76b0873ef6a322bef9a2c5667e9b74f9a4cc08db24746a753266fcbee640365a4c5f1481c8a1b55ffde171392a8d09604630669d1035ea72b7cf0fed996c8b84001b31138c311636fcce6ae1d72f1d9c1587c455584c144c0dac63ba16f7c8cf1f9eeaeaf6e554da89627aa1a3f721cc62695da76568dd20fa8809b3ccd74d27b34a443282bd5bc9a60d1b09545c73e9da5512c0b75f5e4439ae6711c2619199ab56f67698b2e1c2850fa9bc26e2f1331c1d9a6e52992a21304f2d21d9cdc1a8ba04704a80c28d7b98147a8c7db9306b226b5376cffd573ff8606658e41a225190536b6f4333c25fed6869de010ed82aec478fd997a34bac56d8589a2860ebd008f4dfaff6b213d2f96abc120bd3407d15225241471916ef147c442497fb02f906a1b207604d85d2d31d3f05ef87ce010b8224cd22d98b90ad4fc2b5d2b823f0d46300e22985128233a7e1a572b7b0c955a4d53fc0bcf8adb1de8bb86f2be7782279de73485a2305b1b78fc081df4f18652ca272a01ec4dcd1a346b88a46191a2d90e8d85fc3ac623df9e3bc879ea6783ccd38f4dbd68d21acc4b635a79fc1494be5655a69afc28d002b90a365e1f9353632459f08a05f697dd9575ef8b89966c035e246fc7be25168d7dad5e6b9ab827b405beca8c9b24b3c7b66c8ee43f8b46bfcdc6989b4d1f05d6b73e7d076f1297da491c1cd22948430cfc2e306f189583612f492d35aa187a7c8cca3b70a5116401b74676b801f8f93e4104fb30f5b0ead34c7d4375ba883bfe73ac20bca8b67bf0de625f0fa0c4afd3e4b54b187c05b35f41b1037653dcc637f3783de877357a694e012ea80943cba17b6a70df1475a0aee40845cc42be6abcf4488a134ec85c37abbb9852a37c96b01f965899e723822f5ea84365a6533ed55abcbba902bc5c73a93c44c76fbf8c06eb5fa2194ea5a0b91fc8c3142e668b096294809c89ba0a60ae32db7267f7cb766bdf0808eb1f9a95ac94b63d4c8be495f5a0818a43f148fa31588fec24de7cdb82c63dda3cbb0c82d284279f54593e357ec14d7755a1befc1ee5f409baaea5e78508f3fe5946a0d2d8df0521aaf6d690cd365a560b3abefe6529191c19dfb539d4f285365c03cabf07d856e7d05eeb6e4c1a6141fe9c2318c32b49d8bc470ee01539e4164e4c12654dc4d9670a897054b0e5f9342c52ec62a8195b4f8a9982a9ba26bbbb4495bf190a70307b02f00bc5c0072d1fd56b58c1b63244e573dbe088ed702e03894763996bcd8603006d7b69596fac398f010c6f20df51fe110cc416d4019d65f192fe9d9b53a9e31734e8a9cb692806145532e35571222e3507877b6a80ec5ebdd68dffb5434a8af80ccc243cfb27f2d5715dda3278b95847010e10bca7514e39cd29595fe90e36d59e85896359c8281ad5398d81e78a768607c4b5bd813e0996dea0cc91ac0f84e55b7c75d7c2d7880c66d7fd90d0753087668bb431da7fc7e141022819d1755c5a7979122c94f2d4a063d563fe637a0ca7e938a73b541ad2f7bc5f6e72878d4176d54d6dcb5744e16125cd57ac507bf8658d12280d0d1a89131e57b543f6709ca4681876609ec9dca6595e49c8eb4823120009644fbbc092802b489918f4001e2670e4cd073b1377f4dcaae4a54a7a2b5df5ba65a733104a38fde9fa97042503a7b43313fc0ada1d2048d49965a7f12b35a04a659f5699543e77ccc5d82eb686b407c18bc83ac9ca063b74bc8afea0e26d8e667c7d6c1dbe3f60bde40c8ec8d2504e1302befdb00cab209fbac8f58d3e4420b26081f5a7e9fec2d4b5017603fb0a2243229e908023b42d1f0e25d89ab365055d20eb310a304cdadd85d7f1535cfd0b55822475b58e9ac2099d551fb8c324599460f769a196fd8081655ea3db4026c7d32c3b16ff5b63ac71b684189eff50b6ae679e27bf0227026b2a9e1ddee61f205491694e24af6a827dd791ce1a50dd3858bba062eabb0c004ed1a74221cccfc3e52f0ca645a535426d90a2d7448981b2a1a73117240bbf2b8b93359fdc0a60dcd700a4dadb1b81e518ce4d583f03862197d963d1337d52fbe3e751664b8940dbf3675a79117a9bed326a799a64035d94cdfa12ac3a36b18c343e09c6b94bcf605311d86b9efb7feec5d69e5680f73cae431a333a671e917e4f9e790258b07b2d45de84a30f3de23178ad6f72292c9074d9b61bab9ca6c34234008492656226ba933ff5cf361877d60b69c14657eb6d3c297b222b45fd955847beaa0804348319f7027fdcec91e99d88c32da75bcd60b7cf5ccd6730236e40ff02a675c6efebd8aaf68d91055edd597bbc69f0939cab41e505df056fef857f988f9ae00d27e3f4e13ffcebf0afc957f15669a426c981c35862c54f624927b4fa4bb387cf87f354f2d1982fdd75ecbf007d8e261deb632fd3861260ab50cfe7d34c38a7d549891a1727cc3cbb032bf696a5d4d9d1f47891cc75ee02719824f361e6d0c983f0be373071fb0349e45e93a3f7d4cfa2f0148655a481ab48b9ac3f752d2d5cdb38a5677d4e29a5f09ebdd91b2a9c369cd05a3809660c0fe745e842746741c0649e1f355239db5bbcf607148b5117fb5d7bb79abd95185cc56a2e675294025b0266263862399ce7bb5e62e1066a939a829c624f41002b462b81905f41f42c3d1ea6e257f909697cc74ccc470387b6f5ca4810b305ee53eed1acbeeafa1828d5154dacfb4429d014babc71330ba9f8b374b3ab840c453197fd141f6d3e5cc1b0fd909991ed092cae0ef73c733123e758ec2497d6a415c83b5b546b766c9306f4450f62746a4fa907badf13a215fdc8faa2faaf1521ff07e5e94df54d69828deb5ee1e75bb27028fd156c0ccf74ac78b65b3dbb7fc1bcd95ac98e0d4836aa205d4649b6fe37d92a75f131c7f03b24075a7e0966f5d4261172869631f8484c0c3a9a6effb164db66fb605eb2953f02d26e24b8a89ef15290732f7da049f22631a1402bcf502d149c6d8f1bbe81693167b573b911ae115f05a6653b907cc4886a7f0a07d6829a77f38fc27c72bcf285a396ffef7936ceeef58e4fbaf58e43f69e0bcf0e54870c4e3f33f3c320e87404479f423d02974861a13b3ecd2a531bb99ef221f8d9b42cccf543492715f34a1eb88cff6250e4b5f2a83288998ad58c607ebb34223bdfe2050a2f29445ce0c42423910e9900d4fde44391c8e182da823d102c5bfedc12924430000042fab476ac5c2829b31d81e8f8b965884ccd3eb05cf6125817474f2e07a16509f3053006727c09a5bd0c0519bfc2d08871621acb8400ceb789e8f247026f02d64e5088ca9e4acb4e9d98f113554e5da703e2d6fe2ce4f1e347cb53e8b7966498b47b54f32efe7e55ee44d85f43a1e2207b56f659158c746853d46e3d9b7e10541c1acbf9985c302c262312f26874484cd4f034489e14e61a1a44cb037dcb16439cd3c30f8924c1a0f63d677977af99386ece1a5f8c3e4a621564b78a2a9980e351e7b16d687057036dd38530aa0b55e6b56bd363799ae9a06f350fb1b542209da6ef635de3b9f1a59c8936b7a7dc4e7f38c935ecdb69723a133508191484e573dda982cb71369cb301e28508c35a89178b9afa57c23a4b11ed9d9c4b89f2601c88a8bd99a4d0a21f701c8cec46aca59c74e89af3f57b030b8342ffb71026450870fd061f37cf6adb6b974ea829bad05392ac540c8d30259d09fe4068f60a0ab7c6bf16e6fbf8d55e3cc949a7a39c187e719b7ced6e7d6b5c575a2eb4975553a70178d48434e541aaaf69f45446d15b560ddb068eb8e0f8c0f5b6fb5c4f253b04897802dc868c7352b38441988b8da8cd5a979a6ecefb4949f42c6b09e07dcbb11904e9d21ae229276228bdd06d148e78da1c78386b708806f8c448dac8eb18a3b8aaa1358986dec3e2be59fa0aa08b14086b75fc1b009ab6a47858aaaeff3734526ff49845d1ea053c95fc742a9abaa11dfe202f5b0bb0afe230bf270e26284df6ba1171610ac96fa6af433e6112cf723e3432471f46d1469730b1f8c7609ec4a66161f7df165789620649160ab98d15b8882c9fa98b7f7be966615d4ae6373e68152935e2402b251138832520a6779230f009922dfd2345916b9e246e4615433f62687abb62e3398dbcf10513ab9558b0d73317834e9caab57e7970b3fb3466eb33c53636ab7acd1daca3b4f6336abc4f3a62217fc130b93c1524be0eb11fe5400ea3af7a42cdbb0481cbfbafd4219396fdfd7eb7b01562b76146671d65aab1ab376c16fb170c73b95b7be2d423fdfbbd91cff799fa488bf0609c1de5fd30d271c478a9ef4092b3ef6af907d3496421be6b0e45682026f1fa8b2f249085c342858b7c6b566ea7a41f8790c01fafcd0f4f7afec8555caed4870ee7c97373cd35d08d56b568def3859a5d9693ecb7e557e008581adf680c90431262d201137e61849752185c8bff6d4813e3a72a1f60e72ea450b42c67ad53c0027c665242244388d09ce65450d80e294316b03abf14a21ec1185ada7aade1f9dc31b579f391c820a2ece5833282df8ea81452596a0d9c4530df020a24ec01a6318a01e71afc32dd0aa798a913a6103f60a3f267d2c8806e4072f57c9330e1c39a7be0a2d0984fc754bafb5aa39b06f595a2cb5f02093dfe4146050b2a5acaf2aa8603d55a7013f27d5bdd44565c9d194e455200923ad32f2893f08a26627b5bfdcafe44af96012b52d5adb798627766eacf73fe71c8bc2f4cb9a7261ed434b7b31c2de2767ea98315798a1a7515dae46aa7d864c9f9177d68491c8b23add68bcd918a5b6cc201b03c3a98e3001f2eaedb6b2acab6e07b4ece09680f896f48abcb002e92e76a580d1181a01fc3cab7a2dcade08e39564ba9386607eece642a87736d1218073590ce366771952c244a4bd4a7a1a6cef1035aa72dac62c1732558b22f4b69f1bd65cfbabe1b002dfe0ae2388145aa0d9b1bb23820615dd428c3ff4d14765aac443fef47573a805cb7ec894903db563cb97d82fafe1f68d9a6417dd7d97c46f41a560e61dceb190555aaed709ac6968046fd9651189c0977a6a8aeb1225b7eb3fcf7b0fc2e5599675eda7e68bbbc50adc0d11ecb7ad2132c294c853df12c454435c394239858bb6e28a24e96879be3dce22f4030cc1ea96e4adc6d351b4693dd744f826f101ae0651784418d8657eb6199138f049d304bfba9e3481691f0254e8127f5bbc9e35cd595e82e2286ca9926dd5c0558a8b1cbdfe349bf6fb090f5694bb72e5db3d2c97579273f0f38b5234b0d81c39b0ea48244da1560ccc4ef73756913f5e5819251453c4f30b16b47757cbf802e73cc2d145548bbd597e344d40152b921e7ad2464a230374b0f51b28c9b7a2fb1aa81f4c41b47556d3ada16f0accf00bd6278df5f315f61c6918af0a5d957417d081d1c5c798202705806630d085c50912ed4a65f0e201d50176f6e7e90b1fed22c1a95d4f0e6e556678d7ad5b60d152c9537461e485d703f5325d2dda219829509288f72397e8f40eea53aa979036c978dfcf0061e1b5f44c7fb0a18d7b2330c7c53141260365ec01a58f2c218a5117bfa6527fb5d427c468606c0a17d51ecc1c36ee6567f5816911e06bf0a24c1c69e98fdb08a00df42c6d1747301810d001bf140811bc5cf2bde8aff84da6a86f28df2bb9922ab1f221e80c6f58fa712405bbe6c446e0475f540182bf7e41d9aa9e681670e83ffaa741ef6dfa28e9f7e34aaefe2bfd83fc9dfef9cff696e0dfed5f861c87789ffd2bc7670a82247c8c4894088bf965eca98ab3ed47fedcfc64df1161469c8278f58d164b5b5fdb752ca975a5b3ba84d5ecaf243632082e5ad734aa7be97983e4c57bacab04acf43a4b45f9f1f156e2a65899078e5e25090ea0454a1b4931a68c5e86787ba618926dc635a225f69c5a1a002dab1f798a1854a39270e92527d3e43153a59ae91167ee48e2404655f3c50e253406dfeff673b14c4c4c67421973163dfd82983a58cd6e9e98e88948615a9c1b4a0bc36dbd919960cdeb532ea6651a52e2371e98646d8be3913d673dd71c17e69dd6c66664745a0289a1e0639e66cbe5c47f7d4eccd37079de41c1fea7b862d58c56a40752c7e76a17f19cee0da730440506d256e5fe68c1c539c93252984fd863d055a5e928eeeccf189671b33f1ada482da6936e7c4658a01e68a097b15f788fcd08b3bd8591ae68df0ae922891a57c3c3ffa0b4abbb5dfbf237e386a4837159066049c5b0959441a7a760c673371a475d08bbedc6a32771d359a61fd864cc9e5dfd16a850e71dde13afe89395609459cd035a460e3c196653cbdd01c347647145881cea445bca2f1997f0bc7c997dee2a1fd02c4b0ecb5d0f23f269642475272af6a29c26a743883c68c49c0fbb13f9ad1fb5de59824610e6bc8c4f078d1ee3f619b68d7994df698449cb298f9d571fc194330ddc6c4f306826844dc6fcb87715b5dfceafdc1238caa29e564aade34086d81d209e9876ba08a28565f32688600dbba7da4a71830fdcea63bcb2f79ca582439a035db1dffc5afa58149872e770ae1d0568a4805faa61920cfbf626ed787537a6037b1ad8d611c48b5f9dcee1992c8974c9d5e3f98d47ce194b2dde7695660bb291174cda5a71c4ee382bdfc37feaa288e325c9292eedc2fd35c4468e0466450bfe69c65a9cb8983ebee720dfdb04facecb47ed8d8620c9837a201795e173b27a963946d7934905437a867386d007f5c621729b194b1e61cad8a232cd750b9b751fa3576d309f1428f6ba0bd669f8d3f50f4629f50320ee7ba3cf6f715dcbcc7d83ad00b92434454ee3d22c99356f25fc2ecce1b9c723bcf5db3f034d823502ae1c38932a3bfc0d9dfdced4ab3575647e335a4af431c7185f2c09b67baa5f0cb1c1cf1a3fef7e1dc1095759c2457b473fa343256a3bf2b6eafcae1f73323f393070c7926b81e1f0b50bbc7bf0505d2d32ba99fd45a3588df342cf832ecda7485d98c29520d040208c811fc24d80069609bc67682992c8e90cbd70ccba9bf4db113c17fa1f48cbf7b441e582b5dd2c1e2eda45349592c36ac921ce02047c3b910fe2ce04905388c7e3919aee2adc2e960155593368eca643511653f1ce0d668f18fd7dc03587c3ca4467773b6f2a112692a2bdc1403d6669aa08b7530971592ae55b03301a543534e8d509e5d121d2e86697de8db9a502b9aec3c4a4e58ce21707143f55ee818c9940a625acc20c9ee2717716cc02ed64dc39ca7d0c4491a66601e9759e933e728198140c74a4f487fafd55201793d979b200f5e99e75e19e8b69afe7bd6e8c974606cc91404ec0dbe8f13946fd4ce8da7fdfaa5714e628b2c72ac98a4b62913fcf74e67d967858eb5853f07215c312b9bc6c1a587d2c2bb2524f3c10de89627177b487e44f5a500543b692464ccf0fe835d850e568cd54463e34532ec82bc2f89276a729141cb4ae24c0a1d33de62abea9e4d5011a19c40d0cce00d94652a405391c6c72b09d85d2c64059c3cbb90e2b79bc4619b8daafdf100b1a27809580f0a181a7f8731f96b7526b65cdff7e5cc4fe3ffd01ffeb7df8fddd7df8dfac0e9721f89886059cff67b3d67f733b8957f9cf11087a090a90ec4273c833ea2a1f85b222b92b6abe0a85f36cb8ee72d88fa2fca86dd69922bee9f41ee9a9b8050f541c1a72f6d4e4408803553dff68b4b0352db72cbb2951a202e881fcceac02411c67919ff0399d285a6a881609363c404118f362d1864116df88a6f899a227a009d3f8412999a056b4eb772cd7ef1280af9e3ef0796c1181b917fd8a61ac0619da7614c4c12bec6c1284ad8c8b20811c10e03baef8319ab0c40996ff4d224e94e4ebf58015e34a13672716127d419a902f62a8faed82ad60891e2bd55692c17a05757895862d8ab8f282cbc2fdb66bb2acc8dbcfbe004fa12ea1cfb3ce739f82b3681fc0e326a9e98dbef9d0276b3cb4f5d1020e66f2c36ac470ba0a97b132ef42aca4641ba0a319e8c506c8c8f91cf994ac33ee54d6e1c45a7f1375ba8e046a367f23da5fb58ddefe4d20cd89bc40317c74a00b47c57f7056a0c1e79962096c704a3d65f1063783837cae1462ee44d9a1bee6d743c204c8e515be11826125c0746322a3a84289b5ba74ec61302fbba87177ea804dab2039a41e39addb35400e16fa42ea7b5dc9331f1902c6c9e012c3d151cf0b7e2aee6a32a1077b075f2ba8df3a4aeb5190cb1c12202ee745e4be5a91dbe449df48c340980c100ae631331c55a9eff1e8fd8ea2d3c3dffc43e23cb251491e67005178084452708f7b0dd52fcb737deae0c4c5f0764a27e4e3bd375794c4ec63736bd5cd043b3e9d1047b0cd8c75911b9f943b174f4dffd0d288826f8e06b2d9f868b0c1a68997b8ee76966fe59c43da90be227d5e37d38182db30629adec587c9c23fa5132dd6f79476e1e1a6eb92d69648e68267eabb69d16f09d707dd79ea5f9eea125bc771bdef69423b5b1c3c7ad04f0067536de0b9be33f228cec9cad8e259979ca02e23ca2ff5c113fa01031d9fbba92d2b8e9780616cc0ebd3e4f3ab09f527c7697adb06b867957cd87b5068868e1e7efa34b8db0072d5a8e863f427efc0b56e77a92b7ba507d85786be54e27c446f0a3c9d0b1d283a034bd9c5d0c9dd89da5a1385bfc92a717aa506421a513c847861c64e92bf0b5ab6938c957f402ff3602ff347d373e1aac6f76fb4975f7bb47ead78002bf3d4202b3e65d9292b239bf04b9205df2419e278611eb98b0a4386b52b66ea5b261a45fc53ed8a697b8f0b03de6516f276450156edc1e3e4a1717bb52e123636fc354c4886afc79f3186f5fa8ab6b3b8bd32e709e7ebd4a2ac616bfc92dab4cfc6edf95f8647f5e6f6b2eedfed0ff477d892216efc2ddc75296b01dec29f597ad63c182735f7fbfde6bf9ca5e7ffe72c154a31e88aff68cafbafecea888d760f7e7cfa87ca7d8bf09e31b26120f2cabebdf3c23ac342633f834a424d345a560dba34bcadde8bd654b69f839fd24544dce1c433a84d8e54580998746a28ab95c81f33723a402f034a1a89fb2eb77f5865a1698193395d7c1f897ea09181d1b473b7945106d608eca88e4632d9d4b0106e4feb29524191a889d0a5e0a83fe7398ed309184090971ef24f5683e50bbfb1553625cdbcdf6b4c74e61db31aa217e9bf1203d2b4e880abc4f850293110363458e956b9dec5f7dcfee0081f442839f39e66970c19b591ddca68f75d388379630eb41f153f1e566ecf2c22d9b92a41b0aba4984e45b4ae746bd46e5047357c6e21bb8d9c415564bf169e0c494c7555cfcb94332ee3742b6c7317223b8078c18bb07ab97a66059bef225e064ced504961f86e8a40d2e81842cb2a0bdb986c2881a1b0d7c4884a12946bdd8781ff3e8f7243af7cc5ccea6cc6eb88c89c9aa556eca1ff68a6f6e4c37048fc52f260faf150dcdfb3fb43cb35c1005f13d6d49591757d13bd454425bee2549868238513461fe2ac25c10eee0e42254da9ab653ae9632b6e2c875a66338e4f1640ce004f490e8d8230b6b7ce3ade2b6e8ed693c6abf7ac1db46704fd167f40cd6386245ef03c1c76453dd86cad7f2055d88bd4a1f4ba1535d0ab23b262d14800e510925f17ae0dd16ba8dd9bc10d9e6b4cf8c1cdb245fb2ac6497c5225bba518c51ef18baa18c2061bc10a6f0575c2498ade591ed39b036c673518af1d0a21cef64d8579e67f5b15565e3990be29bb347b2cc548f3eb68f04a38c327026fb1b023316a26baf96e4731a78f04500ad633c6f51df17a36ac711bf560e8a998f55bd159b97267eb72bb4abe18bea85db68a71a74f737b0c857edc4969fdb5fb6c9aa7cba0a29cd9e83e63d64ab7bf2e5460470fd68d1137d90936c855c28e68e2060c5bb4ed03f9eb54703fd3b0cd96b4808f0cdb7fdc389a6b54fb93346e149e96f0fbd20792f6626ebff8aada1080f250290196ab99fc3b973734b84bca65510d092a62c2d0ae6972f2b85484cfa4b129e1344c1b1709952c84bd903a3f3b0c7d1d31261e01a0bb402648c346efe6fd515061110fb032911febf2d486445bd8d15d4b00c23e323d12a4ac156c7f900c7a16da391bbe1f2bc70ae3d6d83bfa888eff49e7f8f6411fe0dfe7625dcb73a45c94fbd31aadbe68c85c4e95b470fb990f07eaa849473422b7f6f7d61e58b127fafc26f4077080c67d2a496c876a4b72840cbc403c253d56ecbc47a0f9ebbe1160e11c695cb60c32ae7cf1cfcf7432fc86b86718a40c405eb98b7018567c50ac7abcc8a5897476aac1c62f7d9604da199071e650347961baf95068690aa4bb8c889f60bbed6b853939913ff5cdf743c61ec0cdc3a889a7b19d073feaa98c87d274dde29bc6545580821f97254a87df179319f3929ed5236eda612ac35d8617855f8df1791451016fab2ad1a6110b36840daadfa3e1a2642bf0b3af7639df0bd409dfef735060f0e38fd6046fe6648c8d0325ed530ac2582051a96e2b172d122ec9637901c2584250e0840e643a7840ecce3301f5b41f19f12f8c281850b73347087e8f133d43b8c809843a24cb7738fe44a5204c1d6c0edb55f02ef8e88e3ffcae58bbd23d1deb13794c14b40982b2ec0076078b8f774707ae48d04a106df9a533882339126d31202483c28b9095451e42b73e636d35a33b7bd83bccc8f1299f14bc533291c7a58bf376de4c8625dfefb9e42bb8a830b60d8444934ad5a23cba28e908779645d82dc3e42193245211f737c6b520c359c6006f68f4e10333e1eb113b6be78be3d466840a4c86ed6151f8c62d88d09cc74da253323fad207949702cb32a9dc20c1006d5b24e0dd578051c7a48759a3170ddf35b5fcc9fc17c906b4c260569071d98c3a40ecc6d7e3bb3accbe94fb6dc798d5776555379ad914232439ebfe33deeba2177b3041ded1cd00d79c9a6c28af1c225224868806fb546ce19c881ef0ec7d980b5a629c00473f8d0ebe1c6853f9db3275b19805ff82706d7af0aade73563f76889ba485ffed862d73ccb1e2d514a08481e447c8b924a78c602d475e856c96e3b07de19e1e2b8c7b9b5d5c1ee76caa7a845f26915f2b7d21d55746d69ce29bd44760ea358579d44f8c64cb930a2346ab3f9c1a7497ffea32f0f8bf25571dcab4974cead981ae5c82674d9cd7812607b552242d0ad6ce088105b4fb71ef2d189b300327d08ee30a7971725f9ca0cea98b6948e52ca4f079681ce11165b16fb1219e3ab997b4e66bae959c35886b9e10d93130d08ddc808f923e54fa7c8312b954fd85925fa66600cc48bf1ab2733b07787710bcfbee2a658c274568d3af10e9fce84e24d5f93b53cb2bdde21a1f9c92728cfb597975689d23e537e224ae3f8542e3dcb23d8e50d44e10dd276b895b47d5d1593b2f85c8fdb3321defc2d1a5651a0d3554cdbd17930b19d747319cb13df0dd97b0f00ad9328fdbbc7935e4c65a508d0e897113e6c2b1c9f760b339b1deb7d48583163b8d3b91cb96b6cb22002ed0a3af0ab3d7b062a34dee43ffc5ad2f7e78e7ba11924f3fe9c4286829f82be5d3378237e4e8dbe4615ad1a88a9e7918488f9b48457a09721c1cdd776e85573101e47dd0e9f8a747eabfea35c5f2123e841811da3c4b60424df76b238a041a7bb014e859421bd5f3e34ad9982d80f0729d3c20852f416874278d87a66ef731fa7b1371aeb37e6192f44285892933fd7f4f370e16445c92daa35fcb8c975a77e59bdda705f0ca887e882a4197ef7c8ca674328c30a437d4bea6945877b514b6b3f8daab6140d7456cd43f1580b85df33a595449e56b3573e94e718570e7f7c06f01634507c45b995f2eb5b80b300fb806e1eac37dbe1218c88142ffc59e8dd2eb1f618b173050bc8f20d8432edb2d7609b552c641229d28a262cb974ac708a7968f503a190f17b608aace8adc7188a14d64b80835f65188556fb5b26e4a7fab4a3b33f93e5c6c5fd049188a1933f071310e5a4eb9415c2a98f44af78b0f72796a32c27dd1c95a11c7f0b0d63040ac115ee5052aa8bcda5f2d4c0e1dc1930801208707f18930e7b081defedfaf7636fefef3aeea0bf624c62e4f9db8ec4ffd54b65fd9d97aacbc4feb243e52b24a5895187cb10f88843bcf7c4e14c7ce3caa664c827e7df8c4b4040586a3b352d63d7ec6e50c087e8b604457c17418abc9b0f1b6d3a0acc26b7d272dde42618d5cf5e1281802e282cefca33d69ea35929bd3643eb435f4b65b068c9aa922c13c831fd0628d0423126d4139195203d7d4272b5f4d5b809213a33e93e142b1388831d76d45d53204c6bdce8ca7cf357fc53116e1347658b1758131f0961f999530d0954ba4d09b1808e014146784caeec4f937281b68d8ed0817838875dff796debbddc3ef838cfceacf89bbbe6278a7c3282e14b458d82764da2d4a24e879c40aa397dfa1492d8b94d1a62af1325701250fd392fd54e7004ce19425923350d5073f292a7522caf53d306df1956b80a9f137d06af6a08bb284ac18ee13f2a1c1f8dd9c00b9d8817d247041234668ad29c6c91c921b5de818ce5a0007ca71c7b844ac60ab5ac0fd820c38ea293904b4176458fc6ea1adf8bac35b6537f231b10eb056861e42d01a01560f9fcdcb77af9e9077472813d0cbbbf6dc7d1139093bfed941b02f25377f8d8a2e94c7db9c9635ba4e8a43b086b8a433867ccb15018c261942eac31cace994313bcf430bca1cb1486c441339e8c833489d74557e91f64c3274e93b5bdcb133a4daae54b0b4cb541526c1418bba6a4c4607dd276932069741e527a1aa8fe4e9db5587d43d29a0fb7acfec71c6f1e1b9f1654f95614bb8d1009150229793984c6cf5793bf298ad6230939d30a78785126805f7a9bf89360069829d9efe94b2343ce30ce7edac7b9a849d8bc219615ac8cbc33298fab7457ca5f1c3fb685ce8bdec7f418abe4c1d26c8c05238fb7bdefd0adb6f3cb66bbf304becaea83d369158cfb257704eda7c171d16d9a9f7086f7f8c44de218bc88860b4ebe8717ce7839c7986f7fb6f5130d577573d50a4a78a8b794128f1625216b57dd6dfbd1e12291810833e9cb05b7a52543a54e910d95e7b1b933a3112cbc823aaf1c3aa2050d000c2f581a41e3ad310475c516fa062b0f9ddf94f155e6a3caaf093431937ab014982281eea6dede392a798f432db80a0729a73e5338221f1ea2181ef95146652fed74f3aaa92c919a5f648cbd5fde66d77fccbc3b110404b4e5df4ff8e7f1175c1dff77199f7f661e24b439eabc716840bea45cb918bc85380c39645c590837d9e8e869880f36429fc5f8cfbbfff99fba05c9163e872048849419759f19bb5dc773db04cb9a2dbf9090615b90a51496d807667f47ba1403eb9f1e1a05e84d4519074a0b8d9281068c9c75654b8202dc05f9f47e8f4ca21a3f4d1ae33181709cfac8a91ba6effa1e9800ae9ff049ddaba5a218eb2a0eb85e3025fe6008a55f053e798699b2ae4320abe1b8106814ef6124869a6c8e128fc009f6b47e11a3fbb29e5fd3115c8fac43dd32584e2c1c177809d256b0e41963a8dd4ea8e3cc288988c07014cbcf774c234d7de4d52af891501e0ea8107618cac90f16b4d3e95dc0aa607f629042d99b6dda4580f593b3d357ac6001ec1ce7a7276c38878603090bc0f1ed22fbd63092a0cba6da2a211cb1081c3a56893ae1225c87435284d63dace3b3cdc20deff9587c0889e6ac3b81dc2cd9ed66d2dab21959ae68d9596ae6d9fb4e9d912e47632bcb3ed1c6729e8f798f01ea695377a744711aef8eaa5281edf3f321f6305d39bf5bab10220ee326791d1b768fe3854512e94adfa554d793b4d798164388fb51b2c87b2791dab9dd3f8a509b3c8d10103e1bd72c228a467a4699704665967b33f9e970c084b89dcf5414a353cc79b75af297f5ab1ef897f9ba8ec6242e72bd189695599ec26f494f1af4f948ef608847b996096422e01475d3b19c2abb6d58884a62b6e21b1179fc48672f9e0289cd594f3b519420ad3c7adbfaeb961ee09435b576eb03efe91a0c7cfdf2bc41f55092d7c4741bdb721502953e9e32a58b2afb2fd0cfa4fbe4358e9de6720290954cdcc10cd118155d5392c83506392a85c9280eb938654a923bd56f2f7fe33b5c185ab1862a6837ef74f07ba028d698f09e38dc59a7edf3870cde806ae6c2d72407fe909182982a3ae04870edea6e65a9e0525e33ed7e0364850d0b1d853554f0e2ec4c4e52672c36fe39707cc3797b8d3616a095cb6fa4e8bfcb95cc237231284c9e6d91daaa86c16334cbecea1ebf93f2167144f52be114e36de40805bcb6b40962b43db47f9346a4005916609225706dfdd59e400a2f42ef53d49125aa72b9215ec21054d773b8862558286ab331f2e9079c658524df904adc00f4feb44e549b85245b123fa5a0a245179a845edc1f1ca228458e69d62b9e16038021e15823d2e47d105fc10acba7e127efca79b1141131fd3c2b2cd33069f6d70bbc3414edd9ba7e2026437397c787abd04bda4eba9c8360a33211d2d94dc3c26489f71ce683b2e0f32b4749ec4f01ebada14f6341a905efe5a9ddd2c3eed38c4ce0d8030bd43d80531968f6bdd8c3a5afe0134dd052f43a1b7bd0c18ff89bdf433c79bbf3e9536fb595b77e4fdbca3be67082bb070e8bcdaf2b02d129172729b162af81023b5f00998a53e074862acb3748359b140c64f7e4b749aa541533e98a881e3d2227847476449c83098f527c80674f7043a3e57c32784afc543163896cca0b78b70a36767fe02f8dec8be34b0d077c183c400abff7a979cd9999aef6a66a957e43a13a484a2fb32ed3befbb00968cf8dffc3db7b2c418ce648630fc403bd3bd27bef79a3297aefc9a75774cff46cecc6fe52ef6aa42b2beaf601c84c2480e0681610a896b8d764e87cf753e0e6da039e162e22ad50a447f54d766ea3e42720b695a88f23645956d2a9e398e2703849c9ae42a508bd8fe27ca9d9d08e687e03ebcdb7ba7a761fb65025bfbe239bef9b640f3b30fb716d1586eb2d212bb7a31e1172322105fa401ed22ed1ea2892e21d24760d8cc1e938e858ae50defeb3b6352bfeb2d2563b0c6360c6dfbb3b49fd0f6adb7fa961b13a95113ce4932bfe247328e4ff341351f68268df1d133c202d22b2d72acc2209335ab0caabbb98d11881e3f754c40b163e989a3912787a322410a98f625735030eba50b20ae4f160ee5c5745900048c73405c607c5c496eeb80a596b8bf7f33d7bf597ba84b8dea7fbcfd324dd2b27f8a429a59e257d2f0cf15cd442f2390ffd5e42171a4c13d091031aab0c8e73ba37a30a70f9ae35f4e49267d3a7ce53b3f667850051b51a4ef19ba90412206244da38f02e8612e384bc37b9a497187e5f2b38e50eece32c15e1bc2bfe2d9558f17a6304b20ce415cecf42baf3ed181f79377c2707379b8dbe2bdf3acf84cc50e60ab403b956c039f3e947b6b86964280c1d6da8c1790226d1ed6925b614c43090e396c5b6bc3aec45331a9669f80b88d25d77fa0152bd1c81052dd6d58596f421332dabf7b03d3a556352240815e3f3e62baa7e6b0de0cd716c53017c74c3229bfb1629293b4d44c9861a3c32f0758a2e661f4c86f69ffccd3e0e737103c66198f456fe167f33ff27fc0da18f3c12cf5478967c0cf91cc191f4bfdc150f06f8cfb774a528c3eae06d81184faf5c28b0e6d0185eadb6a96e2af21def293c8c5f19ec39748053cd83ac2c05fbe369bebb27bff18a2a7492ed9c02659cae31a6f45be4f654a74342262a742a251cf7857947a4468fe562d88130b2709dc7a83cec16b0dd589cc56b768dd5e66ee884cc6864a7a104054c3d862c404011b9ede783f7152d4dfdb0e5035e25f66833aa93c4a83994381af95b7b2775acf8b00bbdb3c816708fc1f9dd8eaec28a2ab3eb7eb0d92a87fe1bc4f53120130c1bc0d8e7fa8b11a6837f933898994122f97855d3a2d046374998a1d12910a9b0d4a2554cf6170e87c5d6dfd4856befbb533e0ffa9f59114de4f14e67aa30d02e061ad76d957fdd9c299811c5682e2d299bfb61f61264fe02b1573bca66c890466c8148088278746b28f27099b5f3e404b974f49022ee19e227b5f5ac8bb4b065f3fbd8ebc02ac28e6fe99b0866f8739685b65420f0198161f4fdefcdb2f0ceff3a2ff928fb9fbc195318e6e163c6a28d59e2fb13bc820dceb0dd22c1e595dd23c39edb6635f06e36119c4cb0dea84f7c29f7dec2d501e8ca1a124f63f499cf7b3e097829ab4a6b32309c680980c002ef5f1581b3a18a3e75f8be83acd003fca1df8463005d55b779b3073d67ac901c296cdc7b9daf0192beec682f6988614d875fb2e3add99b8ebafb5985a9a910ac7f67594264021dcc00e5cf6877811fedbca60209748cb1229ae695eb7503a9395acee3310af7e5c9ae3d473cf30da710c95e7f47fa4e4eebc3e8796b65512c6d87ca9bf863185e7194a0984e3d49aec43dee50d638aac1d3d1d519bf381dd34c1c2493789d46904e41ace7b875d74d689f7419e3b27f071e79b1b48312275a9660cd27d6f40b6fbd75fc813ebd5c6f8d86bc4dc8c28278fa34ea6ae8e20a2f277d6f58882f574f04e23525bcfcb9255873ee1ceccafc46d8969840f9441b89c7156c7426139e61bf2ddb338a7751d1b8319639190d48d563915daaf5ac4e1cfc1d1daae1915de80f3029cccd62f5e3d255dd2a09aea18cd2762233cef8a887adbded83d792a810de8486ade8fd666e3326f89d75ab29ed714e8908d9061959dee40abc7b7b3c3ff250c032cb2aa2d7710d12176a0f1ba5be4386382bf477affd36b733f674a2498e50da7cf3656a2bb6b2a17616545c34931389c13930df31a46a613c7f9e88924dd4f71698b6d5f2dbd9b29cb71663d63d4653baf4a419cbe9dea65385766b77dbbe1329d70a82636f2dd755c60f9e60adf0fc11157e0bdfa16f5335ada1cb887c3194443cba3d92b127278d27ccc2dbb88498f6eb427990dda76eda569c70e6d4cb2db643dd77f198ee573c606fe859d749a9328b570902b28bcc9cd3c3f6b89f7a12a9771026e306874d5a0d5e77311c52aefff34c43a06f1e4264a299895d48cf2e7194a58ea2614005d85e69737588798eefb9e87af2ecdc80b18b3fa297da46174b24a7a95bb2f2c77af5e152324147747ee046bf67042f17ff591bc9c90c806778718f89d17154b09f7406a6102b25b435652dee87974998e30eae51c362228b1769a6a41db6ad5fc60ff183771b3c9afab08bc0dbf6b886fa72c8fc9a39b3d6f97d78c9cbad08843bf2376c376f9506964112c3bf004e6dafcf93d7542515bd177b157992a5948b44b1e4a426146f19ddc396726e89847e05aa4d322811c264034650d15d88a1d07bd2e9a0d41b7cc1819e79096981c9bf624c50badead293ecd82c3331c5065a604418a768d26ea64967e04bb5ab8fa0ade5afe20ac6b5aa950e42e4cbf9eb91f6cd0c887fee4bacae3ce3a2cbd2f12533d56cecbc835e6a6c3af441de3d273486df0117600cb209ef4d641261193cbe828ebe4b1f156f6b0cf8695f06e1cc1a152e5286b29a7c5ef06823bd1a66a57e2426baee72e3072ec6027c9e72da3a01c0c7ddc4e9c0cc0ed221588676fc04f0f60de0aa0c838d3202ecb65cc3c931c9b413f2b349ee0c67408ce332944bf31d8d64a0db0f2799c9d8aa50682de2037549c96a2f38f24fe6518d8e42ec060bf6aa6eb4b3e6a1698861fe775f4e2bbe755b8468ce62e0db41b8d21383eedb746f4bf39e2d86aaf120b2011bb07ca6b9e7f28c2c52edeac05f061ac95ccce320229d6d1e8b8ef4c627b99c8f9d5163043cbd7982a7f11fc5bd0dd2cc3659c7ee4117855b9c1960b7b2f1b571929b7b9eca4848f23cdf5a327625f719827964c7c09949c84144f355b1894b94ffb6a9c156a63147508a49f69fd607467363fc45f1ec64b7b05cf7d992f801d963d4f0f5b9a19e31e91308dec7027a72c349e8dfee94834aff8f8fbc16505feb3862221c9eac21fb04bc5f47fbf6ef59f6b6820896f8184af2a88632985af3b0e6f81ba7e19a9ffd2d8ffaaaf5f98e6fe63ba824d8cba77ef2f1ce13f9d0ef516b93111d13c0e4557680c1ba3e2f72517cbad4af58bd5418602925565555f02c68aeb3ad9ce983d881257f0657ac653203748f9fe0a24b7d01db8d09b31923e656b95bd51d539f75d4d0c303210de3daa620f91ec5b883ecfa0c6b4d4d6de617fd2cd81d24ce44760559d7fa833e97c35a97e19b5a3222a8586f990a54705fd92761b15ca592c5c41f5307f6ce188530cdb2406513d6eb7f1c389e009e4741201be13054c1f0045ab121270df36ac6ead43af3b0b226983b7719afaab31257356833a74ce8d7cb90c1165f8f226c39b875fd49f905103ddbba397f003626fc83132b11423453175f7535b51c2d991f545c37d05eacb49575900471b00cd926415b4586556b64bf49dd343a0245b095396bc5b560403cb127235bd9039a0921870867153df70cf96705a60413f4e9dc74d142d548c8475b99d92549f7bd1bd06c7fbe5d33eac31ba44b37f0ed4bed7b69cf221bdcba0e55dc7c0466330db29b429fd5c1e0c9629729cef0b191b419aba53d7fb7a9fad4bbb7d438aa1b619f44ba5170c4d1f09fb90259734cfe6287052f4ee46bb06d4e3633ce1a724c90a744ced500f7ccaeb7aa216b2922648a569e0ca62555d0c1b545a31d27f04290017bdbc5d2f71bd67e4e4a0ca6259dad32fa9cb0a952f743d8e185a41d59cc6548c09260952c400eb9329850d82bab396957c5adcf87be35cb369b47d0eafd065a685e4f9aa1e4637f82a0e8bef95a676ac6911cbe2c98fab6bb7a12570e2d7dfc9f4d4b6c586d8635eb3d345eb03417762641735bd2d1218522d8b1be026e55fccda2a2ce5771c384ca57fa9e5abbb3acdf2814796084bcf32caf8fe5d615610386a682a0921f54547d14bf29c95db48497d01ca73f39fc50cab1e1ec003babcffb39c0e36e89900116ebd45ea0110f16ae8190942cc2a56efabbb63960f52a4c5e1176171555c6e3ce64b555ddc8fdee56d7395faf3cc7459588d825adf36f1f2d544fe4130812a795b5250dc9a9fedd60d99627c5b886ece79a8d56a5a11b2fcb19f7f05703b051906e9fe9abf84a4f85f054e8824102e972b321edb52690d563f432fefffb89611a14f7636b53c10a3d0da2cf1e7b86fa44f364db7fac7fed10c7c91fd606e86519dfd6ff14be7efed1ffdeff8a593c4ea97c64aef442994c6aafd0fdd02fffeca674b1a1efe63b2825181c58b1c31b38ba2e354822b2edaf32a40af526abf18daa2307fa0a0a85ce1494fc9af0a183020805e7006a870ec5b29deef20caa5acb9d3f762d422adef7a90744a111ae0ed8fa6187c622e2eb16e4caf438f76c52c38323317ba218fb7765aca73c8966c3875ff8f04aa0fb546f62daaa4908a13344df8e472926937cebde01554cbd4ca3884f64fd51cad412d0149749554a91755f422919c9f546f087a18a30a68d9721fc2a9e9fe30662d27856ea32ef762fa06574937d5fc047bf30941e27a53cc5efa84fddf78b605b4b2688b60aa2b1c5e534418cd27e597efcd29b8b010e707a47ebbcbf8f1f71bac5726ee90bb0f36c0123b11c2345c951526b61159dba737effac1c20c3210c46f785c9603712f0316aa851cb60b0e5d5a426d316f68d506a643013f89d54c472518c0c88a5ba12895b94ed6010a1ed3cd13407f33306e58fbf4a8c57d319238a07d9bfc8c9088d2ec24a36ddd5318a376f14e6354b7d170f589c2167b6a576dcef7a3d316b95b83023842a4ecc7cfc56d2b85d3f06946eeb48ee3f47202a2bdbec83bab845ccc875620e84fbc0d7d27eb47801a4bd383f6b4794c512f30f23ecceb739a6e5784bd9412a808a139c1de4f0058b9f620b60acb6fab33c9bf17f527b7e8f35a0c3264263dea135582fe41952cd35c208d2c7e0409f66668a3c2a489c9027392723c35ed895701e56dcffe0f87d34dca85cb4ff3888910c850eef1a618e7fdfc8ee953ee194f0452f0a91a6528f749948fd1ec868e0abc2d80c2c4ae8e667f6446f69caa30c6f0fb2b00d1ed283bf912d8ac281e462d39146d3b5047dddd322ceb7235edf971f5dcb3c91f153ee44d4575bc0abe03fc55cdb8532ab39338f83d67f19d9665d0f68de8a3ae9728762df0b8a7546cd20b44d63af5fe6396517a8e5cc50d8e617896bdff8edf98fdf334dcffa3df1831f7cca3ffb32f20649b623287a275b9344aaf620ca52c56bf5234e1a4ff0b0739ffd49e6c333c615f400a0744e0b7906b5c2d556e09825c77e6bee12c4d7fb821a9ddad0b987c4950244dc82ef3db1ce5a5b805dd8a48412747b3518ede34dc68f86941bafbb652fdfa7e140dfce06dbab76e1a4033f2a261b25c409a02cf8a91752cec23a33051589b333c09b7ed5edb94c7c22e97b7f199f39bd78e55ba2334ecacf2c8f4a395627fbd8f0b5037ecbb62a13ed1100cd5ce4cb92d60ba4ff0a123af5a84a09e631c4846abc651bfbb12dc9652c6b1de67b3ee57bc1f19c5f95ec169dd05195c7521d023c3e1671b68d69ae38d5806280ec7f465fceb22c1281bd95b084e87bd2c17dde8897f726cc1ef34c16288ea9b4624538bda4c68b9afab444a9fe4719d488a241feb86457741f49c52960d70d54086ae8299caed0d1a0d91ba668a6841a5d00831f5d63774c1cfbcce08d87e3029fe309faacb17aa0fe6ae054905af53386258ac72ae2e61f507f99c20bcab25bc596b95faa3849a201fd6ebea103071b6e14664bc8709c197c0296d95d9c537b77cdc8eb5d689b104db1d06e6604ddc081406dda40e9d339f543dd91d4baaf549879b2ee7269a0b2f320b48789bded334b725e253818005b9801c0f7c4d55e167bf6e03fcd8cac68e07e8f9b5b49d54e8af91ca0674e527c2a6ccfea1a67cc4485a0e8f48cc988f77bf8da4f08dd666aef8552025787e54d0a7506352d5d86c5ecac7beae5afe5b7a76c6631748035e343d9d4c34777b4f4d6fa9067739082b77b04d74c40396711e0f1a87384b47631a31eb3493b4e253cf01ea68a5c47a972dba0f07f239e0d65562d86a7c25c81b8eefe1e3c96a48f3c4d22a02c9a3bc0b75ff0c042744bf372c6053be9f223950892218d3c472dfc5cc206f6ec5b6a45ab032e357d76697d88aee77acbc85dbd51a17a24a3aede1734ab551e28df5b2cc87f845e1c6abb8c2e7c985b80c045ab9cb30ee8bb37315ed0aa8e2434364c4b44fc541f4ae6f96b2ddfbc78ef8192f1d32252f40e6aad846964559b0f16a654157f3dca94741e30dd8426f490d93424f551f46ddfc5d754ca71f29178a0f76509d4abfb6f53c676e6072e473cea0535908321e7f144bfb252e0ab93406a6175d7e42883cf59c52e9c25145049134f3c36efb9940fe75db5f32ba9214fa80b392a27ced6e555ecad09994696afb849e50970d2f7ac7030fdfeb435ac38377e97d0413f2b6c1128448604eee2483906ddefec476b3ad94441dfe8af66bc4016d11ff35ed9ff7f9396f536b98d61f65c4bc219afcb00355b1d886e7de3c593ab8e9d93b7023e22af4774ac4f5e94a91a6dc617accfa0f68610f2d0d71a5fd84a4aa32a7c0e71e96cedeeba9eb4ec32a98c3227dcb3442dc49ae91cdc2d3412cc3b96094ab88f2a74d36ce034c9efdd35bb18bf656a18ef1670be06f7154f17faff3fe0747359b0209d57c32877c3297521a9034fc734fd799fef19f986d8a518472f45ffd8423800f5b8084001c33b4d4c27dc933a61d522788575e0c697d5cea51eda14ce5a6058039c9181d12a19e9340c0c7067d51841ecae0497222df02296166669beedeedfd2c6e1cfda6caca0db09a509a1d19dbbab1bd994d86ff20009f8d0f4b502ce4ba6b06f26e2ff9dfad963feb69cd93df16af0dacd3214474dcbe4076034d7466e5ebc32b687433f36ea32c286ef3785eb09b4900701c35609ac78a093b589ce3f59d55491597a12b3bb0e67c81905757a36cc36ca11ae8c62d97c19061b8b1d3f8ddb93257be90cb4e033e094cdda27eb1b57dd0db1a3d01528cd662343722a3f9d54352fab0b9289964b0a1edd07b48faa121bfe383ceaf891567aaaae6227260afc86a460270dfc088d1529f92985e77003af27624263aea033a05e1c759a9c6239fc08f504b5c28adcefee92f9a636fa8c439a496e0e427c05248609ac5b00e41bff0671d748d02426f9d22f4418efec6e96c6e05c4914b67b4686af24f66a951210328b882544622385479f32a61721609f9b553bc10cfb341dc000a16129f03b7835fad7a982926037b7def14b6a951ebeb0a3528fae1018afd4b45663fabdc96de186b7d72cd598b0186be7f774c8080d46b8dd7d3e92211db157dd5f70d5228054dfd10b46556e8e64839aa733f00cecaf9c9bc4ff543cda0efd2c282461ca0f65bef22f87283392fcdca466432654f6d7bea8b898376b383c36fdb4ee9225f70c9b071578e07645a355c8dde29deca951c913565661295caf6de5655379ec45ae74486ffd10feeeac53e64ed0f08a551c2dfd38cf67f433c1e678e96e75f7d98bfbe07a8db9452f017ae3a226b404531884012e99d2f3619c4e8a084d55747f2be43ab5b49b99ddb1732a6a947c9e30ca41d4ee8d62c383cc238e04e85cc756e390b4f6ebfbd9b2dc9ac7da5488a12b0a6d3906d70af0023021d1d41d76dfd4ad9ba858f262cd9a3e9b8bac0121daef47755e8763137bb51f9c819b3740c0714c3b49acd0360f348cb9f4d5fed5b08455bd5b5a9e3a2c86df25233ee0774d3299291bf06f912643423fff4f4534aabb99b327224ea856396436bb88511522e32e97c41e63c5551d604f0bb067fa8c9d4076529027c3d9be2121cdd3eaa5f23854019ceb45082e328718790de1372d668140ac24bebd2599812eaf905dd19fc331238b844e446c5251fa5098aca35df93d1f0a36fe92a024cdd91de03de19e6e43b217452677809f996a04cd27cd611cb1345890e1df5efcbc5f3f51255da7429198e03b5e1d3dc8ba1863588d0622f97331657cf85e07d47da1ba3d5e00ea551f48f4d530bc8abf0d8029eb41c253c594e9c22d7918723768badc8652169bf065e034f0c3b664b038fdbf5226a914760c5130efabd6e1cacc542346552a28c4f145ece36505624bafb03cee294bd7efced3272b7734870424bdc31f3d86a11126d68eaa410f4c44914eec936c51f159c822ede5be1f6a70877de425e71461181a9a96b87291bcbe754548ff8155ea88afaf6d071a7a8d754644ac9dc466b8c7c01ec9d251c6d1ed4a0e1217e211c917158c0c1e170b55708d27b064b82561079183e6e3463ac993586ddcb74ff54f17ad9fea490f7211dcfee4d376b893386104517e39d5bb932ea864c1fa244ec9f7b3b92ce83bc08154a2ef89674017392944371cfe1d018323f0c2a4fdf65eac866075fbb65843748e8562f0da090b5a624731721c2991353f2d7853e0e8f8572f21c9143d2490ba36f5168d2784b613beefe2990479e8925368f3c1bcb106794460fa9407074ce13cbd36996e3381b122d16b6d567770638fbeea121cc7cd54e6f55481661387c2dda6719bb2d0a54a73607ef4352b0081f2a362f949c9bdcdd42240ce7bdab7b391a7a8d84a3a0721aaf9bb340c783563193e6a071ff20b21f8c9649818d3d27e1fc756b84fcf936067baea17336f3722ec42253baa2ccd64d6fffd2b1eb2a271bdaecad4edcf263957ee39ce5b2ca6254e54209f088731bef83920f6776369a05e46b84dc19e515d215c3c1bd500aee45629dc4840b868b11ec6653979a1c317cce790be19da0d0493a50eff8c43617a8e9ab72e39de2d9fa6c1ca2121a66ca9741278c1adc0675739d1010d4ab9e907e6c2692b07345f0a1851d33b09663e40a42ae1dfe3db05677ce498d3109c42d531d0283f1ad3583b64daa0cb4a306f914de4ba9a989b7c4c2057ccb72c37a224d2cdd7895bf1bcaf37ef3b128aaf4b91099fd20b183f31d42aef07a7d4ec621f692f67bfd6999e801817050eefb9ba85987c6307ff31fedb020df9e549f96cf397ec311762c17127e3a0e446e84aa8a3a64c7e91272c274ac7cad115e381efd94f012665948f6770d3148ecf682eb6f9b512ffe27a2f5a5be151f94267b3caec9bb44709122731049135f596e900db5e3a0477eaa5e8fe4d051e91d83777c87174ee08b012131c05264044d5f602cfd82e19a2cfd84e7e7075fff5c823abb204b77dc8185a7bc9d0fbe08e224687a71edbbf11440ca2efa537e68157eebed43eb25fd144885c00b1346eb4c7fea9c1b2500b02639dde05c9c670a454d4fce213d512642ae35d7b799655ce6328edb4a5b5980f343e5aea7ee84fcaa4dbbc1a54f49d610354dbb3a23ad1b401b53dc8c2a00d1c06e5e0deafa7dd9de49e91fb45e1c453b630747a5733a4838a839605c2a3ce41c6fea9afddb315fd218e4013a31780a07fbe6c34cfad8b6382ca99f65930c63d88be4810d6f75103311b3f39404fb281cea71372aeec75711025fa0e07a8c571e851b91e07444197eca002b671c04f4062fd2af114050aaa52bfcc9cbcda1d1653edbfec39a8d8ab31067113fe9a632f428da451eddcc8cc4087af80a05182b2d2c5b7fd4d192a7e67faa86fd1e22b109d24e26f5fa855d63e6790830233c105c56cb99896b78f231800a6b963267152585f3d065ac78cd3d42e1e1e0e0c1654734c7fae73da28e0fb4eacec9f9a1fe20b91a3c6f50e7f3bc8966fcb91616851c1c75af7af9b041ae486740c19554b66811b537c3bcc80540412b0257246a152892f37e6fe3f0b5434dc92fbd255b00c9009c58002488a21f954b28fa1ea41a41def335733762e3226ddf320d787f0d00ab570efe50d41399463f7e189d3b50fa0d2c6afc4efdc4d837bd3788978dc0c95590636ea19cd181ac7a230057fb9c6fa3fbf33e4e8702aca547ab7fea8be77e679b6377d714a9369ff1bcd243e1bb899b417b37c6cf70d0207e1fc21a0639ad2b98516ca596937100abcca50003d6382221543d3e83cb72516ab3bb93c539c043db90ed69c0c2db8b86ded3b5e728d65c94a293f04f8ce8c0861e4c0f44f5e3ac9ef277c5d962ce5995bd5f9c648362405bd94ad36e13d1613e41c3f9b76a4570ff2620ba0407403ffb00dfeba21916f44c20196e9e730328bb1a44a4789bd09f8e01b84a367f4f5bd533b024f11db5d7cdfda9db0b29a9f9a9c5de0ce3bbcedfd2edbdfaffbd6eef47c357207f703bfa2ea5e1ca7bf14d61134a6277f897973e0d73ff3159d1a84008cf227dd84f6eade7b6de128ed45bd31145a110120d67ebecd4f343f8b4f140d374cad8d16edb0dc542f9755d4ffe6e066c9b4e2a91015e6b1d82550887f01e35018aa6bfac0229b00af29bbd7fe9c2d63f4b5ace3dc82f3d3974b5bab8713ab4129f39290e65f3c8e8e18d5f0279f522904212777a84de51b21caa1c7211152f822b366ba668ebc7e72be5d767ccd449a5fae324178b4fcc11de61a93dc82173e12023ce4dbcb8b233dc4982faf8c117e7b02aad76ca2da538c2f384f5295a83428e0dd5378f8cc7f1109046a7692c179b74e66a8c4184a8c1574e45c28ae829dd1ca1a523786e049b371b3b18d661aa0daddd7f80a7a3607dd2cf7b6a4f3e6252bb2b31f7c32ca85b56ac9624293e76b0e8f1372c4bcf87821be71fbcd3afb239ae7139f12d8d9802fe34ecbdb83dc233950b9fc9e01ff5ab6199e0f0f2937f3b95b7842a1199649843d3e1f6364daf260839e9ea151ac6dd29056d474cb79875bb45100e130674a502ddcb46b89bc406f1e4e0afcebaa2cb8e28ebe66e3b0f95406258a2098b98c770846886b026493788fcfe46ed1dc568ca30f2dec19adc8d1d8797f9975e2b963684e992c11566ba35fb6f2bd38ba9dc84228db13bab7a8a5bfbe8d12a77b0190cb872a1ccc384b507448f4c6d43a4f96b3e41b00b44b8db4020240c2d8cc0651afe34d3cac13b4048ac86e6212af6982003cc78ca78e8850b5335fd668e0b6fea03e69226b384ae27ab341067c89a8dbdce904f5ba65909bb1e0116ba1e2ef43d5f62073c84cdab1ed131aa3f40b934df597a035c85067327e78d94e552bdcfcfdac8b38b749e659120d07f25df91be82be6ae1a57d64093366185e27f663f7fa41a158466e82ce7cfb6e5b7124f26187ccc970276949e54e3f8726e633bd6d22927f0c66077b02fe63de6f65d713c8fea0989e53fcbdbcf0bff78bfe475ef827df74e2b229fef55df54b498452ef9ff37f6418c601e53bae434374120d4b10b1867339dac37948d400c2e03acf7cab35e2c1bcc71ec080e8c295a1518a70e0e2834c4c608a31ce7de2551803be533be97aa8ae144a50a59e5ae0ef57004071c615415667bcdd5c44799c241896a410bb94a3ece73f0d5cb5ec8ec1fcebf67f3caa27750f6281c9a1d4c21641acdc137d1d3f2c31ed361878b5080c400f53114d31b45b5aac8d31ee37b541c8f0b0b82ab6c8191c5292053b4048bbc045b5cac5a2e4b66344d21ced0da9e0efd98ac6767d585eb59ee0e194ecb346258158568a8da216ead7ae9bdc593dcdd5e8d495a3c24993765b3578bcbcaf3760e2ecb3b7638baa3f5c2d1e369dfe92daeb4ef1810c8fb63039f04d1f7f49a5f6d079329cafa3b090ae76ce94b6dfe61e923f0ca8b9c409ac5d59dbf56792b2ed8d9a766da86518467b5c6f9bb0e745017cee7d3ed58602ed8479ebf9f8bcbeb3dd1e4d415fa4e8d9c3c52abd14f5062705371e68c9a97a3f8f67141ffad26ab8621824f6f59a2f1b975731e19d2ce0ff50a9508d4686b981fefd7ebd7a46a50eb73bf09266e4d6ab4e0cce41523425a8bf15a0b5367f12aa7e719b1008c2df6205f97dc3b5c27a914a136c81096d6151795e2e9c41d1a005c8936593339d35a7af0795d0dc0fd1230f78063886a4d7a65d8d9fbb2d6d3314754d3b28c3d695dc2d336c846d786e9c9abeee43ce962c44103c318545c6eec3a8e6d828f638aa7002e08f7763a51876531b21dac10fbca9cd5e56eec90a3fe56d811500a7e38d7ce108e81a3c5398ace2217cebea57a49dcf51ecc8ee3e7628567d3ad9676342ce4cc53aedec55bae10e03f83efc598966076a536aa5550a2fe8cbb78f7b78e1b5a8c593d785a2fcb87de0ee471548580248318e6aad39ef5d0ad52fe78f0bdea9fc5ea0086fc913f217dd1be359cc1bdba24e68dbd260848c73eebcfc861701f86bd710cdd0cd3a730cc34d7fb3f727fe1b7a7f7ff5fdfff8fd4e62b52925fa5fb3784be8fe87a7297b83a2856a8c09c26cd8cf3859156f91f430b532b67f56cff68f4020b57eca50a4445b14e464ca527449e88d0fc4aa99c4121cb9518583b427f97d065222e94e1a2589e1314ad360add45d5464ccec84ef4b2e73bb6a16ac5d2d0f2fc4491f41066bd10b44bc0f6fa1b771a881e5cb741fb95065c2738430c91ac7f013f5f0d3e18669698bd0ec4c8a9b70f24c3245d2520e21014b28ed86e1b7db169010e836e64df3199c8e7351ce13f6234378ce52beba8662ce8656d38e323c38b29c722324540983cedd50fe897ad6d01bf6e01696f0a370803865a64c9341e5f140a3de42e7b4fe7ced00daf24b02e7592589e9a5f93067a589b99fe0d1da21911d7df5ce5bddcbe7e473ca7b9620c205b7fcf8ac197aa2f13223291fe740359fb2b6f7b5ef2f7d335c2ad2033585db6d3aaa7fe5c1684cb97463362e9fee3738464f72d9ab82d3608c954b10064f25952f3994ba63ce21124e739d02ed26e45b2f32de3ff238938d349daf94618950afa7aac98e31dcb16a97778b086b3de08600686a2599fa18a5bab157fdb13da4c79a6304c4ab573145f75c953bac6672180d1dd31fefc738c19739cc308ebcce005077f606b51b3b32cae4df099b1da30884baf341b60321ae1606da9c99f5207c0d7c78d8051ef9ed205434cee11985929a2a9f1f0dd34ba9cfa299cd9984f8f69486a49f8c287cbbdbb518051a324f5a46b0b0b1448280e2f841429d247f908bae0c030238cdddd029e7f11c8aa6c3228173d2c15e0931e86f68bdb3bb418031a6e0ede3a5269d0af39b03f5142800b032f91efad78f10a2cf1c2fc11d05180d83dd674cbf5157c42cb85a9a0d33938c130b45c606784eda08495a0678ac87114f2aba9d6c765942983b45151921ffcc8c3ceb102c791b6c2eabcd267e914a758b995f8e7e64aeacd4f915ecdbed27273f432d55a2f39b1240031a5448209aacfbd04e375e2816ff30fc4fe4c64b289678308c1dee6c4cfa0737d9b9a1a9cc3f3048fd373188fbefe026ffb79ab735fcc1b6218871aa9f8579bf533205a4a94ce3e7080bb11a5118368153079c86f40b6bc57c7e7226aaa1c7b1f93fd1a6189ba84795f900468683878092b515712d3c169a82b22f477f3ffca8860ea79878d4c826e1ef7363974d58c349d68a153510cafd6defa21e93e4107293e2dbfea91ebb03e196b600f8cea53edf21e2ef8365444eafa3be8a6c96688c5d028c297e63ce64561200599c820289a0280d15a82ed2d44b020d26336cf1e5de430fa6d5a0fb1d33d2412acdb9a6edf4f4fe781359b6bab95cec020a0c74b4e415e0067d43b09296d9e3c19343ce89dadc3970e770b2dc6e06c8193873b7265708210e82055424469d308e73ac4d27e098f0284b77d792d12b886924b9db804d845ff818b9a15e74f5032818dc4e9260ebe9e8a8ec96a36c5db766c57cb1a1d1b452b4af3284cee63410405f92231a6a47d54c922e6e6b0bce9e6c2edac5d661d512b9461b7766850942a8f7aa550a93290fef882b016e3a310b96b623d94849eedced02a62f0e69226f49cae1adbc1dbf9fce821110e3944d89dcad3e7223a48420a49896cfb19bffe3e68b36abb1373002c368c1df9b9311847f43bfe69f3c7af867cff4fd27562642ff0fac1cb80c1dc02bb249e7c23a1bd63a9ba76fce569dac0c3bc5a3b68960aa7556d9da7b79837e6c9749cefab380b55ea9a1e0ad9a6a531c980afe940f85d0cea3d4d044f94372eb53471c42687222296e144cd3c11687c2ac512d372e5ecac8431ef543e7bc95d39c5df2c33a320e45667523e5f9676b382728a9cf11a8425568b8ea0c95ce1934fb5473d4ded09ed4b245d4d1ca476b3253dd66cd6e7732842197506df46880124395dfdcff042254af98a3bdadb13d0ec579e26cf9c4e374087ea750c3ec9a676745318134859e59932a210bb12cb76075b6e26447426f862f8e2c4ea6af4ae163cacddf1bec27b75c9233fe2fca8c696b1b098e2f71f7f40223636e438f85172d4e0cd75f8d35f79e7d0d95c57e25dd42582867d3a88a325756281098e72640ea572bda18a30cad96fd2ca781a41adb314315765c0e3a2bb0b5d22e2d83dc0e3057fe6a98c3f3ce91db76094263f119e393b8b0574870fb34955324c24dd87ed606b09b68127539a0065ab90858c8ded9a6413ec5508142d1a1797ad1ab60cf7d03c7b47e899f15ad6ceb63d93a379c91e2d854df61dc688261967717dab4cd6505b62a91fc559705d27bc08d5b8a78eb1cfecaabe9c473b2210285737c3915e90b91c2184ba4e7cda9c4f9ca5f5b6d38f38fc569d2b757556644be131e28733b8963d97cad3f7168d72059f6cae4a6af59ad30a749aa119f6653ac8ffc648075adadc9c53296841ba5c48005025b33f299e464082389ec6474f8715623df5381c9a6d05b97141423a0330796f66afc87710591ea1fa60c854f75be2e46f0a6f6df26a927f071a5fa0981423553e15aa870e841d507519539ed75012365d14865901d3f81f0283b314dc87ff9f7a385edfcf20f482b25e2ff7fbdd8ff12dbff073f4428c0b60009493566441a85a966526d34b06cc60d089bbcb1d0e8deaa0dcbad79922bd1fc98bbfab1d926d9a42087bfd42f67621d67e7a4fbc819fbae9cdb952665c6b4334892fe51d4f7d99f455c284d038cd8f1673d5994a9d8d98ccfedb894560d3faa1a7f86cb9b4bfd16eb59106e0eba82b5d624b7e161ed353c9ba2232e6f2b3407a7b648489628aee5c86afd4a50603e2afbd8abba7e274acd2b2ea94c92ab96b96ab101e0ab542488ec8512023d2aafa7b69375044b2bdcdd1b88cf3ecd2b0d34fd2c66950e9440ee3f5c6d2eeb899bbc9898a122d18c71e11271b038c62f9a990db50b11cd8e5e7c7ad94cb4d24c40fb164e47830bda62d099c97bcd357d06b22182236a7ffb0ba796f2bb21a22a94bd1db820f49a88e8e3bddf000d31149b8cb65ae6d5d0b8e0ad80b6d7414b9bc691d748e65ba0467b812f8fa5b5e699066c8247b9e45f6d4d1e10b0ce230e2db8e821f572b54b338cea5e460a31f1775777e17e243604c5d41932baa86264fcd1f964ba9974274b1ebcea4a24e7fd73ed56c34b62877fb61eea82def6434d28d33d7092dabc5225038164a597e5296dd1c187cdd91ee72e2a703a6661c347ef97cad41bdffc8d7851e79bf6f485b94172a972b9c4e539d9b835cb8dd9e89320792a172c7a286a1065727c186bda18cf59cf51ad174da98a4c5999d1130e6ea150eb6776effb19fac9dfb4c08dd9572151e5f83359021fdf8e423fdc58d34d5b5e0ac54a3be53a0820d606210f13f462755ea05de23caf84810ab6f8e92d19bba0df90780e69cd4b845f7055a908e012bc1c7e4a212ad0c6662ad813eaa431edd98d4a02dc4833fec33d345151b6380a1d6f2c15e7cccd8d7b6c1a43baf6a5375dd869c7bbe1dc3eda3e4bd031ffe4b626e14fbf98fa83dbaaecdfdaa3cb32ff066efbdf6b5f44e47f11e93bac277e105a5853e8f77592bd13d05450df259b30881e2b2a9c28e659184439975b9a2d0c3e623d23e6929427f141bdff18e6c74db2cc2f0c84a46e326ec347c63b387d560654d306dc14a3a36caf402526fdc646a3724e827a54144bef7401585280a1dc50a6a40f57626698b01b6daafbd22391b889b05618275e599ceb51c39b2124891c27d0996635a9e22444c9b75db80b8e77617d2073510c0a9e97e4f6d62695996940c48a986c977fbd069a7b4aa83c81ee21e017f583f251a32c57408c483a9dc46d00d3efb2d87ef153e576634302bc7d3440a00dcb0ea02eb93b01bebe5656ddc6f11d906b7e9d91634cf7b481455488d44429da249276e30521886f53e73110a50bba4477999b5155f38b7e58541d1b54adaaa882d5f422af3d7ac0732e6baaa159cf6271b84bd18fc215ed76270987561fc5bfee27cffe16c3bc6b71468c7afd54f2bd53bc7427d9a76ceec7316238ef5cec28eefc24632552bdeb5d1e4b24ffaaae1dd38b390b247d7101db9a87760041d751f5fef159e504d14e916b22c67c51eb0374c0ace644912565be18fb239f0f0e72013a82236752cceb92b641aa0ef0813d845257d5a33001f87026e0a31d15c250f7c543119209bd24f79b9ac35cf1ea825abf64a4bb2c8aee6dc08889a86ee37ceeed32379e89d6c8721c79152feb1f98b7234bd1e2c93f67c399bfe951fa1feca0fb3fd545313c3304bf4a04ff4b07faef63860ac308fa0303f3c0329489d8368a0628a6988725575f3f1d73158e9b55c7d5209ec44a64b15ee4c410e4456fe2021fc755ced60101c6c6d8b8c129aa0862d0b125abdccd9059b376ee6d341dbe6fbf5183060dab4471aa4aca5a968bd633859fe5616e6806ae8ca7e3183dca087fb01b85ede49b95d1bf0b0ebf51d98a5671461ca51dde54cd63857ae5901fea13dbc5f911e8aa4c363bc88dcdd56ece8ca2a041d152f8c50bb766c6172ae689d1eb43df06391aa5ec5c7eccfab49ea95be12b678124b427000a1532193b8202b1496345793cfa8d582de9f5445882fb699bcaad70936cd6379d849572503be9a11d4e97c27522e7f7ef5b5acd34b31822905558f42ce8daa66d2270b2616ad1a1095a877ef18a1fdabb5e3fc5c279d414a21cc81372b9752c931f0cbc4cc641bcd86e1e6a799968d09563703619148d23a49cde573ce2e98c2ef10c8e055634f069b60f1a148e3c71ead2eda834a8665853a302d2bbd20828b7ef8a830819bb9d8a0ac962a1ce046a0e0a66f0823669ac3bc2dd13e382b73c733ff1d419aa4837d910f8d8f869fa0206e7815f32384a1e5617a0fa43655a8ffb7ccc76da9a71d5bae7c1819eadb786e16862f45abd12c9299553504dfe53cd8ffc411bd655cb00c774f0ba5d5fef3635ce95bb02d89091e8fa5dab97bf9f2e099ac693f9868b511a3e52e425160245819113bafc4a64dbf0d2dbfe1c42c6dcbbdfa885aded43e9b76b2e05b9344d99368589b6ad34702a46736ee65a13ae5f81a5e7c42aa046e15715d0577bcdfebe61e875efafa52ddf429df4a1e30da7a453f13e8b2db1711627d8ec38c02fe449a7204ba8d08903dbe064a9018967cdfa5dd764adf9c6c681ebf2551ff5f9443106d5235aef7388c421e6c17d4db1effd752ad51943bc8b4297270d2e0bc14c447285c285699da531e9a4373dba79e4c73ce2c10478caa009cce0173ccfa43192837e3258c1ad92e4ba448bb0fedad89741d33f76e1d8b6b5b9cfad308c19c8ff5fef9cf82baffc877e3ceb95e8876345836fe49f9fe5684ada298a500b4a2bf7b3d7ce9ef37fb1f75ebd6e2359dbe87ff1ad7a468c92d8c0774152cc49cce1e0e005939883c4cc0fef7f3f20b5b7bdededeef1c473330dd82dc9ac55ab567856a822495c710e52130e2471440cf9eb9d9f18b55a8b053fb0a704c85af5a9d924d83d20f969f9b4675315feb0ed6c1ca2677c866d3482cdb83d5767ebe940c8b97f5ae91dba2b70142f3a2e1d6e83171e2e287cec2ff011bba0133ab2f588721c297ac28111299a96644df31d35787a60e579f1bca8b3192488074760f51045eb7c1a3a12f640c665202f38e143c8716908a944132601a2cc8b9f030cc228cb60f6cc65b53386e8baeb9891534092f01070197d6f38695d96e55137f9cdc1ca24a24311a6a043dee0da49adbce41198a0d796a4476b78e488466f4fa81754a7b13625e93c1d102560e03958c5a009e824794c4efebcd74f3cedae53081107aa3d54581149652763c1835432b9d2695ced43d5798a7a6535d6a51682e61229b27483609bb8a353e18b30341903d33686843b957ee4c4b642cd816cc8b3efb1cdcc26aebf32ae4ed9b075207b42cb58894a6db082887081a036e7da2ecba9d1a59ea27f7569679e53c422aeadcbc8370be9bca1f4db5666c5e40131f793a95d1e251c63bce7ce558a182b31f339b6c05d061b80a6f512303cf861a019eaa13d1503ab89b647a759597549858d877174a9b9b09253c6f9c9a542262e2a56f28ab566a79fe22a1e3ce17a82ee0f3f159840a24a0d640540d78c148bc63b69ca6be6c7917ecfd5a654cce3358dd6a786f391e7aae7ca54634be0492dc632d62827bf4daf1426766d123baee06703b0b0f95372738faec85a38959648202d0736a0bca2691c047d1d94838aa34e610750013648552751b91cfce2e4cce3e3a4140b8e52c838458e2b300cd427959d32cdd5b525a7f21c567367065927a93cb807300bdd7a012ca6bc2405a4597e17d9272127cb6811a9327b306163b1a7287f1ed0a75b3ae742f039bcb55b50b189a4ae3ce884a7955927674f3388c6d720cb2ae69a9fd5f6a28712983c659da37a963aa165770dbd637a320ec692f2d76a894ce65863b43d291a8183fe63a421ebc10f9a2cb443f9e03d536386b5a88ee4d2810e89b9255d7b068d357d125dd194bf0bc4dc9eaa6a0657d04d604b8026886c816679869a142df2f51097723b1e5049261f8d6b36cab53928fd13b758a5c57337534d1e75c38702cae30a06759350d8d5036661793c946b947239fe706d30c5bd4b58f044aca60fd4c4457b013929097a4315fd5c00e4b16928043fa438692ed5b81cd25e320a232bd49b00f08bae35ae3d8064be90cf519eaeb73578421c1ff30f0d7591637a45b024d39ca39f0030796a565964a03a66e615006e4127f4426d0d14acdf79d6516e84adcb867475c4f4daf0b6f3040b3838001d7ab72265406d2e524e399e9669ef8437e339cc0edcc9170e136de6cc2c45f3f02ea8d2f00fe07cca90d380d498d5d7a1c0676c5c654ece6817ba494f62561cfd50ab56d648803341c7e1439f22e7a25c939c81040494dc16b927635132d1e00502253a8790f78a08730abb25470e8eae0be9a8cb45c4882a28eb786ddb345346cb6c0fc27146adfbd169933312e5871ae1d3530d30781275386f3d0cf16228eb612ac8a432a1a713a422680c4fba74c6a79f59920c9372c147775a0958aaa1199dbd30a02928d7113c529865a99735e1b4690e3971b5ceb2b3dca92bac038d89ddea43c03862ca047e284a597d11a64731448a29364f3a340fac7e4c34c74a80138543977ae9090a49fcf6c1dbc2314f2809e87a4e923da44578dbec493612976ee82e336bfb540a76dd8579b6e9dac6a6575f8f36c10d47b09a69f51c9b39fb3826daf5ae07898b722d66dfc1c7a89cc2f0140eb486de2583f50fcf3a9c64227d5ca3ead053375766cdd8941eb0410addc512b5e32356c6828a2eddd9a0e4ea345fc6b58bc830ce0fb7a150d305e8dc39b847651630ba5a122b9fd53445648f66140dd9d04ea0dcb849365d42685643026d3aa8754f63a1f794f504dc585414200728e7eee3b1288ed60190bb685894307c4a65c50b8836b297de18d0900192d0affcda60124b1800c57f5e9f3e02d6d5d9caad8b23e74f49a32ee6d3549ed42062ebf3482b75fe2c6844bf126cf554cf87db7d61850706cbc172079e5ac4acbc2c57807f4bd54e11e0e9719ce0277dc693e9382927a7e4602faa0c8f6f4e9a27dfb1e04851fc51511a232779210defc82cc947d4d14399abd9fb413e827402449e7d3a4647553ff2d2f17c935c7d818e2bae3da5fe5e8c278b6183f9f4300ecf8b741e31edbeaa217a729a9ee23423b8161702315c432d74f80afaae07b7d4f45cf883a8a261181ae22d638db92620074890a5916d7fa0c56539b7f4c318346d35189d154b910201bc0a1eb9593952dc4a8be23103a74d6569d9f3753051a55b9c3aaf2368e20e6596c9faddad4b993830cf5213a8015dd2c682496cc11738ad179b5fce33d96407e1a0858e1ef01ef1d49ffab92f4f568b0128720086d87c08d589160a7c0842ffe62e527af2845e022bcd5b619d1f25528886d41089c8703d7b4d59ab8ace475b184ddda9dc6734c752d1e25a23655dd975cbf9e48e96fd3899fab31868ffc9473d3397f113420931466798466201b7db53bf5cac07149625fb8cbbc8abf2055cd092bef574c21549db851d7a0ba3f8969831a42fe7b29de3875a564d3c595c5ef1fa7043a6a827cf696e01223d9b2d859a987548f5c7745a6ad63b1ae7d4486cd4274869e92f31303f0f8ffc4a3091dda542519fdcdc8234bed573f4c0d7180553c72167f0a34d2ba536a2ba726eaf5e90d09780f446940d89baba133c190c4aab5cfb32719ce66c3b8ff844475825f57115d7eca385ce3a769e50fe8809d5cdc5abd5d323f0f138e9d2e596d05e6434ac8155261197692378c0f151a489eeddbdfa24afdd0a45e9e9da154f02245a72b0d6dbd33cd5d9555f8ccc4483635bb6581a0b7d6da3e700d33bf900965021a14d91c6c56c4410681003a94760a6dbc4f1ae8bdea316cdb377ca79a302ebb32096cb3d244d198ed363a565b1c73f57d100c0472e64c574246f8721af8aec1a34596a00ee9a5db82973ce3977e122a93941f083832cfa7a0d843e991704101e717e42b582b0f02790cdc79b5052d850cdba05f6375b86cbe9d15f0af3e450acff3c3533ce11498b8cb44153cbb208049d44a9e4a306e366b06fc87ec6c4e6ea2b6ced73289ca3462f956db03a04a28c2c8c34d311bf8061ad5d71e3a942e1c4e4f74ce0326f8862717643c569f5f40cd2d1d1a09589efbd56bc0b4d2ea62b6d9d18246347307171afcbcfae801972a7b77171eca8c8bfaf075ba4d265b2fdb16d6ff73227100a3cdbe16468882a335ea3b580260fddd53524152bac4b75593447938dc3a29ad5b04aa30206d598817c5c2ad339ab1dec5a34e1720cf200992ada675287e99e96450b7a041ed4a0c5860b5821905af90f7a89fc8518bd4370030de5d6d5dd749c16f0a6b8671094ef2446007370705bff79a4c3ae5583f0397a59351879ae51ddb90ef44ba0e2a705642ef35dbe2165623ac7436801ec53e943ef82699d545c23e2188b34b63205e37697b0998d1b282fd6ed202f6848a0ca8140878ce58e3d6dc8699d7939370227b1c59fb59ddf12e8a4228775429eb23db7a1e2c2b7896c93258b09bc246dff36070267a751808f6aa3d87eba129ee537c3a97e70e6d93774d5d30c8771568e3cfb39565e464143c1ec5a9dbbb824831a6d717f4065eca13f07a11bbafee05a1a137817cc37f2b07a20c5849ae10962c2cbb3888300b5351f1b60c3c6f5c99d14b1d6e03c2a49c364b5fba3edf8d3b3194fa67b0f0a02f761577f96f76b576fe5e1ed89400669cbc9216f821ae0c3299e6a91e0042498f930489f4c35049a443c19288c5c152c65df781e2ea70ef0d4e79858f7ecc92a563c4f3879bf73d173918e5243c8f73009e60296b321b6e71a452b5981af87ab722ba6a28d624d42c81ec7521bbdab27e288e364c815b194648f1b7eba0cae8c280cba666989eb2524804ff9011711619ed9b81961d310651e5360510856d16acae819f6e0d04ff35008ce85a46e7a926016aa9f017690c4b37c73c685a24bce522cf3583f22f5980ef4d8aa0f46450317b2a37b568a412f744b025647b1ba54d405f4d62346128786cceeec8510fd7eb6d1bb70226a32b91ecbd8bacc0ed450915f3f10c98e8701c574167706fc795fbc3ab678a052e7392832b5f3837e7d94890067e39518c3fbfd2c85ba5d53086491c193c04a07cab466245ce568f90df6b8d4d3136285ae652f64e0e98fa87b8080d2a4c2b18458324808e04cc699ad24d70c6c54b2b71b13c6fa8653a12745b341c2d65142b0f39925c609678ed472bc66a4384e3a1e2c34773be141bd08ccc5e60b459f93a5a434716d0abf764522ca32cc58b17a9283560007bab691d96be713dcc5f6c970fa69b81e28050a61988719f88e63016ad4a100288831a16935afccf1ce296c4be6317d8d27e0b670ce6da1d629bb5fdce1312db169177d7d718484c21cc48ea4c3542fe288f8f7cb8daa176f44e23b621fdb90bf8f53744ce8651129736ccfd0702a0cf0365d8f8955cf68bdfa0d9a3be7161b1e75cc1fe3a3ca2b87d4280125d7b8fb94a3ab718a3809444f02188c63cb7aa3c21b271b9107f32cf837f3882b8ab122ed9cfb361b1c3ad01e8e087fec23baba3e408bf04f9632063978b2f9a1b990e043e9e030d6716a1071d01be2946135a444924c84dad49999f314d01e856533d264d764c96fa1398fc0598a1978e69a5b55d6e971ad38788ded19a073923d0ad3a34def52e31f408c9c66fcc0411c72385286654bb65bcf71a9ddca1be01d084339f697e6ec01e412d867ad4aeef41aac56332cf13dd7909bc3e2a133464f3c602934cf22ddd2e114940f3a3b9b947ae4fbf25958f4536f45e138dc6eb105e75e3c118c19f3208daae89d3e39453c3c9ea76b7c2141d29be758068b82ab3d8f35fc9c8faaf502cf4a131437c51ea5f2fa9ccfb560cb3dee018cf2e8a02b71d02e54d54020c8d252a6f0ad3e32dcc3147ad72f5646807beaf26096839597b10a7b4b6ff5a92b4f30c7df8d67978b25586768ce2216a03c1e17831b4f25a890b5bd4ea8d75c425b86e802e2f0119ad5f120a6c67c3ec6de933a5e174cf0164b88733b42837c6141278bbde074f3ee13d90f347de3324717ab3b8dcb48ed4847ef521d739b0a67f53853d6999857e3a0f088254f27314f8fa2214e55b826c3a4f4cb2d70ce173708535d5eaed8c92cd71a666aa40ace7861ddc51e915991e03ae7ac51f6c914aa1aece3d268bd9936c06554169b0fd4735f2dfa092df4bc6d50f51a178fc19d1ee3dccada6af90aa81cac871d3e21571bab65e5eccaeb6dba18ae98a39a2850e5423efb07ae31bb395d7d211a685f31acc7c9400381ec4acb730a01357dd8994543284f09f87874ed73e8fdb2f6cdcbda2e716fd437ac7dd601b3008f27e11cd96871d8b613e6cccb43585182db212b00becf1620634111959196111e775fb3153d1893a0efc086ec1ccb62463e004f5979be270b909f8fb268a87a4543a9dfca0d9a097aec26808b24e021d41b1249f9d63130356f0dcdd65b249af4a913d0beea000d7c14a0dd5865d104f8e51ad0c393e209be362da18fa86b74cc30bc71547d9827fe2972880c9397e2c0de19cae419f3e0949e8c75e8e319266725b28d9b05da810497503209ac348e2e869fc41a2b824cf0203b92889376322f02b31c8590e509fe0ee77316db036490e874bec20724c70f01e8c9807005e456f312817e64119c6884ef38ce49d64b0cad2c68bde6fd635c4a51a52f80a71c8d338e4d6c8e160a7b669f439263253b7617f6cc4d07e88631607e662264412f45aa2f639dc2a01ec276045b0ab900d746edc2122c3c5bb2635ff24a0fae8b762ce974e0b3059cbc55960ef0195bb9c40eca5317ea8ef874f88069038f3b0f8753a6db10263f1463d617842bca7c2cd65ced4ae46c9ae9383e44d91de3e7080782e54e69de12ea13254eb57d38d1cb35d061c99805f07a7c1446f138e997fa204306af46ac7864b02944ef2d605df22babcdb3978b674e1c9efe5a33f0b4c8184b5ccae3ca28394c1d961b13d4ec2144e6db74bcbe9e8b2447f9f928722a8e938080ffd27b5881bf63fff8b5e765fff0dea4affbc5a0edefef63b50ecf391017ee46e439d590a6974ca2a08a81afbac400f78d727d68b1f0b00003a87495a82bee493079e12a6b6fc2c199191c91d5ee27353cf0126634bc5e2fe7f0601cbb7b551d51c6aeef3114163ae622a4a1dd653644316c854725c4b46374af8fe732987005e12e1a811b27d1181cb0e94f5e4f73e2a116b58cc54a017032c48fd6c19031b28ec4b4f624bb6f751d2bf80b445226cdb93799be5be50d3d5aa49883ebf12168a1aa42b6e9b03dfe2801cff2e6d515151f9584c7b0b887c030e1763699ebf5c917cf1375f6e444b54f75ccf265140d09c2f0878b0471cbe90e932e7656edc0970b9a98e187a5debcc89b7c998fc603bf8e0e5f38acd7dd434329bd7b93370804ce4b2053a30e1c10503f0c889f360b79725751c441d3962644cba07b8e8ed75ba090e68a9cd5199313f04050e9bd31a8a70fa89ac6c58c11251945adc05ad893e5133d1d23fc1868dcf9716b34296448797972ee52910a3a76244f9bd15adb03ac7638ab91ac2bc0a2fc906d3138340fe9863c10ff1c0509e2cb6294891aae62f800c9935d379a252490a7adf399a39554c16467566265b88a6696de10e190b5f1c951c1f6ccdc39c2f6c446b8658de9c7c94c85c7eb52ca2bee4d36434c70984f59a234fa4d20eb5e9d000911d2abccf87d16089d68868f997015bd59182277cc80525707f49a673b7b17da97b45cd63c0901fc79c4270a04ba02b159aa010a59382312697b6c7f9f480ae134220081a79a9571830a9781e3cc93535e90004b2bef567939d03d9b835147f2e084f634a1d912e4307b608970ca322bb18afc79c91acd4289f6f21c6f4c975ed56c78324c78bc16c1f8140f7326266ea55e82bba9ac6678055ae1620a522cdf8d1a5a5d62790295f3446334f5717fed43290f17f2d0a2ba00c2e132685e997b67e3426407cd4686528759862c0b036caac1ac11ec9433d98943d22c044ed7fc06d3cb7426edc8cd2bdfbf6a174cbcd1d6c11a16f1c21e9e9a591f24ad50f4de47237681dc838fa59a27b35a4ed9844a36033f87e08d2b2ea13940245811b7f418e641849cbb64ce340e0352590ce6f3bd65677179704564b59045c00c9883b7f02c0141df947652558f535d7877559400bced0afc19f7e72c3d9e3ae3c6ad4c154c4f89e0e1633e3c92b698e1369ecef799759bd99dcd10f6346bb8d8f5e992338dc6d63ac394786edb0fa6c25dd03d18ebd85ade133ac447543f101d0923897288c527ae1ccd553c95ab15cec923b0b0b360684f517b9efdec3a62a69a14e39a5090bbde811b5ec19560787ce840cac826d1e508e41d3940cdb2dafd123f51bd09c3d19b16ba9b8b23d5e795db9ce1335983333ed8d4e5e2d3682605ecc50c0e527d498f07d831a949887006a222e7a828be7f3c5f8f7c2cd55d40f7b1069b2e5681668c1eb50b64e7c47a2445923d2b282862be0a1dcb5bc30165938ce4dc0b56ad08798b40c97dae83e07a046ef888dda6f83c250c80430acad73c922b76659e5d6409bab284e574ed4b889c0bb4112e23106a627f111dca46f405f7ba332a3e9e8abde6f5e1149e82833954422db362f70c021d2fb80ba0389743acdd609e39e4e181aafa126473e97656e4f9c05a4038e7751869707480d034bf5c01cb5b9b01b1307c3ce2895f078a6444c4e4910fad43c2a4bbe2892c5b670a0307cd63898ee38f07ca26a790c460d24204b75c4796f0cf17ec201d02f88a71b3a311ecf19c698b2475060c675e379f6137316037f56fcd9ca51032cf357d2cc1e1e686549ef2a78b5c24299bf86842814c2200c87a11e82a9ef49a519ac7f5706d15e0d0a152ce88d2bace57ab7df4acd8a36ba277cd7129cfab1aa0373f3b87637a3b0808c54d8b4e9e8241d420d75659361011ef381fb858d0913aeccd4bab09e7fbc0850d773b968fe75c97b7e331940dea7ca88385170e24a8a4ae770f933b61b15c463f0e3add971821cb763c4cf47aebed437b3dcda604740ab9f4b47b3c7ac9a3bb62d13478475fa1889225f5677ac963d7e62e53cf5c19e5ba869cdae50e3d66e5d28775755a06ab75683e94eb9ba33555d3ac298175c3c55da2b5a3a6415dad501f879ae6a32e9e4f0eb54e162286fd105f98ba3d39da55b4d14940accc1c1fc9a214283f13fecdb859240d841e5597f430229df328b583712e8fa92fa9e319040e3554ae0fc08ab453a0b7825eae28aeb07acf3dbd5bd2c78f2b6b3f7cea902687075263d95951d05426230babf408b3dc14bb099935554902e165451132c88aa3acdab73b6cc520699316712a0e49dd632a4eb05e2b1cb55b100cb73ebdbbf7b4d507ac282c38d46f4714f54b4b38674334eba3c9e7b5452e8fe9bad876598666866a7072b84217e7e0d4f864164f1727ba6439838706b44e3727949d990ed6a77667a672ed65b672cddb0426c78704facea02bdde8b414f43cf4ec244ca67ab85a07042eba58a91f8f412eedc7933cebe411d52cecb1a68115e1f60838d589174efca13c3de4b3d1daadffe0e9e0e2c35dc40b3a47df8f0d3b4747ed95bb65245bab4ac7e03871a27e2d773bfdd3b99bf976def7dbfb2e8daff7bba2de2098038197f6a1c553d23eabcf6cb473da74a85450b5026dfc98187d3de88b0182207b368e99710a0e8a70e5b396a046c76321fbd29d0720755dc7813de8dccfe7f3737f971c7a38487542d89d70c4e7a7ecf759e70623ad5a7603dc495a3e07779a51c1d45f2212a4b1f9918d3c335a41eee5d55841c2d98d7bd00418dc75b23b0b5f6584f168083b07f462079c93e3b9e7354059c78abd7ac3832d31df8fbc38194f846d400b284ae4122a9773a980090d61a2acd7beac371c0a47462fabde912bcb826456735938e9367916462a9dcba5698f2b4050d6175310682aa493db9c65c2d8a81e91e92b7f80fd7a24e3ae86af24a7ae5124c264bae8687416e76c7aacedbc1e8ca3360b19736ab86149689748459eed5932554a5db38c4a0842a1c24e836184cf867b5e4525ca32f84a11d64033f3905d00988f1980246945b74fe7582c86aa66d6a08b9ff3f5aaaca182343070ca89322cef4f4942a63a2e8a229b1424cd4c3a9b16ad3bc709d750c5125d4df8fc00fa8277bd365f9454cc63012c21f679a598d3ea956d065ba496162e2d8be76e884c6c1806e9c909968478f3e2e1ad919939ec2b7555db67ef49d531473b449da123835a766ea5502b5a8ee6c0218fb9e67d09a9f454a3241ae1c7486849eb14928ea2ced6f3d271e618949e8f65ec55a1c9d1b6adf92a4771159cf07c28782daf4e52806172c239c643b31a0bba355a339f74f664f478a1c7e66c2791918284e10149572b14625fdc43cc1739c6c1c8404a1c82bb6995440d0a3fc01e1fd0514752a98b9dee765d4efac13d7018515ca66e56a25b28864f4c737262ce13fb8c2673a4d46e80cde77c98a0637894d781c99478c2f5b9ee54aead197ae51d3ca0efb0218e67315a2aa18e0f961bd35ac978c072d7941341f06b7e2722d1219ee5357462aa458dbe98ab25be152ea3617114ab9c024562c99753c8f0c3b309f3e38c24a7b35e83073745f3e9645af19595a4b3703bdd485c3dd4b102c192d94343002d52793ae22f4c41ae40aa62e17e0bdb2f9e27e6fe1e4c092bece1fd03efae6c3d5a36169ea0b8e04e251a75a4f8288ae574e428deb8aee7424f2b0352cbc949c7b4e61b6995305f6ba423d0def8f47cc1ef48e35e0ef8fc240dc7bbf5ea19b6ca7bdc1ab58d8d3974c4af39b92e9c4d129170389db8d4881279d6f2bc9fcf622cb87ddcd1c000365118c79dcd3db55198da9057b51b04e56256364faaef322433a01ceb430c0da00c38d061ae0e34a5f5424839027848801406794ccc14b6551bdbd4c98ebf9fefcdf9ca1eca2780679e095d1a637261557ad6b7ac2ed682ba91de7d3ca66b5705b7fce27a6d389bfe231309eb71be8f339d21899b5e7a6800f2db9a53b9cb8124db1d4d3aec526a415884b7114db8b110ea1a6675666224454fb66f3dc9bc04f51201d664e6e56778ea8106f13a590a16ff3a1a7855cf05743c19ea09d18db9767da35353c6612efa520220909e8f4557dc58077d1e1877e11234c110b64019b0c220220722347c401a78b9e37c6bc68128109dbb507d5089dedc3d4d9735cbd98a67b99102694d1dc739b82a1c1f1ab1bcf5fc8308ba537e40eb264a82933b23d842e1fc702a9fe719dcedf40cf07d8a24048ee320fe6bf774b37f879d1ab123039e0d6ef63a790e0ff8b6b5fec27bc4ca22ec1566a5cc74c4ae6aca91a2472c2d32b6e2a33273b1cd26d322332b4b429ed6bd18938c2c1ebccecdf35931fba579f2847b51898b806805a90e05c745b6181e6f47f63ebaf7f938b2d3f532d18847229ad13aa0334b5cd06983409af721d7bc79959f203ed450dbd4e9856e9ef64aeac5d915d499928755ccfaa6a9fa2e3be5a4901eed53000074d6dfaed20101b856973cdd9149415683bb29cc4fd70b3595160530a5b280f44fd99145dc2b68ac1457d1d7a7505ca8bb4f975577103443d1b30034b033562b8bde1d8ef3723e945620e802498ca036c670852730c5b323d62c76e160ee643c08a531a23b9228cc425dd9d29f542b55ba46093acf54c7c1e728e0288ac29c54f055750fd24502908bb93e1f252433677e8545743af5c7c5060e0b05c006acf0b3a25daf95d6f4ead9af666c4ca5b639ea0729bb3c1df571e76e18eeeb4f9fbc9d2fbd6f07b1e71b983bde9fd8158d5c863ca5be7d7908b23e07c391ebba1b6aa4f5913925f3b00e0419c4f08d159f20914197e6698698d45d86f62006839fd847a52910498f72d13aa7affb339e70f0e89a62b3d3eacd4e093c55f19fbc03fddbfbcbf1e253e2f63a970ed21645f5ba8932224888b8ca99f8579bc7714e25c42602e6c74eaddbe6343f9f41dddfd9226b96468866a9681926ab26ca6b856558242a6be5cfe8be8d4dbe52b97da24b4ac40f74df7d4bd5278aa4775ef67ba3f16ff746735f87339ffd35c3551c374ccb547590370af7ebbdd2be7d1922867eba0edffe5c0e9ff8ad3ff12b747fc46f1b2c28e0da7d1a56c5fb9cfd87fbb37fba1e43d470c268b66fe8f697fc39f7ded5fd37d7f37e1ed8f9761e3864b05eac8925808932acb5d673e45f9229f19985fbc6c38e81bf2637f1130959223f9d61fe355ada275a3872fdc3f3d0bf46d3fb4492bafc31cd0f67acdffcf0fadd796d59748f92476e798f8b37387e95bea72daa44854bbf720f3f194018b0bfa7db2164d72e0713d6d2b0d6caf0bd6e7a5fdffc5dcc02cf949251db57c5bce238befca03f00373afe57d6a73156e53a561751da184168174074e1395c21e97f36ff5564c08b40aa1c8eb3fbbd32c6a7f97d40fc67e637e1728d18abff2eff0337db4e51d5b1009fb186882973d7d1c63f971571955dfd166ea0cab82e8e6f1f7e9455a8fc13bcbec5f4775f93be7bb643cab230f5dce6b9e6dbdfc20ffedee314cd4cbf906f00bf3e27ead301814d371c273976c27101ff34a7c4fe4a8e039443086b69c0cc7fc31e498a5fc6fcb89902036cf6587e9631d2fd8a8c0d06abbd0ff72ffcd4ff087a0acf60444e38becc098e93974ffe97ebc8aff89fbcafb97c9f9fdf7df0cfe79ec715a8ce5bcc89361fbf229fe6d6d6e657e6565d476b54475e3d1bcc02c65a786a1e5d88ee34a65c23966fdddafaeefda13fe5878b2e027a3912138ec30982e3e4f4899f209ffe217efe745eb6235d126ef6c47a2a70fcea7e9a9700d45f99f7a739b4ced083f7b7edee841b58ba632d99f0388eaf9fecce927f0907ad777e0a790c2aaff5606b719d8fef91feb9af1da438573c6a8b3b1d35e1b898fce86bb464a8bfe06be0571ba463c6caa39fe1da9fc7b808fff1bf6b69fff27d443fc7f9c9a369e8b8e13cbdfd851f3fc9d7f57e7d0e80cef65867cbc0dfae917e2e6f7f0813ed8150387e5536a0d13fe1293bd9bf22ef57fd46b8b50c84159d47f47779d30fbd4c790c6aaffcdb71f97a0e0cdfb4761c0cc99fca4bb3eeff9ef79cff5c5e3723bb97d444e03879de229f3c7d9297edfea3f779ffb25cf01fde19f93a1bf0bd1d45d9bfea3dcb3fc5ab1fdfed46159ff0ea5085ffaa77b9fdc97b9c7eaea71fdf3ba57eb26b26f67f254ff8f3fbf1096fd355f1d69bafa53fe5e94c182718dbe3f97e4ba2fe09db982448fe13efbefa397f88609cb5657f5edfb8c5210bff64db60f8cff377751db9d46d74f56c74f51dad8d2acbd8e27350453f7d66df4fedefc76714efcf54f9defe1ac7fca7ed4fff957bc97feea342e23fc76aff5ab0efef35fbce47ed14fbe79f0303b6212c6fb27be79108abe817f823cfc015621efb3b44c28d3ff1137fcee35ff79c9a82865d872f7ffefcb49fdba33e09367d01367bdc7d58fbecc351f2cffbf09f3e2ff2a7b6873f923212cc2d676d5509c7a9cfb91abc9546ffd667cefd5c66f4437501d8ddbe565b3dfd19f7d832fbd73d63f3cd6fc33fe5e9c767a5e89f63a690fdebf4f8f763c9ad074ce4d66dfadcfffaf11182a24a4ccd2fd53f7faacfbf478fc6ba3e8070cb79aed68e719febdcb0f8f5bcec8f646605d5afbcd3e70ff4fac31946f953bca0e3f29fb6b53fc5308e8b23fc34b938ce36ea4ff3204728ff8e9c7d9fd3a3bec7b23fcf83708c336fceebab89e3d7e693ed8ca75faa1777db79937ff1830ddd7e2537fd716f46ffa40ff6f0fc753ffb87f70c7f2a2701834e4f81dfdc8b4f36cc0c3fc9e92852bf2ea79ff5b37e8d379a78e55d234e5e7022e570fcf678ab73ffcffff9f2db97d67fc675ffe5f7fffbe556245f7efff2e5b72fb25fc5dba7fffddfdfbe14b5df6763fcd7281e8f45fd97b61c92acfecb7da8c3df8f7d5cb5a5dfc7ddb16b9f599d044dd31fc3b219a2788cebbe3bfeb51aebe3f4f4db367e1e2b7f8cebbfbc7dfb6bfb6cdaf8d96771b74d9dd5f766fb7f14f77e56ee3fd52f26fe70d46f5fba6c8dbffc0e8197dfbe544d147ff91d8180fde3fff4d93e160220f02f20f817103040ec7718f91d44fe0a9d31e07c3a5fc0bf00e8ef00f0e5b72f59f73f51f6fcf2fbdd2fbbf8b72fddb24f7f8dc72fbf9f1014447ffbc2d5cd97df6104025104b9fcf6452eb3baf8f23bf8db17699f1686c1cbe5b72f66167df91d0400f0b72fccb78fcefffc4feb47c097df81dfbe68d14614f8ed8bfe8d73a22c5eeb4000ecb47d6dc2a2fbf2fbe5b72f789f551b277a1c7ef91d3cc12714032e28f2db17b9db7ec1b013085f80f3e57f7ffb22fdf9a55fd7fcbfbf7d217ffd52e77ffe67a8872e8ebefcfeff00bf01bf01ffefff6e1691c6cf5d409bccbe1cd3a68a8f795c1759dd1da7e65974ad1fc6c7303bbe59ce5fea2c49fb72f94b98fde57b03fac19e8e51136e6ae5aab679f637bf4fbfb3c6b77fbd36e1eb67c37f2671fffaac35cddb27c9efc3f4cbeff55096bf7dd17bbf8cbf2a76ffa6c57ed7d4af6b9986cecacdfe5e57bfe6fdfaf51ab75f3f1b71d7ff70f5f6d30f23a4261ab6f9feef9737e6ffd877764eb3facbeffd73887ffbd7cb725f9dd444ff620d25cd5fab26da895bf1b3cb7649827f054f3b54b4fbaadf71e44f17ffa6d37f1582fcef6f5f22bff7bffcfec5fba1f969397c77b35320628955c92e5ba138050bfa1604d077e01d5e41e21528a50cfb7900fd1a44c0b7f19755ccdd41fa06e0fdfb469eb42090984bbd5b958358b76d88b75f03ce3fc8531b2cd89f6c185e26313707f9eb0623f82dc019f820eb0824566d1a26cdbf1bf4350abf4ad45fabe8cf81fddb655f911cc6b0ff089483e7130ac010f62f84f29df5ff62f97fb1fcbf58fe0bc0f00dafb98560221bcd5f877d89e93d092793d6f1ec390f20b0e4586de4d8728c1c2e092a0be6280f0c2a79c7778e2596006a4b17565332694d9f29578e95d3c0213a4fff468f63e431a8b5d4b7d19563a8647ff11634971cf38116c3a75b31c231d8c0d1f2f47a8838710d180cf4c80f7ce64de27e18172ee8eb9a0f7ca90e3105af0de6bd90895e9b33b9ebc8a54096894812b0cf94b94f128be7686058a12bc76a8da713e08ee7959c86909904909b444c5a72cc56a05249b815871b8facd7bafa1b6f940579360a840b22909994736f1b811c63219e2d833bcf49231836fdf474628d1c7e9369e33a6ae2526d1a555422195462029ae892441b2e441bd432e0da73e7d9eab0c93558883562e8252289d57378c8db74c160f9764dac134b6423894b2263e07843b4106bf86a94f46e858dd1b55d221b4dc45d3f66e2be177be41b4d564a7c5603c20fb4b7c29863683062b678a6b5db7a02b648228806b6981c2e4415c05ce242691a54d1f67df432620d606b71a17d8ec2d31141b7dd24843030ace472b3016f9fffeb18c0fff09d63a33660a6c4adcc24dc0b2dba761dadf4480208966d8de8e0db68cdb17219d65e196648a26f32b4e7355888ad301bc285283c9b073d28dad69f840cb6c92c910d7c926d5c08a14be2ea5faf29c38cc8dd4d769599b88e06ecf985ad26beed6eb65e7a8c5588492358cc25096b6be058ad0c616de598978e3799ecbf33f820422014d4611231d61a31f840264dce2dc44be62f7b4d384a9674b5117447adc385583c7b2f22cba0fabaced5dbedc2b38c42be9b85c5ea966c9a6599708c354455b90410da6ff6c6b15e1a5665ea5673b9f1e83244124269b9c93084e4c5770880cca464cf6f183af774e2202e68e63a72135652e2d64512db181866c4ea33561790c4e22e44e5db73f9c3b82280e4a7e770836f5f46bfc29aa0d2464f2760dfd19a776c082babf61d1908eb42f09c740a601ee03eada3c03c06cbfdfd9040398a503bfa0c5a04902978b6dc040b9efd036333ee8a1c381619c56ac3907471a7367119fce58f0b414676d9794c3978d3a6cb74f3b1fcbd01c4313ce8db73112e441a64c44d058ac4b7c1d483ccc4abb0e50d17aa6f3889086445242ebbd9cadc71ac9c8755394578bb5ff34e8f23418823f78ec90f7f36d95b6dc0a8895fd1cb4e0b6f046e91728ee6c1a04237db15c8526b7c47fae8af9b0fac1ff9f96887fe66c7fab62e1470ed72f01c4e881c79f783178695bd6b479b1f2e9e4d039b9dbb363f4695b9614ce2325fed607561be0d5955f06a6b7077df4376fb7ad9b49468cc661b18baf9e357dc67be6efc2411546e74b25dee24b1ffe6bd8df92ccf0defb49163e42e72e47d13f96ff053780ed1057091888e9b709bde5879e4586df1eda8f61c7e7dd7c107d926da3616dee341e2db28144072fa8ecdda373d973143f721336ff89479f63c46cb946cdfb7d8c1311b76cb60589949b4610264016fe312cbe225972420d7e15bd7e6b7f8b7f9f38e7161858111f38a276f3ef7bd3d95e518e944bdf9feae2b961f2347dbe64339c61b03661e23688f875fedf60f7dbedab046dad65805ef7e50a0e336ff8bb69706ac55720c567164f33077deac55c99a07c7784b00016ff68281114b801139bdd6c9e0c5db1ab775b55bdc882aba8becdd7eee0ea8f1268ddd95a4d9717f5b27c75aeb261b1f42935d4e36f2fa9d91375f5bbfadd75a367b898de60f7cabc939a61fdeb0bfdd628cc758bb5d6cd87dfb2e8f40d3c0360f1cf38a713e83c15fe5b9cd83b765cc126358abbbce6ebadaf810b2ad7189aa72c73bcfd9e7cd3c1d2f84575e32b8365872a4a65a80da722438460edf09ea7738936ff4fec8765d785b23de47199ef1b4a51b24f631d7c8387a123812ef7512cff666e286f72468c60e512a7b2d396f71f8b5590eb56b00213f8c317bdd564f92ce250ede241c09721cc95f3d1d34229bdff330a5b4f69ad485e8d5fbc9756ff1fbe442f318d96aef6db56cbdfd3f7dcbe93e8d79e34f2ba30c7d06150df88e578a9585b8363805cc8feb327b13264a17f6cab096375f3c493a3271191192199e88b69a70751f72553984ac05382477e2e829e3c914f6192c0deca275481e73482efb0e37a9d4b468a2f5d43ff289addec75f78916996594ce3c79cf07dfe5f94fb4b06945c8a66592839f5edbb25836eb5e7c327eb23fd5d06c42fcaf89d17b3b7d872f28cb6f01c77f02174c32bc8d3d1af18f5916ec8587954594b08ed39f22ce6f88b2fe625cbcdce23281d5d1b6cbfb35b4aee3c9b1e2207df62cec8b17c19d818b4e1d7865defb8bdc50bef03867a353f063a816eebf980dd1dc7f260907fefc7ef98e43156e7395af9a6bb7f772fa4f2ebec1e77fd5f17bf2aff56a3fbe3a5ef3d11f4efeb885c00e07cba9c4eff58470406fe751d11f43fd50f795ff22ff4433e5cfadf7ec87ffb21ff7ff743bef7f86f3d91576eae95612d9d361cf6de0f8e5f9b2474ac34d6d13658b02c80e531c8b0cab5e955b45b28d0c157becb588b52bb93982783fc1fc0b8b19efe06b46d57bc231a080067e02ba861f0bf1dd4c09f811a7402ff01507be3fd0f700d42fe0b6cff05b6ff02db0b113ef678a971df0783e586cca444d481fedffe476d728edaf2666b78f54bb7bc72af9389b7fdb5c484b02a62a374aba5b50a03834a7bd5e319dea896cc083ab1fd56861931069529700b318619d107305fbef59317dfe6c188c1168e799fcb4c5c3b5a3cdbeadf7ab20947cbe57b2e6b1498a99b32cd315e1b303bcd62ef59556516bd7a8d6f3dad57ef2582b0c57fef75da5ae1effd64340d48a20d2a6f0c2bf0bd87906f79b307d1cbde67daea749840c3aaac7d564d02381a3c875f7da69cc40c4facade6a56843cb88ceb7e532a8e5b77e68b97ee06dabb3d1003693c8460bcfe15eb532f5be0f4a48ef634592b077fa5bfd7be50689c49bedda4ddf5cf155369960746ff53798c63a3104b09a445b7df2b65eaf2abb570f442e43567df59420acdf6b201bcdbd4daf6cd4464cf2c6cb57da034712dec66b60d328c76059c4d06d9011e9a6ab902dbef5d2a90fba7254819b9a7cef8b31dff664233882c5ea7d9de8be1f1c3065eed9e8ea39d26850e555335143d38145ccf1170dda1a02c65af7beaa4383bec36ffacc629d48437697f3de2be598398d5eb6947a305f6e754dc45cf6b54630df46bbfea64dfe6b007940b4e954ff6427efb6f9b2ab77def4bd7fffe3b5e32687dd46489e30178237172e510bdad02da9e3e888b7a8f466596a6201b46e16b46251256d2ec4cdcc88ab01a0946e69bc01a00647610c47d18abdfb57cf1b85da718cd56e720d33a28cd96dedf2caed3e51ee7af36c75d38de1d9e627f97fed6fee7a9527cf965baf2af34d46411581af7e61346e7565f0da8fd96adade77e4f5b5f7f2eaed054cd9fbce9bffd6d226bb3f900f22700bfeefc71f1de8f75e25f91fc03a1dd8d6fbba192d238cb77d1a2b2409d275b4dcffd0037ad9295f868ed58695557094a558d9de335c953fe3577df9885ed0b66a619c0180344702af3da0d71ed7ee5fae4e081ad5253e83f52f9be55e73be1f8caee8eee39c7f120f363d251c052c0e90de0cd34c449de8bef64cb37dbfe775d621e7ea1ff6acbe9f7fa703125661290e80a916bdcd49ec876503db02f67e2d4ba4212cbfef81ec36a35734e4ea846de804ec33d6b0f7155ebdf1c4789dbf78d126f1c4d3d15accf6b1afbd9d6ffa6823562e03c6edf65ee49b1cf73fac5c462421ab96471b25763369cdb8e9a0eb315616d961225ae912d9e8c363a349a9b5c5b5d175df4fba82454463eb6b4f44ed5e7d436bb9394517c2d61a32d6e05d415464e8c263f93284254cb9e29384bfe6364cdad64cf46e023d6fd298ae2e78cf315ee7dae18e431e53ae6ffde3fd86d17dcf8bc1aa0db3a3ca1ac2ea0da71de93fe84b6deb6544c091e08923b9e2f31ab8c4d1f1f35b8f57d8ea26df76137bc17b2fc347cfd1f2f7b3341bff1faf7de9034944c802dce5edfc4ccde77bed55153fd2ca786ab7c751acbed2cb381a4894dd6eac61bb9e23f161e353a73059d32fc3ebbc0ebab80b27702451f96a23bc684b89014a490813a50b95956f6f9fade9b56f88241ca941aec3250e048221acdddffaff9bdd6cb6566eb9c21e97591ef4f43da654ae3def38e7c2651d41e570b3bd3460e55299dac27578d8b711ccabe82e84cc3359816d5045f0fb35e4dbbe33576df849f79e8d671c53ee6b52c192b5805211b222f94adbd196c8361365edb675c9ba89b2d6d2b41cf346f7f5ef67656a128ed2d2b08eda20dbfefded730e02616d956f32db62e8eae9f81839f2224273eb5616e2d9d2e86fbe6861cd7e1e80292b8ea121d72ebb979d4e49006f72e0617fdf23f1d2d73e2e9dfb7b0e838f06536661452fb18e09aee3a522908e816d0aeffb612664951fe3bfc7589067cffb615bf1d5832dc54a1e031deb7c9b5f5c8747377b72176c76756c760d6a96577c74a072f0180b11ab1408ece9457fe397ee12d169122ed304d5f288374cdbece6073bfc666b318967e2e6cfd93e671933562e426d1a55f4fd856f5ce218dd1e5383a4f9b6bfc758c8dbbef3c7b930aefa73b9ba24f795076fb321f517686698f4551ec07e9660d45fbc7da355156f72f0da373d9f95a92d4388ce7ff4ebefe24b4644dcf5c3fabeca917bf7d57acbb103e8d28795d57936bde53fdf8ff92166dd6ce2b1ebdf7ebb5177c32fbb5d3c1d7cc960ef577b2d5979ed27cc31f8fbcb9fb91ff123e7f69c4f1e03d6dbf2bb36a8fa758b8ffc157fcb47b79a81daf294e165936fb12b8b568e79b74542358b10e33275e292e6459741dff2c37dcf78af03b6b5bafb8d646612c265bfd384a56d3cec337bfebcf1dc6c3c9b34cfbecbd1632e6f7a98d79b4d74e182f701a36e36b9cd9bed6b27f1178f2b98784e3a851bde31f3ca65f88923c341c88003474f8d98b5a1a0abf5fb98cd663f5cdf06559771d726e197cb20646172db3098b1201142c180993ed9fcc6e74de78a977cde6c87b1368cfae11a7e8b4fcb8e4d3a9ef134a16b0b9f888bd6f936fae4de74feb239a20820b424b7df5879c3ea621b7bb3892982b464fffd5b7e81b98cd686d5be77f74d26e46510bfea024c7dc84c7c67df87789dbd70ac346036dcb68acdb6bfda8801262eb4cb5696ca777bc62b3efb303723179b8e42688b0d5b6dc765bb7f2c5b2c48c70d0b5fb1175838860638f21bad977d6e7995b761fe35b6a30dd7b75c7c08616bab1726d7d19a2d3fdeeadbadb6b04c94b7c9cd86f87e3ffb5359d5ab96a587d8d19ad75ce5bad5cad1eb1c8ab0e9956764d48337dcfe68f3bb8d0d3ff18b8a7fd3c177b280cb3a6468c027f15e74acc17792ef6553e1dfd1fc8403a45bbdb0e37bfc7177de8874ab07451d0483aa443e8dff81b60acc8409caaa6a69dc0fb4af06451b2648101695fc487b97e7961f4736da6ed8cc53b2a45ab26152b4a9937cf2834ee44d9ed132255bddf13a73b5d14a578ed9ebb9ad36b58ca27439e6ad8e2789ec7533ab99b8368a6e3ebfe59a7b1f80c140174a4b0fdf30092f02bb1c3c38fc2ee7d86246b0e7275f6d7acf4bf8cc7df9d0075be72abcf9649f7997846c5408369e7d4faf25ac82fea98ebfc3569d4f84379bfe4efe1fe9fe04577fd4f5c735edf1c97c3fc7466701b3f1fef5ecdc8ee52ef4e2f73d6eee3c337b9c7c7f18c2abee7ed3354752db7599bbc534964b1c922b3ecf63852fcc8b4281ee638e061e0e59d42ec925371dcf82eaf293d8bd9f594abd17fe35925eecba0b2a0cf83e5f21d2f0759e6ef0365b78d5e74600cd6958952b77a526f14dbe3bbdfda6a80e73d9a8f16db9e158be74ed17de7dc45f7bc1538e79d5e03bae7c1bfbc262706a6c10491c7dc3ee28e1ae40c255e8f8a3ccbfe62ca4f69e2ffe98dbbee6dc65b6c7ae4d2785eff0af330af4f453f93b249f70dfe5299fafd96c68b3cb6f3ad9e8efba78c34e35112d2279cb83f26ff48872cf5f3ff1f7c97616cfa6dfe2cc96cf13219769bb1d694e5abab005ec3ab2a6ecbb7ce83d87f9a7d7fdb2d93d47323ec6d87d1cb7e7b7ef7647229bcdedbd531ec2bfceffbdcf7d9493997dd3df4ff3b5eff2b06d4d7b0d527dce4f5500a4fe30ffb291cf792cf939effa98c77e8f21d823accc31849257fef9399f7aad612178b500b6da7eef29041092a866e9ee75b4b3d5497b4d5c7b1ffb02b5f4f1cc5cf9510fe1f455075fd7b8c9efa33c4568cb05b1d527b15d4f5ff389eff2e13f1bcfb741f6c3d8572ef2c13e3f8ee793084a5b174a5e76f586bd3fea86d3bf93e3d530d54f35e7fbf945cde19700e64edc7732dffb827bbfd563accab7d1d223893c80f9c5b36520608b81cbf0039feff5e92bff20b984a3f7f37a6950a163447e9567c9911fede4dbb8982901ee4afda15d7d8c4b3fe3dd82e8579f6f6dbeef35fdc9d9d33d676176fe56cf51072e69f7fafa2dce3b06c84b1a2ddf0d8ab68c42e6348bc3f67b6b2a79cb491bf7ff63ef4f9b5bd59d7d71fcaddcda4fd7b93b0c2609ffaafbc01083c1430c18317cebd42d0607306258c6d8c6affe5f1283b133ae61affdbba758555909a0b1d56ab55a9f6e99e03c4fb9c23643d2ab1a075cda3f78c929f62aa6b04c5062cc71c42cbabf914e5871849708948d1d9e17582fc5b4a465469a2ed1be76eb4fb12e967809bbafb1ea4be8d19d5d1fc90e68d1eac14be3daf682ed2a4bc6a355e86a283d8b31b476022b0f8f5dbf8eda0e3e4f48ca8db8b36fc857e535d8cdd2a3606cd7b6e81e1e5ec6fbfc7e79686d7613f5a5b155bc588970b60d35f7a22097a6c5951d648364d6d3048d231af7dedad0f28e8c0342b5e3e28960eb1876dedaba6d34c642636b816c64994b88da225dd63dc237e512f1526b2f9178ae4b87e6dd02ef3139faf6f9b20792629f42ed9702694da0bd48daf05dec1eaf65948de6d6d4c73af8bc62f67e327a53267534d91275d917b91ea1f5d6396637eb4533d688af6950da7cbd87d3625950c078fffc149f97d53843b24da7d8c232e5dcabc6a705cfae3d51a8ac2abeb6211858677bc075a7c49bf603fc6ddbed3f307de6d5a86cf5b05667e8b7d1c638643691a688eff7a187cfc394cb1eaa3747e5e9be1b87174d9abd28782e6c5d8ad95aa60add4420d07cb08c5351ef85c1b9b61f4e6afe56f236ed0b5a876d7391cd34eee1959dade6afebfe213e121f032952327f2a05737311c8e4a994ab712af15eb0e2eb7c33adb5b3e52c1fe4bc02968249a8b2be25dfe73d5e8a67538eb6f938b2c6d73aaa120b6b15b0130d48376dea64de43a7ff578b7fe3078d81b099aad0ad718d789ea13170692fb04c40b8143e2b6c7d366297f64b5764c3e6bc10dbbc5ffb1532df2d536ab1768d4d9bdce2b3cd4428906c6af0ec21c60823d97685f9ae6da4d2b40b3e80f7a2de543e3809928f686f13a2bd0f924d9963c8b9cf735b078d738d3746fba4c8319810c9345b14080b9fe1fc2b34de5ed63409cdad0b5f458fa56bda574116dea1e51b3cddacf191ba0431639aa42de8b1bcd2093d423a7a63db7d43476fe6426c1f7c347f792cb7fac1035efb822679e845d2450f4c7a36965f6ec7f2e01ba7d88d7c029f21274ab336f5832dbc0a3c5b3a8950cdf957fc98fbfcb89c47a346a7c56bc095ccaef7a6a4b186fe8b1e03654d026dcdbf6513453ab70cbce4c85efa260bfa84c5385cc7783c7c141877c18fc8f9d67a633c89c6e7b61ed776fdbbda878879e84150b94f44847d9ca68bfb79c556b6c975e707afce99eb7aaa39050f735a0dd1dae1686f8ce5b9f1eb7ddde67dd3664cdb6b3d741c48781f7982d2048afa9988569a54ef33796e679b718ba97f9044f570e947732e10a9280d3e1390f8f0caa779a65dd199b28c13696bd28324221d53d8494fc5438f67ce96b168f84e3db8895ecbee89cce904785127506bd6e18ff9f92a60f1a21d8346764bf11ad8cf80640d15c8fc9a5c0a523466a5697d66f1069fb4bacbe48617b1fef61c8dd15e0bf7f50d9ab60118679659eb3e4827e9ad1b87afce05a9b77fea6c6fdb576dedcad112a1d24581709e6eed6c9ded8a760c06cdaf33d689ba60958837719aa8af13f46878f151e2494a9afad83fe4335beecfd3bf3d7b68f631b50e12f8940f1b5970595bf03ba95f67271fde387369e63c58ab407e56f4c6a6383d3dbe4ec3b57b86c99b7691eeecb6a6456d3bc03c1f493cb97a8fbefdfcafce569af1b42940483cb1af7d2149d2a340b5d2de68fb25cdd1329767a45fda4f444b6b4501cb3520584de56bbb02963fbc14ccf547ac0fbee29b77e8681ba7d73c202e492f39fe711e687c57ae78a07ef72ff240438bb9f12e5d6ff923f9021f6c7d245f7862ef9b4be845e3967e402780b68e85a5bacede1aeb7dad9bbf96435274c30786754bb337cf5b7edf180a855bcbd1c83296bb1a8bd79c6d34fec735ee80a5dde474b00ce57abef46c6fadfd4cc181a116ec673a588dd360cc766cd4ae0eb5d1c72e769a762f847df126ed99c731f068b4cf5e669dfd1eb55ff0d15e19ebbb76c256ae21a03d35447fdb5acf57b8b6eb6dafec921fcaf5be8db10ee2b432b8edc6f0bbf3878b7cbfb4a1b5613674e9e4b9747dee7abde7d53abbe313b67954ef9c275ff1c22498d7e763bf42f7ede7f55db5b5d3f3400c342566d7aa26052b8dc3d881b7f6c0b73f2d2f4a3c1128184f088b9affea35f812c0f93a507a6d9feceba1b73f3732a7ff537138289f639c2efba186dfebc0668b77da1bdcda4b23c718d5b6526311499d6dbce60f298a5f95733d67de18f78ff5acdbc0e63d7de8125cec43d958fff4fd89db38067dfabeddff9fdd87bc2aa7b5158cf7fd767c4926f0a3721ebdd7beebf9d4fbc96eec9c35ee199f554c90fcdf7afcf876ae7cd21eccfb35768de4b435910b0a59cf3d34769f8f7d6f3d6f6ccaffdade395a046a6b6712c1c81741897d05ff459b099f74e7242d0e4fd16376a6ea4b1debeeba2aeb5b22de102d7e10cf1ba4cfdfcfaff5fbe845c97f7cbd6c78f4a331c676a5f80abfc84a919259145b5a944098546363ebe3e20479a5c5e0094cbaf6b6fb8fef7e429428af9dc0548ae24bdd75d9d19bb882e992766a2c698b2b20dc8a33bb7dc51b67d85e0aca06b38be714b69df0eab629f3376109dedee35cca91839f3acbfeda9a7b75a681d7dccbf9581f4b70730edfc30d7c71cf768559b8c1337c30e637f5becf635feceffb7324eae11f70307c3bc7b156b471842f0149d4d04bd47c9380588a38da32ebf30e2f01849740e8272d367cb9d0342ef412ffdcc6a8c1b11cc618f77ff092023d130ecf452ead667d3dac8ea5c11cdc88ecf1652f064eba282ff368b9540576a1e98c601282a69258976cfbf7b4261851d3bd409e8ca33764c4d35a575fd613f8ac0296d3637fcd07b9a9c782a24f806612270ee8cc933601daca602bbbeac574ab6d3b65cf26f8e625227c90e3b3b60e1fa12f972adffabeab5798e1d6bfbd0996da8ce19764c1e7b688c62f5d8ac849db768c3d5c2399d8e249008bf618735d6d63d8ed7de344383a79b0a7a0b0411ba3499df4cea75879ba7f9f9ff0d906ee57bc217d4d019ca202b9778627b33d3a74e32545ea58fae763dc2587f4f8b7f75988bb2e55ebfb787f4ffc58b0d25f747da47e9f3f77ddf4773c1fc9fbc1f371f07c1c3c1f2f72e1e2fda808b2b0d6fe909744cc69aa4e5cbc9d9ad3f61bafbd75cfab4cc4a7d2621d5d44e2434e27ac5c9aa277a09244b6b4957cacc760597b7491353a9162cb36caaa4b4b817bf13e6b3cdaf03533e77934ae91f5351ae7794daab242e8ed297053ae9a7b74eb4909e29e775fee551cedd2f20e6b971117daa29a775e44222c5bcb0b6a7bdb772f01a965ca8dd7caf2e04d61e5187ee6f31cda79422f5d668e392e25be8e8ca680a578f1de04e72b4fc4b68d6d0442eddaab4c6922c4f63cda0a49e822cb048b687494f810a59d357c105d3cd1a4fcb9f1aeac11e21829417a94dea1bdf1298d084616058e3e8f4f42b72e451e5d11866eb2846d9f1b8de8d6d32d9004dce63dd2b65c4ac651b9247182c6efb8d1b007d5adf760e88feb3eb76563cbc1e5e48af669afec22e326387c79cf831469544b610d97c27c2d958b9bb280c114d83b70daf340c311a6ba2837912bea812b0a74cd6f42ea25a0f5ca42fda7bd0412686ce7e3766c96073b55f1751baf79a9e1e39aff3a6fd51a31749356644b49143a3e9262612d4de05a8a38a425cb7a750c0001756dc202c073a602644dd1195dd3c15a9ab09a3459aed6b12a83095cade122581356a0e88cdd96a711f059e58f816d40c2c1730b8cbcda3b2b4073c8c1d18a20b4f91b8fe1cbd860e408f6aa6d79bde735e48a4269d3a08e1a47b1946dca4db4420e7a49736d0ac59c9ba854856390b9dfcc7befd8d2f26d7acd83e6fb1ff2666cfbf72764e6bc9de38d255012968465ca842480a33491c3daf2db45d8bbe2673d0127df801592b3aace181895962eeebb31ff096f492c27ba36bde335d9caf96e973bde3791f89a0864176fbd05f630b95cc568f35ce345a5e65ed0f5bdb36e80c9523209f0a44d1e83b9d646487b0c648a2de57ad70fdda49ea7b5450f6c1d91c596b54bb4d2866e5d443ef5d2e66657a2c482ae10e18b3e11804ee8efd5455b06245af92f897bb8c19ecdecced62e9606db60b0bcbfad634d72ba5e8df7d8bb3311f6b689a3aaf4a2a8765101b0579824d84b69eae328713deb45bd43ebe6407d523c4fbc12e7175568a5a0b3244b22243c0a147674c49eeddd5ca50071e385cace41d8788b8ef706f62ecd639f1edffb533974d3258e42b93254c2a497078bda439f3fb51152d98d763afbe6f288fabe32e3c232d4d84bc0d93b13a3c5d3f8784b8bdfe1edf94775998e3765685368dd120a97affbd4a0c69a756f9c2abcd7440ac01e60edae905780faa409aca010e10acb7cde3fb89137531aab9b4bd9c9d5f84c917e71aa23135e47932c6d91a5f9b4f9ceeb1d7d6d836950a8977960a5312eaff6e47fa73d8877baf6c044e225783b37547d29ad2b6cf566255e3eb89174b118ea6fce59d8d10d7b898e612d1fea68917554023b74718439b4fe8f6b0f556cb91c47b28e2d59508ac6ec4a1b475234ce305d78b9419b03fc5b156419c43aacd3036c95923529bf8c596b75d1918cc327d9689e60e49da17451f17a27664de409ac6fe676542395a508b4b45b6b04544c527e92352958ad89408a24b4cee188b50e058f7ab254bca4d5b31a0459eb3137c55eb3b50ce78f814b31db2e7a2c928994b0dd68e3d24a044212d11a88c7ad8e2cd04fcb335bd7502ef22681d892ed984b028d5f4d6be075debe247bf412bd2e1747fa3d159fa6abbd63e04684679fbf8c89d9cdc7e50beacf3c59ee6d5e0a70f4d5cfd3cd9ed3e5ce3139cd22b9ca56b29982f8a389deca073996bd2a90b53529bf28043b51d7c4b11b4f01c9397876a95388c6d43118c2c65e0fc7c04f84ca31b0c7ccb98ddee989ecd9a3205e23d0df7e1781403dcf798ec651ae71a414e6d0448e38dba68a51fcee381f239eaba34b1f3b5d60b526d895c6adc144d000cf198a7e92d589a06b3afb8ce6c76a4dcceaa8c96c3d16bdb5f70d9e5939448ebd2df820c7a89f79f35b9a80ca4bd8ea39baf29c68bc781aa49d08cb36eab06d309463ca0737417b1ea5949e46c9a22d4be05aafd44ba4d16b547e3f5a2bd26f9b6886b76877447fb2d145d07a5523eeeb53cd575111ea329a9346c760ce3e929d8dae378ffa7947b3861ed04be5831764b3e798dd6971ed91da7875e65e3d17fbf480a628e72e3cd5deb40918d95a47dbdc4d20f155baa2bd56237b0f483745b4f513a1708c6bb4fb75bbafcb40b24ad6fb74c51199ff9f1e8766ad457ccd22dd4f7d87e7f96dded2bb91bd35f2b28e6adb45c7af91ebb58e5948625ca2fd6173228bf6615b5f64ab0d96c3c275b4fc265ab24b9d70042029c2a7c5d1fc521fd22b2fc80e71497aa98ce642837cc7b2f4da33a19da7cd7c9a07d9ec4a3f7aeb844203bd75b47e272bb9ac46dcf39abc5a2bde389dd0a3d59a88a4884b5d1ab51194f64485be08b6fe0447d79d20dd9b4f716405c19880a71a2d4e40855060f3de6cda71f91ee9b3e7da6b82b7cc25544558f13114a509b034b0d4911c0275bac8acd1b9ed1c89daf40dc26966514a308f46334db7505f705db226b12b4dc26db8b4bd6daffcecd26a6dbf19d7f21bf4db9cf887ced3a2dfc76dfeaaee2fd0de6ce8bdc59e123ab0547df9d2b4b1e35d37512748c7b6e81e3d82ec1ef39eaee65ecc1cfc493de60d4d3f3a75852a080585c4a7ab904fb067e9d53b09c9abe49db1c4e3c0ac001e4fb806b8ddeff75106477c326f8a39e56accd6a598c431bc08471f4274349858c71e95426c8b10cf61cb383d35e9d03a7559c3784ea8f748a087c867ced2049458c6e82a744581b10d55d84cb9b041eccfb0e71acf8a122f239d09cf290fdf1670ca5d73c14ad118cac604ebbab39ebef8c6090facf98df19cd4dee3c81538da81944b22daf360dacf404ca2b5fe598de1d4247ab421b9f54a133efc2e69b82d48972eed468f9078abd9e7e4c61ab4a732fe4bbf9dbab06065fdc3ef10f1cca7f4864b015cf8a7590f80a5ae899bb500785602d1b822395cda6608a546df01a4cce90227e838bfc47e2c4380874fcde0a93b356b75add708de57e52f14009e152214f42d79f092be0dad2923bd94718b08591b42ee7632525d018259ac09616292405bffbbc8f2991ab35ac3b3844beda19b2ed88576c4fabe2bc2bd77266abed52781a67f9d6fbb135278fa14f53dd3b8c9ba1a670d725956d15e46039cb42558a9a36b83c21430df4cd6a4ffbc9eb09c2a602f0056d600cf4771a76faa6648e02b9bf12d335837295c91a5dfba95e4825c545f79bebce28d46476e2248ed2d0a9478bf3fee74edfad605ecb9e39f3ba464bd0e37b4b8a0bf6b5db43b61ed4ecdb1878d0823c75402c46716b5afa309e0db4660699932d3dc2a535eef6340ef243be7f4480f663d2f7334476e5059dd7eb14666495dfa3e0aab45f2cae0729aabc5822637e8a49992e50d02f5aabe569f6f10359a0ab81500f2a2afd35fd5f7cef85edadd797ec0dfed6131537e9d4e0ac592aea89632add46b373f8637720a7ee02dd3477e357af7057157db7630ffdd4b3cb8a551ebb592f3ad17a6c8d275d44880f698fbee9a56b496a645640699cc6b52eca3b58a3ae558477e22f02d4d73838db08717cfad37e692b00da25c278098431f5af1b2700c50fa4f6d19726e47e36c8ef683fc3833681cbdb0b449e2fe3986e7750a0a77c256aa411efd699cc9157885e696352f97f8da5ef3f5fc17a437ca3fd3e26053c91b3e8865ec3969c85b5784785fa7d032b4d17e4084a13b5d042b8d2b6dd3dbbb547db38124b45ebbccb36d2ab8af58ff2596956d201d40cd2de3f85edb0b89f7e06b54b79eced61d8d58098e66bc124706c1409f67d6b629538eb184bac8e66eaa2e2d83096d0a54e63abbd729b0f54d39f7a750f1129670a9e5c1e5c7ac24ec71fbdefc2ea88c2702ff799bebee74715a6c8b409efad04a9af1e2990b127482a384a2febce223b93a0672f54a8ea433ada16d4af43c75b05e7683eeed6c5e35c2376a657b1fcdcb898ec1e41e1542fbd57c783d673ade8ee2d64624d4f61dbcc7ed64fdc5e6f14fa0985adbdc6f40325debcfaf10492b4dffce0759b7d636f610c198e850e2c187ba9dac8de1b50d5defd91b55418160dad8b0a1c4938dc77c8d5c7b25dfb59f40067da4a76bd2551d3daf7ed4af5b44109478fd3b5edf2640d363565b4f80a1eac760a1757b416c97e8f64b686f82f4cf3a8a42a373d5794d62b952273abb509a7dc7381fa3f48dad2a909b1b656eec68f0ea59d3ebc808f8bcb7bf2759ce35c0bde8f1a2677f6dda38ed6c77078f56deb6715ed9d9944212d9d2a2f496c70adbf0438b8e837922873e8ff76ab5adba46e4f6d28e4b8b22e3ce0e7afc823d12d7cd4496a944385a847844eb5f6d7b03a72ea2a249e3f67fddce5997bb758d2f968bda1d64f71eb5cf3d41deea28ffb8b5a57047cbc4b701d53722753668c41b37b67492e300580a7534ac36dae23875a9516df37dc356df9c637563876fc79972213e030a5afb7a3bd6aaa0c7a4bc8e055d45fb205db9ce8775312590f52bbe83352a101212cff2120f041dca2b1df3ba2ac8ca3f8e7acbb3e4efd367f798b4895accdba88df1ff87306ff4efc3bcd54d1f306f03e66dc0bc7d2e152e90b7d5133b72f1d1507b19141135976c411707dd81a57d2622005471be0ea2d579345bf54cd51b912cdc74c14af5a559f7f33628efede5d824b75a6b8fc47c3b2e17bcd4e6bbdf4c97f94a93337faa1ebb60eea977aee14a8fd5e2697c9a93e1722d2cd112bab734b2091ecd6cd1b60ce57f4e9b6ffa0556d12fb30543df40a19435411c96fce838df5ec1a6de6e3f1d9e6dbefd4634fd60461ea5442bb4057b3aed5d4a85ee0552f6ad29fb714e91075b0405e8685c073d5e61a803da5a355bc1a753ea252ce94d60bcc26d649acb59fda486446055b4ac2f6a3d1e6c5a3ef82627db97fc2136b324c2d64765a4edc5b864e4522c31376bb80cda127ba250a12de08a67aff334dbc9d5f4d28f453422703f2e17b17d6b54f4c74b8053503bb0f28ff8db8a678f96898f16bef1357d7a7d5b1edcdec564f3a4b914f7fcaa4f8fa8bd8e618716adcaf61373b908717b3c5c7fabd35ff818d3be5c68e47a8db63644b8024fc743ef3b4e8f8393ae997573096ea0d417adf52f80bc7f8edb4b7b39a16df38a677120b966ecdb4b006b08d096e13ebc94b8869b5cd787d523f5bce2d99bb23a5ee99bd13afad74e8f0cd55ee8b0da4e4eab2620da3c7d63bc68aec2903c6359b83488e7c6e532c47efa45353acdb793c739ddf1d0b6ee07d9bb8cb2576fcb37e2f2e09a5cee8aa09a9b5ce11b7e7e956ebb289ff9116ae3b671b8845e441edd29481d6354de8c0f9e57cd7ceca567ae02c2af52ecacf5d8997e925e1bd22b385147874e26340ea6b62995ede5c30d0ddfaab7bdb4f8c3727c34b728407c500e9a87a96d2a97716983ecf04c73116a5b17102e7298016062ed9f9f8e87afa5ef68d805139ba732c40e3278ebcd1c7c533dfaa6fa591dd8548d78cf4dbcd2a501e14d01a11aa84ff85d37e7bd843dda785e82f3aa0ec6fb688b00439f6c83d96e7432741321ad61c797fef7d334795b13c275fef595e3f0e3455e60b379d9f2b79d62fec090e47952f3fa8a672f32a8efc4fcbedc7c83e7c9d836f1960cad8f682e3ece2901d133b18c25a1195d9f5ec95179babf5cb6dd5ee878913317de4f89b7646d539eca78a2fecd13d9fd8a67898dc9c19bbe9c2d8a3dda6b2677f19829680e6f91ece8d3744ea9105f3e20a2fae36e1caede53107a350fdda487adf90a1fb5bf35cefd315c896fd6f5f5f5aea6d5e39cf22b9706c72b1a7f3e76f5c5e54816f4659de943ebed352490d0dafa16cf6139df8d3d73c5a3bfce87b76bdd47bcb2b7eacb4747480f78b30f98ee1748ea4546f6deb5e383d79cd7fdfae5717b4f4fc1655fcf99cbba241f5c5ad97bb48ac615ad0d846d2edfd553b0eca496073427f065ea486e35cf6ff274d38f9b3ed76b6abd96d7f2f4a253356b137325933cf144da142c6fe6de2fd3e5433e40f978b23dfa68d7cc8fe5cfb529f2db8d33fca3dd04d2edafe157df293674a7aff23565fb07cb387ef31270b48ce5ce327ca417a52e75e1ad7e59730aa53f9d6fbfad78b60d56fa5ade5d7dbb1e8339dde817db1e5f4d5fbf7b83a62d0d71b06f3b8195ad7d959ecdf13c5a6bdf682fd6c9d0ba3805714f4febf348ee26cbc23754b88ab2eff32ad7117f7b551dcc60c5b397ef6fd0b02b7b3dfa3e8b1ebf03c4f3fce779fbdfbcf34df08da713dc88ef7c6b78c8a24ea42deadf665176500cf9ec4fe5d0a295eff3041fd53fcea94b9a5b7a5cbe81ebb147b2ab716ef74d396cf5dd5e9bdb31b9cce576cc1b5e5ef16c375f6b3d19eb3767c7540f5e022ffd793ad53a0c053144adcf474e5ffe984bb44f3c3b228bf723cef55a53ebfcb0d3edd76e221c3d2a3cf853a407d49789f7d2935e72fcf6eac8bf5ba3f0e5a08563c8e77ebd73a38668ac7816e7ef9577eed5773bcf6bb88aa17cc34796ebe3a1853b5fc95d9e7dbb0c441fa3beb8fe86071e2fe530f58535ef97fdba0c248f137074e9658e616beb1f1c0f83447afcd917d9b2d6b5ae65ffedfe6d6de0a0bc844b31108d5ffdbd2f1f40e53e31d836e09db3c39c46fcf2d8add7f3041ef0a52be962eff6cafad531692ef14173a17b772903ad594ce84d97994babe7debafc268dae783cbd5a97f3fe7ad15db4f205bae957697f8a8fbbb1ffd76974c3739d2e7a59cbb55e9eabfd74bbaeeb6ff12c6eef958e79be9eff9fd0b8dffebefda049ef9b72b14a2e171be13e743a84573ac6e3c11561e4f5ebe5c91ac6f6743ce0fc577ad16b7ab5f2be81bcc517bdf0eb346fed3e0dbffcfc78be2ee322dfe19b3cfea3e3b3c7fb6d5a3db8094034cfaf75d09acff566ee4b935b59f30bf2bc2fb7b45f1ca3a4bef00be942ddbb2b3da8bf66f5e4ee47b47a7b2e7cb02ecad01541e8515fa0a37095f657f8bc9329ff92fc7d9f46efd0b7b57b34b6106c7359fdf3412e8a9df7f1511f4ad01ef3d1dd9dde14397a183d8ec811f90b677df5a1cb7b477d238a7e1c8d885177d4376a8ffac8fbc787879f38eaa3dfbfd69b78e79cef81684fe498fb11c53004f13fe598eff684ef2be744e8691f65e927e77fbfb795cd51e27ffefafbafffeece126bd6b93e4a2cd0d3fff237f926f537a957fdfffe5710edc3d2fddbcb92bb20fbdf41b447bfdc08c2eaeec0f44f1efff39707a34dbaff3bc8fefaafbfbc2c7d8982faef1794a02af69ba4796e48503fe571b0f1eb3f779b3c2ba27db68b36c5cd9baa7e2eb2dd7ee3179ba696766a5e3fe1bcffdd3b05fd0f6ace7e73dafff55f7f6d76bb6c57a05624e8f1b3ee7df8fd2ed9242fc57ba9d0aff7cba8bfde15fb6ce7041b5452b6abae1327ce2e76b1e04134da7df811fd1fa5012ae7265db4f7c20d8421aa143115121bfff55790e571f07794de554e02ff3e5048a464f8bfbb282bf711fcebbffe8a1f8bbfa3eccec9a3c4f1c228ddec2a540d7a71b7db1459b9f3367f7d243bef5041883ee9667f57ee509959f1577dba7a87b8021fb3a2510e36a71cfd51a6580ad6038d7eed91c445798a0a7332fefcdfed91f67ffe72cb17dc6eb7da6f0acc7749bedb14c59d7b8e72aaffe205b146ff45708ef2fef319466ecdb97b0775f60e46c5be7951f38eb7abf27dd6fd71e7d455d60f5e948778909a67bfffd12f9ccbc3c6bb7ef4298621d9572feea274bfd9a50ebcdbf84767e717b7c9208cf27de45dde8489d37beab2ef9cd46f86f4f65351ba7bb8b97c487ce6f280f2f59ebc51efa1df812274c8ab278ab9bf7a6648aaf77c53e51ef6e8746208f6fae92e8fa3139ab7a997f9511af4febc738a94ec3fbb4eb1b91f5dbd8952074fabee4d90b9fdc770d32ffc6e5b60c9dc3de7783abd2f3356bb6c9fa50b2782687a35cd76a3bd57ee0e9be22b69774e94e65906bf9076e39cbe90aa1b5b34259a61ff2c4fe6b95f49956fd23cc8bf9e124d90bb78531d77ce0fe5da25d9ee07d26f3c3ffc91e4307012e74b646973b4e3ffd50cdd183830c876d13e4c7e26f3c6f37e2adb65a67c356fee78f1e62bacdd6628a8f83af5268976b95344de5d90f9c55d27448b0f932109fb851477ce6ee7548d387e3fed7eb7b99d736fa5688442b8b965ca9bc4ede2f5c6f2edbd04ef7eb82b3c274d6f97eb7e827d166fd20f3e57f96d377e4235093730dfeceebc708714ca2fa6ce3358bd4410fe9ae2d3a5ca8a2f247a2da27e5085aa55cd4f125d16c3cd212a6afdfb4be96bb5e5a3a4392c13f7d57c7b37d99de778e1e6cb8933782b0bdf4f8c542abcb7fc6afa6c9738fbaf11f036931fbdbcfc609620da47419aed7eb47d917f423dfbd15ca9bf39fd609eccddfe444d487afe4cb6780fa3f4cbb93277bbf1de9dc9b7a97324bdbd0ce2c6e53f97ebce7372c78d60b4af7eb28022f2376ead457e29fb6e73782de5df4f8e364fef09dad7a9f73b272df27a5ff16319eeea9ded8fe7fb11aeb8e40aa29fa82adcefbf3ccc975c9d98f3b224f95428be5140b1d91d7e6208ee8a22fcdacef88bfbe78b8de18733dcf9d9fe73927fb4517f9518ab0e97cdc7e749bf204deb84dde6fcf3a4c96617c3cd7e177d46c3dbe45f27e6ab9c5f11ba6f646a98f065e7243fdcd834f35f33a05bbebc3830bb0b37af579b20abc5945bbed47f5c278812dfd94519aa22b8f9b47537e90637a6b109dc453729e2cd214add72176f1087ffdfb756d61fb2eabc6eff6d8a8e788993175f31117dc98cb449dc8dff9306a7b7d3157b3fbb6ddf3ba6a94b8a62b30b22f415cd0f3c491267ef853936675ea53c39e9b94234ffdf4ed088ea0c3a69f077b60bee4e77ed6e1b66c797a8163d6f7cf69c62cfbcf72d74bcd0a188f73ea30d7f6ba0f938418fdfa30df4df497fb10abdf5f5b501e7ad54489d2769e2bd2e15ef12a228c2bb8fe888be5fec0cf8e5ffcdddd87ff9207d9c66c734cc9a0d5f3f119a531723dbab4f97bee273863752e4bbec54dd7e28aae26e73da788efb2a0ffa7451f0d3c279d9841ba71123b709cb14db9f3a836994befc7d20fa6f8ece2e8dd2a0b8797db1ac860ea634fa75e7f870b3a3dbb777deceab1ff6d8152c4aea250fffee94fffaa96b317e6c9681fad336dfa0797d65fa71e0d52b2f2ffb8f2fc9be31b176afd2cd7ebf73b049b77b9715d8f6d17f9567787fd8b32e5e67d96d5ee0c6dbc3687ff5ba88d2006e5e60148457b51655e13910e2a1daa487b73e3523d0bddf6f8a3dccae7a773388ad291b6f3f7fc6a4fd4e3254cac51af461aa62b3ff34cdc18191ef34a7415f4cd9098d2f98dd6b2225b5911dfdba73a3e0f2276e20febbb1f426b5ed1dfdba4b4ab88f7207b3087ef1bdccf61b3fdf45e9de71b1c849b1c9084dc046f96cffc4ffb5bcd4bd6c07ab7987a67bbbfcde9c0f64f5ccadff2a0b3ca4cd51c1eba303cc6d578708f88fbba24af7d8607a395468febaf3eab3a5e6e962acdb670936a7bffad290f0d5fba22aaece2abc0c73f0ab530bf4eb527cc3d7ed69c67ffd55a691576fdb9bbfeecafd0b797ffdfc881f119bfff55f7f1d36a99fedee3e59a8be90aab7447c941aff4252e5abe95adbfc4789fb4be607e9c27a5df920c5ebd5f083c49ff418b1a29f16e827d914452d8edf4bd8317b50e2c9f469ba76a5fa28217517a2ddf307a9223f75def98c56ac5ad4bff515ebacc5c62b779b3b37f2a35df92eb57052bc5f7bc976c947895a1e45057e255d8acafbef1b4fd4ff3427c6ff1709f7e6fcf6ca2ff53f57020f09c67cbf6b0506ca8454dbff1e3c57ff09cfd562e75dbc566b07e17f184f7397e081f9f0d21894a243d5307f1055c3100f2cfd403ffe46540df30ba81a961a518fccff1ce7f9015533a06a0654cd80aa19503503aae66e40d50ca89a015533a06a0654cd80aa19503503aa6640d50ca89a015533a06a0654cd80aa19503503aa6640d50ca89a015533a06a0654cd80aa19503503aa6640d50ca89aff77503535cce55f80d6dc6d9d83f331be06a768f13514fd27f1352caa82653b7c0dfdabf81aeafdeb293ec7d7903431a2c947ea6100d80c009b016033006c0680cd00b019003603c06600d80c009b016033006c0680cd00b019003603c06600d80c009b016033006c0680cd00b019003603c06600d80c009b016033006c0680cd00b019003603c06600d8fc3b009b1aecf26fa16cee5adc40f131dee692ac05dd3c8efe20e8e6fee1fef19126e90e7443fd2ae80635ffe741370fe48866689a1a403703e86600dd0ca09b017433806e06d0cd00ba19403703e86600dd0ca09b017433806e06d0cd00ba19403703e86600dd0ca09b017433806e06d0cd00ba19403703e86600dd0ca09b017433806e06d0cd00ba194037ff22e8a6877df9f7e13777529a97fbbf3f8f7cd34bd74271c8c72e00ce88227e0184f3e2c0e27314cea843e1902d0a87a6c9c7c79f40e1e096bf03c3797c07867301ccb0ec3d493f12ff732e97baf333afb8c5e25c98aff9fa11dae60291a939b941c834037b0d91e9635eead49d8caa1f6b6842fdf7958cbbbcbac931c8ac3f26b3fa02a3135f7f79a2b0752821b5352ef10d66eb8bf0e0a68b073ec88fbe21178eb1082cea147af422d00ce6e89b4ab039663389e7baef3aad568ec1a492084b6f0a88e7fafb784ddbd04be5dc16f5b7d34fd543fbf78c8f51b981c48f032f01846fcaa5c4cbb29b72a43f2d22892f66e85bf31339755b58b9928259c5e5381d3fde49bcefc99517cc9ab2ea1f9f95cf283fc7f22931fbebdf11d8cfe5fe6b12bb9fb0bb12f091f893229bf97d221bb77c10d983c81e44f62f898c9f93d96b1a1048264bd362c647e3c09b82c815e15612968497c0d26e65e753f18e4c678fb62987b88eedbb69487ffa5119a0f212b6fa8debc2ca37d5a36faa0f5234dea17e75b23ea9d7a095e6a1352368d68960568d5393f7d2db7564ce73074f049565aab94b8ddaf5a4ffeec3bc753bba75a87dfe280feafbc1db12296a7b4b1bd456993ca67275dd1f9926d267d4ff29317b51b2fff32fad5d1a4ecea394139c729ce730f2b05dee0b2bdae7d9bbd09c0f34f92717bafbdfb7d0d54d1f56ba61a51b56ba7f40c07c69fdcb5d933b78a91278b48ad6acad24b2955d31676f2ae76ee2275e22ec6dd33f7849515ad4e9e01b4a69a7a0b4682ceb9b772af41350fa3cf3e48a2c694f00651b0cb136c0d943f5024038c6e93c8fe1e4f9f887eb84cb1500f293ba2e668e411e5d5a26a4e992406b9585d6adc42b3d9ac36ba79dcaa16b00daa5e5dd3c59162e0de27962936eb2241c832ddb77b6694337554aa56e8780db3121a1472f439b02c01761e155cc5a9f802710034d27e06abdfdf3f5035d9ea9fa52477a4457b798877e32297db456f30c00faf598388940591a43a232aeea8e2f7fbf9ffe74b0293f7713af5c8b683c8e0f7c02f79ec8563ecf7db74c3b9ca7685c8ea52bb2a94d217d8a59b8949fdaa6d44ffb015de4834b2ba5de7c534cee88f4b346f7f8a1322c13102eb53cb8899ddb34a86c8d59373cc8bb144bfc5cd93f3a6e21b40c157a3128bd046e1d11547dfabab49cced3e511eb9e945d5906097d8aad9c8ad962bee799cb9c8e18da36a4766c25db1062db946b7e38f7f8efc3f9c696be08463ecf846ec21c7c5168c65f8696f1551a84843f1d97da5425bcb67f48de7c296fcbc7983796b6b93c5b860f110f2b424307028d9fca7953ae708c65ad6bbfa1cb773cd2a7f774799d2fe21ef800e98b5ce59876e88b7a4f2ed9b99b088534c17c0dbd885bac097faa022958695ccbb7a54d01628df91954b3716b47e15a5eba924f1e211c3df1945b94d0f186652ecff3c487fe84095d43cf665adcb689b492139213e77a1c16819fb0b9cd737bcb80e5acdd93907b5f1285caa61739dab7e0fa3b5addd497caa41b853fd6369e0bbdc43fcfd68d4d08b56dc2f1b62194577ba4c985e7579d3cd21f1b3bd8b739cf35fb10e59b340547bc67a084b3ad8557edd04410da22a85483a91c6399d9a614d897bf2f7d9ccad09f82ca8db8bdc413dfbaf7fc38b8e1bdc0b9795e69dcf5fca898c44bd87db77e68e1be1e932e4f3d2eed5ee332ce2d4f6099369b9cd0ba54cc63f8acc68f456793e3b92755e364fb297f584c09b4afc9fca97a6cfbea554c6a9baae898f2d9e783fe1e289026707255f7e4b452095fd023a670292f6b646da9e98cb8ae8e8114d77b3a69b214101fd8c6220009a83c0aed499bfac77d7bdff8963e98a7d504561ead643ac9090a690b3a5cca6b6294d77c50e75b4fd8a94a000dcbfe2a5c6019c733f23ab657737e1cb5365085d0039d62492f59c2e7b438be685271b50ffd901ee17a4d024d21f49faf9b06919380adfff433fd07bc168327c0c779bd276f78ac29bfdd33af34aee619810b37c6e960194af633eddd9c3956e2a5a2b50f5f95d1da275a1b023f662591817ed5cdadab3add26fdbcd9e74b4f44dbdeb2f97de1abae4ce66a3fbfd23e1e9b56cf78bbde7e3beb36746de127a8eda42b1e8355679366dadf844bd63242c13222c8a5a72c906266254d540e4c26d17367b3e62adb54492f1975f5b6df5e3e9559f5daace2b5596d6582e0a6726e512192f9a13f552bc790495f04677d2a1ffc04c6b62965338d6b6877a9df3255249323df54a1578df7ab9bfc7d9e9fa74be8e3f9b9346c533e23b939e3a5d37c3b8e664a9f3f99b36daab2cd87585f9ba3f532510f2e0040d395ec3a2dfe297d915dfb58c67b486ef5e549e9518068e7e28c97f1d83e478f07db0c43d7e40a5b63b62e451c7c933bdaa6bcb5cc2594a2d76580293cda5a105914bb9fa732b4c530f47926b10ce17cd1596a5dabd67dd4b314d572ec45c1f3e8308beaf9348bb03c2e7c310810dd2d6adfd02a0bdadf4a2bef03dcdfeff3e317d6a1ce6e77ecec65ab88cb9abade1c436f2a1fac440fe6eb51674b93782eb7a37126a5480f5273370167af924adb1448cb389d6753ae722919ceb4b897a7bf468d232f01a13d8dfb7ccb4a22283c4a0f1cc30a66bc5c38884e3f51b62b42cad6a4cb5c9e12816d9cce76d7bff12b9ba0565da56fd654a2199f9ce583fff3c7ec672da4ee9330199764dd41cffd1f0c93f1703f22588a607f5f980cfafe17c26450043ba21f9947f27f8a096c08933184c918c2640c613286301943988cbb214cc610266308933184c918c2640c613286301943988c214cc610266308933184c918c2640c613286301943988c214cc610266308933184c918c2640c613286301943988c214cc61026e3ff35af8e0b9ee5df8890d1d57ee7f4bc47f25d966f76fbe8332cce3b79baa0197fc42dad46e490c46f0c9931f8a40d3e6983f4fa2df2e3e283f687b08468ddfa586ae11497c03e7f103cf8387a20091a499f4654d1bf0a1e44cdff79f020438e4614f930800707f0e0001e1cc083037870000f0ee0c1013c38800707f0e0001e1cc083037870000f0ee0c1013c38800707f0e0001e1cc083037870000f0ee0c1013c38800707f0e0001e1cc083037870000f0ee0c1013c388007ff05f80d46b1fc61c820aaf3eef3d8f5d7e1e9e93f08b061699a2046cce3ef03d850efdf9ef505800d4b8e460cc30e009b016033006c0680cd00b019003603c06600d80c009b016033006c0680cd00b019003603c06600d80c009b016033006c0680cd00b019003603c06600d80c009b016033006c0680cd00b019003603c06600d80c009b7f096073777d8ffa1f46d95c2e7bff186f7349d6826e18ea0f826e48822289c7c7d1fdefbb130fb5ffa75137344d8e462c410ea89b017533a06e06d4cd80ba19503703ea6640dd0ca89b017533a06e06d4cd80ba19503703ea6640dd0ca89b017533a06e06d4cd80ba19503703ea6640dd0ca89b017533a06e06d4cd80ba19503703ea6640dd0ca89b7f1375d303bffcfbf89b3b0d27e751ca094e39be5c7785f8a7f8fbf3b0385f2ca30b9c73cfd27fe402bd16bff3f0fb6ed0abdb3e5ca2375ca23788bb7f4ad65c6ed6f34461eb50426a6b5ce21bccd617e1c14d170f7c90e7aec91dbc54093c5a0d7d116e2591adec8ac92c83dc7a0938fb3cb3b44c75eb88a052cce5d93665629e08678f02952fa899652a0f7c02f79ec8563ecf9d7d51201c6311b8b49cce9330748d65659b4b621e93a12f2e33db94cff3049c7c432880f8f8137999833f6148573c19967122ed7531730cf2e8d232214d978465aab95571072ff14a4714f6162d438f56cab521101615422f5d946e0a0a57b043770ae0f3f15d1a9cbda99cbb899f7889b0b74dffe025456951a7836f28a59d82d2a2d5dca546cd3b15fa09287d9e79724596b42780b20d86581be0ec21da034038c6e93c8fe1e48fd709972b00e427f5035a793457390693daa91cba06a05d5adecd9365e1d2209e2736e9264bc231d8b27d679b367453a554ea7608b81d13127af432b429007c11165ec5acf509780231d07402aed6db3f5f3fd0e599aa2ff53f4f73d5d627fad51cb328763f4fecd0a355e8a5e1dee599ef96b1dc7914ea176a9310390613cf63367212b0f52764e84d39e8f5e926e6a19f4c4a3701c41c024d5bbffee69b6aeef20c00fa35afd5f32a27dd0412e8b72742c236a5d232b97c0e55344ffaf3f1837191a1653067d4178b560f5e1a9796c1946e4dd7831b319c6faa079f82956d7cb9cc834b2ba52f6299b3752986b0cd9098c3e5d14b606913e8bbaa2379f0aa4f699386b22bcb20a14fb1955331914bb1c43cc5fd2a2d8a45658f7c9e5937e3cda3efa0aecfb40d5970533bf712b6740d50fa4f7dba7ec027097bf079d4d625314f7d6845ccd61521e64d5cb680e48faadba82c5120aee4d507e53a5395f07846f2a7ea511341688ba0f2ce3f9477691b6a6e0195f144fd8b631012fe745cea583e83b33f01a52f4262f3636dd66c73797429e66ceb97fc7cccbd41f770eb8a782d394b4f44a0376dba9ad3d325e74db9c231962d6fd579aae34ce2c78134f5a11583d24f60e552cc1ecd455416a040a41a0ce598f2c14d483c1e7a2c3cab13766992dc4a874acea71c69252724839a32bb365ecd6d8f108e9e78ca2d4ac03208b77dba0836c72c90c659204db83ebfcf249e43fc4859a60a2501f19f8a6882fabcf7c453e88b7a80d7d6a762c647e3409908a42fb2b463cad0c6e5ddccff883b58490e2d5a5d5a2677b44d2958695c699b5eb0a6e4efb6b124d6066a23a8667cfcc007b84d78aea0f2bd29885c24efa6f6c1319400cf3101e0f40a259c6d3d3fbb1423bb2947fa7c904b5335f31296f62a4ed8884be84db1fc43fdad693e81a53705842436bf9f88c04d00ddbeefdac08f03c7608ebea994cdef60a58d234704852b3e46cf5d7988ef38c9368418adf192b8841dcf5763561219e857dcf55ca882fcf958d76151a0cb3b4f84d8e6c3eb75273a06d276522e78e9a33cb2ca1f030080acf24c65194cec522496a1333eaedb59ff94bec8ae7dcc275e36d3e207446389e7b6b61e42cb50b18e61196a3c13f01a5048bcbc7529a2f412103ba24060b9692eba39d8972152f45179cd3aae1d03a99eabf7f38a2d5c6a19ba6278f068e5fef9693c5af02c89f92659861ea547b37551b7ff8aae4c688b4aa69380d762f004f86320c5cb839bda10c9555f7c0c00e635f9c9329710b7ab19533d01674f644b8f02829baab93f8d1f755ac57d59455cd5cd7f6dcc225e72505f6b5d126ec4656621b9a3053d9a729a6d0a24eabf6a308463aacc3ce5507f32cc5702d0342d88e674cdb316e2594dca674a16f4c6058f4d23e74b5fc0722f5b1b20760c41df981c9cc782a24f4eb24208baa6b3cf2691afd7c428afe9ddff61b29637665734bbe203fc83d62d7b1a670d7fe7f371af4dc292c0eb52d5caac0b0dad4697066218fa7cd8a31993daa6ba46bab06f2e9f5c4a85aff82f110adfd0b399760c10dd2ce3a4bb55502d9ec67937d65ddd5ce4522a83e6a8d78d9b5eda142094848d375a6f1e5db709e79bf31c5ad79f7de35480aede8e4757bea9e279edd280e864c18d4c9aa7485f506b7d5d6bcaedd369c292fe14c99e1e9deaf2438f5e422f5575346f66629bee18b8094bac7b7afc8c8fdfebc7a169632b830a49ecf61f999484d0154f0729fa3cbf4ba33955af01739e839e094257500f335e7e7229864279a4a97a90fab215f16937ffaef64d594bb37972e9576f3c236d0216ebc963d4a3f73bf460a097ca072f3a06ee5b349912b31725fb276e57c7272e1f5ab59a3399e63675eae7ae532789877b96a17ed8f18c651ed97b6ce1a90d57a35fbe4f9dfa950bd5e97b76c45014c37ec56ed5f4f92b76ab4bd2c1f36cf03c1b3ccf06cfb3c1f36cf03c1b3ccf06cfb3c1f36cf03c1b3ccf06cfb3c1f36cf03c1b3ccf06cfb3c1f36cf03c1b3ccf06cfb3c1f36cf03c1b3ccf06cfb3c1f36cf03c1b3ccf06cfb3c1f36cf03c1b3ccf06cfb3c115e31adaf20fbb96e169f1f7c68ff6d9aed92a7d08a6b94edaa16a68ea0f3982d5781ae6f73982e1a60f7e60831fd8207c3e130c3d7f2e8c17c6d8daca37f4190f8befa692e76ea24237555f3c5a655c510f561a77f644616bf7bf51f01ee3729fa4994585a1972e615d1620ec8818f1a95a3906f9e24fe5d0314eb99bf82f3e15e6be08eab2505ed10edde912f2092c6b3c239b380613ba025bdaa65f380603a52722b013a1f0287df60fe10eeffebe9ca77c2c35fbe72eb5a4a159e68f8accfbdf273271d307913988cc41647e28122ef2529b8085ce337b7b9c139629a7b6a91cf86852baa65dce69bf6a7c6a0eae2150b631dafbb4dcf8dd30df2d539a495af67d4e2f2bab62f79601cb79859ed5d04b7ce8f38ffdefb51fd8cd773e5a6ca58a5b03611148d562cb474ce84dd5179b02a56dcaa12f82986ffd9a682ef4c56076f1ad8347cb54333e628e5ec2625c3d1f3167db5409c76052ef98757e244a0242375dcce6e992f0cecadea284ad23ea6dfdb29baad0154fb91671b23a019cc42fb6d2312b1d438596927d9f2790f68ef8f7de1de3df472fc866a8cdd28481fea4f6fb6bf21ddc44eeda34476d30edd017f5031fb1a595c8a4639ce2f9313bd8223c233acc2926eafeae98d28ac8d44b84d845792ee9c359941d3c5adece2932748cd1013d5b29c85d118fdbf759c49ebd6471a87d051fd173e41bb0b02fb436f48ac3be136d1ffd74b945cff3e33f8683bffb3b39a49fac44284517c081fc9397b0900f2cf3c03e5cb0f0f4af62e151fb7f1a0a3f22ee470c33a2a8ff29ebd000851fa0f003147e80c20f50f8010a7f3740e10728fc00851fa0f003147e80c20f50f8010a3f40e10728fc00851fa0f003147e80c20f50f8010a3f40e10728fc00851fa0f003147e80c20f50f8010a3f40e10728fcffe7a155c921fd3378f8e490de1d774e9ed7508df7e1346da21651c3fe5c74c99f44d450f72392601f2f881aea571135ec8f07977cbcbf605f9847927abca70744cd80a819103503a26640d40c889a015133206a0644cd80a819103503a26640d40c889a015133206a0644cd80a819103503a26640d40c889a015133206a0644cd80a819103503a26640d40c889a015133206a0644cd1f44d47440973f8dacb95b38874d6ad40f4fd93185195adeffde3a07e763d4cd47195b24ce881dfda198940d0ae737c6a4acdbfe0e0e87bc1f42ac0d21d606a9f505217209c036afb299c4678142b1c78d29e7361512d293745c3c797b6f2a438f02a5cf738423ea814ba3efb0b48c636099807044b692f08f40fa6278f0d245c947e3efe8479a9c728b02a54781589a82d21641254dd5ccd638ce1371f0b3602dc2ad6d30675b3b0620019547c1831b8dabf9761ccc70da71744923e10bb36711c7b8b41eb886c0482273f0798ef4283df0c530f72a2e718c13944430b22870f4792e77236eeb52e4d11561e8264b284dfddc1703941e5edaa8e3764b023cf81ab7b7cc38702999b00c584ae224b0106d34ee6047351d2e6de2427f9c05b300b5abb9305d0c097fca9d9fa3c7834ffbf43c118e96b1cc6c8d3978897770dbbce6e2b09ec0275567d6aa46a03ea371c063010ca6b0cde55942f43741ee25209644999144e1e889a8cd42e4a2f11005baa17fea2500da3c47b815ee33ed251007a19bf3dcd9a56cc2a784ca5630fd62c7c417d047bea9a23ca49ba8d07bdd3744cfdbb40737e242371a470a58041a5844d244e67402aee7635cb6a901555a934097049fd3a1ccada12aab6011ac49295008f6599d407cc1bf5e712b35e2b8358c038d80cf2a7f0c6c03120ee213118c30efd18bc0a5a5c031f0f8419b1f61fae814800d2f2d1c6309dd740925d13eb47df0680e5a144c1c63816854da34086d4a0f6c8aa56c532e115da42907bd84cc3d7a99bb14739650baba0f856390b92fd697c97bd57bf4c16d39f009dc7b225bf93cf7dd32ed709e30d0e747df9f8f79ee9adcc14b95c04904cad298dcadde7c5f3ac663695161e8260c74a78b72b62d66b8cfb44c48621efac9a4f44d35777946f112f6689b32e118e0fc7ccc66de144488a72471595888672664e827a0046da0c4583df81453b89410dba6146c8e597de1fdb40b0a1878b41afab80c3b7713a190043ce6a55d71a61e0b8a3e019a49da820e97f29a18052b6d1c2df81139df5a517b31ffbccabef3cd1c9845dcc436ecd0374e8424006d5df365ecd27ee98a6c68b7f2e4eda08e819dca07573b068e61056ef218c8d4a50fc0940bb9c2bc79f41296720cb5e10b5cf7f779d31e6f2ae77e2210b6c69debb15c047652cb2e9d5671504669a20a6a2c80b5a0bea813d65cc7a795a2ab2f00c80be98908a4e43297bd041cdd8ad95ba60ddd88091b1956bab49ccea99ae68b88cddd8a252c631f7a49fc46d0cac7a8a511a6d33bf49d55e3a82d736e764130f75234de4982af2980535420bf8018683a01576bf49e974a27112a695bcc9a3a0eb328ebe82209387865e08b8fb5ec135f955f7a53f9e089a0f245085b593ae739da11e1d6e1b9bd63f899cf2379ca74b2d11659da4d4e07cb5081971c83ae8c698ceabad43f0558a6b8e992b00d2196443669e670dcf18ac896f5bcfa99b1243910836793bcd04717e415a22d98404127594501aa243d116df9979f88d9fbc9e8701927b6196792f612247341354fb9caa539e8a56a6e9b0bc4f74d398fdf91fcafffce021db50fd30c54b6f6319ffb142c5c9e8b50bf507db5fcfe7dfdd7624133498e03932058295970d3ef689e90941bb1973ebee6b98f796ac284aea1072e65d53c35ed68c448533f738c65264d97994b83c2aefb49d6fa807a90442c8b2b347f5ff3c165be4b5350b93c97a075a0aee3d2b68bbc79fc1199a6e8318be8a31b807d567452e8d3ac9bfb695b8f8cf8fa32de538eb492536e5597b1f01336b7790e07a09d5dea09bdc43f1b24914bd3a2c773dc7a63a23940942e0d08c4578ec110ae38caa48808d4cb7c426b0eaaa3f245104b51fcd0971d6a020b5be322cb5c425584956d2c09979619d4763701b434b17357d433cb94538f2c8ea6769d5fa7e1d917c17e9eb0a4cf3347d4665f3c95335eda4b0238639e12e510e95676affce7681c497c11588970b67515e9265b5f64ab8dc6a4b6a97256ba3cb85340d800cb9b6c86ea0dfabcf7789026b09dfb9fcdb3c036c3dca3d5f39ce7aa5a6e4002afd53cb77544b0752a2eb7232eefcb25afe242495c921ead1e5ce5a6eee9d5b8069e28549641421fd5dd6f674dbf66ee3266db3ebd936f50c4bae62dbd5fd1e518ac75c15075e6059032a70b9ca043b6e3414d07eb668ee6ed5a8a7f2e7c44a276ae346ea2ea3607f4936e12ea0a10cc624d08139304dafae98abf723b0a6bbac2aeaf9ddeb0d1713bcb96ae333ebee1cf1e7fe9b0f4a6804032c636847dbb6674ba05bcccf737d323daa4a0709f5e97ef4f65e6ad7a6b1dfa27eae9c600c86eca913ea61f085ded535a5cd3bdf7a35faf87ef968374b1ae0dc215ff66b3f50ff711e56bf4a4cfda7edbd7eb39dee38996873eecc33cf1a17f693f3313386d4d227e556d9360b8b50efa3c0cf4f858d4f2f98d7aa744605102615141309bc0956a865bdbe4b04e2d89fa9b3cd7f03de3d12a7435e6e09b0ad2497237550b370aa2b986ea95577ac4e1b501cb28dec3f2e88b730ceb567225bd31e61cdbae15ee34467af29b3cf121df7e79fedd8edb385c695ce91ba762a671ef8ce1cfcf8f79b22c5c7a09676f8d53efe7e5b58e50bfd7b8ad65aa5b871f679ace0a1b7109bda99abbd428b0b5f769d593f7a99bb095ad8dcb79347a9b76d3d77ad9557baebe7f790dcdddc4abf713eb2cc0fa73cbaf6fc97a1a10886ef5da3a662591817ec561393fc36b219838a60cebe0ef71695380500cf9ec5227d2178162996a36e3e3e2135dec9af74498cc78e1e09bead137555c57330f432f01a5dfac2b338d811b119efde902ada96fd01cf15d105ef701afc98a65cad04debb2677c5cbac63e764cf95dd9ffc93cfc80f75b7d9a0854206b68cf6fd132b4cc7a1cdab649627f7d1ca7785c4496f4a71cd9f417d3561785ca3698a62f418ee93211228f620bdf5461ad6b07399aff52e4456fc9dadfc543bef8782ff112dab3bd1eab37da74dd168ef0d237c7ecb227aed72ed14bd83dd24167984f8f373cf9c6fcfd405eaa783ff5a6acebfa8ef4009f0f8e37ed65257119fae23293f85077a6f2c16f6c4e6fcff74f6869ca15d2dfed6b9abe395eb6d6e8a2c292b08ce50e4ce5d0a2f437d7d18b0e0b468ea9648b1bfab463ffa27c60f398da07c750fa6dc3e3aa22990180b6e6c3b58f688a78c0948b76bf35e76bb920892af468d49fda5e34437b3e442f7a115cad79d35b1d6d9c5ddaef23fdb3f4a3205a03fb19902cd009a0ad6361a96a522ef113248b48573c067264051fe45314b05c0382d554fe2adf9bf3bcdb3ba2bdb92997480f467acc57dbf5065f6d1d51a80c92407af5d9a3fd83972848efb8f01b0508db60a8192f2f41cc984826eae4d25c93f2448ae2d217d927548662ca9565c66f8ebb826dcfa044e36799eac1ab2fdde86c4eb35a6e73bea966487e3806e265b69af1efaf55cae4b21f7d47873a7a094ba07d906d28689fdff44fbda9071edc886be4eef2ec536c654fb07d1cc9e01ce944984f3e684bcdab32f4910c88b8d236bd4fea0bd1beba7213616f6bc73eeddfd56d5faff51c7b2b03fa74c0fbe2a90fad7499fbf50556b85d9daceaf62b37fbcc0484b6886407e037a60a95d6cec97395952caed27a89bc45fca7f46ca148a7bee40969db90cf8ea9c239d2a70c06cd4d681944bdcfbcdd1febcd9ad2e9595ce2d28baeed6fa70963db5c128ec134b4bd2ed74ed85a4f9e2c33cb604adb38a2b599f012a1f4281b7ab15db91491a1beccf9f171ce730b9762d2794c7286c01a8a7e02aaf656996feb68b89c57df38960f72960ffecf3f7a614a77949438874dfabf9ba7bfb7ce27b11f5e276fcf9e19e28124fee8e1f36fbcddab69fc7ba7cfc468387e1e8e9f87e3e77765c6e5d0599f144f1ca78c918c1b8fc7634919dffe93d17f6b1de88a46caebd83a8c8f9ca21d3da9fe2c7509bf50967e5bd65a179e35dd16745229d7ba03b6c46476dc8e15f565c3d1fcc4d4660150ddefe75d94494161ec43519b296c11afc59540b17b03cc829dffb8ba3bd287c780b62d457d81a2133e3d9c67277d0c53552d1c67210853cb576018b8d544db6de8a76abdcd2699fc2d7daa0475f66026eee490445b5ad99f23ed819e8c4eee219acfd9704299dfc467b19476bc972a92b55b3e3de6a66bc4d5a990f7fceebbb85f56cbe459996c8e9307ca5bc0c92823196d76b7a1a67bbf04535986df52ef99bc7ba2d425a69b763ff5174e8048b11b2b5fa2dbea966ecd41c6af8c85fd5e998ef158faa2b0b34c399f1f17a8ac295fe7e1bbdc02371f1f157d8cd746f465f29a718ee3f178420a6032d96b3a2376871a143ccc53357428a172b4370e787ea1cea5f29375d2dcc1c51b9e8b116e4614fb59f1b0383f2c48e2690516df96b3f9637698bf708bc2a31764b597cf93515195ea6cceefe4f564bf98079319133946be7173187a5008b55848271c6a3b770c17fbc958784643ff148fc76334768b89301e23fd02353f7cd521c420630e03167e61ace7e8bffa80b405413c3ed56d0aea14419bf40b6de2265d9b2c930b2d2a841d9d7f61ec44d46e91adec8a6d0f753b9eec1ddc7eadddca1bed7e5abcdfeede0d874ac21efc29524285e3da1072172e09cb9409db944a8b3a851efd0c4001a909e1e907cb1085ef339b1bbbb1c52fa3a32c4d7d732c8dadd23a5a93400af7db8010ad279ecaddb9a196b959c6bbc9596638c62c419c0083b2b4d543c83d57e7d15d3c67668fce0e149a6d9fd7bb75f63dcd81ef7f7bd87dbbdf11397b777767e9c749fa988963f7f8c0c13915deabdea35902d7800f51be729f482d335d2a32e793ec3e385a6a993c2df9fdd1a08597c066a3f377ed21378882101eccbc8c379ea0dcf19ea5e6d1763131d78fc7eadb62b31f07774fe137e2fb3808aa87c5c892f36f054c57dee17b9a6af9318c77d36a9340637f2418363b7dd3d78ac745f4f93092670b45f128431f09f9dddc9d28b4449d9fccc916cc2d079a6b61b6e2cd2d4fb29bf3e179b6e0cf6b5de5426abe39d934913c492e3bdbe5c760317b593e9e78f5fb3747903976ed7af6a65ceebfcfc827cef2aca75d96c4c7c39e4cd5e430531ed685abf1e7994c2ba7ef8f946285acb8cb667ec8269c3e9d888b6a9ceec854731ec307fab054e91c2cc395b4dff287dc217ce9fbb67c9eec2beaec8052dc17fa29e39f38626e7265157f13ac85251da4b9b9a88a67696626df2c2b0ba8119b10a50b6782bcf50ff923b92e0b7239f16c2e95954a14056929dda7132f333429b5179387702f49a6b157a9820acf07e72952ed5348c9c9810a6777ee77f5687c9b7d37c885664355e0cb8db45bac8452d46787e8e4f05373ba1f1d234e9e139a2a6f17f1377e5ee64026e3fcd100df1fd3b93f7e2c4ac13ec595ba148bef13457b49f8282b47aa1467133b9a57e9f8f100132f6166365f0a50ff1eecbe516b75962ef26d547c370b014ca219648df973a1e7e0e8f8846e54e983258a9e42d89cf38db267ec371865c962911c03463ad960afebc94c18e9d5f4b81a3d80c5a37e0cd78c3361447a3b4f1526483423638eec7a26dd3382b70b72d5e4e799f36def3f65a3ac58bfe4fb32583f19a53429098a9ec596743fdbc7cf79484fa6bb7b389a1a77babcde72aa3f893c70ce942957eadf1c97f7f3c743ac9a09694f2571ec6f149d09e3a5bb03823a5e92a1e22dbda264d60c559dcf77b9406de6eb45a553c928ba77a36f8a35771e66bb7026254f16696764988f1fee7d468ccde3d4d4bdb3c11eef66ea8bb57822c1c39ed239d2ff16eea1641e5e0cc7988c88e9f7d58e541cff2efde6efc3f3987a8e057a9e9dd9099c874005ae38e11e64f169e24b603b7336e2ac840ef44a671eb90ebc0b3d86d0a3bbf364790fcbe7efe4f3f2181fbe4de3e39c8eb37804be3d8dbe8115c7394771c4dc3ffcff193b6b25e8d12cdb3e900c31992966664fcccc7afa1b7fdf9a89eae936ca4d2f23b475ce5edf92d4cae8a3bb6250f82ae23e046e06d110ddaef5ee1cff445e28f865b67d902e4f9faa77f015f8ad3086ad12ce9d2d4b8d2148cb69e38fb2a1bff5499f728ab16c09ed8b87b9e40decde213ef0a4d962581560037e4ad54fd9a825579b1e86c9903002e938c1781f0f939a7b1d233b466f89df306e9f7cb222db043801ca9b28b4b7d95034ef30d03f09a80ca7a3f10f6867085a9b01fec562d00884a7c0076be828c1ace41e9b403a41cce19d8be2089d41a0a98d42605725aa28a57cd1d7588230b350ede30430357c51e43c4c55fe432d5862a0a44669c37e2f6c1b1cf059cb0e5c3693b960072656ac7a6699938140b70623752e87c0c0bb9476dff444758c29ffb3ed3f17a8090f15ce92093943e20c09223380a101759d815060d14dcacce78ba170767db60d252d4fab9065746ea8eca71716088473cd77339a58ed58f2fc5043791e7a3a42fac9bb17dc0e9823069734e96769e79aca688baccff76ae6ddc2f63bd61103c678260fab09bfd8d3f6c67b38440f34a455895de3b1f7a01c90664538576fac90c2edf11e20afdced69296d29f95c245308f32c167d3da9af248d537315803d72330ce5007c5803088ed5859375ec65afebea4c0a36bb1080f41ee12743d581cebf7d0f753666e32ef8386224cd4f70734b112dcbf0b8dd915df7e69f16e6ed11511de02ff833833b17b13ed1aefddf4ffca9ff6c06cbff68063b6230c651b017fcbf4973bdeefef505603cf0329ff26c870186232e27b9f2d3f9c2987e138e91b5c48d6e2035131ed516ec266801910d8b71b222a9cc2e17e12bc2af04d5542cea5725c94b07b2f19387e7cd49e3fbbecf4ac40cc109fab26ec6a70c8f1175d38506a4e2d09654c01bb01eceb56887d2192eddb083b6eac7881c54f52dd184ac51ad5f87236b1dc434cc7f56caf47c5ae64917f793b949a28519046afcf64c70837c26d1befe91968a31f9d9c35d9ef45d18f0855e9be2dabc877cfa4d0dcd2697deaf52d7816ed8f202cf156da5524569b0ad8b76baee2897a518573e98d09309d45cf2405b7aa04ec8a852f7d8110ab778fb7436fcfc7a4ca57219709c0b05c92b27e9d65ec15c77eafe8d144f89a213786c217204f8b16d23d665bb49766c8f01aefd126465ceab4e4827d68097cf0b67120c2e61864aac728e89c9b79948e5507231d46d3de82e57108cc71413d789b5d2cb9d1918c45b2335785327aebe5e21b68d9be1ba43a29a6418898eb34bfaacf76f259370b693c61322eb8c004a10b3a56dd256bdf748c7a6a452ac75eb8ebb0ac17ac120a108edd1848b52b2ed061452133d73978f5d6e7e1985cb0e90b656797b37f7e163dac940e744faa96340e955a3a2eae11cdae918822d7168e13ade5cf9f267927a0e2f867c986e4c456a2bd6d934d5672737b6262f4ce50b9252d1a348385e883cead035b20f9663a024f9887d7938333888ad0ca2e6cb4bd2126d7513de92e94ed611566ffc6b4fe6a2dd2664f74f5c705bffbf7b32f3dff664fffe277b32fdbf10fedf4526e7af0300f8df84035f52ae521afe03d46be3ff9759b7c429b247610439ab7ea4a31d74ddaa430b86d73568edba45cb507bbfd668ed297dda55210adf7786f6fb142e99f3d6d2d71e3d0e899700d6d277eca76e7e4ffa3e8a78fd97530485e33dbe83d7079379f563c8ae8d751e4b027f8b19384c2da3be311263b559a5b3236f829db2815d00fa03714a27e191139e72692fd342724323c472cad860ab8616eb20273b8e8d6575de9eb5468b947f427d5e75235337f0defe1ce1a62b2dc094b0ebdb26689f3b39d399b1e27ea1bd0b15fd6d64a4c103f0f0132eaeef9dca844ff045f716ded9a06263a26993aa11ebefc73615b1649543da9398ddf6728ae315409e17e10b0383e7ca8b14fc1289c26e70e1395c6b3837a81ee4e7b64ab5cc8332371492a7b92c1fc9224c0afca815b30cce4c5c989b973b8b102f21e251f49027468e79a07f418c7beac8cfcb967d092ad97b0b796a4f81c5c3bdc46bd2f57048a918a68b8d33c90263d08325a91b0f9d80e8080461218ed3a7664f1fa9808c220c83d1db8e10e2c5e4fc76d0004cfc9aa4643244d58996d7d065587cf5ed48f0bb1ca9a9e262659fbb410e91e08c557751c17a5231f87bc2b8e47c633f64f7d561c6b62fe4ea138b46edc366246b1d488cf1e90551ba1484b1c39d6bca88133f78a8b0eefcc8c8c4e200d5d17c2bcdbccc37b2211bf414c07ccebd7c0e9dc88855812a5e918ac7a7fdd085d4fbe604b8b8da6da568c9c4cbed510374e039fed597dfe7a8d8baff13a79bf98fbeccffb7be7cff675ffe1f66f037491372866414e04c72f8ff3d3cfef3fb5f9919825a8a992b102ba2d4aac9c43ad69cb8c6b1e75e662bd1de92d5e195e3875136530310ff46e9caf09d451d3dd04bd158685ac76d6bddc4996bd7c530084aea0c57da3749df935c0a1d8c41d3384992e84ce3781f6671c0d69373552258a12408d2a4b580380908fc2f2b65416c677e6c1ed4101773d4fb47fd96d31bb685509ccdeb9f389b5cc90895d1a7313379d722df9fe6a5a39a275afa536e687efbcf72b6c288dc64a86c28f88d793edee753eaac911ddd49115a91471d4096954533e81c73b3d035c0895b662966a9f8395e98ee2ed25ddc6f2f60eefc72c4893209004b04f6954cbd035396287fca5c5abc27342ccdf0d698691a0a6cc1b705cac9536858636c7131c2f8752710884cd06ee7c4660da661c520aedeb0a3bbb8a0668350246aa1dd79b5d95386d89bddd07e54da3a33ce323cfcf330b1356a471fbe7850940f6e3b242952b2da24a52b872b1237cd89203e76a7d1a937d7c943d7c95d5eff4ae085e0242f2452cbab499f97fc81fa315921c9394c97da81ed7ecc57b7896842b0f2b2f7987f44cba4da2256d602ff3d93cc2172237236a4fd9ab3faa6ee4ff9190d4ef7673c9152aa73c727c68ef8e6443c3fd3b076080945ce15b5daf793f714d5e38bc261ce6557f913a83b68b91c64c8b162c687b730cecde75280ea6819bc627be7fa9839e5553c5b653ad30f1c8e3b9990da6537e1a43077500de1aae84238ca25e309cdcaed800e9d3ac8020b3b004c84e26cb0f01129af8fa127f93114e1545d13c9d692832a536f3615e1b5b2b9b85db5921f513b83ccdd750c6a28ff6048ea8f947fc440bc6f8239af1e13d09c45e4e933927b8a15b73468d660f106836b9ec490c0a7cf375838482c0f41d2a0c61f5dac50d651b9e64c6c2a79a0428c13defec4f0dc42105c54062eb73900e923d2ec4e024ac861d1dfb01e738bdb96b0d99555681a89bbe14cdc695310d423d1c4fed28ef4ce2882bd3b9e1b00c6fd65e0c4e90ee1369e9e81b98db5747beff443ecafd909ed6964f74640706f852993c4f826324a1cb8eb5670f98fa7f4b7db1c20cc8d16bfcb5b228cb7c01e3899087490c5f6acef854bf22b5020409a4ba8c7186b27d7314cc3004bf708f158107e05da44a49add181da64d670a33d16b89d38be181cf4c7f0c1cfde64cfb71bd4d208e485ff6d7f2f77012910e67dbfb52051d2e98a756592f601155937f1146f86934a8697fefbd18d5c930f06cfe29639408436fe6ebe07d445e9bd7cd5e0b83a88709a390481c175b34aad16d542fd1d8af1cb17129bcf466af27f3d36d144f89b38c72f91c3fbe042cf2b1575df605caf3da8986b675686a5a293bb76043c373f38750bc97db196c9ea4c3bbe16e02df899f65b918a57c8a06450f28a4065c760706cc9f0ff5cc164541c57962a1cdbda80a89d962a29d072479a78683446d3a2d29d005c2b82b08c1f626a2b9040fb61eb61c19a0130c92df9da157c2ea4f204fe1f526fba4cf334ca05e5fe3bc39a2b734bcb092626ae579b4feba7cded113ef9330fe38a6984b0958e8ec50d319fc31379a7790a1cfb63f1370f2845a2e6f88dfd088443834a188412f499d6bf7787b28a3d772568c5d5eaaddcf5c8653c3acbb2e7627d384a579becaba7caa7ae30f2d49314c16debde64658669908901bf9ddb59e48f55ba134009ac4e36ada7d3f94662e66287e91177b63b92b0a2561a1e7d0a164b1391d5cdecf6aa27de0758bd334f6b412375054b441dd49fbd4c613931db6f0fb78e77d3339fac4585d5d03731ce9ecd183a45d63a9435a3a64c70e332da3dbd3b008bd43c8bab55cb401bf6c03fb2d80cf946bdde9eac4458f6835a92efb5b55f04964ae43e941609ddf69799f05ee8e8936d6c25906b1d5cada8fdba7b6bd534011cdb68470a0fffc360cb48016ef06b35498ee7c2ea272f4d4eb5fd60309d5a57308332bcc6a78555f155431c76f249d61962e6cbaf07195462b0ed114a9970127f084f62df664e6c461dc2d4155c6962896031d4ab4d8f9bc9fdf070adf5d43628eb07373011d72bdeb79618c03ffe84a318bd55fae4fbb53f01e39fa285b40ec6798b69be30494e25181ec0a5d7931bb32c67d83bbd8a388d600dd584481415928f7c3edafe71773552e52624505b951e12d01e8f36d803f18545e6da755e733fd8b193a65d9095a575ab8802ec1524efa075244b8236e0a1ed7af02b9aa326f72f9104d5ba10ba7157af2368ddd951787b8adae049fc0d9421ac9228ed6d1f8e0662fea870d06b2d02520357a9e43071cf92ebc91d8c9c87924b57c0a796a6df0e053484f573b6a3bf23e945cb4e5f81c4707f805790eb2e9963aa194e5b98f696f748f9bfc849b8c03d94702b377b184776e1eb4f9e360e7abc863f4ce14eca4684ce4a346373bc861386e4fab0e7db674f024879ab40a5f5d37ad8f57da0eae14af40043498ebe8e75ad1777c43b10ce7bb24be0aad73dbe07d3962fe7b238fbda4beda2efde2e649ac492eaf1e7ccbcb23ee866f8a388e09cba2fa0ba55dbe657a6cacd6b1f044bc62b0ffe064a5b0d761b624439c2e07a92857b5cf25fd71f356ebf2957344d53c2ee03d2179b5a7627c14a5931b618ae5bafa5c7e4521d82be71e3d607d2d04414f3e42ee44102dc76ea63b9cc719a39e97e34b7d2196b823892a67fa298a5cd29b7440776ff023f0cfe1269634678d1625a9ca69261b82a46773f1417dc70c09444325e5c7d7d40ad5ab246c61f485a0651c8ba5d04015786b02e5ce7ec8998ef9c90b512b08006d60b8ebd1bb260def2441b24bff764545834f6c2a9f39a8e064710f1dda9865e65e58e54f40b12b2ae66ef0fd2029b9273d1f7e1075916ab651fe0bd631be4383f796a0ba34936f783ed85aebf8ca46fc14c30a4e5729e77eff1960b09aca35fcd4ca7b922391fc544c5eb35c1ea6f07fe963675b2e2f4498e27e3cfba99bf30128ed6dd0783c3978eb8f3a3902291e62907c89e77b39cc6c733e9132e9e1f62cc671d243e2604f9ce9f0fcf671a15240dd7130ae49b0ada6cfa07b2c76c41d149d070cea97f93598994cc33ee38315fd996689cd7d2602b26c452c993ae7627412526583e76a38ee09bdf312d99c5dbc4645f8c66c1e6c7cc92f7d4a5b827b1e3ca8a71d28649299caa139ba203a40847ec9ea14f45c5ec20fdf2260c92dc1a3bab754b14298900e3580d24e558aa82f4491bf9f3728447efb4db5b2b374d2680433dffbe56c832603a295b6e6cd2124a9097735ef9959f985c01db91bc419209489ca865c858c4017d188f70c1d73436904248d1f872392cf2aacb49323c737b3611f10c4fc9d22d173408fa34c170f06fc38b0550171b989105a8f5417e70d28489b3c51faa1f9657394de4d2fdc837002c2b51374cd0988830fa4f8ba429af1fe2c30304ff52f055aa3a81c5e4621c789e51b918f6f8fc1fb8c6d9a2622089770f79a5b9064a9a7611c70871fd0f0939bf3b38491bfc619354a195e332427925b9d47a1ab0bab163ae2409eb64b1c6c7eb910835b10c7b9b6675dcef165835dcfa847072e18ca384a791de5af3ae52f01aa5d03b599044e0a0d11544b835dfee3ae6780f5e96de02bd95dc35cc1c1db72f7fb2048cb504a388d0134fcea708c55a322f2b522f618fba1f740ab0ee911f64afd13d371acee3a2342051b014c2ee5ba2ede51eb85f2629dd0bb4336222156c16546064d8c310ccdb3b0e047545fc96b9d0551060fb4eacafed4d19e3fd55cfbdb2b05cb80c4e58a037e8d0c3310840079cfb275bfaa7ebd14ad092fa19c32709ae88e71d2701c7dc882f9e53c6fa08cb8b8e83e65510a6c1a4aac828f603320ba5f129729ad78c169af706c523106ec22f1430fbb3b0320bb1734015fa67a73527ffda2cf413e37c15763a68794480b26e55d9cca4c315b43ed2a17692549aaf8404c56c60286666c2c3f160a57dbe531713a038586ea1ba542e02948e209f1390280afc3892f8ee6470b0fefe855bac664cbc05cfe3a23ed7af3e8f46b1c4c91629b31872a0276fc4e19cb0744d072d97e687dd9bc468025ae97a922c06ac77981d69803e20812b59393549925b92cc98355b333cc81093196f8f58b4ab3db6c055a45da936cd9a154343c79239a2946ae340f0dc4ed808ffebce9b9ac3d1a12241363230b75fa4cf290e21c812d3e62ccfc084620277e3257cd70d60b5208d9797157291b7261af87abf92bfd8d7bf0b98c0d235720bc894ae4e09f0b23d2dd13c161a1e95071ae0986b161045264e55ff45de9504955e4fced1e475722bf7d6349c91545f94eb0b26b09f14a6aa98284cd53ba3619b00b9c9040517671d1361837a95660019bd089d609ba7f5d6e83e8a5945a79a3d77cb92123ba478cf7853ba93d1b034cbbfb4312cc39b3074372d4298db5af59a9dec10f3b462d56141c92e93b3e3eb53d11684ad86ae6208dea66f245313fd16c5bb8c5f06ade521cf89787c019b16be5bffbf713e3f81f717bb6ff87dcfeefacf12f560f85e66d938ccdb02248887ebf30d8ef97475a979997ab3a2eebf200324f873a15c9106d887353b59cbb21e6284a6780e0488d2060e0e76dc6b389b476d3ccf9f37b875c741e7f1a37de6912657df9c02856ded37a19d21a9a35121717e42360362b7e98676cf80873ec09c02aeb5475522834f0b5dacd8d9d7b22e707654618e2bccd9057d2d494554241b0f8342d7284c7b84b3f9a41d6d45d723165c1718463e08dc23d8a157e49f18be9f329ed7217fec57465e7a11ff55f0c09bbffc37df8af4c57fdfd23a6ab649301c5e1b3ffcd45284269a8253380c10f5e96603c9ea5d433f9e2b45f86f752508b886b7715df88bedd87411b3ec652eb746ae27a489ad45e0ea37bd622e4b2262fbbb928e6dc65fe6ccfdb35d98985994d032b35cc41403ae74893add432f43a350a2d9126ea1b8b93e085d66990442f182051f4431380069bf427449a6ecb43ddffb9736c4a0befbff27c8796cccccecb8d477dd20f83d003f23d979dabe3fc89566cc507dc119b1a3e4283af08a99182d4d76a3a6c9931823359b4c84a8674425f213d233442af6861a22bba7147d80bc1733bb4f7c9655b13079f7f31ce7656aa6916bb16bbf66e98dae687c8cf3d7f2b17c48c66d3409baa7687a91aeb16f4ad49e0790c27ef8725fc3d93fbb2a9ec12e6000cc3f29b5a430a598e2fa9c56c5d93c4ce76b1a5f900fa8aa59cf96cc29c9a2efaa73bb95d4e6e1241012fb819a50a6e001ac6a8d4cd68f84e7b2cc59a37a74992865c1bf0f41975539d7bc9b7d5fe52f4eb41cd79b6ae8e9c0ef70c0775a37ce61ecb41ab57bd1e6037a1f45801fa1732b3ca8468dff2d33926893261cd820c9f2adedb49a6cecf3bc7f2eeb96a97f2b6eac6827c6285fb9100b91105021f044dba2719710d74de08cf1c7e45421d9bbac5eef17cfb0cac9ced0b83160adc5285b8a99a7211ef9c133073c4d1fe39a86739359f32bcbf424ea8297e5175c80de7ee02e7d0da1699b915c888d74a008140c58901dbe93c7b912ff4e4dd18bfc85a2ce718dcfd4824b44297c71362f66ad04aaa539337d0d1c106d0eaf2013ec40d712d3f2b00066b2a7321365f73c59f7937ea29f0ea65c153bda63671d9b3e109687563aa22bccdc7395006505767cd3ccd6dbb388c0a4e661933dfa7224594e16b18ff204b77ef8c85856a90645d6b4f1e81cb5b3fdb53430535fcc4aa06386dac64bcbb3f2dd1020aafe16c34cb1db5243ec754b96e06325d82996d5b7a0c080e3745e6b91a1ec5730f19908ab5828c401f12984798b2a5a35d622331f2ac0998f2abf2f420a1608e8a8b5701689f00997314dd8cc7e35bebe3d522b2af7c6cd2788ab67d64efd93b3779efc9fb9446278bc818b34d47dde64281e9f715cd798f1233319fb3523253935479919bd55558afd958082c228434f57bab2a892ddca393bc28b7ba7c6736280802a5ca8bc3490c88c8a35c4fec5592d2eef951909f1ed282beaac46d720651fcbd2a99b59d450f3c8ef26dea8ec72c16e4bab3cc6ec669baeb6126f4e44ccf4ba00e5a83a599d413e5121221f5e5d9be99482b85b650a2fc54b08339f30b285a76762afbf9a56c963236716b4b1c2648fa68cda434d097b714703b635f904537b266a2fbd3961435aa576e760630ed7be9fa831b96f12af6d7e6606757b29263e085f01fd583432f4dfd8a1a0eb37661500add4337fc9882a29975cf8acd17c637a3d87789f722123a6525d4f30149776862c919c734c4940d06ea391fc3131fbd72883bfd6e1009b50fdbafdd4cd1b58c025867bc29c4ca61bd701cd9ed4f1ceb03fc21240f61d890d9304347230eddd44612dbcbbb46b0eeab03c1d4534241493cbc40040415f8632202fecc341e38e0d4546d588fe155993d33d686d4673c8a9a0bfc27cf5fd22a233360cec41dcd4d27bec18c2af20b686a8898adfe5ae677b1b840bb23dcb5dcb7207743c3fd85310abe42f6208282831ae2f3be3c8602c722c4cccc2e28f29bc5cbcb643af9e9ddb7469fd48c7c762406f552cee67ac6c0280ff110c6be2d40ff9814f11e28e40548a77bf88249a5b16f938b1cdb84a4a93a78d3e53dc28e29416bef8a71c860f253d7be988bd37420556964cc815ee799ee0d131c136ca76a067b67be0008a1a2f8429b282fd9544a2ac49fb93daf00d72be30bd3839fdcc7ead861e3e269340b475bd7a844f264feb1cadfdedef8758486991cfb4ad46fce69b1e7af2fdbf5bfaa712b6e21b8a1a77414c8769da27e644eadf5805fbfccdd7a174ada3290bb51e68da6cde67aaff637e498f417c0154c3e0037a72f86dc60df4f70936811949b82873473da069e1e28d5d95fb69a2fcf8d5279884145dc238f6985aba011146bf86a90516bdc833796fbf3d3ce0b7d53919674e955e16d3c82befcce1c1ba4393ab6403546ca85a915047b5bc8dcd0f246ea03889067cd452b31283e61251278bcbf413a78e6586c4720d44cf9e1cc7117c7005b85efcfd5c8adfe6236779140625b946ac8dfb7b75ec3682061e8435155dbb4d20d358283ee645faae58a1e14a9dc00ddce950ed85c64f88031cd5231b994f420011ce55994b1ec6742cb2511e6211f246810638fe9f8bd81b9f8fd2585ee774fbae8e12bf4cb599c42a58a05549ad4b4be4748585fe29012d6faf255f12c18bcd340c4c872433299dd2982d0bdc155dae3e25796cea4e0f7ed9605adfb6dd91a2ffb6b8ff9938403fcbbc51188a57946d41f23786a862e3f9cb62437f5a799fb847e6bd4e2a6dd44d65739f0dca8f47dfc2826015add3590a175a3ed1bd1420569eb0af76e765bee2bb4ce27d7d29874962055f9452097ce4c7c9db802bb09d1f77555fc51582d07d7590bae37cb433fec903687fd49466c832a7eee52e6700a883c69c573933b9eee6badc397aed94b85d2e601b7ad8702f2da6f1ff1e85c8c3462247ae437af4e8cba898ab83854c47cea6a4356b549a792810a3ace453035ccb703f59504da5c9e216d7c96306bb51487e4978621183f73f607bc07ffae44ee7e4bdda8f17625415a8e6948aecaf4be060514ca4ce3410b9aecb78edff7d1bcc2c8cc82f8c2ae427c2a3a719efef8f3a6dc4cba60c07dc8f806a2d30c68f78e155a9cede7b99e4d73061e261882f4212f3a21fd52207b597a64d791e4255124bdbd53f28d3348d3343f2e0fc5c977174e74fe861e48a0562c70a581cce5698eb615634023c2bea6bdf842df263e88df23ab59b57945bf5ad1da757576f019247be8b92d3e3978aba619e17ad1cae46a5f8949fdd1f7a29f0aa2d272c0d3205c67eba3e7f17537855c14b9aa2d1af22a92ac8ab2de8eb55e3084b86115f33acc52a106b739325c60322bc59a356f07f132425b32aba3328d683a70fc24f71c2c4cbf5df6b4415068439dfc2fbbb7a4cc6a48c13f76f7650a619b0b668b5304cfce70447544cda51459853c0260cdea41d0a57558bd5fdb385fe8fde8beb9b835bfc89e3610d73d13856326854e849d7faf9ccec73be470e50d21b5d0cacd0595973da79c6e99777907f44d731cb26f6c2ff87611915cea23ebe13fbac4a885a16d63ff9aadf896c7040e097e00c9d386e8c290808bede22b1cb7204984116163aa86896516eefc28b4a7de8ad8ab5d12cc117340230061df03af5e8e26be970b1cc31bb3844d409601f78bd87c784e35d2962e464fb298f7eb0d4d1114e486e1738deba0b341c6dfdc6516b5bf6fd1c18f2bfb85dfbcaa500b726d1fcb251f3f8ac850a530e6e33910fd189f3e771acd81ab0e37558eee12df254120a59dd0617e08613871cfc558cfce3145f8b9f38b72ffb7305513d59fea53d454fbf748ad866a0dc213116ea18257f1666f3252518e4cb7da4391f9117b7c2f0889a75f3b6d17067fdc754a03594b97751fb8087a69f75bbc97a85bf9570171fced015e6b87ab97ea19083f0506aaee77e1d52be5a53520f3afdf239f1357d903e6f3ac79edc4d7f2076e22adc445ed44ddaa2fba8c05751c7b21178a70e01f69fa1ee10e5406979a71644ee41014378e889fb67b29478924284367a76408d904139454c97c5d3f0a2ac1838c232143b5fcebd2a1d04a1fc6c59d0f67d24b4200c2eb7d4e650cceba9315f3f2360863719c6d95133490f1dcb60ed8f303d57d2e9a0a0abf74544d06179218b1d63be72bdf68ab63aa1ef80224a08f356cb735693985dea820203b825dcff39693c3c3bc536eee90cfe1c28fca1f747784d83cddad28a79521c6e112f682f7bdb2aa8781a9237d463e3a887fa240cd11c3176645018349249033a727315e94effb1af74c04d6ecb85569ae807ddd88892b8663a8efccf35652781d50e54db7cbd92c15e18fb92a08c273b1a2bf818639d5840b92875bda02ac021891e638f5fe4efc04074f37c64f17563069d56078959466596efd046db80511d83170c525b6391ef3cb1a6d90a99a8bf30749f5be52c99349c10ecd28d1289eef04fbc520853c2bb31bd8e0bc2390b7dd20f777455bd90656d97aa2b50c0c57c996ddc9315d37112518797393b887e6a4996d35f5e4c9009d1139101c4d37c14afe2ceb4eab05c6919ee75fe253f108553522878fdebb45b4ad80ec889a8bcd22c56f14af6a0ef047930775565573540a9554490561bf2aa7030d74419eac8482e92a4abc80f3b47655023838c5086b64415eaa8452e1889677ab31b91ce02dfb0d1a6f1c0469f6b83cfa7d4123d836d78631b07330fe01b5d64ba34f8bd3afbf3e4a39141784832744ce1b6f2e637dd79d56c92316251a109508e6dcea811e0d9240473ed292208dc9b388b16a75981d60c01e8f758779c98feb0e46644b3b0542dacd7333b76a8481622b497863e09dc68806192cced7840dad2a4d471229015e09752fe7b3eda4c47f06b1c6b22f3d4c095ef16de9250c2d4904dabab60e26f15c82335b8f01ff027505095c01d80538cad266268d3868f2b9984a4bb0d47b36108195d0c793713b75f6ab42dc5fd2e552735536d931f778168365c7d737554f7a5819fc032f0d57725a0f7051510fbc48948cc1769327256f3af5467422fd45b89df432281c0cccb0bb5ab21bc55285f913dbe47787df9d303deb15e05013caf0c303116c88e928028cd9414dbe2af025e5bec577524f00508f3632b8e6b1ce06b91fe52a18c538f0387663a8013049a9cb5a43d08aaf70ab33667ceab16829e70a5cca1947d23dcd949d2867015989ea82a6a589fe4c4e9ab8ee50807241c02faf969f36459dc154d75baf67a01568a286d99bee761f04afe85a59dd8b78a4acc99b95ad1b649a507c554705af525ecafcc3837d4eae4baa75a198023fc8f8701bd504a69f003831f590b45c4b15d46c44c96bc06d7868bb4b29758597332538ed5c5417ad14f6edbe4be8086c754daa61c95b37a86af6520b5852fd053919b90c4e7fdd2cc43a9596ae6a18145876881f714627319527771f57820c04863771826461e5479be8acbceb6696bddd49ea5f52fb062cb055e59541cdf73e15a42a8e676b8621fd30d46be35cf3f90c277ffd752b4af6946e58e6784868ac7e92801664d7f8cab4d1fc8ac1cc3a1d0701c01681a975bc9fcc9500f995d8c0b464052c751ed66fa059ca7b75fdad753bf752558ff76f4a8699c83887c9aed57b20c1a59c7cd77c42c5a55bd4bc8de1ce9757dd4f2464003713e096761fa174d8a9261993abac9cf48ff8200e189e445d6b279c3c4fd8dbf9045c876a6025e01c2160bb41159f04e569417587728b845bebdd472983ea3866d0a57b858931445e30c8a78d868a76bc8473e619a31e1c7a159ab41603541060eea9e4674365f545a4b18e6bbd6cb5c086c0d096a2ad5a67a52497020546c949e4922230676e2a760076b1fc11218e54811ae4dc1fd1572b647142e3fc321f5d1975b96b34fbcc74c11b99441919f0e2f3ce76813daa5148894001226ddb55985a6c6acb588b05fca44c6235a07edbf789a3b460d04eec6e1990c36b1fef6081708db3c6480f236e51ccbfb8ac1936e15de5dcfdfbb50cf58fb8acf28f9e49a3f50c29a6bf3159c147600b827fb115e5590a57ea6d0af6d2c9f623422bed460f4bd931ebc62313df9f528ada995e917fa83045c6059556984ed97ce780d4afc2660c35c9a629a5dd1fc88ca2bfe9b0be494bc1ea0231b6fc39d358cf3a6777443050b701717115e1beec857de97275c2865234963db3a81c674a95de1eb55c9647b1938248b2333764194ceec596c7084770d7c98bd5594fdfd3aa5b9671beb1ea68bd173de96809bf92aa9d7c083d25255ea162d289820d7d02e59213a0f0348ffaba7ed8746fb7772b71e9be030e34f612ba6d6424c936834686fe1481feacca8a77d3c43d7a1930a03e6bf2db23a57bc7c4522c245cfd72dde2197dd62132aeda0581d0c77ab5921260c1fc643c97b8a504ce1d64a83e462e8c6f851eda6da1f424b07e6e5ca327ac8bda72952442014f895f05235cdbec98fd6c71dc538a9ccf06f701f394571c31095267d922c5137b3e01778d8bffa9a05732f5acda8bb63e389626e7ab246629bb881ca36e1b6c53b7ac373f394816090cac0902eb5cad2a36fdaa146d344366d3af065788f5623b6430c2fa77ad0a5913430e5d0de3de3c420c732f7da610366d5b348551b670124c6543d9a0750dd316c6332627a68e6c8ebfc76f70553dbe07e95ece209f3c9d74163c695b83b9245b36b929c2a8be66c2ea9fdab5f9d242ac568e0634c7173269158bc2471f32cda79d7628b43f12f85726647b52018bfad9bf5ff60ffd73ed9ff9e7c6ff79f19a1187c3f97737b6628e48ac0010d1841ecfb4de9cfb4f6c23631783ec1d3bd7e04729632f9e4abf039122171ebe7e2760ff1c0c73c16e935d835f1886975eaf83cf250b4baa731a18218b44975f65a50cb1cc6f8ec01337618db93ee00d891200009a42419a442f0a302c0bacefda84dbeede358699f5fc7b67e5f0e48649f5f5cd612bead480d195cf7e90b708ed1d68dc999cb5c1d6b46edd27386474382f392b2fcdf411b4580c3280e7e6dcac7eae50ccba71d3f956832857bcbb9a6f9ac91d9f60a12192f8124d4dbb96f299eaa21b91a32897df96213b5293c4a8b8cdae7f059bcfc3c3a1e5d4afde8fca5717454dc5a4beb16611864b968b1b543104db95abd7adc43def9268fa5cb823e8b02aba3594c46949a875c9e1171d786264602802d72995d796a216634ec0aed1609c93e70161b7ca38c5eb74d69695e456846c78e7625117083bd5c201103fc89024a7eb726ed0f16fd594b56822644cd52b41c719100e9f3320db4bb41ce4e76bf5cbe3ade38d687a917987a40b248b71e843ab8ad56df744340ad3e86c2d30dd02df7f4316194d2e681aa04383d6be57dc4e5baaaf7872a5194308cbc46899ffdd4f7853f7c181cf9cafe233aa28edf9fcf7abd5b3ff94db0af541631068104b5c3a763fd373b34e373a4c8fed25fa8fd033a1e0fd9b37a88603e030ff4d08a5b0fcca612bc4dd97486ac07e466790fd2c0018ae17fd01ecf0d811944969c7ce6c93b6edd5ad9db9a4c5bb001ea74bb0a83f5ea9e5adda3e7611eaef16d284cf0be1ea3804d1de8623186ce7205f7705239b06b98709c161575a99cb3f1fc40aded1424118dbfb3a7e5d80afc71d716474fa06ab688732250eec7a7972227b3af3de6d77e1442a6268d5039e2bd98f72f1497006b7239b2a146833320be28af95f59e0a3186781e0653dba8a8c7c4e85329c619db4e9323c874e1b3343470bf1895546ee7b4a8256adaa388c392b436706b1d27a2cd185ce1485f2088e487b02575f48c20e761e3fe41487c8768d5b0a2f76d0d9d11721efe03cc12c0b5ea404f6b77ad3d2bb391e33dbd37383a92c97daace22fc3cb54d6754592f2c6addf8027babadc5d19ee3d95dd230c5ba1cb2ca85b152257709a9a4d1bc7810a4d0895dbadf527e4d18c88ef3e94e7ad631c3045f5fe2a3c6fded2545c0b4441a5b40974f6cf7f309a53a0c4fee83759cf3b8413818ed1733d57f7901f58d20e09c5ac13832d064d8d54b6c3dbe399ee1d65c3371fb2a7406be419c594a0d89b018907ca8a351ee725c9f278b1c2742ea6803af677e9c179e11052dc3cf99bdef33efc8f5195e2d4bad7c2c3274c3364351c4155361febb2e0016f5938a8b30f91cf93c2c4b0c636c28deb96db1ec772d128e5812a89e9b88fc978cd11ccd0b495cf11d95bba539337b8e468193317ebe5704461c570818562e0b9b70562c18400331223de6f8b65f94a93231a4922991967739c7e09e2a5874f86eea6baa663a4769c168f3cc8cc13468a78aef73c81f38eada55afbf9fd39407f891539032691ae81de7610d4d1eb5d7d1876e2df5c11c72f15621a6174de850e767d446b05d7f952acd84c507f92b8b271e2086d317b548ce82e8632ac688c1209a526afdbab23141b104847b439a68507a18822bf5958e34a723610837e1b4ca3b18985e73d596e6213808ba77dfa3bfc61570da03b177b5ae11ea87941a29c841e6804736279b84176529ea3587501b40a0502e888fafd80877165d3c4fcd4daab66077be8633f2ae29b2f5a6ce6b749974fca8cb04d42a7562763c6ef6b0e64a3c5f44511881c5afbd51f1e97a3d29800660463d60951a32e77fbfcd09ec9b64808b01133c1186361c3efac167efdd2c15971485c85c544c1d4c03aa66b718ffcfce1a9ae6e5f4ea59d28a6173a7a1fc22c96d6755a86d60da28f9830cb7cdd7432ab442423d8bb956cdab09140c53597ae5d25017cfbe54594e37a16211c1699b96a656f87291b2e5cf890ca6b221e3fc3d1a1e92695a91202f3d41292dd1c8caa4b00a70428dcb88749a1c7d8970bb326b23665f7dc7ff5830f668645ae21120539b5f6363423fcd58e96e61de080adc27ef4987d39bac46a858da58902b60e8d40fffd6a2f3b219dafc62bb1300dd457212215749461f14ec1474472b92f906f102a7b00d654283dddf153f07ee81cb02048d22c92bd08d9fa245c2b8d3b024f3d06209e52282138731a5e2a770b9b5c455afd03cc8bdf1aebbd88fbb6728e2792e73d87a43552107bfb081cf8fd8451c6222a07ea41cc1d3d6a84ab6894a1d102898efd35cc2ad6933fce7be8698ac7d38c43bf6ddd18c24a6c5b73fa199cb4545ea695f62adc08b002395a169e5f632353f48900fa95d6977de5858f9b69065c236ec4bf271e8576ad5d6d9ebb2ab807b4c58e9a2cbbc4b36786ec3e844fbbc6cf9d96481b0ddfb536770e6d179fd2471a19dc2c424908f32c3c6e109f886523412f39ad157a788acc3c7aab106501b44177b606f8f138490ef134fbb0e5d04a734c7db3853af87bae23bca0bc78f6db605e02afcfa0d4efb344157b08bc5543bf017153d6c33cf67733e87d3877654a092ea10e48c9a37b617bda107fa4a5e00e44c845bc62befa4c84184ac35e38acb79b5ba87293bc16905f96e829872352af4e68a35536d35eb5baac0bb9527cac3349cc64b78f0fec56ab1f42a9aeb510c9cf1823648e066b99829480bc096aaa30de726bf2c7776bd60b0fe8189b9faa95bc34468dec9bf4a5858041fa43f1385a81e82fdc74de8ccb32d63dba0c8bdc822294575f34397ec54e715da7b5f11eecfe05b4a9aaee8507f5f8534ea9d6d0d2082fa5f1da96c6305d560a36bbfa6e2e151919dcb93fd5f984325506ccb30adf57e8d657e06e4b1e6c4af1912e1cc32843dbb9480ce71e30e51944461e6c42c5dd6409877a59b0e4f0352954ec62ac1258498b9f8aa9b229bab64b9bb4150f793a7000fb02c0cb052017dd6f55cbb83146e274d5e38be0782d008e43699763c98b0d0663706d5b69a93f8c090f612cdf50ff110ec11cd4069461fd95f1929e5dabe31933e7a4c8692b09185634e552732521320e8577678bea50bcde8df6bd4f4583fa0ac82c3cf42cfbd77255d13d7ab25849080711bea05c4731ce295d59e90f39de96858e6559c32918d83a8589ed81778a06c6b7b4853d019ed9a6ce90ac018cef54757bdcc5d7820768dcf697dd7030856087b63bd471caef47012112d87951557c7a192992fcd4a264d063f5637e03aaec37a938571bd4fab2576c7f8e82477dd14665cd5d4be76421c155ad577cf06b88152d02081d8d1a1953be47f57396a06c14786896c0dea95c5649cee9482b1803026049b4cf9b8022409b18f90814207ee6c0043d177bf3d7a4ecaa44752a5afbbd65aa35174330fae8fd990a2704a5b33714f303dc1a2a4dd09864a9f52731ab45609a559f563974cec7dc25b88eb606c487c13bc8ca093a76bb84fcaaee60826d7e766c1dbc3d6ebfe00d84ccde5842100eb3f2be0da02c9bb0cffa88354d2eb46082f0a1e5f7c9deb2047501f6032b4a2293928e20b023140d2fde95b86a035525ed300b314ad0dc8addf55751f30c5d8b2572b48595ce0a92591db5cf28539469f460a799f1868d6051a5de432bc0d627331cfb566fab73bc811694f85ebfa0669e27be072f0267229b1adeed1e265f90644129ae648f7ad29dc7115eda305db8a86be0b20a0b4cd0ae4127c2c1ccef2305af4ca635456592add0428784b9a1a231172107b42b8f9b3b93d5ff63edabb5b0d7b2231f4881984231332b137e62e6a79f756fbbedb6c7c1dfb32651a254a7ead456d52e066cdac88aa6c8d21b9bef11d54c5f238c8e2351d067d97369d382f2eb337741864bddf06bd3761a7991fa3b1d729a690ad4d2cd0a5caa367dfa076378049cf30f25af7d412c9765effbfd7dceaeb64abc4705650998d999d3b8f40bf2fc75c8d2c50739ea2e0d359c05ff514a55ef7b09c99583a6ad28db3c75369b1120c434976a89b3b55978aef970a23eb45a5e8ef320df69f1cb3809daaffc2aa33d7351c025e44448f9937ee7748f2d6c4659fd3a5efb05bedfccfde6146c4806f06b775c6ee1bdcaaf6cb908d59c3550ba26980925cef51ed03cf056ffceaf0a31fb5d21a4330caf4b7f965f05fe28bf0ab34d29356c819a431ea97b1a2bbd2fd15d123dc2bf944d2d3982fd73ae6506036c0bb0e0d8b9719c301b477a0e331fcd72521f97566c6abcd0080aacce6f96d957f32b8ea3428e632ff1938cc0271f8f36012cc6c684c2c5072c4b6649bececf18d3fe4b01529d1692069df2c7e37b251bdae6db656bb85a79cdaf8cf5de4839d4e1b6d68251404bb0607fba2f2210233a0e83ac0ac5aa93eedadd67b8b8a4d648cccfefbda2d59db846663bd58a5f254215b0a65263452399cd7bbd161e10e599356819c6a6f41001b46a7a3905f41f42c3f1ea6d957090b69fce74c2267034fb6f5266a107b07eed3ded9a281ed350e1c6aa1a1de47aa9cd80adffc613303bc6c39b251b3c2016a85cb8e830670c25f7c7437123b607f4b43685fbdcf19c844f83a770d2985a10d7617dfda15bb3e4983f2228c74831a93de4fed30583502e9ea17e17d5f85900f88c1f17379537168a77adb7c7ddee4bc063b635300bbdda0952d5eccead30a3b592351b9e46584fb4885a5cf36d42400af46b812333200bf4eb54dc0eec4b2c9d12251dec8390087878cd0a82c0a6c9f6cdb7703d150abea5547a49290dfc32e341f65e9bf053154c872240b05f203ec9043b988b6e31797176ad93a8115e01bf65378d7fc09c64050a0fdb87960b9ac1e1bff778153945abe72d308cecf07fe645beffc88bfcf7027041fc0a243c92f1f92f3f320e47404cf9f423d21974463a9b70dcd26509b759efa21c8d97412c63a93ac97a2f9ad2bf58c8f72589aa40aec2388dd9ad5cc607ebf35227fdfe2050a2f6d545c94d42467910e9900d4fdf543d5c9e186da823d112c5bfedc12924470000042fbb477eaa8d85376b723d9e942db188b96ffc16bc80d51432d0c9877fb38806849501383701f6dc82268e3a24b3203c5a46b0ea01096ce0453192c099c2b79857233066b2bbd296ef3c66dc50b5e7c0c5b4bca9373f45d808f5fa2cd699a72d1eff02927d3fbff0637f2ae5d7f51125fc05761e4bbfc4acb1c76c7ce736fd302cd9959939382a212c918a72724944dc822c44d404ee540e4aab147ba31d4b97d32a4253a8c8b4f131767d77b9573e79c81f414e3e4c691a62b5c5279ecae9d092b1e7606358007733cc33a3005aeff566357ed6a6d075d3603eea7c8346a461dbcd812ef8e7f34316f2e49bde18f1f93c93b4d7f2ede549e80c356024d2d3d38e3621abed44da2a4a060a94121d6a6441e97f72b111f2f81bb9d9c27846970164c5a57ccd279550fa10e46662b594bce3a634309e2b5c585c9e97fd380132fc450fd061f37cf6adbe7974e6819ba387052a274024d02259d29fec858f68a2ab72ebc9ee6cccc669496ec9cd6f39c1471058ef97afcf6de88be7c6d793199a7ce01e1a93a6926a3454ef8c4dc46d1db7e0afe1d0d61b1f181fb6de6e898551b1d890812dcc69d7b36a38425988b8da9c33a879a69cefb455462513d82842fedd08c8a0ce08d710593f91c569c378a48bc6349241c75b04c03756a646cec038d51b25cd0d6dcc31f780938b4fd434845820d3dfaf70d8c45573e25243b5f7613c892d189970aa03746be5eb3828f3342d165a5ca41e6ed7c0bf6441114d7c8208fb4fecc50504ebe57735c69908085604b1f921b234060e8ab4858d0f66bb844eadb04b80bef8323c4b187148b8d5ece82f44c9e67d22387bff93670dd4af6373e781d2d25e2242b2d1528832330ae704b308018522dfcab2380eb9924612605437f7a680ebf657e530bf9f11a2764aab951be661f068d1b5ff5b5da61019eb87dc567566e6d46e79a3b7b57f9ee66cd5a9ef4f6521062716a583ad55c0d723c2a902d475ee6955b55199ba417d07a53af2febeafd7f7029c5eee28cce19cbdd63fccdec5a0c5a21def34c1feb618fd02ffe60a9cf13f5995980689c03e58b30d275c578e9fec896a2109ae887b748e421bf6b0955686427f1fa8aa0e48085c74285cb7c6b367ea7a41f8794c11fa82c80af6afeac5552e9c5874ef6257363c373c08357e9c96dc49bacab3db7cb6f36ac2008a0357ef219b8b5242da402a6dec3192da428a7170ed990b7d74ec41ed1d16d48b968482f59a75006e822b484c48709610bcc7493a0025196bfd4cec87d72ae18c286c3f75fd3274016ffcef2ce008547169c69a416dc1d7086d2ab545dd219e7a8007097543ce1ca310f5897b1d6e91d6ac538ab5091bb05764d8ecb1211a501ebc5a65df3c70e49cfa3ab265100ad62dbbd6fac7837dcbd152a547079932935b8261c5558ab16aa08af5d42f0b8539adefe557d6b6124f695187b238d21aab9cf883205a7e52fbcb33155f29079b6a6dd93aee333c897b637df0b9e758965650fd280fd63fb4721633ea0372a68e19f3c4197a1acde37f48bdcf9015b0cace593012db7667988d3f9ba3dc5639e4606034fd624c84fcdf76db79ded5b70bda4e78cb4072cb464d5e58897417b752c0680e8d087ebe5dbf36e56c84f9ca0addc943383f4e7321d43b5be810c285224549b37b2c296312d25e153d0d8e7f483a55bb6d63550b99696519f91be3453fbe657e7054836f78ff6288145ba0d9b1bb23c20695bc524a3ef4314675aaa543f98c7573a905cb19644ac99edab1e54b9d57d071e7462db28befbe4b93b7a43230f70ff758c83aabd6eb04d62c32c3b7eaf29844e04b3b75d5f3888adf0dc6f7df83f0048ee33ce7f909e5dd6225ee4508c66c6b848c302509d4b78409d5105781506ee9a1adb4226936da7ee08cb304318029dadd92bef578baaa3eade79a8adf243dc0d520aa808803b7cccf3623320f3e5996e257d7931630ed43888a5d1a6c8bdf7396352b4b581ea523d78aa399b846f1b16bfc3edda1837ec2c315e5af42fd761f2b9495e45dfcfce20c0d6dae400eac3e525957a91503f3d363c63a0ec60babe29462cb647ec192f6ef7a195fe09c4738be887a71363b88a709a8135536225fde487964810eb6998192033bbeaf8162600aa2edb39e6e1d7d3360865ff077d2583f5f51cf93a6f96ad055cb77091d185d7eac05f27208e8260b5d589222f1aed6a6201dd02fc4cefe3c03f1a33d243cf5eb29c0adce4dffba0d1b2c5b2a7dca2e8afde87aa05ea1eb453f442b032a12f11972894fffa03eb57e097993cdf7fd4c10165fdbc88d071bdaa437436b5c5c0b647350c11e50fec80aa2586d097e5416acb6f644180d8c4de9a1fa8359c3c6bfdcac3d302d01c20fbc280b475afae33702684323cfdac5154d16040c20a84442022f8f7c2ffa2b99c9928c0d157ab5503335513f049de10dcb3e9ea460cf9ab818fce88b2a4190e91794ab7f13cd012efdb7fe69d07b9b3e4a6618bee27f7fa47f903fd33fff51d812fe6be197a92411dee7ffb2c7670ac3347acc5892099b6572eed4a4d909e2606e182570259895a6305903b3c5b236d077034b7f86dad95dcae9ce57111b1986176de83ad5bdf4bc41cae23ff6550176769d95aa3242b255b825d5d681a3574582036893f24652aca5a09729ddbe2545649bf38d644b3daf5526402bda479e1206fd5059bc8c8a5768f298a94acb8d98b776247521b3fe09e50ea53406dfefc678582ea5963ba1ac354bbe7141ec2f5cad6e9ed8f88949715adc1bca4ad36bfd919d60ddef333ea1151a52933719d8746dcbe3517c773dd70217e79dd6c766640d5a0689a1141281e6aae5c499be20e669b87cffa0e0e0533da96e463b3642b9130aad8b05def087531ce2120369bbf6185af4705eb6cd0c1652ee180c4d6d3a8a3ffb338115dcea8f8636339bede41b9f110ef80d34d02b1813dd6333c25c6f63a42739b74a7a48aa25f5f0080c9475bf6ed7bfe2cdf921ed605c510058d6306c2515d0ed2998f5bd8dc6510fc26ea7f1e949da0c8eed072e1df367d7be052ab57987f7d42ffb74255875d68a905690034f87d9d20b6fc0f011593c0922875faa2fd5978e4b745e81c23d775d0c689ea787edad871907343292861b977b594d93db21441136522144dd8930eb47ad779ea23184b92f1bd0616324b873466d631dd5779a51daf2eae314f547b0d54c0337d7132c9a8b5193b30cffae92ceecc2ca2fa1ab2eda6967d43a0e6484dd21e24b596748205ada8e608108d6707ba6af143f04c0ad3de6abf8cf59a938a4bbd095040dd3d2c7a2c2943747f3cf5581460e85a51e26d9746e7fd28fd7f0123a74a6816b5d51ba84d5ed5c81cdd3d8903d2399df64e4ddb1d2936dd768ae241b65c1e4ad9546ec4ef2ea3d82e7579649b2a405c5675db4bfa6d428b1c8ae68293ccdf893263ea18fef39c8f7b680bef38b517fe3214c8bf037908bc60a05593fcb9ca0ebc966a2293fc33943e883fae3107bcd8ca58f38e55c595bd6ba45cdba8ff1ab3558408a1477dd25e736c2e90507ab56c60110f7bdd1e7b7789e6d1581c9d5805211baaa64496555ec5ab4327e97d6f0dce311ddc61d9ca12ec33a01d72e9ccbb5133143e7bc33f5eacd2fb6be19ad64fa98134c289714db7d2d2887c414665d98f7e017c3295fdbe245fb473fa3432de93bf2b6dafcae1f7bb28c129ab86b2b3f91e5f1b50bfd7bf051432b73ba998345a7389df723df872e3da048439ca29520d05024cc4118a24d84068e0dfd6768299228e81cbd70ccbe9becdb11bc107b06a4957bdaa06ac1da6e960e0fed629acac861b59508e70002bedd3800717702c829c293f1c82c6f156f0fcb81bafab168e26543599553f9ce0de68c18fd7dc03547c3cac66777bb6f26131692a1bdc9423d66eb9a04b75305f17926175b03b03a543734e8ff52caa723a431ac2ebb1b6bcb44725d8789cdaa19c52f1e28194de9819c9d40b625ecd20a9ff2f1760ecc43fd64bd392e020c4491e6c701f2eb3e277d142231a918e8ca198306fd5522179b3b45ba00bfd33b7fa5772e96b39ef7bab17e169b304f0205016fa32f1418c558d0b533df6ad414e6aa8acfa9e98acb52593ccf74167d9efa58ebda53f8f235cb1185b26c3a587f1c2771724f3c10de49527977b48f144f5652254bb6b24e4c0f03f43a6c6a4abce61aab1cbaa594e4156342457bd314892efaab65c0a5b33de16ba1a995d5051a05c44d0cce01c54132a405791c6c0ab09dc5cac14045c7abf917d5ca788d0a70b55fbf2136344e002703d143034ff9371f56b7fad3ab9fc0307cccfd5ffd01ff2b1f7e7fc687ffe9d5e173041fb3a8848bff28d3fa4fdf4eead7c17384a2518122a478d01c09acb62a47a9ae48e1497aa041d13c9b9eb71ccea3aa0cb5cd065b26379ddd233d95b7e883aa4b43ee9e593c08f1a066141f8d968eae17b6ed34154ad4003d90df99d72088e31cc2889fdb4992ad45689962c3039484392f366d9a64f98d68869f197a02ba388d1f9491296ac7bb7127caef5d42f035b2073e8f2d2630efa25f294ab43047db8e82787885dd4d86b095f510245442027cc7153f460b9679d10ebe49c2898a7cfd1eb0135c6d92fcc422a22f490b0a240cd5be5d74542c3512b5de2a325caff0175d95e94812aebee0b2f0cc764db61dfbfbd997e029fe2ae8f3edf3dca7f02cdb07f0f9496e7ab36f3ef4c91b1f6d03b484c399fcb01f62ba5d8d2b5855741156518a03d0f10cf45203e4e47c8e4246fe72fe54d7e1c4da60930cfa178bd46c3123da5f3f07bd839b409a13798172f8e8d0108f5af8e0bc44c3cfb7a40ad8e08c7aaaf20d6f160785422da5c28df3437badaf87c40950aa2b7a6304c32a80edc654415195927edad27187c9bedca225dd69000ead81e490f9e4b46ed700b958148859e07795c07e640498278bcb2c4fc7bd200699b46be9841edc1d7eada87deb28af47492e734480b85294b1f7ea65e190277d230d0b610a40a898cfce705c67812fa0f73b4a6e0f7f33832445eca0b232ce00a20a108864e09ef43a6a5cb6ef05d4c14b8be9ef944128c77b6f9e244bf9c715f66a5829767c06218d609b9beba23401a9741e9e59c1a1673105df3c0de4b3f9d160834d9320f3dded2edfcabb87bc217d4d068261650305b751cc36bd870f938d7f6a27d95ce0abed22c04dd7a5ad2393ec05cfd477d352d0125e007af3d4bf02d5a58e81e346dfd3847eb63878f4609002eea639c0737d67ec53bc9b57892d701e39415d4e545f168027c400039d9cbba52f2b8e5780696ec01bd0e4c3fc088d51922cbb1d13dcf35a399c3d2c75d3408f207b1adc6b00a56e34f431fb5370e19fe17499a7f8950f38578ebe54ea7e446f89025d881d28b9034739e5d029dd893a7a1347cc645738bd5203218f281e418238632729dc25ad3869ce290cd02b02d82bc2d1f47cb46ac9cd8ccec2b4471bfc541fe014811a1435a06c27e314641399345df04d56205e10e791bfa8286239a766a7be65e351c23fcda9d9b6f7f928143c76216f4f1261cd197c5e191aafd77e65ca2566b04629c90abf9131c7e8b7be92e32e5eafce45ca0706b5a86bd49a4cfab39cb3f17a81c9f1f8b779bd620477cb80c10edb0ac48fccc25f97ba96e02dfe8da5e74f0093f4c7330c33ff21969eff26968a951476e53fcaf1feb9bb3ae6e2dd879f806650a56f11c137472e0a2541ddb7775e387758688c31a934d225b3e5b4b0cba2dbeefd78cd14e73984295b24c41b4e3c87daf4c8c4958049f707e53f350ec69c9c0ed0cf818a4692be2b1c06ab6d342b71b2a0cbef23d10f3473309e76fe9673cac41a911bb5d14c27871a16c2eb6923436a28967409ba541c0de6a2c0713a054308f2b34361142d5cbee81b5b7553b3dc675e73a273ff98b508bdc8e0955990a625175c6536802a9985b0a1c12aaf2e8c2eb9e79681637c90a0f42c7a9a5b7264d4476eabe23df0e01c16cc39d4192a797cacda9e5942f27355c370d748299bca785de9d6fc79e12ffec1e71671dbc89b544df66be92b90ccd657fdbc6c35e30a4eb7e2367711b203881fbe086754ab6fd5b0f52ed265c2d40e551486ef9604a48d8121b4a271b08329a61a9a2a774daca4a661b5fefa280cdee7516fe855ae845dddcd7c5d099933abd2cb3d0a1eddd29f62180e59582a01cc3e014afa7bf618b45a530c087471cd3c0559d737355a4452932bc9c489363338658d21c95b12ece0ee2034d292bb9f42a77d62278ded52cb6c25c9c901c819e219c9a3711825ced6d9c77b25cdd1faf278f5bebd83ce8ca0df120ca875cc902c88be8fc39e64849ba3f70fa4897b99b994f16b251df47f315973682c824a0429af07ff4cc96fa8dd9fc10d9e7f98c8c0cdb2c5fb2a2569725215b76518c51dc98b6a18c2851bc1896f0d75e2494afe591dd35b005c673798a01f2a21cdce4d45451e7c5b1dd57e359081a57834772ce5480beb680a6a34c327026f89b823096aa586f56e4739678f0c502ad6b3e6f51dc97a369c799bbfc1343229efb7b2b30bf5ced7e5f6d462310349bf1c0de3cf80e6f7048a82a493b3dfd7eeb3659d1e8b4a4aeea0fb8cd92bdd325da4c2ae11ae1b2b6d8a1b6e90a7461dd1240d18b568db87cad769e07e66519b2f59091f39b633fc385a6bfc0b2679dc283cabe0f7a50f24eba5c279f15573200015a04a066c4fb78477ae6e68f0968ccfe31f246a880543bbae2be9e351313e93e6a646d3306d7c2cd68a18f562e6324e140506624e02024077894c908e8dfe2d04a3a8c1121e6255aa3cf6e56b0d89b6b06b78b608447d6cf92448d92bd8329002fa36dab91bbe1f2bcf89e3d6383bfa486ef0c9e7f8f6611fe2dfe7615d2bf0a45256fbd39aadb1e8c85c4db5bcf0fb590c07ea6a69473412bff6f7d61e58b9a7c6fca6f407f080ce7f1a496c87e6c84a8c0c82483c153dd6dcbcc7a0c574df08707081341e5785395fbdf817e406197d43d2b32c5285a0a0de65340c2b3ea8f66fbcc8a5890d6efa814d50051c09b433a0e0eca1eacac276f3a1d2f214ca7715138ce878ed6b470539918cf616fba1600fe01551dc24d3d8ce4310f7542e4059b66ec94d639a264221c3e7a9dae1f7c5e6e6bc6467fd489b7e58ea7057d145e157637e3e45d4c0db6a6abce9c4820d51831af7687a28d98ac21c685d21f42275c2f7fb1c141832c2d15ae0cd9eacb9f1a0ac7f6a49980b24a9f56d17924dc215792c2f40984b048abcd8816c070f88d3f916a09dcea320c18511250b1a4eee8a21f3b8f133448b9242a84b724287e34f5c89e2d4c1d6b05da5e0818fe106037325fa95edd9f83b91c74241872028db09616fb08564770de08a45bd02d156583a9338d223d51713427228ba08455d9421f27e67a2af567ce70f774739393ed593817746a6cab87449d1ce9bc572e4fb3d9772851715258e8990685a6b7a5cc417251fd1ce7108b7e59832e4b24caad2fe26b81ee638c79ae00d8d017c60167c3d5267ef42799cfa8c50a1c5723d2c89dfb885315a08b845746a1e6435a42c298ee5766d509809c2a056fd3253335f11871e529b660c5cf7e236168b31d90ff2ccc9a220fda0436b98b481bdad6f6797753983c9513abff1abae6e6abf35334861c99339dee3fe35e46e55a0ab9f03ba212fd9d458395eb84c84290d08adde28050bb9f0dde1381772f6348598680d1f7a3dfcb808a77bf664ab00f00b3352783175643faf9578474bfccaec158e2df1acb3ead10aa5c490144024b029b982672c443d976ed5fc760ae09d113e497a9c5f5b03ec6eb77aca9f443ead4a322bdd5165d756d69cd14bec14308a75f549446fc2560b2bc9a33e5b1f7c5af4173cc6f270a85097c7bd5a44e7deaaa553ae624197d38c2701b6572d2104dd2a268e8889fd74eba11c9d348b20db47e00ef346755172a0cea081e94be5aa95f27460151a3c617355b92fb139bebab517646e58be3d8c555498fe30b9f180d08d82900ca97c06458e79a57ee2cea9f1370363285d6c503fb989bd3b8cdb78fe9537c51196bbead48977f874a6946005baa217b1e3f72e09cd4f314145a1bf82bcca94fe59ca13533a2f644ae5db3ec12d6f28896f98b5c3ad66edeb69989c27e77adcbe050916b3e8584d816e57b36d4717e1c475f2cde79c407c37e4ec3d00b46eaaf6ef9e4c463955b52a426350c5f8b0ad70723a2dcc6e4e62f4116127ace94de772149eb929a204b42be8c2affeec39a8d2785330f8b5642fe38d7ba99b24fb326ea94021a3a26fd70cfe889f5363ac714d6b266219452c2352312dd1151a5544f0f3b51d46dd1c84cf53b72b64125ddc5af0a8d7572a087a5060c7aa892303e9b79d1c0ee8d0e96d805b235544ef57004d6bae22cec343eab4b0a21cbfe5a1123eb69ef9fbdcc769ee8dce058d75260b1189b6ec16cf35313e2e9e9c247b65bd461f3f79ded42fabff33bd17037e437c41f20cbf7b6c17b32956518da1812df7b46ac0bda467bf208bebb6924c74d6ac43f5391b85df33a3d5549956ab573f54e0594f89182107041b1a28a1a6bc5a65fa16e06dc039a05b007f9be30a1046c4aa1f31367ab74ba23f66e25ee102724203a16cbbec3fb0cd6b0eb2880c69250b963d3a5179d53af4df03a190c93c3045d6f4d6632c458aeb25c221539b66a9ff822d178b537bdad1dd9fc9f692f27ec258c2d02998c309880bd273ab1ae1b547a6573cdcfb132b508e976f9eca515eb8c586354395e04b6fa828cdc3e64a7d7ec0e1de3930803208f07f7b4c3aec210cbc777e0cc3ddfe9f75dc417fe4314990e74f3b12ffd72c95fd6759aa2e97facb89d4af94d526415d3e47e02389f0de9786330dcc2b9fd2a198dc7ff5b8840484658efba315ec9abd0d0a8508dd96b04cee32cc90770b60b3cd4691dd94565eae9bdc44b3669c251509e882a2eaae7d73ed799a93b36b33f53e0af44c01cb96ac6bd9b68002336e80026d1463232395381932b2272257db58cd9b10e33397ef43b5739138b86147bd3503a2ec879b5d556cc18a7f1ac26fd2a86ec902ebd223239c30f39a29836ab7a91116d209202a888029b5f3e97221d28ed91106900ce7b01b8cdfb6fecbef43800bdccc49ccdc358c2409e908462f15372ada35a9fa930c3ae245522be833a090d4291cd2947a83a88093807e9ffb52ed04c7e09c23943d52d30035a720fb1ac50906356df09d63a5a70a05d1e7f0aa45b087a214ec9ac1a3c1c9d1580dbcd0a974217d4c2061636528cd2b36991e72eb1fc8580d2a2074eab1c7a86cae50cb058003b2dc28b929b9946457f668a2adc9bd287ae3b8bf6fe44262bd003d8afd2504f412ac1ec67beb579818a0534aec61b9fd6d3b9e9e808264b653690828c8bce1e3caa6b38ce5268f6d91e393ee20ac290ff19c31d74661088751bab4c7383f671e4df1cac7f086ae32189206dd7c721ed265c1903cb57f900d9f785dd1f7ae48e92cad972f2b31cd0149a95161ec9ad20a838d49df2d82a4d179c8e869a0fa3b73d7720d4c596f3edcb67b863dde22313f3dac8bad2c770721522a0232f272095d98afa6783314fd8d24e44e2be0e365950241e56f1223c32c30534ad0d3974e46bc699efdb48f73f92361eb86384eb473f2cee522a9b35dad9824791c1b9d17a34fe831d1c883a3b9040b47016ffbc0a55b7d1796cdf1e6097cd53500a7d32e59ef4bef18da4f93e7e3dbb23ef18ceef1499ad43505098d169c7c0f3f9af16a4eb0c0f91c9b914c4ff30acd0e2b78f86d19251d2d4a42f6ae79dbc6d0d12293a104b3d9cb87b7ada743ad4db10355e7b17933ab131cbc8286a01e06a2870d000c2f589961e3af090475e5160526a70c5dd054c95515a326ac2934b1937670149821a1e165fedeb91a798fc34ff4541e524f63a67044397c44357df2a3ccda59dae916344b5d62adb8c8047bbfa2cdaf7f60de9d8a22023a0ac3887f3dfec05727fcd98ecfbf310f12db0275df2432a14056af420adf521a860232af3c829b7c748d2cc20707a1cf72fcebdd7ffd4fddc2748b9e43146542cecd5f9f9bbbf34be6b60997355f988850604754e40c96b907e698235bca810b4e1f8d43f4a6e29c07e58546c9500746debef2254501fe82027abf4736d54c4697c7644c211ca73e72ea86e9bbbe0726808b113fb97bf54c921243c301cf0fa734184cb10aea3020cf2857d77508152d1a17028d933d8aa54857ac51161038c59e362813745fd6f36b3a82ef9175f8b52c56100bcf877e8ab4352cfbe618e9b71b19383bca1222b23cc509f39dd048f33b8a7a158358ac0e175409278a94948145fd747b0fb06b389858a454f7669b7609e082f4ec8c152b39003bc7f9e909072ea0e140a2127003a7ccbf358a65e872a8b64e09572a43974e34e297f2316ec0112941eb1efd92b3cda30def85447a0899e6ed3b85bc3cdd9d66d2dbaa1939be6cb9596ee6d9ff4e83952f57e76adb39d1c6769f8f7d8f01ea69cbf0a654751bff8eeb4a859df30b20eeb03ca5b85bbb14631ee327651d1b6e4f92854352f9cadea5d2d69374d68496228867284512fc93c89cc2e91f55fc59028d10103e9bd72c21aa4efa6695f2666d557b3305d970c084b49dcf5496a35bce45b7daca97f7ab110697f57aaecea61e72bd1896577991c16f454f3af40548ef62884f79b605e412e096bfa6e3784df1daa894d4d46aa537268ae491cf5e3a45129bf39e76e338455a65f4b795e9961ee0d535b377fb03efe91a4c7cfd8aa2418d4856d6d4f21ac7f65402953f81b2e48baafa2f34ceb4fb943549dce6724390932ddcc54cc91c554357d3d8330725aec4c92c0fa53c154a563a2d68af60133a5c1c5ae907d5d06eddd910f44059ae09e13f49b4736edb170f19be21d5cc65a0cb2efc212305b1757cc0b1e839f5dd2a72c967826e39fd06282a1795060aeba8e827f9999ea4c1da5cc2b87072c3457b8d0e16a2b5276ca414bccb95ce2372b1284c9e6d99399a8ec1633c2bdcea1dcc49f98b34a2c695f2aaf9364a8c027e5b3904313a3edabf69235180a28830c911b8be323f5f24c517a1f729eec80ad5f8c2942e7108ebeb393cd3166d1475b804f98c03cef352566e48236e007a19bd93b46621c996c44f39ac69c98326b197f60787284a55129af3cba7c500604879ce8c75651fa457b4a3ea6984c9bf0a41aa2444ca3edf8eaa2c4a9bfdf5433f8b2467b62f06c41468ee8ae4f0547ac9dac9500a106c3436463aa7693898acf09ec70250110361e529996354f0b735f4692e28b5e0bd32b55b76387d9693299cf860897a0770aa03cdbd177778f4157e9205daaaf1cbc71e74f123f9e6f7904ec1e902fa345a7d156ce6695b65c75c5ef4f6d0e5b0f9f524203e95f224654eea7550e4e60b2033690addced414e506a96693c381ec9ee2b6488daa13365b11c9a747e48490ce898973b0e0514e0ef0ec097e68f44248075f4d9e3a616d89cb0411ef56d1c1ee0f64b2d8b978a1d2712080c103a4f07b9f9ad79ad9e96a6feaa7d16f24d607491955dee5fa771f0e01ed85191ccd0202f512f79a0c9def7e0adcfcf380a7858b482b14e9517d939ddb28a904c4b612f571842ccb4a3a751c531c0e2729d955a815a1f7519c2f351bda11cd6f60bdf95657cfeec316eaa4ea3bb2f9be49f6b003b31fd75661f8b72564ed76d423424e26a4401fc843da25da2f8aa47807895d0363703a0e3a966b94b7ffe6b666c55f56da7e0ec31898f167bd93d4bfc16dff83c362752a2378c82757ac247328e4ff9689287b41b4ef8e091e901611d96b15669184192d58e5d55dcc688cc0f17b2ae2050b1f4ccd1c093c3d191288d447b1eb1f030eba50b20ae4f160ee5c574d900048c73405c607c5c496eeb80af9d316aff23d7bf5975f0971bd4ff79fa749ba574ef04953ca6f96f4bd30c473510bc9e73cf47b095d68304d40470e68ac3238cee9de8c3ac0e5fba7a127973c9b3e759e9ab595150244dd6a38c56fa6124880881169e3c0bb184a8c13f2dee4925e62f8fd4fc12977601f67a909e75df16fa9c59ad71b23906520af717e16d29d6fc7f8c8bbe13b39b8d96cf45df9d6792664863257a01dc8b502ce994f3fb2c54d234361e868430dce1330896e4f6bb1a52086811cb72cb6e5d5612f9ad1b04cc32a204a77dde90748f5720416b45857175ad287ccb4ecb787edd1a91a932241a8189f375f515dad3f006f8e639b0ae0a31b16d9dcb74849d969224a36d4e09181af537431fb6032b4ffd66ff671988b1b300ec3a4b7f247facdfc77f41b421f79249ea9f02cf918f2398223e9ffe8150f06f8ef6fe94a5186d5c1db02319e5eb95060cda131bc9fdaa6baa9c877bca7f0307e65b0e7d0014e3f1e646529d81f4ff3dd3da9c62baad149b6730a9471fa8731a5df22b7a73a1d123251a15329e1b82fcc3b22357a2c17c30e849185eb3c46ed61b780edc6e22c5eb36bac367743276446233b0d252860ea316401028ac86d950fde57b434bf872d1ff02ab1479b519d2446cda1c4d1c8df9f7752c78a0fbbd03b8b6c01f7189cdfede82aaca832bbee079bad72e8bf41fc3b066482610318fb5c7f31c274f06f1207333348241faf7a5a14dae8260933343a052215965ab48ec9fec2e1b0d8fa9bba70ed7d77cae741ff336ba2893cdee94c1506dac540e35f5be75f37670a6644319a4b4bcae67e98bd0499bf40ecfd1c6533644823b6402404413cba351479b8ccda7972825c3a7a4811f70cf1939ff5ac8bb4b065537dec75603561c7b7f44d0433fc9d65a12d15087c4660187dffb32c0beffc3fe3928fb2ffcd9b3185611e3e662cda9825be95e0156c7086ed16092eafec1e19f6dc36ab8177b389e06482f5467de24bb9f716ae0e4057d690781aa3cf7cdef349c04b59d75a9381e1444b00041678ffaa089c0d75f4a9c3f71d648d1e60857e138e01745ddfe6cd1ef49cb14272a4b071efbf7c0d90f465477b49430c6b3afc921d6fcdde74d4ddcf2a4c4d8560fd3bcb122213e86006287f46bb0bfc68e7351548a0638c15d134af5cff35909aa3e53c1ea3705f9eecda73c433df700a91ecf577a4efe4b43e8c9eb75616c5d276a8bc893f86e11547098ae9d493e44adce30e658da31a3c1d5d9d51c5e99866e22099c4eb3482740ae26f8e5b77dd84f64997312efb77e091174b3b2871a26509d67c624dbff0d65bc71fe8d3cbf5d668c8db842c2c88a74fa3ee075d5ce1e5a4ef0d0bf1e5ea8940bca684973fb7046bce9d835d99df08db1213289f6823f1b8828dce64c233ecb7657b46f12e2a1a37c63227a301a97a2cb24bb59ed58983bfa3433d3cb20bfd759914e666b1fa71e9ea6e9504d75046693b9119677cd4c3d6def6c16b4954086f42c356f47e33b71913fccebad594f638a744846c838c2c6f7205debd3d9e1f792860996515d1ebb806890bb5878d52df21439c15fabbd77e9bdb197b3ad12447286dbef932b5155bd9503b0b2a2e9ac989c4e01c98ef1852b5309ebf2ba26413f5bd05a66db5fc76b62ce7adc598758fd1942e3d69c672bab7e954a1dd9fbb6ddf89946b0dc1b1b796eb2ae3074fb0567856448ddfc277e8db544f6be832225f0c25118f6e8f64ecc949e309b3f0362e21a6555d280fb2fbfc9ab615279c39f5728bed50f75d3ca6fb150fd81b7ad67552eacce2558280ec2233e7f4b03dae524f22f50ec264dce0b049abc17f5d0c8794eb579e6908f4cd43884c3433b10be9d9258eb2fca268185001b657da5c1d629ee37b2eba9e3c3b3760ece2afd34b6da38b2592d3fc5ab2f6c7dfeac3a564828ee854e046bf67042f17ff591bc9c90c806778718f89d17154b09f7406a6102b25b435652dee87974998e30eae51c362228b1769a6a41db6ad5fc60ff183771b3c9afab08bc0dbf6b886fa72c854cd9c59ebfc3ebce4e55604c21d590ddbcd5ba5816590c4f02f8053dbebf3e435d5494defc55e479e6429e522512c39a909c55b46f7b0a59c5b22a15f816a930c4a8430d980115474176228f49e743a28f5065f70a0675e425a6072558c094aff766b8a4fb3e0f00c075499294190a25da3893a99a51fc1ae17ee7705ef4ffe20ac6b5aa950e42e4cbf9eb91f6cd0c887fee45f9dc79d75587a5f24a67aac9c97916bcc4d875f8b3ac6a5e790dae023ec0096413ce9ad834c222697d151d6c963e3adec619f0d2be1dd388243adca51d6524e8bdf0d0477a24dfd5c890badf93777819163073b493e6f1905e560e8e376e264006e17a9403c7b037e7a00f3d60045c6990671592e63e699e4d80cfa59a1f10437a643709e4921fa8dc1b6566a80b5cfe3ec542c3f20e80d7243c569293aff48e22ac3c026770106abea99fe5df2f1638169a838afa317df3dafc23562347769a0dd680cc1f169bf35a2afe68863ebbd4e2c8044ec1e28af79ae50848b5dbc590be0c3582b999d650452aca3d171df99c4f63291f3eb2d608696ff61aafc4570b5a0bb5986cb3855e4117875b9c1960b7b2f1bd71929b7b9eca4848f23cd55d113b1af38cc134b26be044a4e428aa79a2d0ccadca77d3dce0ab5318a3a0452655a158ceecce687f8cbc37869afe0b92ff305b0c3b2e7e9614b3363dc2312a6911deee49485c6b3d1958e44f38a8f55059735f81f1c8a8424ab0b7f5dbb544cffff3fb7faef1c1a48e25b20e1ab0ae2584ae1eb8ec35ba0ae5f46ea7fced8ffc9af5f98e6fe63ba824d8cba77ef2f1ce1954e877a8bdc9888681e87a22b34868d51f3fb928be556a7fac5ea204301c9aab2aa2f0163cd759d6c67cc1e44892bf8323de329901ba47c7f05925be80e5ce8cd18499fb23f95bd51d539f75d4d0c303210de3dea620f91ec5b883ecfa0c6b4d4d6de617fd2cd81d24ca422b0fa977fa833e97c3da97e19b5a3222a8586f990a54705fd92761b15ca592c5c41f5307f6ce188530cdb2406513f6eb7f1c389e009e4741201be13054c1f0045ab121270df36ac6ead43af3b0b226983b7719a5afd30257356833a74ce8d7cb90c1165f8f226c39b875fd44ac8a881eeddd14bf801b137e41899588a91a298bafbf95951c2d991f545c37d05eacb49575900471b00cd926435b4586556b64bf49dd343a0245b0b5396bc5b560403cb12723dbd9039a0921870867153df70cf96705a60413fce2f8f9b285aa818097fe5764ad2efdc8bee3538de2f9ff6618dd1259afd73a0f6bdb6e5940fe95d062def3a06361a83d94ea14de9e7f260b04c91e37c5fc8d808d2d49ddf6f5fefb37569b76f4831d436837ea9f482a1e923611fb2e492e6d91c054e8adedd68d780dff8184ff82949b2021df373a8073ee5753d510b594913a4d2347065b1ae2f860d6aad18e9bf0e290017bdbc5d2f71bd67e4e4a0ca6259dad32fa9cb0a952ff46f1c31b486ea398da918134c12a48801d627530a1b0475672d2bf9b4b8f1f7c6b966d368fb1c5ea1cb4c0bc9f3553d8c6ef0551c16df2b4ded58d32296c5938afbfddc8696c0895fab93e9a96d8b0db1c7bc66a78bd60782eec4c82e6a7a5b2430a45e1637c04dcabf98b55558caef3870984aff52cb5777759ae5038f2c11969e6594f1fdbbc6ac2070d4d0541242ea8b8ea297e4396bb79192df0528cfcd7f1633ac7a78000fe8f27e65391d6cd0330122dc7a8bd40320e2d5d03312849855acdef7eb8e593e489116872ac2e2bab8dc78cc97babeb88adee56d7395dfe799e9b2b01a05b5be6de2e5ab89fc83600255f2b6a4a0b8353fdbad1b32c5f8b610dd9cf350abd5b42264f9633f5705703b051906e9fe9a5542527c558313220984cbe58a8cc7b6545a83d5cfd0cbfb15d73222f4c9cea6960762145a9b25fe1cf78df4c9a6e9d6ffd83f9a812fb21fcccd30aab3ff91be74fe6cffe8ffa62f9d2456bf34567a274aa13456ed7fcc2df0ef9f78b6a4e1e13f262b183558bcc81133bb283a4e2db8e2a23daf02f42aa5f68ba12d0af3d72d282a5778d253f2ab03060c08a0179c012a1cfb568af73b8872297fdce97b316a91d6773d483aa5080df0f647530c3e3117975837a6ff428f76c52c38323317ba218fb7765aca73c8966c3875ff2f00d5879f46f62daaa4908a13344df8e472926937cebde01554cbfc947108ed4ad51cad412d0149749554a91755f422919c4afa6d087a18a30a68d9721fc2a9e9fe30662d27856ea32ef762fa06574b37d55482bdf9842071bd29662f7dc27e359e6d01ad2cda2298ea0a87d7141146f349f9e57b730a2e2cc4f901a9dfee327efc5583f5cac41d72f7c106586227429886abb2c2c436226bfbf4e6fd7bb030830c04f11b1e97e540dccb80857e420edb05872e2da1b69837b46a03d3a1809fc46aa6a3120c6064c5ad5094cafc4bd6010a1ed3cd13407f33306e58fbfff0f6164bd02b6994d8036921a6a598a512c34ecccc7a7ac7dfddb73bec98b1afc7edd96645ed325387be93a74b2dce8b91c401eddbe4a58444146627196deb9cc218b68b7b1aa3ba8d86a34f14b6fca676d5e66c3f3a6d91bbd5cf8123408a7efc1cfc672570123ccdc89dd6719c6e4640b4dbe7596715908379d00af8fd89b78167a7fd08506361bad09e348f29ea3946de87797d76d3ed8ab017520ce50134c7d8fb09002bd72ec45641f16d752a79f7a296728b3eafc520436ad2a33e5105e81d54c132cd05d2c8e28590f0db0c6d5498243659608e138ea7a63d762ba0b87fb357e270b249997079491632210219ca3dde1463bf9fd7317dc23de389400a3e55a30c651e89f2119aded05181b7055098d8d5e1ec8dccc89e531544187e7f39203a1df58bbf18362b8a87514b0ec4dfcf5747ddd9522ced3235e9f971759db3c91e153ee44d4575bcf2bf032cab66dc2995d9491cfc9e33ff4ecb32e8df8de8a3ae1728762df0b8275464d20b44d63af5fe7396517a8e4cc50d8e617896bdff4ede98fdc7d370ff8f7963c4dc5397fe3fe70202b6c92773c85b874bc2e4cac7404a23f52b44138efbbf7090fd2fede9670627ec09486e8308fce6728dab85ca2dbe9fe9f6dc379ca5e90f37c4b5b3753e932d318a2431d9a55e9ba1bc14b5a05311096867683acae19b041b0d3f2d4877df56a85fdf8fa2811ffc8feead9b06d094bc68982c1690a6c0b362641d0bfad0c84d14d6e6148f836dbbd736e1b1a0cbe46d7ce6ece6b56395ee100d3aab3852fd68a5c85befe302d40dfbae48a84f340003b533136ef399ee133ce8c8aa1621a8e7180792d1aa71d4efae00b7a59071acf7d8b42bf3f723c328db2b38a93b3f85ab2e007a6438bc7403cd5ab3dd114b01c5e698be88ca2e148ca291dd85e074d84d33d1099fa894230b7ea709160354df34229e5af4c70496f33a4aa8f47116d5b1a448f2b16e5878e744cf2945d100570da4e82a9889dcdea0d11089632688e6570a8d10536f7d43e797e67586c056c2a458621e55172f541fcc5d0b920a5ea77044b058655c5dc06a09799c20bcab25bc696b15faa3049a201fd6ebe81030713fc309c9680f62822f8053da2ab38b6e6ef9b81d6bad136309b63b0cccc69aa811280cba491d3a673eae7ab23b9644ebe30e371dce8935075e641690f036b9a7696e0bc4a37c01f33301391ef89aaadc4bcb6e03bcc84ac78e07e8f9b5b49d54e8af918a0674e427c4a6f457a2a67c4448520c8f48cc988777e54652f8466b339797154809ae17e6f429d49854353f362be4635f572d2b979e9df1c801129f174d572763cdd9de53d35baac11d0ec28a1d6c631d7181659cc783c621ced2d18846cc3a49252dffd473803a5a29b0de61f3eec3816cf6b9759518b61a5f097287e37bf868b21ad23cb1a40a41f228ee5cdd3f03c109d1eb0d0bd894af54241b2a5004639a48eebb8819e4cda9d89654735666bceada7e05b6a2fb1d296fee74b5c605a8924c7bf09c526d147863bd2cf3215e9e3bd12aaef07972012e03be56ec328c7be26c5f79bb02aaf8d0101932ed537110bdeb9ba56cf7feb1237e464b874cf10b90992ab6a16551166cbc5a91d3d53c77ea91d37803b6d05b50c3a4d053d50761377f571dd1c947cab9e2811d542752d9b6ae6bcf0d4c8e7cc61974220b7ecae38f626965eca09043636072d1c52704c853cf09952c1c95871049332576ff9e09e45fa72de3d191a4c003ec9514e56b77aae25286cea44c53db27f484ba7478d13b1a78f85e1fd21a1ebc4beec39f90b7f5173f407c73722619847ee6ed4d6c37ff9482a883326fbf461cd016f15ef357ba9f97f13f6a0d92faa38c883744931f76a0ca979fe13a374f16366ebabf1db8117115fa3b21a2fa74a45053ee203966bd045ad8450b435c692f26a9aac828f0b987a5fbedf5d475a761e5cc61919e651a016ec7d7c8a6c1692396615f30ca5544516ad30fe701264bff95add8c5df56a1b6f10f0be06f7154f17f5de7fd0f47359b1c09d46c32876c3297421a9024f8474fd799fcf94fc436f9284219fa6f3fe1f0e1e32740820f8e295a68c1be6429d30e89ed472b2f06b43e2ef5a8f650aa72d302c09c648c368950cf4920e0f3033d51841ecae0497222df1c296066669beede7ffb99df38fa4d9595196035a1343b323febc6f6663619fe83007c363e2c46b180ebae19c8babde0cb5b2d4aeb69cd93df16b7f5add3264474dc3e5f767c4db467e5eb83cb6f7433756fa3c8296e73795ef8359300e0386ac0348fe51376b038c7eb3bab922a2e43577a60cdf90201afae46d106e94235d08d5b0e8321c37063a751de9932579e90c976033e314cdda27eb1f5efa0b7357c7c241fadc5686e4446b3ab87a4e461335132497f43dba17791e443037ec7079d5f632b4a5555cd44e4c05e91d58c18e0be8111c3a53e2531b96e1fb4e5ed884d74d40774f2838fb3128d473e811fa196b8505a9dbdd35b34fbb7a11267935a8c939f004b01816916c3da04fdc29f75d0350a08bd758ad007d9fa1b25b3b9e510472e9dd1a289c93fa9a586b90ca0e00a522989e050e5ceab84c9692864d74ef14234cf06710328984b7c06dc367eb5ea6126980cecf5bd53d8a686ada72bd4a0e8870b28bf321199fdacb29ff44658eb916bc65a0c30f4fdbb630204246e6bbcae4ee7b1d8aee8abbeaf9f400968ea87a02db3423747c2519df301705acc4fea7eaa1768067d1716e637e200b5df7ae7fe9719cc7969563a229329bb6adb535f441cb4931e1c7eff7e099d670b2e193fdc91a30199560d57c3778ab6622547644d989944a5a2bdb755d58d27b6d63996e17ffac15dbdfc0e59fb03a1344af87b9ad1fe5f388fc799a1c5f9970ff3d7ba8f3a4d21f97fe1aa23b4065414fd102491defe2293418c0e8a597db525f73bb4ba9594dbbe3d21659a7a945cce40dae1846ecd828323887cee54c84ce7963377e5f6dbbbd992ccda53f2382f006b3a0df907ee156084a0ad23e8baad5f215bb7f0d18425bb341d551758a0c3959457856e1773b31b958d9c314bc77040114cabe93c003f1e69f9b3e9ab7d0ba070abba36b11d14b94d5e6ac6fd806e3a4152b26c902f464633f44e573fa5a49abb292547a25e386639b4865b1821e14293ce1664ce1215654d00bf6bb0444da63e284b11e0ebd91487e0e8f651bd1ac905cab0a785126c5b893a84749f80b3462357105e5a97cec29440cf2ee84ee1d28861ff12911b15976c9426282cd66c8f47c30bbfa5ab083071467af7797b98e3ef84d0499de125e05b823249f359472c8b15253c74d4bb2f07cfd64b5469d3a16438f2d5864f3237821ad620028bbd1cce581c3d13fcf71d69770c57833b9446d13f36492c20ab8263f379d2b295e06439710a1d5b1e8ec8c9b73c9385b8fd1a78f55d31e8982df15d6ed7f3b0451e81154fd8eff7bab1b1160bd0844988223a5178395b5f5991f0ee0f388d12f62af9db61e46ee710ff8496a863e6b1d54224dcd0c44e20e889e230d8e36d8a3eca3f055dbcb7dce94f11eedc85bca294227c5353d70e533696cfa8b01ef12bb85015f57e43c79da25e53a129c5731bae11f2f9b07b1670b8b950830687f805704846410efb87cdd56e2e48efe92f315a41e46178b8d18c9166d618762fd35daae2f5b2fd4921ef43daeeaf379db425ce0842145d8c766ee58ab01b527d0863b17feeed883b177243542838ff5b9205cc48520ec43d83036348bdc0af5c7d97a9239d6d7ced9611de20a15bddc48702d69ae2d4598410674e4cc95e07fa383c128ac9b5450e49262d08bf45a149e32d84edb8fb27471e792696c83cb2742c029c511a3da07cc1d639572c4ebb598ee36c48345fd8569f9d19e07e770f0d41eaa9bfe45685781186c3d3c27d96b1dba240756a33f03e24050bf1a162b35cc9b8c9d92d44c270debdba97a3a1d788390a2aa6f1ba390bb45d68155369f61be70f91fd60b488736cec3909e7af5b23e4cffb61b0eb183af7635ece8158644a5694d9bae9ed5f3a721ce564831f7bab13b794acd26f9cbd5c56918faa9c2b3e1e724ee37e50fce1ccce86b3807c8d90d9a3bc42ba62d8b81b48febd48ac1d9b70ce701182dd6ce250932d06cf396f01bc13143a4907ea1e9fd86602357d5566bc53345bdf0f87a8988699e265d009a306a7419d4c27040475ab27a09f1f134ad8b922f8d0c2b6e95bcb31723921d736ff1e58abdbe7a4469804e296a90ebec178d69a42db265506da51837c0aefa5d4d4c45b62ee009e6539413d9126966cbccadf0de5bae57c2c8a2a7d0e44a625247670b643c8155cafc7c938c45ed27eafa5968a2ee00b07e5bce544cd3a3406d99b95b4cd827c7b527d523ce7f80d47d0b15c4078c938109911a82a6a931da74bc809d391f2b54670e178582ac125ccb210efef1a6090d8ed39d7df3f46bdf85244eb4b7d2bde2f4cf6781c937708ff2245e620e226bad2cc201b6ac74197fc54bd1ec9a1a3923b02efe80e2e9cc01703422280a5c8109a3edf58fa05c335592a85a7f4fcaf7f2e419d1d90a53beec08253dece075f047112343dbff6dd7872206117fd293eb40abef5f6a0f5924a055221f0c284d13a93529d33a30000d624a71b9cf3f34ca0b0e9c939a027ca44c8b5e6fa36b58ccb5cc6715b692bf5717ea89cf5d4ed805fb56937b8e429c81aa2a6695767a4757c6863f29b5105201cd8cdad415dbfaf9f7b52fa07ad1747d1f6d8c161619f36120c6a0618970a0f19c79bbaf62b77cc93340679804ef49fdcc6bef930e33efa591c16d7cfb2498631ec79fcc086bbda88198be9794ac2efc86dea71362aeac757117c4fa0e07a8c561e851b91e07444194a65809533f27d7a8317a96c0410946ae90a4a79b93934bccc67db4bacd9a8280d7016f1e26e2a0297a21de4d1cdd4880dbf87af4080b1c2c2d2b5a48e963c35ef5335ac7c88f84790bf7852af32e81a33cb028019e181e0d25a4e4d5cc3e38f015458b39439ad282998872e65c56bee110a0f061bf7af5f4873ac77de236a7b40abee9c9c1d6a09c9d5e0ba833a9fe74d3463e95858187070d8bdeae5c106b9229d01f9575cfd448ba8dd19e645ce07725a11b83c562b5f91ecf77b1b9baf6d6a8acbe4967e0248fae0c4022041e4fda85c42def720d508f29eada9b3111b176afb966ac05b3600ac5e1958a2a82b328d7e94189dd950f20d2c6a94a77e62ec9bdc1bc4cb866f672ac831b750cce84056bde183ebef9c6fa3fbc7fb381d0ab0961eaedea92faef39d6d86dd5d9327da7c46f34a0fb9e7c44e0aeddd183dc34183f87d086be067b4ae6046be155a46463eac3297020c58638b8450f5f80c2ecb45a9cdee4c1667030ffd837eae062cfc6fd1d07bbaf60cc59a8b5274122ec590f67fd083e9bea87e9cd553deaed85bc4d9abb2f78b1d6f5004682b5b69da6d223accc7683097ab96fb773901e125d800fafd0ef0bd2e9a6141d704e2e1e639c787d2ab41448aff11fad3310057c966f9b4553d034b1cdd617bdddc3f747b2121352fb1d89b613cc7fe5bbabd5bff7fd7edbd70f872e40fb7a3ef421aaeac17df0436a13872867f67e99320f31e93158d0a84f034d487fde4d67a6eeb2de648bd356d51147221d670b64e4f3d3b844f1b0f3449a6941d7f6dbba15820bf8ee3cadfcd806dd3490532c06bad43b00ae110dea32640d1f497562005567e76b377992c6c5d5ad272ee7e76e9f1a1abd5c58dd3a115f8cc4951209b474a0f6ff412c8abe7be1490b8dd23f48e92c550659083a878ee5f915933795b3f1e5f29659f325327156ac9490e169d982dbcc352bb904d66c241869c13bb51f54b713bf6eba3842fce66555aed945b4a7084e709eb53b40685ec1f54df3c321ec743401a9d24919c6fd299a9110611a2065f19150a2ba227747304968ee099e16fee6cec6050078936b4bffe035c1d05eb937ede537bb21193da5d89b812b3a06e59b15a92a4e8d8c1bcc7dfa0285c0ff26f9c7ff04ebf8ae6b8c6e5c4b7246472f8d3b0f7e2f6104f552e7826837fd4af866582c38b4f2e772a6b09552252c93087a6c37fdb34bd9a2064a4a357681075a7e4b71d31dd62daed1641d84ce0d3950a742f1be24e1c19c49381659d7679971e61dacddd761e2a8144b0441316318fc108d10c614d926e10d9fd8dda3b8ae19462e4bd8335b91b3b0e2f73995c2b963484e990fe15a4ba357b6f2bd38ba9dc84228d9133ab7a825bfbe8d22a77b0290c3872aeccc384b507448f4cfd8348b36c3e41f8e58870b7be4048189a1bbec334fc6926958d7780105b0dcd4354e4327e0a98d194f2d00be7a66a7acd1ce5eed4fbcc254d66015d4f5a6920ce90351bb99d219f3f996625ec7a0458e87a38d7f76c896cf01036b77a44dba8fe807269bed3e406b80af5e74ece1a29cda47a9f9fb5916707e95ccb2241a0ff0abe233d057dd5dc4dfad01266cc30dc4eecc7eef5fc5cb18ccc04edf9f69cb6e248e4c30e9993e14ed2e2ca994a9b26e633b97f4428970cf6f3f718fce7bcdfcaae2790fea198ae9dffbd7be17f3d2ffa9f7be15f7cd38e8a26fff7baea15920825eebfe6ffc820887ccab31d9b86e8381c163f640dfbb2b5877391b00184c1b19ff9566bc48579973d8001d1852b45c304e1c0c5039988c014639cfbd8ad30067ca776d2f5405d2994a00a3db1c0b2cc01203fa38a20ab33da6e2ea45c4e120c4b52885dca50f6f39e06ae5a76c760fe75fa3f9bea499c8358607228b4a045102b73454fc70f4b4cba0d065e2d047dd0c55444530ced96166b638cfb4d7e2064b85854e55b680f3629c9c2cf47c85f8e8b6a958979c16dc7882419da1b52cedfb3158eedfab0bc6a3dfec329e9678d4a0cb1ac1419792dd4efaf6e327b753547a313470e733b89db6dd5e0f172bfde8089b34fdf8ecdabfe70b468d874fa8b6bb73bc507325cdac264df333dfc2595da45e7c9b0bf8ec202bada3953dacacd39246f185073896258bbd2b6ebcf3861db1b357fb5a1164110ee51bd6dc29ee539f039f7f9541b0ab413e6aee7e3f1face767b38f97d9ea0670fe7abf452d4eb9f14dcb8a02527eafd3cae917fe84babc18a6190d8d76bb66c5c5645847bb28057a252ae1a8d0c73035d9665af9e61a1c3ed0ebca4193af5aa13837d90144d096ab902b4d6664f4cd52ffe230482f0b64841ca6fb85658cf1369822d30a62d2c2ccecb8153281c341f79d274b2a7b3e6f4f5a0629a2b113d7481678023487a7fb4a3f173b7256d8aa28ef9f38ba07524674b8d1fc2363c374e4d5ff701f7932c44105c318145e6d70761cdb161e472546efbc09f7d63251876531b21fefc12bca9edb7acdc93e65ec2ff045600ec8e37b28523a06b704d61b2f287f0acab5f91763e47b123bbfbd8a148f5e8789f8d09395315ebb4b357e9863b0ce0fbf067259a1da84da9955629b8a02fdb3eeee185d7a216575e178af2a2f681bb92ca91a000907c1cd55ab3dfbb10aa32e38f0bdea9ec5ea0106fc913f216dd1da359cc9a9f459dd0b625fe0819e7dcb9d90d2f02f057d710cdd0cd3a730cc34d7fd3fb13ff0bdedf5fbeff9fdfef38529b42a2ff3d8bb704ce7f324de9ebe72d54638c1fa4c37e46f1aab88ba4078995b2fdb3ba3feff00552eba714450ab445414ea62c459784def840ac9a492cc6911b5538487be2f23390024976d228480c8f509a066ba5eec23c65663b785f7299db55b360ed6a7978214efaf053580b5f20e43d780bdc8d430d2c5ba6fbc8842a159e238049d6388652d4834f871ba6a52d42fba552d404936b92099214720009584c69370cbfddb6808440b7116f9acf60779c8372aeb01f29c27396f2d53514713f68357f618afb479a514e88042a61d09913c8a5a8a70dbd610f6e61313f0a07885366c23429541c0f34ea2d744e6be96907d0165fecdbcf2a494c2fcd87392b4dc495824b6b874476f4d5db6f752f9f9dcd09ef5a8208e7dc52f26933f444e3a6465c3cf6816a1e656deffbbbbfe44d71294f0ed4146ea7e9a8fe9507a331e5c289d8a878ba72b08d9ee4d25705a7c1182b87200c9e8a2b4fb22975c7ec4324ece63a05da89c9b75e64bc7fe471261b693a5f29c562a15e4f55936d63b823f557dc2d22acf5801b02a0a99564ea6398e8c65ef5c7f6902e6b8e2110ad6ec5e4dd7355ceb09af1613474447fbc17e1045f6430c3d8f23a0340ddfd36a8ddd8915126ef8ed9f4184520d0ed0ffad910e26881afcda9590fc2d7c0878b5de091dd364285e31c9c6120a989f279e130bd94fa2c9ad99c71806f4f6148fac988c2b73b5d8b51a021f3a465f80b1b49240828b6e7c7d449f207b9e8ca302080dddc0d9d702ecfa168322c1238c71dec1610839643eb9edd0d028c31f96f1f2d35695798d71ca8ab403e8015f1f7d0653f42883e73bc04771460340c769f11fd865d1eb1e06a693f9899649c58283232c073d24648d252c0655d8c7812d1e964b34b63c2dc292a4f09b93453f2ac03b0e07f6073596d3af18b54a85bc49419fa9199b252e797b36fb79f9cfc0cb554897639c5800634a810433459f7c12fd978215fbcc3f03e911b2f215fa2c13076b8fb61d23fb9c9ce0d4d65fec120f5dfc420ce7f839bfcdf6aded6f0876d43106357a585b9e5299902d254a651dac242ac4618048d6fd73ea721fdc25a119f9d9c896ae8716c5e29fe28e647d4a3ca7c0023c3fe4340f1da8ab8161c0b4d41e997a165891fd5d0e114138d1ad9c4fc7d6eecb2096b30c95abea2064239e5f62eea314936213709beed9feab23b106c490b80ef5ce8f31d20de3e584668f73aeaa9c86689c6d8c5c098e037664f66250190c52928100b8ad250beea204dbdc4d06032c3165dce3df460520dbad73123ed27d29c69da4e4f6fc99bc8b2d5cde560179063a0adc5af0037e81b8095b4cc2e0f9e1c724ed4e6ccbe330793e5743340cec0993935b9420871102ca022116a075194616d3201c7848769b23b968c5e7e4423f1ddfa6c2c94c16364867ad155095030b89d24c1d6d3d151e92d87e9ba6ecd8a796243a349a5685f6508dd8fd340007d498e68a81d555349bab8adcdb9dff4e3c25d6c6d562d906bfce1f6ac307e00f56eb54a413c65c11d7205c04d2766c1d276c41b29c99db35dc0f445014d642d49d9bc95b5e357ea2c1802114efd2891bbd5476e8484108404d3b23972b27fbef9a2cd6ae40e8cc0309afff7e66404e1bfe0d7fc8b470ffff24cdf7f616522f0fe6065df61681f5e914d3a17d6deb0d6de5c7db3b7ea6465d8ce1fb58d0553add3eaa7bd973be8c77699e4ac3f0b58eb951a08eeaaa93f8a0313c19bb22117da79941a9a284a24b33e75c42184262792e246c1346d6cb129cc1ad562e3a2a5085de4513f74ce5a39c9d8253bac23e550645637529ecb9f86738292781c812a548506abce50c99c42b3473547ed0eed492d5b481dad7cb42633d56ddaecbf4e8630e412aa8d1e0d5062a8e29bfb522002f58a38dadd9a9fcba1384f9c2d1fbb9c0ec1ef1468d8afe6d959514c2049a067d6a44a48032ccd2c589dad28de91c09de18b23f393e9ab42f89862f3f6062be5968b33c62bc3d498b6b691e0e8127757cf3132e236f45878d1e2c4602d6bacb9f7f46ba834f22ae916825c399b465594b9b20281c05c270612af5ad1c6186568b57ecf721a48a2b11d335441c765a0bd025b2bedd232c8ed00734559c31c9e75b6dcb68b1f188bc7189fc405bd4282dba7a99c22114eccf6b33680dd4493a8c30135d0cab9cf42bf9d6d1ae4530c15c8151d9aa717bd72f6dc37704cea9728ad70655b0f4bd7b9e18c04c7a6fa0ea246130cb3b8bbe047ffb834c7562594bfeab2407af7b9714b10779d83b2b89a4e3ca71f44a070862fa7227d01921b6381f4bc3915385f796bab0d67f6b1384d7abf55951991ef84074a9d4ee258365beb4f1cdad58f97bd32b9e96b562bc868926ac4a7d914eb233f19601d6b6b32b18824e14629d16701ffa719d94c72328491447a323afcd8ab91ed89c0a453e0ae4b028a21d099034bbb355e625c4e24fa872943ee519da78b21bca9fdb749ea097c5ca17e82af50cd943b162a1cba5ff57e58a5767b5dc0485934521964c74f203cca764413f25ff9fd70613baff80369a558fcdfe7c5fe5fcef6ff240f1108f04f8084b81a532209834433a9361c5836e506848ddf48687477d586e5d65cc991687ecc1cfdd87e26d9242087bf549931918eb373dc7de48c7d57c6ed4a933063d21924499714f57dbfcf222e94a60146ecf8b39e2cca547ee98ccfedb814560d3faa1a7d86c39b4bfde6eb99134e063a82b5d624b7e141ed363c9ba0232e6f2b34fba7b648481a2b8e65cb6afd4a906f3e2afbfc5675fd4e949a575c529938532d73d52203c057298f11d90d24047a545e4f7e76da112cad70776f201efb34af34d0f4b39855325002b997b8da5cd61335593e314345a229e3c005626351845f34331b6a1720da2f7cf1e96553d14a5201ed5b38190dce6ff3416726f735d7e419c886f08fb02df7174e2ca5bc21a2ca95bd1d383f709b90e8a3bddf000d31941f196eb5ccab8171c15b0e6daf8d163f1a475e239e6f811a7f0b7cb92cad35cf3460133cca05ff6a6bfc8080751e5160c1790fa997a35d9a6154f732528889bfbbba0bf723b1012826f690d279152163496793e9a4d21d2f99ffaa2b119f77e9fc5a0d2f881d2e7f7aa00b7adb0f35a14cf7c0496af34a950cf892955c96abb479071f3feee772cea202a76de63ff8e8bd42997ae39bbf11cfeb6cd39e3e3737482e542e93b82c231ba766b9311d3d12244fe5824517450da2888f0f63cd1fc673d67354eb4553aa2253566af4848d5b28d47ae9aff7bc14fde46f5ae0c6ecab80a832fc992c818f6e5ba11f6eace9a62d2e8562a59d726c04106b839087097ab13acbd12eb69f57c240055bbce4968c5dd06f483c87a4e625c2cbb9aa500470f15f0e3fa5001568633315ec0974d298f6f44625016ea4192f71178d5594cd8f5cc71b4bc5397373a21e9bc680ae3de94d1676daf16e38b78ffe9d05689bffe0b626e14d6544fde1b62afbb77a7459e6bfc06dffc7da17117a5f487a36eb8a1f84e6d614787d1da7ef043415d477f1260ca2cb8a0a278a591af861c66596f613060fb19e117348ca9578bfde4b8629b94996f9858190c489c76df8c86807a7cf4a816ada809b627494ed15a8c0a4726c342ae324a84745b1704f07802505188a0d650afa70246686895fa34d755fb824123521d60ae3c42b8b7d3d6a7033842491e304dad3acc655140728f9b60b77c1d12eac0f642e8a41c1f312dfeeda2432330d885811d3cfe15fb781e69e122a57a07b0828c37e503e6a94e50a881049a7e3a8f561fa5d969f9797aadc6e6c4080b787fa08b461e901d40577c7c0d7d7caaaff707c07e49a5f67e418933d69601115423556f2360ea5dd784108e2dbc47e0c44e9fc2ed61de66654d5fcc2120bab6383aa551555b09a5ee4fd8d2ef09ccb9a6868dab35814ec525852b8a2ddce24e1d0eaa1f8d795f2ec6d11cc3b166744a8db4f05dfdbf94b77d2ef94cdfd38460ce7ed8b1dc59d9f64ac40aa77bd8b6309e5b2eada31b9983347921717b0ad79681b10741d55ef924f2bdb0f778a5c6331e2f35a1fa00366353b0c2d29f5c4c81bf96cb0910bd0111c39e37c5e97a4f51375800fec2194baaa1e85f1c18733010feda80086ba2f1af2808ce925bedfc41ce68a5717d42ae391eed230bcb7012326a2ba8df3b9b7cbdc78265c43cbb6e555bcac7f62de8e2c448b27ff311bcefccd8cd2ff8b0ebaffd977510cce14c1af02c1ffd281fec767860a8210fa83817960198a586c1b45031453cc8282abaf52c71c85e366d576348827b10259ac1739310479d19bb8c0c77694b3b54180f9616cd4e01495fb1168ff24abd8cd8059d376ee7f68327cdf7ea3060d1a5681e2541517b52ce7ad6b0aa5e5624e60fa8e8c27e3183eca087fb01306ede49995d1bf0b0ebf61d18a567e861ca51dee54cd6385bac5901dea13fdf2f323d055997eec20373fae76326614050d0a97dccb5fb835533e5731570c5f0ffa36c8d62865e7b263d6a7f54c9c0a5f390b24a13d06502897c9c81614888d1b2bcca2d16bc46a49ae27c462dc4bda446e859b64d3bee924ac90fdda4e0eedb0bb04ae6339bbcb6f6935d34c2388405661d153bf6b9bb609c1e907538b0e4dd03af48b9b9768efb8fd1409e751538872204fc065d6b14c9e3ff03219f9d1f273b240cb8a5883ae0c83d3c9a0681c21e5e4bea2114f6674896670ccb1bc814fb37d503fb7e58953976e47a54135839a1a1590de954640b97d576c4448d9ed54544816737526507350308317b449639d11ee9e0817dce599fb89a7ce4045bae90781cf0f3f4d4fc0e0ccf70a0647c9c3ea7c547fa854eb718f8fd84e5b53ae5af7cc3fd0b375d720184d8c5eab572239a5b273aac94ad5fcc812dab0ae5a0638a2fdd7e9fa7aff51e35c392b800d2989aedfb5bad9fbe992a0693c996db81826c123856e6c2150e81b19a1cbaf44b60d2fbd6d691332e6dcfd462d6cfd3b947ebbe642900bd394695398e89f95f876c568f6cd5c6bccf52bb0f49c58f9d42894550e7db5dbecef1b046ef7962d6d79166a270f1d6d38259d8afb596c818db338c166c7015e2e4f3a055942854e1cd8fa274b0d48346b56795d93b5661b1bf98ec3577dd86713c518548f68bdc72112879807f735f9bef7d7a9546704f10e0a5dae34382c043321c9e50a1724759a44a49ddcf4e864a117f1880b13e029832630839fff3c93c64836fac96005b74a9ce9122dc2fafbc3be149afed985f3fb599bf3dc0ac398befcff77e7c45ff7ca7ff4e359af442f182b1a7c43effc2c5b53924e51845a505ab99fdd76766d966714c4ae159863303d57f94abd257bfcfa970164a286dac5de9c9083f71531b7201593501899350cdbeb2cb6924443bc40fd72214732d82204238f2d682aa4b2d0a27c5dc6007e679203148e820785823485dff8254f17ae289c9e6880a40ba268988e934676b625f09824e5f3da8f9fd5588216f0b8ea7a4012e7cea1092cc51292640473e68ad2e488cdce799d61d6f3a61d246192f59efe21515fd84aecbef357cbdd19c7a167a6b462352bc6f7beef3acddd2fa287ba10731d1510a09b1987b0c7a45e331f4e96814b44872922dd3bc21b4fb291b826df30c81bc0ac4c429fecd3b33913eb7abda36eaba68d6976fece1116101660a4fbc2187693ce56ce6acdd11519fbc8ed68d3dd3198036ad2b2992a2cd3f82168c856f8dda73a8adcde292db36730d1e8828abe8cb87f723347a6893c3f721da79f14bb4288060077b04e2b1b4213c223c2e62f822c9db2ec6d275cb1b0e9291f8bd1f33458c0f24b2c99bf00db93734897c594f57a45a48af01d6a1dd0925693f8191bccfbd847ede817dd5bd4831ce730a07355cf539484d5d92c8f9ed8e5c0efc7fa5cc346bdd50363e1e9839a6895b4a646ec568afee3787af1779728c7f24c349e40aa356d34293384c181650d721dafa18babe27cf36bd3b270abce9e07cb07f9a6f83687518b24b6c9d1b7cb405339a7a45bd91bee74697881d6f7a52ea3584bdb137ae56e33e22e11476ed28821d0596c51e019363fbc29b3ec98b2e1b4193ceac30ce9e1191ba7ba185e20ed89e8b956c2ea5f0617b0eb2ea2589324e4a8c7b091663e0e8d684c22d9891f09fb6e630062006ef3787aa1401aa8ba479c20dd8b90d03a6e285e5d18da55cae740268a6e03f02d1e22b2d7528559c205b642b69ec604219866f4a79a4c1c8f9d53070982fe99d4c75e283737e07a335d45386481c0879dcf13b0213cc07b1b951fdfc297c08916c3db7258064ed74b4482553d1d535bce615513df91ceaf1f41eedde188a3e3419c124fa4e7a32e78bc512b8d7d16621c1ff883e31a0d34e446b8059adf2d778ce23579a01ccce50270c3e4d639f6678b9f01ebd89840b616a68b5bdb57f1385f2dd8bc3e389be65aa0f9047ab4775d2dbe68948e59e3106e9884ca7b952ded66c57d460f5f5831eaecf06c3ded34c8bce659c018a06138ff1daf17680ec3ebbdb6b77f1aa4beae33c7e10973ddcb6d9779f3bf2fdb10452dd5d5c1630c6c788cae5b2702d31a423962fe4c5d42a6527a3e08fa65bb766853700aa85ba97264fdd8d0353d838ff4869fd530dae01ecd0068c7aba0b04e3c540a8be89866688e28ff79dbf944e86e520aad871229bdfdbc26146ecdea0a91448b112736d1c131e59adacae5d8469de450e2dc107adb8369ee8c9fecd510c98a65beba771151165f7712a261b0112f58555ffd2015679269821e01b99af4051df5e1c25d0a5af02f17d92fa5d3ec980d53f92d4bd35a57e02f80063e785081d1529358d10113a636c404494c5dec8c1aac9e4e79d607dc3d578f3eb24559a3c3deb98943746d691b1826ca99bd5a54a295c9c22c4aae4c49b0af59fc0583021d0436f5d58a733fb9a27f0169466f25f0a80bcd3efd9b804c8af446cad25c37da89d2eeb53f0bcbd7e74dcc7d4076c1da89821a220406a1a6f76005ac4e97550d35b0ab0503da0fc530136cc1d4d03f38b9d0dffddca9470e53a181f79d92b6a5f996d24f261e0c59e504e1f1116db2f43b79056b87afdcac8e7165a1c30a5e2f8bc873223f4507af0c4f4e816dca6f936d56be188143f8c5a6ec97beb1a21ea7ed54a03be05a5a572f14d44e7a8239120f757d7bc1e56507fccede6e5e688f9fac2a8636935c7b603fb59d44816dd7f9d23dd37308d89ce3babda91c79ec9cc5e71d5962e2eadd430836282e75cb823a4888aa942975fd0a00c8dc8bf3b5f27c338651d530e792a9c33bf15c82ea3c1dd3c993ea403b212bddf82dc5e06924832ea022b3db0c47a0fccdb736e1d4e96f03456beab65ec45c9e95c7cd26815ff5cada4aa366f656d0e614d2a79ae608a5bfc6de2d0dbd57f046379164ea1bbc2d221a143429462f5167c249cc8ace40415041cb9abd8e53b526afb0c730413c72735399e40a304158aca1220909b0006d17540d90fc19b1fb22e0c7389b7154fd4504929c3dc4ea011b659017ed549f9de344341f82e27819df532ce6c59eddbb280fa771822ec2bdbd2aa0db789ee79efe6b65ef995824826aec9dcd303d45fd7dc9455cbdd3713e4f72657dd0051862c66cedfc3132cac578ad443a15e71e86207cf8d3c7adfd8da66e2a905b0186b635dd2a9e069305a46d7034e1c4df660e508e7e99176da637545ff2e1e616d000278fdc4c4dd8cddd5cf2188860a1211c03a0b3f4576d2444ad67ce2c4f7ff16b3444a21d063c3ac987baea65705a71369ece165e9c845f2307634182a176f96e34c65bf19446bf30ce6cb4fbb0ef2f49c45710ae84ef6efd29a69b5a1cd233941b82b37a893fa888951a132ec4f152c18ae4c3206fe55e2463f7c22f3e88bf43ac95be5ef67cc77f7951fe6abf44dc971c96a75ced619ccb3b50ba5175cf1f76170747365d00e9e2e32f02eed301d0b8eb4dbc939c801ed9787588a72c67bc075542cf06ac1dcf4a45b8375a3f117117208ebab81d0ea8132da0027876120386a2353817ee5ae4c227592d5219975cb89cb3d358b12a979dd662f1c75047d14c86d15a1262418fc6518ee524af0b42ba3479e32a486be32f66c62f710b785d09d7a07eb59814de2c7bf4e8b3e5d0cc5a02816bdfd46e522513617efb87140dc1effdc6c2ecc29dc1f7db7c626a79f7f55a1fcfc06558e8a6d48e29c4c98c7677138007a437f0b96fcafef10a04f6d893730bb8754316ac5c3d5927dd2713a253bd119e484d1fde2ae77c132d1b7074da3251b74ff72078edb4b6bf41ee079cddd8b77c36b78d07c55f4b29771b919d422985311308ba2a4820f27ca61df5f36290b6961d813b3d1b301bd43ee04f1b04fa1c1f37808f5f68a2c3bd1e54ef139120a71b313f8cc2d60b76899e28bcefabb1625d34468a7b52dca2a967a6ad54fa5f6ac953aae068877b87312cd917b19875c92836df2043c1f9e4f08cb7d9487e4b5dd56a4a9b9c45a93f716e458bdb90b058809e68ddea912c7aa5cd9dde7c624048582b5f701d33c9de91b1467be6ee2e650fee4291561f10ea42f3de617a2dcbaf1a3a16136032cc6fcfc16c534a6667811cf3dcf9d8336cba0fa8917a9dc8313de0b5fdf1fc8ccb82b3f16a61b51cac9b6ca788e6fb397fc1accbb07b1453a989a47d0b0251730b18b0b3853e2978c4107b4c57f12dd297bd1220fbc19ef5dba7fd06ef17fe593109c366c5d12cf46440bca41b28e6fb6267f97625ed787a5de7083b39652e95d90cf1c212f554e60f1b6a3f02813c80e4cd3af284a29ddde8f982054b5da43fa997e29dcae7c7fbc1e61bfc00f3c57316b700163f5b59010fd1339ba94d3ae582087d61b629ec7e3542d818f0ddd86686cf925b31fabbb9a57edb9265062e4c7f4fa629615364cc65cf5698361f9b04e97c12d3aaf864eab976e27891147d0a47a61d3d5097e6e070cb8fe45e0e5c36e10b939eb849afee766afbb91f401c3852965074ea75f9b862fd8dfb39814839b5f56596e1a193d227ea858c7bc7b7a54f0eda1503e7f9b253adcbae12db7c117e5c653dcba468ec6e43c5efd31f7af8db30c4e342b306ba399b2035bfcb7bd25945c3b247cdb36693c633730c769390bc886d7830536f03286287127bbbeaa06a37d90acae766b8aa528aed35406366cd2aafb3a747cdf62cc367c2f1d1b4501ee0ad5f7ff74b513a06c61d0cdd847865132cc8305caef4a551b7eb8f21a83336314bc2bfb61918774034783357b42f589f94cbf9427d4f3755da42752dfbf4601e8a2d3fe0f3b89fb3d7228a137e6e5dd301ee92907c1a3a69fea2eb15c44109acc007a7b5b0c1e614afc55e251bcf62242caa76d0b343dbdf1a1e417da4468182930fa4391698b9b69229564f8f27c42b8d6027aee6c1a10ca8274266a148a71533c2f23c71da9599e864b6ea4da63250a1d17e9eac6fed3dcd8e6f1d6a0d6d2f9ebdf2aa228ddc0d270143022edb587a8890d6992f36b6c0209de9959aee0d91b57d91292e4bdcb5d85718b2e646030744e6b29a8548ae6c43abe65b78b6b9239c7d943e66c546364194b35a9e8a9a951f5266af9b9140e105f996d3afdb65b257547e04934daf2651a1da5bee53bf83e0e8dfdca753acb345dbd2de474fb7992d1a7c8a53883dc9f210e85e8684171df7c9038285e428aaa2125a3174867b53ae4116e6dd78333e9f04568a252f5c578a7c7943bf57897eaff0dd6d45c5e77abfa51ff6c744455a2dd011161606704faf7e616945fd84e94d2eacacb0105c72b5baee02acc5f7d505ff5a48e4247a0ffedd3c5807d3834f5f3ae35d442ef4b94ea50a96a0ad5a40e30d90d5394a7577f8e7118562c038a1c1d9752d727259aa47849879faa496fe7c90b12cefc396a74b43390376383c414c058f421cf9150ed89408ac2beb602254cf99e2e0d5dad1bc7419e1d4193839cb46921d6cc0ea564796267a24f2cec444a0db079b5bbe7ebb5fee3f17441aa5843ecafc1b87a901bf5141bf327c20b1e36450bbd7a5a98c3905609abb1f065010050340c10b42238ca7a71c9cdff0831280f52cf0a06632f93fd8fbd31ed591a46118fe2fe72b3d83170cb8a5fb836dbc620cde9757af2e79a1bc2f600c985bd77f7f94694341559dd335d33d337af44c4b75ba0ad299911191b165441861fac05e6865fcc6dd829b5577fdfe2dd3663b47a042e71c1da94060892c8d744bc7135499e8c2d564d5a9742a8eb9c51df5465e4fbbdd6e6fe199b7bfd0bcb997508e5089376eeee4fbee709caff64b0665bceb75afa0792e569e27187e2645e56d895fb77590efb6f67953ac8ed745b5b69513e521fcf6d0622b7aa22dd9b2c65054e036e9566af4332f1eccf5c9f5f31bbfc64fecf2c0f7132b2bf62aeef527eb94b8ca0517a537e3d866728156299109330bd91e0e4b433ccf0b74cb54f6ed4278f532b4158ccb31913a6357f53c9113e3ba98eebd233b5df5e4daebadf53eb32322c87a0175d2bd17cc77dedb8539751cb713534797cb378e526695b3997acb729ad96c7855a757d65ad0d79b31d94a334bb9cce52c99ca867c29c35bdc5db6a77e17388ba51b8489aef42b726e16b70ae7ab59192ca8dc7a934f33459069b175161a6bcfcd7559a1a77d6134de9533d0febced6d295017a7b2d7e744ae674d4da8ab7d7ee8dccbe17c6d14ed66f95b743bb10e7678c45ced5cf637d12ebd93cde5dd8a74549340ca6c9d5dfd89589bed35b9f9eba8e3fcad611de60611ac99b6b03c275f13a68f3b57d95817f3183d1cdae6d89dfca2f2cde5ade9f727a3da91cdb10af81e391c69672a44bd2334edfa9a7a59886fb7c16e92e688744a7b2415509950660dbf3ebcf99abdd583731c9c5ab4665ac7b2f8b314a0f3b458bcc53d922da68a6ca87ac96189df283591aef5bd1b23ee2c4627a15e33b3446a1c8354b3c6d06cbd994517fdd2ae8953d9221a7ac851bbb68abc0ea8e52ae0ba232bd152655aeb53c4aea2694a52b5a3eaddf5221d6571a6e0cc329f086f3c6b4abc39710a4f215be2700ce3c536b28d9d85dac1062fb0f8b21636e7b34b5273b922f3205d7b981d6de8b93637976bbe9fae4341a2a5373cbba67bbbc30c86b82c56f86496519300f51464bd429446f3e2357748233cd668df719cb9a21724515ad86d959d0ee7be90556e8978dba9b1a0c88b9011f9565808c72ecec84238b74b61215e26d88ee4d16cc147b39e58e689de9fab0447f510b723dcda323db2aad5362cd0dcb337f6dedf7885875779732eb8a493d21ebd78376533c117e44d8ceda098b7a1eec847470af826f0c4453799a7ba8d91ca616b5cf57e26e64576ce6f99da16b3856926e7f34156dcf3fe78c683b5e55e92aca1d52341cf2b7b32e7fa55a0e31be3ba4657d3436ee487b9beac260a66486a24c8539ebc84c45b8358cb6c2568d7ab97c90b51ee8efeade2f14baf9002bd2ca6377e9be1eca4dff141254cc2d9757799ae86be484a942da6b2a8521483aca96fbd8715f907ee8f873b2ffbc37b931ef7c5a8edc3f7b15a93e335907b714767195b33a6175fe4b52a07beead21d7eaab7ab83b65f1f2cc4404a5da5ab523cd27c96bbdbdbc9c48305df39b2a0bdcdd570226d48a396f4aa5f841363dabe95e594e0edea6d8f85b94eba33c6d0de14212448f2869fb721a94da3b76aba28820bb59d894b8da68cb96c740e5a9fe6de8913e549256ba940166bc449677e74eb0c8564aa484e2a6f639f1a5d2773698931acc989ee4ee1deac62474c2d46ced0dbf4b0d64255c56cd3114ed4a1403ccbbbde5c79eb139bf5a1ebdd496098787335f9d5ea28e5c739bbf09458b5e7d55e908a28eae2192f4d961b4cece76f38e3920bd50e7c25e7e82b7eb0d49d1779175f91a2f344ba9d1d297704af7d0b8d6de1bdd5593dc3d06b1f28ec59472633549f74333fa97b66eede6499424d7b73996929f69611e7d52ed832e66db650afa412a3139a4dde6a833dfa88aa69e29e37a23865d91b72cbed8be5d3276e3f93ce81262e0ebb5adb843ca3f447d1ed4b664b9c5b46e2cce856d91daeb694a03182bbc665e5a0d87230a90f9bddec30f3175110cf7c458e5259a35492ea30e56257b566ad63ccd36ed785c86d932da938d7ed7edbad64334d76b3f5246df67347459b05ff26d2b627d7eb5d5a9bfe3ebeb2e174d517ca8df22e364f5ff030bba4f1b6d6776ba63aa91764335b272b85f74f69b06e65333c5c6977abd73d4f678e19b0eacd41bdfad85cbd25e76fb44cd1bccd0cf1af67eac2a2489bcf6c81ad915c592f661bc6f684d3db856167a24607287254d3625f13eb65278ae6dc2996b3804c4a6f577a19d21eeb8951454ae784f6e542a47d90e1c244a0c34b9a5ab19567c7655a6b164137cbe379c7b7c94a4dbb23cf87d3551e9c8ff2e49acab15baacbe0cddcdecc708534eba5b9deec9537a3c26e2edd1f91d239127b22f129ff760a3759d8339386d0d7281ef69de61599b73096743ad1ec5957e8b8c033456ea075d999d58c9c677c3a1767491a22f355b6c3b9feb260ecc8cd4adf5f694b52de71d6c4ea7a79294c8e9a594d365abed54f3e11093de64e7c32d13c45d032d6a655a6eea46b88eec47c199a1dc6a025bd4ba6611644b3451b5f534d2491449183ebe2ad11ae727f10f3c86a308bc679344377e1628304a7bab0e3b23cccabdc7b53e50d42356d4e1df7a7459a4ce7adb1136f7c195c8e1b5ac2a75977889bfc8a37fbcbe2ed2ab8f5d5bd9a21ee6956b7b4abf932e36b4da8749e2fa8ccb60f7c49b9a83b316ee7c6f28ed8643f25f409dd32f82cde4ef6f291da4ecd9b3c2f6e56788d0f81452ed6867694b5e3c24f5767d254e3fc7c8b59ccbdbd213baac4cbb5e149a1836dcf421c2da748d6321d56f737fbd4ef8f845e87e1d9bbf45c7bcda7ec292bdd7a812f980abd529dcd2e973e47a49b40589ac164532d93e904774cf6b28e281e632367baddfafe74b19a4afb4dd506dc69afe1a64b96a8b927a6da12b333fa36656446586c0954267d159b16bb5a448a3a3e33d7d3daaab6ebac9961f1dbb50a82d514d951677277d92f2e318f50d896902a69966dedd25cb8b33e688b025792dba9c0986b4ed4ebe5190935f9b4941dd69ee93de5b50b423e1cb7f62dab26f3701e4cccae5c578a20b7c720d0a95c5c225b6739d96b3b5ce227593861cb53810ad966b7d82ad7896021e135abc248c3a3094624d9728558deadee6616499da754ec57c1766344f4c5630e5a3b0be37645c58a622d5812ed344fa05b519a4e589bb9840c8933d66ced16b7b340fb8b2539d94c027c458a5747a385e922d5facda635703cf5daeb0277630377137f575fd3049b5daf15372dd06ee7866c9648f3a592c78910fb44cca27cbc4666b7e59a2bf717bde2b7f5613559355b64d2129b8c9737b7db7565358793209f885bacb7f5b42f16373520767eba08cfc96eb29eb1e2a5d79979d0c91ae6daaa2004f2cc9b5e27e27eadcfaaf0642e1b6dbd78ebc4b01677d3e270bc56c56e3a0d15835d4caaa097d61306dd26aef716c66fb42588297798e8dca9206945b1f7dd85bbed4ef6a459cdafe60669b74c7fe2dce9d48b0fed8a8c2e9d37f5b72c5d088c7e4c96d9deb5c5e5e5c4aff8edea168a6a9b39dc392dfa535895f3beb31a879342a5da395a5dd6f52da1c9b65bba7d746bd94ba7deac503f77152745edfe3a77d8dbc59ac9e1a9db2ff9aa993bda4ab689cb7a66a5e6f910f7db9c90aeb4bf337616c321a1c75605d79d67ad7328b489b128a689bf51cf0b14995458713b2056a4cd03bd59ebc58da0b6827e128fde2e3eed0f2bc13ef8ec248927875945a68bed96481426b2c8528f48cb4dc8dd3ab52e651c635451b2b4820af25951eddd1b6eed51c6662c7a9e4fe2ea44aa142d78cd7aaaed82a0db9d9237f72d69f48ecc730b0ff5dd9420fcc25a2fd22ebaea6753ca2a8be90f97556fdb45119a29a1e1f164852d9d89535117333fba14ddc6fd029dd4a835df39a1e25cb9e076d4def84b713b2942e99abb0b1a4f0f1bd4773a7ddb9e9d86c58e939370595f4c75b2b226333c6ff7dbea70e894c23e1c9985ce4c09cd220fb724b022ca3e234e3997d6736952cc0fcac268ecc63f485cb0f4f13692d6bac8bd4d6be11a4db5c1764b19a152b72d4f51f49cfd9eed36ffd3b69b39e6fbbebfefd278d4bb125eb7363b9a2aec4943258cbd508fe9d9ce38d36193b5aae544edefe9b3af07a7bcc330ccbe1ad3d4980793ed7a25a50dcd9e1d4fc0ec65bbe890c4751d07f7b0c5e9ba581ce1bbe488c96453c5b4ddaea7d4f5a8f8a7b4758333a75a768dbc319cb208de385e4513bf8f189423af87f42cf1672bc8bcac3c97d87ae1ee4fa889f094eba46f02be5266bcc761e422e07a3b109d8cca3caf468a6abfb56f5e77100ad2f7236f1f9fe7b46d603d2a6f983edc2e17c5168d398c9415bdf215bd16093c324e8aea4dc5a2c819fe66f6bdb8d95d3c8b64b6ad2b26c989da2241512dcdf59a63432ede5dd3747dae558f4ef59b34c1fdeaccecdb0a5f31a27a8b221967925e27a2857c4d2f875b73bd4d8ca9765da7fcbc16bb3ee65c3a9125e12430c9b6d035cb28d741b82ec9796718e1b1168f2b791ba529be6269abe3f86b972e115cdaf308c3705bdd9e2ff672de95157f0bdafdf1ba5a6d6fe17656e3c83ca38bb0783b6e36b34bb5cff33cbd6c67496a72e9a5d7dac53e166b36efa395892f0ec829975cafc9fa6d2267fb355a60c271c5f2f39b5734296e315a92bb9c222fda2e32c9aeeb3647716d6d66deb5f7a8c648cd0cf7b75559d90befc8567b9173e82a25ce3c61d99995608d6c399a838712e99a6f7dc826f38a6088889a46eb86b1e621e36cd5ab755cb6a2790e0acf275361b5e598b36d5bd79512edcb604e655d2e695939df0424a9c4a2631c34abb6b05dadd5d7b92ecc8d1395eb7bf36ac79191a0b4e121715b6dd999bd74277b29cf48119f75cc469c516e52c6514de007f44475c4599f259b76efb4bb553fd727ee4424e97c7969afdb6817cae191d49c8cbe66b1bd20e26bb4addc80bc2eb2ee824dc3a972ebf874bbbf50fab56a55b1a978ee263954c0bde1867c5ec8515faeabfdc472f79c56f01ed2bf69db394d4bb7ec8d8e64873e16abd0d9b30d619cf26bd9ef77b9cb6be43edaabe2168be4422a2e212f75c73acca6d7593c5fe8153a711322bbcc4d6bbf12369bc57a37df31943aa9f65b0cdf9827ac0bb07e53cca7d42053662b2451c91096b07d339f58fc47644a589207ef9f787765e3718ad14b342b066f6cacb153568aa2bd929c45563256b745ae27a581a9c5c549ce4925d59bdb86f4b57a33459a9d942c96d4dbac769713ea7a640cc7db9dd4056e156ffbc6a86cf29c61536a9531b75eb4193a5a4fe6733131a258b96a5976ba2ee4fdda3ded5b0ee9d03a0af7fbd6168fda797d694249d5761896c969511fd9539bce5203cbc8534812019622132eccd48e63b5d33a649d353a8991044725524eb742a3d6b6a933adf4b678ab172b61521c112af54c6c591b17175737c76a9756f92d67778cf7769e26b7b60c76d9d2f59af06afa8754a6adc3e2ed7ce5d259ec26cb13d621d9ee96b1992ba28cd04e4d2e6c13b69f0933c99e69eb9d8011ae61960b7e3f4b88b9ed5b47262b50bd9821b7f82a29c7707e42ea99d72a9ba0f75767832aab6b8e4de7863a9fe9c6b5727da35513dee1977a5f2028922ca6799bef0487384e78b71763222667424ef06849627486444478c03474f946498db90fe435ddba3d7b0a4ad9bbb647d315cce26aedaf4abd0936b7c4719c89abe2fb492d17bb9374a083769e4d88aa8ee260ee5e6764cf5252372f8e8b2b0af9748148a76416d31445a1d4f76aba857f804f8dbda3209e8d027ebd788e84f8b675fbc67bc48a3c3c6df91b6b266772a52622237b74dfccce8d7c28cd4c6ed28b6931a995c6a1c4e9de9edc18e9bef35a37cbae5bf3d4d7478976972abd5ccfb49c51bb5c14235b0ea7bba9f07676dfaed3b370592d2fdccc63669ad138a873dd8841ab756bc67ceb32cdbbde94234a7515d6d455b2e4eaa37d63f47ce1aed52bab7437393dd575796ad379c6ac93a93d0f10844b4fbbd5663243c446df78baa3306b450ddeccf5f5e87aa1a672f21a4dd83460fc793a1566ee0a356eac5872abe33a5fb26f3e5794ed64ad195b3d0d50835c90d5b6d7dbc9f4da2f268515acf535439f51edbcc74b2ac659493893756fe70ee95e8c03bdad8de86d166ff99e5d09857f51ad64dbd6dba0f54cf5dcf9228b4c65797d8d4b7ca5ba93cd7283cc96e6ed782830855f48375c262ef3d3b4b79149cf22b8816fa5eb565bad4aad3ea90bbfbc92e764d3d4537db2499747473dbc893b92f2f5a3cfec16cb936f077bcf3748f7fc76245744e4f2cc3cf1ede561ade8d7a09b8a6dbb238ca49af2f3f8dadd3a9a09f6f84e908f289d62cbfa6886e4a65d76cd440e3a3fb6a7db3a9f6df42893ad4532d4671cf1e0d0d639e0d372e4539a4a54ea8b77a0bfbfbf9cca3f196e435e3aca592c7bd24d8297515aa654d1a41e3c4f51a24acb75845c0f70b616ac697ece4185ef6c51344ba365b3d86a29a9a8262169b965580ca168c557f38ecfc68f59769fe66536f48779ef674bd52f2cc34158606d34f55e1b2d3e1ee73f9fd7945229ca302d53d551c9c8dd47adb46f2fbb88e78eae23355fe3e113bcd52778d7edcfe06d829e405cfb9484657e5ff3f4549ffde57e0c59a368a3067f11e01fe5b3ed0dc9fd87fbb9e7033beff9c0214f9ee48aee039c2ec24a6b3c47f9164ee9cf20bc0118a00cfc1edee44f53281be6530ef3f7e6d23ecd45cd563fcd87fede9cdea729d9e5cfe77ccab11ecfe1ea255f5b91dde9c66380dde3523545ad36af73cb2a5d529befd4f033014622f03ddd0eadb876d199b8968495568477bfe9bebfeb8bce4217ec3665c19f5b73455154ff817e0865b4d277f6a7f156e93a561bb1da39c28836c0b8dc73c47ca3ff6afd95cca3cb35a38a1425c05a19e3d3fa3e22ff99f54dbcb845bc757ab1ff50c0db09a13a16e2f35617f145e63adaf9d7b8a2578aabef42205479d7a528f0cb475c85db3f01eba8d3ef676df3d2db2111049c3d82755619f877fde1bc9f2896e32fdfb03790efaf49f85c4093971d4531a270a1a835f569cd8df01d1b0729ba10d79280bffe013f32acd49fb32960051e01fc587cc6f1acfd0e8e0d9eacbca7fa852fcf1fcd5dc2051a31178aeaaf314531cb4fe72fd367df397f0adc73715f5f8267f0d76b5fcf37a45c009d138133be9a7d5a5bbbd5df595b751dad561de5e6d9681af0562fb1d7b38b71adc617b748901ab7b25ede1ffa253c62b45c13cb297da1283c9e511473f9044f905dfe29787eb9aed0322e83d7d0b0bee414b5723fad4b23ea77d6fdd286d679aef3fe98efe694412650d632b14451d4ed13df59cab7e4a075872757ce41e9351e6ef5aef3fc1ee9afcfda64b3cfb61e0bf44ecb5e284a8e3f9e356e63a8df386be88307b93d6f65d15772edd73a2ea23efeb72aec6fd7117d2de72f1ec7615320e739f00f35fd845fd7fbfe1a0897425d672bc81ffb485fe3dbefc2583bcc588a5a6d81a0d13fc953e1627f07df83ff46bb958284259745dc8bddf42196a99c83ca2bfe582faf1681e19b16948321f325be34ebed5ff39ef3aff1b533d2b782bdd014c52c80e6532e9ff065bbff6c9df7b7f1427d7867e4901bf0ca4751fa57bd67f94b79f5f1dd6e6cfe495e4dcaf0af7a97db2fdee3f4359d3ebe774afdc4d7fcdeff8e9df0eb7a7cda03b4cac7d87cb5f9254c0bda98e324d4e7b02451ff24dbf83888ff1defbefa1abed9da58683decd777067ac8a23ef1361afe79f856aea314ba4ddc3c9bb8f98ed644a56500fd1c94d1973dfbbee4bf8f3d8a614f9557feab1df34ff39ffe9d5af2afcfe83af68fe712fe990bf7f79abd9c513b21ff7c1f18b4097105e0ee0e231d96d137e06316c80ae30ff01d2221804ffe049f73f8ebfad4e41cee3a52f175ffb4aff951bfac6d6e89007e846758fb7c86a3f8cf9fe15ff68bfc92f7a8435c446b13d8ac8dbaa128f6b3ad8603d7e85fda73ee6b9c7107d5457017fc59027ffab3dc138af4afebb1399edbf097307dec95a27fd699ebf4afa3e33f2e4b7627c49ced5a404ff8cfc71682b24a5fea6ff93fbfa4e73f4247e3763b2021b079561694719ffddc30ffbe5df6339c5941f99d77fafc84ae1f7218954ffa82db177f9ad77e29c344711f51f38b4b5142ad7e690739ebe21fb0d9e19a1efb2acb7e6d0751a468ee9ce14f93a256f527de39cfbfe52f42de19f19f7fe0a1dd776cd38f7733fa277a0893e3f7cfd93f7d67f8259ed624363fae2570bca418c8ccf0139ea632fb7d3c7d15cffa1e6c1c3dd85d678a5952742252d4ee30fab9ffe7fffcf8ed47e31ff7d5e9c7effff7c72e8f7ffcfee3c76f3f14bfdc83dffef77f7ffb9157fe293defff1eedcfd3bcfa5b5374715afdedadabc2dfa7a77dd914fe69df4edbe698567150d7a769723a35d3bf97e76a7a39fa4db33f4e4bffbcaffe36fef5f7e65837fbe329ddb760cdb47aabc1ffa3fdc94f0bf85135acfed3a77efbd1a6b7fd8fdf3174f9db8fb28ef63f7e9f6108fcf57f4e297c164330f46f28fa37143150f2777cf63b3afb3bb64490c57c399fff0d217e47901fbffd48dbff89d2e38fdfdffca2ddfff6a3ede1f2abfdf9c7eff3198112bffd10abfac7ef28369fa108b95cfcf64329d22afff13bfadb8f0d5c17c7d1e5f2b71f661afdf81d4510f4b71ffcfbafcefffc4fe347c88fdf91df7e68119815f9ed87fe0e3a5de4c346660839077fd661defef87df9db0fea949600147d1ffef81d9de373824496c4ecb71f4a0b3e21c9058a2fd1f9ec7f7ffbb1f9f5d0c7a6fff7b71fccf7873afff33f5dd5b5fbe8c7efff3fe437e437e4ffffbf801792fd11620820edc734a9cbfd34db57795ab5d34b7dccdbc60ff7d3309d8e3cf3b72a8d9353d1ff2d4cfff6ca3a1f38691ad521a0ab5836f5f1b4f34fc90b1f8edfaeea70f8d8f08ff1fe34fcaed5f5f8dbc63f85c98fdfabae287efba19ffc62ffa02cfc4bdbfb6d5d0d63f99a4b0bc080c3e861ddc79fab7df3f8ddd8b7a70fa3c1471f9ed8d45107d6fbbf3f46e07f7e6a20a469f5e3f7d3b1dbfff6d7e312ee6e53477f3185e2faef651dc1c9adfdb14d2126d1bfa37328241ab8ebbb04f9e5e6479afe69d9f1bfbffd88fc93ffe3f71fde8778a7e548edce4e9048a06fdb74097cc34bd013a3dc27eeb2b61bf4c2a01b3729f9b5ce7ce80d747c7e799333b7dbbccbecd3fdee6ed3cf3039db9cdcb2e8e4aa6942aa79e8987f12a626e8c95fdc112e2f726676cae34e117dd76906d529fa0c93cb2609e3fa5f26e735965a6dd8bf97d1af65f9fbb087f046b07f93f446486249ce89bf527a43d8ff2bbeff2bbeff2bbe7f2512de45b4d8d37c6413d990d24b5feea63613378e675fb300430b51d0cea2509c23478c83d2c245d643835281225d14e83ec09ac2c5d584891bd3e78b9b282849e0d0ada7bfcf27f2ca39a8b4c4b7899bc8b3317cbd16762d44fe692e5e4a80cb21f2642772ca6568154eaf029e443de609ceac8edda7e7c29e18c63cc1a53af42518ae91a1bb120d573099eb28c59a296299a1719f2f329fa17bcfd1d0b0246ea2a0d59e4ea35084974a1262661c606e1cf14921f2c00d65e310b8809895cb71bd16fb4d6cf064e6da97d87392c2c50735c7c48de2daa7421414342c4df07c123174ac971ce6ead475a3d386c69e6211e08a7fbf8af598d99a2900ae15c4752444149422acbc224ce936c01430861005090d523a9653f21495042e0a773ca1698091c8b692d0a0a43aa6807bc9eeaeec7dceb0a7eb48d02e4f732741a9c6ae632101506f0067f6b5ddeb34ee3a5ae6f3d64de4bd7398d299cf739d8781bfc952149473e448d9b08656c8712379297d0b70ab77313376313207df3d9e19703bfe6dc61156b40143a7238f5c5c3b4a22deca075e037b209aa00ce310b37ae03ac9292d450c9d0482721679f2e2413ed20ab7b22a0f837c7209700911790addac28d4a59a5bd0d3c9fb18ab1779250952b86612091a34273c866ebc94ee3cdbca3d5b05b433839eee237b1647bc758b844d1c401a439cc0cf5d66760e1caf8b7a1af11c057101ddd24d2672708fb157599d8b51b18a5c25266ea488896ea220152e74a5adce7bec5329005f6885b5555152d7cc4832514db76d2af66c02f31de91c946811546a1c955cefdb5c1af02680317679fae6f316c0e1cdc5a52614d4b5d8035ea65bd7560a51989de5129ca7a4777b3addeb340168230a4aedd9d75614a44ce4bd26e0cdd7e778edec62a7224c0960e21c022ce93c9e2c44216a223e8ef736898629dd7b76d484b8d6efd5a6d80bf439acd4cffb30d03cc094a3e7889d6f2fcf7e49d641a99d3db5295c2c398b8cf48f3fab8bf12e9bc56fe9b2734beee60b52c69474ec52f03c66222ba1be7dcd7d9ba81ef2887f5c3bc46e653501afdd449eeb44965ce93add043657793a5d06b8389ef5773902ceb9cbd371882545c05fe210537adfa111a6046336e37c6a2c3b6e2c32d4573f99c80f30893c30f900eda8815f7a5a8f6ca2fb19ac616575614f233e6f0e3cd53fc901bee8801c7531b28b78ae094aab672aeb06e61acfda7d5f59585ac3d9e2b934c0bde28ff604d67dc5a95684fcf5bcb78bcebbd46b8b4f9ab07f962d5103e6b9e3027ec68fcfe84ff0e35016c7be4d2001785eb06e3024f207f078bc7509789210191413994decda5770b691b02ce0b90e7b3a8deca2f5a827dc3eeb28bee8a292bceb823593437936c0e52483ae7236b15b5a6d8087ad28d0ad6773374f87b2e2163952f1745ee1732e67e9064f3d9fcb38e29703ff08d23972b462909383de7cda3f38bf5e809bb18759c848ab3ec02d04acb7077c885ddb008fa0fc73efe1372063004d1ee757c9c2b2b844545302bd08f6e8954b8847266eb601ae15e3dc986b5f514fa7cf5e4a1dd6c5005b78ab0feb942ec3923c8de3c0e797c851dbbb5c92ee7be497b1ef683751f09240b020ff382869ea16fde6dcea359317c33e81ee04b29f3f752ec493d58d9f67ae3d03b21c79e8d812f04b3eff852c3b06297df31c09f307b95440beb0a5425c5dcb279ba5736db4d88d7a2cc49273d43ff009d6597b4e32e806b09f1592aff95337eabf06e82a8fb7e0ba6e69c61293a4c046084aeee4e9546e7211bbd6a913909d01938ff8ad33a0fb5dd4d20dea67bcabc03d42b9906a96995fcecf368898d2219352b16cc6b19843db08c8f993251417cf6810cf4910190732b9e81e636d351653b58eb0e4ecda68b3d6c51778744e334dbe287e8653cf56eaa0a7528949709f2793c0ce1b31a597220fdc5feae7b03ecb2c560167a38b1c6ab055f8e1ef91ae39d023015e00bdfa4c23a0375f69fde05bad08780bf1d4618d7f953b5c9eabcb1f4435c188bb138c22c8027978c124feaff782975f79c1d81cfd27bce011f89fb8c1d8ecbf7ef07ffde0ff2ffbc1f0a43fbbc0ec19460671a566d24d2cebc8e95ffea3d699c85e1b17b33ae8f242f3028a507a8c38c6264696911025c085d44a120d4ae08202714ad5aaa5f06b9d069f0117ee1c94d08c0766cd29c0a56274b781ba44239eec45febe9619bb76d47bb675f26c0209fb592c724ae18d669a9193a66e2adc936b90fb0e7cb34f0acc060fb8cd8e5603587d67134718d9fbfd603abbb696fbd0c4229280a19ba0f4ce61890e3003152548858771bdc743772d0b709a00269c2fa87180479de748379f2f2e724ac51630a358ced052ba05ea3fa8946230858189fc800d98910430a5229bc83d6734dfd97b6498dedc9f9519da86f303737025761b86aac158406f317fe0265d1b2d7471441e4df63add05b81a4740058efbf5caa2f574ba18b2f4d4d807ee20469e42805f9bc83c40d7d1551a6079ccdd890c0dcdbec0e60891275368b6a7c04555cea190bf871ad8275a39ea5abcd4197425f8f728758447b85cdef749c00879c01719708b3d677336d862a59984a1e9482f67d430076775016fdd42e8ee71a8ef48809ec0e44c4201e23971cb6b21f2d7241a7829f170a9f06c753001814b8c4b4d04e97701f8bf0598874480a6fa273eb9f3e6c05777d8741ab80e1fc7021321813cc248b4d9d392d98bb19a73866e6d5a918b248b4d7696a5c616c2e966ce6d2db6e0cc9ede9929bd321082d52d4d3210c210599217596e6bc3f375928c5c6d45de6a005ec39406ee66ef39ca4d8467a28074036ebfc8d086679b9ff0ef95640fcf25a4ab72f16ca5f1ca2203380aca0875eda810f9e81c95561f0ce12a60369d7c47b90da1a9c12c0df8e2e43be3f9ad3600773fc1cf6c2df6d4bf5efee8c8099a8dccbf41d6e908d8ef90919fd246c4737dc4d056c8d00c0c313d9bfd904fa52274ac262cad5c64adad95d298eb48b7edafe0558733a2e79cad5aa46820282732c810ba19dc3e78be5c9d5e6b6c1bfb3c791a78561cd6bc6787955cfbbce62ff401a0532cb248ef20c9ce30cd58d607f77c3479cf5e4a0fb73f9958853ddd049582b8f6b505e7e9657d380f4a5bb9b5751052b538b0260d338602db4280dc12053a0971059c1520f320cf0ce144da36741a1f5cadf7b09931dc480d733354ece94425a7f0d9dcb325d47ba74713094a11f06e2b0ad6cd1bf1087f063750512d8f330a7267729ab1d351d7e3ad34b2c358b6923eb289832744976da5f5ae4ddc429eeca3159a471c791bc2376a7b0fe1ed9cbc0d71eb16f256e7ad5042e6b9dc13a422c437e476455d36d4b0b66172b666126f2672924c8ed4d59e3a89bcd7ba7608e590c71737d796801c86553330e4015c6d7eb89d0bcb514e3b9b7fe3596a1a2fa5039141e72223e69ff720c68e4e2da02cb1676be0cef9b61bdb3d75f252eaec395a76bf5d04f03f8f1de8318b65cc42dc7ebc51aca40ccce195f9c7b9528985fc7896cbc77ca9c821f1b61f5c72305e64a80ec0a9b3a4a2e9cb6eb8c1247ab717d7224397be5aaf87b937b1816ee210a70b172b4adf06bf5b17486766168b8c86b98e183b188a86b8f626f252710f93043d5d005b01ea654182218830a54bd7be4239e7e245156145b7b3bd241094627b6972d79170df9e915ec9b521662e98126d8232c2ef6398312c2f96407e7227cfa652912fe09e54b4102ca4d8aed33c7ecced687d649bf1f6d6827d29ba4908565f37223fce3b7cbfd85eea5864b524aca22648c1f7e3ef198a8495558c38033af4e6e9d43972945ec6ae8d5b5a33cfde9c7d70162db286d7257c518a3c87b976d10e7c7a89031ce041c27d604bf05e02c3652597f9d086a1ce065fa461c9f57b9d5cbb8e97c848720e6c73a4fd263631ab78d6ff1e6f619e7d85194732bc59be1672a99c039d6c7d5bea5d4722003fb93d797575f2ea1aec55b95167072b3a8fb766729920817d19e607f0726d2c3b3570ffd7aae5d1a34c037cf3810fdf796dcf50a90cce730ad72cf6bc95c958934425f736c83731768c16ead420aedf43a2bc351bf8877e5e8b14cb5fe3d565c4070c1ee021f51b73a6e4e6810f04c0c69ef501b6f7b9ca7cc483d78c745e6c2f4d11625cf6f15cbfe897948ec4d5d3fe1e7814ef67b5023676802d4f6169dd438aafcf7cd0593b9b3e40fadb63b512905f76d37b3a3ae080aa07384baff924730ce96d38cfe247f9910d217ee51c081eb0ef9aa03cdd807e9456d4688f029f8105764a37f0e4a8bbd2e826f2775ea455330f4931552f625c0ff3f2c4681fc29030f403c05e5d984d6fc6215e9ce09cf8063c8ffb3cb49f01cc3580d9e424e18e478f5f8e74b8de7636dd863d750a7815f0245837857b67a801c61b1a7b4e720981bce3af3731a5e6221376eb149988dca596d3265ceb6a757f06f0ecd3f82628db545cd5b1d42fbb751ac63b2083790b9331020df8cb279e0770ee74311ff033f20e6f0119f5618c04f4533f860f5389a375ad9762b9d75adf268ee248f381e7e83cc08882019f090a90d539787667d39708d362f8f9bb7d41babcd684259104b6f98e136609af28065aa0898f99b1efa8b157596d20e471e85849c003b96de580b71f3c62a0b18b41dc2a9be2cecf5429a54f6bf34a0e681462403700df4e4ce1f9e8e9e1fa861baf1b78a417790e1199f7b906fe0476150cb5aff67604e43ab0c5bb10b780bf70711dad06f631f06f816f61998464338087a493eba8b15b5ae5e0cb72ddded1ea61ade2067ce508f83db6ba0674957885f07020b79f791ef258f7c5b928a591062fb8c08b2ae439c467a893ec589defc4afb829a997393fc901c62d07d9f12a7f5c081b9d007f50d65134288bd9a7e73fccad2257da441555b534f1c3dc2b83e50c13a5698b8d3fce0df109ece3c8261a209b2556d9a89662982c67ea8c147fa08902f019f59718f81dc31507982bb9893cf4e7806f6a1979e1c2eb5f604b30743a54f498b16b130438f3c0d68471009e44e1752a056412950776d17978f86273009d1140fbe4c1d3d02e91527738434fbc2e9654fd893fb3360e85285fdb54fa3a5f435b39f7258d5f64ab2ec5eb91a75ff0ff3cef1772f523ad9ff704f59309749582463cbc0622c5f2915a0065b98b0df0def5268499877af25e113af8dd23ad458605e35217e834418c1d46cc3faf638583cc8bc23577da8b1c727098bc721931dee9541a94cb2f74f706c8e6c41be45fbdd17348bba02491577b854ec29ebe45b05297eb47ffdc08b06b1296c54d5cb11779c42f9c0f6686b7a42b44b56f2b35bceab60779f72c7fed9e4a447ef0c1a15c797f7690c5e8a5b6d159ece8407647b1b84262b124ce1f71feb05918ed6e2f7eb46d873521cea0ee0234c97d478257452277f912ff0e23c5e28b9df2790ce021c097ef3401f3435a8cb2538d658b8e473b287b9f8f2ea0fdfa09be4fbcd37b3637ea1960cfd3a1986a908fb431c504d2c8baa42ff6d0dd86f9d3fb1e7816da48c6b38e85cf89d0bebdf31d33033c0763a712463dd67f3d73cf7832d377fa7d69afbdd861604fd007293fdba72a82b23fb5bfecd9673b96f96c773ddbb1af32843c84a5790eb178b03f3fdb53c31e7a5a527304f8f630a61060b358350b17fad10ef093a04f5c79cf71816af31e538271c4773a8497070d1e7b04f87bc6a78c015b90bcf90c09e9f4b0275eece15f3d2f3541fae1d9c11679e2cfe7e7a538c292c6c5e281af46d9fb9136a2fe82c79561aa9f7ccefbf5a3e6487d808b73f105e7302e08e3ad1e6f95be4d141e4367012ef59ead20819077624a4da40cfaa763fa88188b5c54c0b49e923847cc039f85c83cf3c9fb737bbe40c415fb53be7ad64b5fc16e61dc10e7bbd5afb126deeaa2b2e8038c80717551f080ac1ce3a9c54de4217c37cf513b316ea07f3dea79c740a58dc6296f06cb5946ae889a259230dbb854804d5abb8e75932bbaf59c040dfbb10a098fce6179cdc39e685dc7ea80ee0d5362f3f81da6a7d14858729807abbe36d02e85b8c425421414e0d76691006db1310d80ee034c2942fc11d707b2a37071ed1c56f9107b817115850871ad0874309e449814c65bfa10d2ee798d210e2e972816a4f42db2a597f980ee7131b20bb122f78658f453baa004fdfce7f9806e0e4aed6d8c55bcb92577f36cad09d3b81185f6250eb207326bc5023a02ba3fe9863bef48b02bc69d2e216f65beed35f758b70768cc8db196828429010016f15def219123758097eef11291a11fe3c0b9db401f93c63ffefdee0389798401f8c5583410e08b5423dfe5c1e5554679e06c0911b4c1e59e3845e5ec4b99f4c049860c73bfcbf514e85bff527fd01723ad015fe356e731830fa7e712a75ad469bbca6f4a4fd540b69918d9ba8ed4843d75dd30a411f25ceff6f96b0c01a628680bb876857c193f80df650fff03e247ee67dddd0ebbdb0ccf307a30a5882c4501f0fd2909e17d98faee433d9d5149383de8f0a68beb37159e852cc088cc75b422283904a6fbd8d776f085c794469e1df85b6dee63df801ef69c4dbdd6e9c5a738dbc05faffb037cc42f87340d418c6567134be8b5937aaa129930de31c3736bfd1e676b48266e18d5523807d12433437fce7b8c98af051af7983c75a9571b55cd3943b34856b7c40f303d64dee261fff79bffc40fa001b717b422a814188f07e70cd020c0c3afd24ff3008fba802793f1be10c6bc3f575a100717a65749e740bfc7b4d10cde6d965c0b64d398ae9604fcf51c01d9e628d06f1952fd8618a9283c2a30a12f1a0ad2d92f817cdcdcd377816caa7d5b6a2286ce7c40e721ed14f849a96f130990691ecf212ebcc3f98fe0387bd76922385bef7c952ebbc0f15e2a4d7f82cb2f787ad4f1a9a65839e138a8c799b9b43311330536fa18dbfdc2461fcf42ee9d23707e1928b79e2b283f57c7944d12a6e2bb1d583ec558fe341cca39b2af79904608bc432ed551373d579c7eeabed7f925d7cbcc277e6c2286eae47436dab45007bcc8ecc137456da388deccdc520dd4d20de6ab9828b0b9252b2c2fe4fbde24ce6449988ae5dbcbf3afba036e98192a67ee17f444c62aa481ae77fdf7e287f04d1216561fac90d4173424143673b9277bcfa11ff7079fee9987757a192bce32ae254077f8fa17b4bc8d954e9f613e8d3043dcbedaa1542c423ff25a886cc19b3724dde9e2e06732f4d173f2382ab936b2cd85c86be7f77d8cf702a906c6c03b0191495eaabcd6fa0b9ec7b4487121f2c0c6e48ee2aa5d3cf1cccdb53723df69e7a03407d9cd4ab489586f1a5be8a31efe353fbf746ddcdc6930ca6e31372c6f6ba1a4ad591263a00a27a614290ac39dc5177c72b75dd80fbc08edb76d4a015f0beef50b9cdebb50ad5d67b07d804df2a437cedf3d0be293fff488bd659f607dcca3975c6ff21ce2af3ec6d91eb12bdcb70970be6ed0267a74ec02bc09c7a4cf36c1130edf539019141385a8f21cf50f63b9ff3cfeef770fa31f33d820718445c5280bde750bfc4c7c5ef3211fbeb87319cfbc656896b455cd31a6285c979fc7d0779f81fd322ef2b8bb1d7031c40e20cfa72283ee7e86dfe7e73fddad8cf484e9ca0c7282728241d110b3fa9dfe05ecef632eaea3dc807de9ad903bae55d5520c0b21758d19e20a50fe30622c9b4b680f7ee29b9fe0d1b3af9f79801fd26effdd3ce0c2f4e0571e183efb0ff2c0880bd9fe295e3ff247f90d3ec822205f18e414394a11a6d41d7f968958ba91738a66d45fd1fa34d8e69fe590987ee003dbfd88b32fef5bfe3a1a726d30c8d1d4b595e3908b37de6db0f0ce70cc3b20f1a0bc9e5d5b7d3d2f4fb1b77bfc4c85dd3136e41fd960439e06e1dc69a33dd6d0467bec3d4e73f785b492ec45f67ee77189431cf8d94afd88df03f8b908f8cad0def54ab20f6c0ef8d405f8dd83654c43d9c918e3cc5ee292bf94ebcf31c6a193c5cea6b3bd1d3dee1fdee5fb3b0cf718e68897873c175fef5d5f7d5efd11775cc19847ff93fbe4175e606379b81ffb3378cffe78bd17581f769e955bba9a9386a68bf14ea761eec0573ef0c79f3b2f8a0c12ab309fb06807fe1b74f07b17cbd76eb1437cf2d90efdf8f341e63cfff434ec4ce4dbd7777f68e4f7a1bbcbe627f0c61fe3a5a96fcf8658a9bd49c5476c7ce00f31cd3fcdf37a66bea0fbafedac8fdd5d9feca1f70e2bbf948dc34f2672ef39536399e7337ebfdeff3feb877c9ae71e2ba04ecf707c4b2630b34e4e7f06dfeb797afaa93fc43987bc677857c102f99f850cf5f1acfc013c90f787dc3594d60da4e15474387b80767f4cfb277d3ec694ff63be73ba89b57b9c89b766116f752136e62eff8762264cf9b827b9e7e1a9664eae355331a1ed6e6a929921f91eb9e70fc27303ecf9b9fc6adfa76f6af38febcb91477f45631857ca5ff2174931556b17233b17e310071b636ccf79719cb4d3736b65b10f78effec7212a910e3ceb954525a6f9fbdac3dce99779058282fb432ee93daf00097ada79f8155fdc618795d58d39bbf04cc1d809a365e39c7f512ec1d73ecefb3c52fc4fdd657f4fe7bedc69409dfb7e3ff69c4bf0e11efe296fe09b3edb4bcec2877c865fd0fcc3ba3fe7b16feef7e767247dca7f801d81bdc6e3cdd8d5a91496df975a12965ab32fad5c4c69dc7586fb8eb0b490b02c8aa8bce7862b1b5da793b08c6049bbeba843293b05f3fecf61d982bf119fa1d300d7ea673b6c288b25ce418a3ef1e5fdfe77e8dafa7e8e1445e3c88d6e129c8370ba86425bf2bebf958110bc6e86b1c452e91732626598da9bc1165bcd2269338f0c266e1c33e75493b57407b9d29649ac74d6d27736d97bfd53979b21b6d33dc504bfeca4cec40dbc6b7be447988aa23162ec40bb4e7bc91916399867781a3bc68d34fc962cf8e358c4581a29a6287b871de61e1a4026def3492c12f818b2a9ddbbfa9c22fb8af8267af604abf5ac7b0b0b8d7dba9f2225e1f4737e82771b705ff91e8d74d5a255cd929eeef024f2090f0f7a89a94689ffc2ae3fe5b9bafc3dfca3a63f8f51f772c7f91cf9077bfea0c8624e12d83f5bed48fe753d7f06d87f52ec88ceffda62c771dbdf29767c1ffadf62c7ff163bfe478b1de1597f2f7854398933f47f5361444eeb9a89bc17388d17ec1f0af58ca742321e5e4403056f939dc824b489b88d28c0be29bdc8939da73694995bca50c4850e098918d9dd5bcd05b81807ef056763111b6caf7f93536a48a61f1270b606aa492a62de2f7ec77935d8db64289eb4f2a782be26ec693cc0a5e3d81327f178ad79140ec11e0c43b005f6011af71e9656e53ad258a8a29c43a1e87d3baa238606ce6611564aed3b542732b4e9f366ac5a0aff5eb039f4ce79141fde61bcf764d25f0bc9d4b14dde53115b2b721e58035eba6ed2d945641230763df241fa5e7c2636dbb1a072480a87c911b0a7c33dc11b5eccf0d6ccc5ac4bc4c0cbcf2cc0d04bc01749502ac57dcfa311f4b1b82d163908f3091858012621b0bfc1d0c7e4b2873d2a3e150c261135ecf93e370c16bc5f56e1111e768ff680256cdbfa54340a8c2885330a85930db1db7c98cbb2891616040a4f4567bc44883c2caa685c6ce8ed11f01c3ef01b5785a5752fc402fbc7c3b240006d65ea4e1be5ec551a6c33fe9997463e1ef8ef51a03a24097d18cb939dc8730f3e1273ce10d9c210531a18c692d95f620b294c9d252d8ba11dd59274d5244cddb40c91257591557646ae49165bec8c62131b881bab26e1dde7d39162ab3197d8b30bc48767cb9a854341560cce906f43ba161ef3a148f89d368f9e390f5e7f2a140a78aef3702bf13033f63012f31c69083ac2fe5a63bb788c80bd783c866e7d1b6da2f1dc87973b2ebfc6971c8fdfff9b0a18effbfb77c84cf97ec6c7e09fc88dfdc038eb22b25232047b1ffd5f5ef8d92cad6b64173d90b39a49d83011addacc1f34ff270a24a19c78c0f49342c9bb9c7f38b6d449e4e16b8fc61e3cef057a1b5854f2dcf78c1e0ba7b4268c1f7b7f04342c56111dc45ae9ec329675984407758884919d3438fa4550de7bf024c510b4206130edbd7fdb88b7477f25ed1de6d1115173ce5491e4cd6439cb44cc9fad85bb7681dce5bfc89f8a3d2c66268fb05fd0185cf06c62e841f5610d03a54db3a74eb0a0b3e44e9ea31561b579f4957b6a04000bc144ce534421aa3d7bf61cb0189cb2c719182e87e532ece0f363cfb307fff005126256eba51758ccfe38ab98857c283c25652b190b44a9930d0b4a9b3cc2a9792448495029b08fceced6100757609fb088b9c21e3d9e23927bfd7a8b1ce502f6be73f2d6b5b53c2cad5b7843669b1575f9888bbfa2c0f3df6acb3c78532a3c0ce82dae0d98614f63a2d8a8f7a84a65c2b139002cfaba3b828c6a692b9d233915497650e633d13948c3b53a06da02cc2b5fe82300fbe23af4927aea0d16c1423e1267aaf17bc67ce0d7b38931f1f4fd1cb8550ee71b8af77f020fe09d073c45293262f1f16c68a6221a3d0c749322239d83547c0f129a5f9ed9e2813758184a15837c18fa650d8d08bc24e0ad0ed8435e4a0d45a9305849a592098357859852e44ea75231a56a8817461a13cc2df87f8d93242b378b61bc050351922e36ef34bb075a4c20e3e0e535382730d9ce561f7d9b9e2ec9c66613d0de843d02035c8dc5d4bae3ced0914275506925e962bc3390584c45a0e7808cb8f95871314b450dcbbb9d35268ddd8be40458283bc870e61207189179fad85c03c8448ccbf63ad5b92587883cd081906e433381e7b10c9105b6fa2e6fca0206af7d474100fd065c5be1a3c017252f61690ef3a6344cb6fbc37143414cb1e78b5bc4bcd3c4799c47e50dec472e9593c78880e7dbe08fc7adb79572f41d5a7751baf7d47aad02fe187446cbc40d94bd9a25e9062abda908c96a067279d0930372aeb805d8350134f56d02f160a1c3e5a9271bec5dd9071812873c790bb102ea08f07bf4683aa0dd6486c6bd7bef329b388fcd226e9ea30dfdf6a886023c37f481bc3c6c819d81903b9d362c96d32d86b655f32a692c67ea26b905e7636720b0400d16d8001c3fe9de2f7866e7230d2cb060e2a13fa23cfe5f64ad3e2cc97e9bbe144b8c853b63721d5f748f5e73afbd233b71352b37f7b9b8476fbb51b7c14bbfe7447ca0cf9b51fe02fb76e81bf929c11de01f1d6d11a0af8624fbe122f3532384618ef172d1b7895b0464e768ebc9e9f3b3b3f5888f22aca47318d7eb6d4e1ef57c28421d0b399b70388bcff8281c5e6a82e23a14d096d6ccd31fb86d82b240be8b57e06b8db2f70cfb44c2fe815cebdbaf09eeaf70bfce016495643ee315c8ccff77d361d4b580af4960fb693fe179266beef81e65ef906c39f4467cf40b1e92d5071bb315f9bc03fee178090bfcb02ce2c97ee81fc9bdf60f1eeca332c0aeb0e98f98c20be2547e5f0fd895efc91cbc82869534f45185c9ee5096be1623dccfe9789ee4b85ebfd8475f5d4ae8d6931e1d3e93d446d2527a6ba02fbae28b0b0933dd19482aa67415e00046abf358ad88782b8b58d8079905b63753c1660a9ccd5aab21411c2954442dc6cf9d118ef7ef5373bd1d0a2518d7510a8d2f7a262f7891b55cdd524c2087ac615cea0c09b9f73392dec78f494d6b175363399dad75d3057b816b49ba48ee7411c2f00efb1d5e691be0da10bfa106f96d3dc35c46e74771c5f31eb3e6d3dadfc0bd33e23b83c511a6e56aa6f236c2f8e0dda0d4586063bbf8133ee27a0e79cfd49a3027ce113bd07cc4e9af2e5a0bcd4a38158517aa0553c262d297cf4420afca9fd012d281d859909e856141b87fbe47c9bac0cb78876fb04027b200234adf0e53d87008e0d1267213165172b9c717f00cbbf675358e037aea5d87313437f848d653123e711359ab8332c6d48a80e708cfd6b8bd40276392fe1a16ab31242f3212b099e0990a753af7ec6b13381b524ca942b25968ebae9fecc52f2e758a81df88d0afbc136c56011b1c888dc83f7aabaead1c05ba7eabe585e0204fb8416963a773bffc5ed4212cc096eebcd18e101977f4731adbb0ee1731d1db339c26b72125f397df178067fe10df85c259effc33ea03cbd50ce4832eb042b72c005d811cee3c2729c4d1deb1508936399a33e1f322f96b196285f0a2acb83e2ecaeeb6d6e7a4dd4ff36f54cbdaaa48c299197a0ecbe718da3847f53ec7c72410c3e69ae02123b59d85101b03e15807853d56ff93c9e46b2d27f5916791003b1541b52137faa51f7a8d16a7f0860c7c6bb2b16e7e9f6f1f97a2c5f50f13bdd73acd1a3d558fc9ca92067c19dda2c50c21c5075ec7c44b0ef20d6ba0d1d660495ae360e23f29e916c3a4f9c3ded49c0481afaa847df7a16dd2063c898b3c87463cc099d640db5bc89f9215b54fc52e9f7863b491c7a6512717b33ae8ef530f5b1bc69f87629de8f6488e1cf4f0888bf784efc1167d5caa3e2eca61510d5fa4bea3c680cf5cec343410007e725974ae2311639ffdeed58fb19e2eaf1bda4ccd78fd54580ecec88744ac87bf382463898ff1cf8957f7e45dc97abfc0d5734e97c684a4b55a3763d2e9cb7a777b7e4ca2d1358bde5996b479b6e95fd6fb097ddfe17e147b147f7551c55afdf3785231120d78ad937075d0dd0c557c9053c52f0a649e93bd46bbfb3dc96e88ed40fe9b8b8cf51147f7429586b9175ef2243e348ab4808f797abc9e0ee8d2aa4d9db896185dcc23a0abb06b036de41502df5b21db640a8bba187a7c3539d219a585c84554b8b9d2fab6d545abfb1c52e3a5542d037f90a16a1b870d0b3b0f45e6dbbcb81995d5062cd96b367a8984bc967aeb5302b7a4878dc80cf19aef3fff9edc0d9e5feb79bcefa53d13e7122c96b4a52ce00be8d7a9b85478c01fe08b241036f14ea73bcf094f01260d45b4dcbd5097d87a8e0af70aed5f44e93d1bd8005ae3da979fc1de8a4c587c4ee436abb5f1c0112916b335a3e6a98d1045c410c6bd5fb7c9934d50698a6b13898759bd63d47313b3b2c8919a4828d4b024910053ce014391227782f07df93da711216f45dbac31036173dd646d2c0951e19623bd18e23df993858d41c17e3ef191d45f62a9ff2447aab53ee2b6429e8a73a05df621a1f711f31a927ad3bb6c7f4ee0a579df269a7078afc487f3f0f9cc3c783bcdef31226e88ef401ff721ebdf631eff8ac4a57b6cee2f485e7ab59f3f2521ed74f3c0c4f543d78ef110ce66cd4264ac5fda76924e15af3174f329dea8716a6109630cbb1019742c921f92d53ec977fd9f4806fa959dae8b2f6b3c15f2837d7d4c022a44c63c40fdc65aba9993bac15ab6665ee28dfef005615ce2e12f01df04d89f43e384d1e61a9e751065a7b126b95147bf836a28307e8c55c5524a7f15472b5efed6cda11902bcef7df6491459b7e83733df3cc55f47188547ecee1ce2ead731ce97389bda8a3cd9b9c3bb5f008fb59e1d252e9ec772292511037db521563d24e13e8da53a1743f3471cf4f28d78245c9b485d474d618308fe02f4df107bb3ae8f268a0e0ee1ff7e9c7398370bec6fce0be08eeb79889d9a909332133c4fdd6329f4c575acdbfd5ef53d060d78e3432c1da569cb52b8a101d6bdc1225505d86c88f97e11ab1fefb11eb40bb0590a8b441ca5189a1c3dd35ae3cc1c958c9c3335e00799eaeb73d0165363c97ce1bb6248042c1091211991b138b3907626e4758d93d47f5da25b53977fbf96c5aff3dcee83ee696eb339fe6f4d739b237f5d9adb00fb7fd3dcfe9be6f6df34b75fc883f72cb7dd8a9c05f036c8ea61194786a41b7d761153a0699433d4243724b52c8d978d38dddd66ebdd53747acfa36d506d48b1846f4799cbf7d6bb1f5f0a8ad23b435f227246751b46bc3f37df0b4ab3d325f8b6b547cbf62abc0d194acb7eb3a2ae329a2806a700ad797275746c114d64c01303cf6fabf13bf33d93e279ce7bcaf387ec27d54090b3c2cc2e72f69229f535fc7872f398fb77c8b80f6216626aba035ed7ea7a0a30ad08deb3c826e3dc4b1943cf1e6fb5d603c7d0db5b863cd703cf6b377a6d3b3eea03dcbae8b63a816b56e35beb30af776db418da0d11f00d763b86acc2924443b6c8df9fe7fa882f4ad75610304788d33dccb8b2a57380ab27600987955684297cd13ef08e9632f6facc686d2fdff961d6cb99da6d569773f40a3fd873efd9d724e20bccb3c69287dbb03719075634f0148736cecf7b7331f22497d6cc859953e652c6debf1bc6bec2f4f456a82fe1dd09ef38df409cb32713216893534403559732fefefd303f6c0f3a3147fc88acd206b8953fbf0d6b9b35e2ffc3debb3637aa2b7be35fe5a9f576edb3c2c564c2bfea79116c834d0c89b948a05dbb4e81e4311881191bdbc0a7ff17175f73759235fbecf3f06226061a4948ad56b7f4eb6e201bd3f1f0b49dcd7b4d196da625a749c4ff14c96f67630c774de6a13ad48c9c6125a74f7d31424e7bbaad34fdda7ccfd92ed9614c1a374681dba768785a0cf3a736c4d92439ffc69abfcec77ff3d298be41b31fe3128fd44ae3cc5c2edf1238cd4eb3749dd09793c570a3f559cbaaac4726780267e5377d3c812759e35e68b3dbba7522675cf5118b387a46a715bdde6431bc9b5456af23a5be028a8923ad0924a91f9ef4cd614eec77544fe8933354d19ff5ae8eb53bca89631b3675f8a66aee55d64679e893bd8c58b4aea11487c23eabe39f9a55b5efa57adb6c90d69be530aea326c899be514e65cd125acdadb69c4348b049dc64d13bd46583ea7bea1da4270a6c23647a4f7df163f4fb3e3ccafb4d9df899571b24672cb26424b164f84e1d894a6bd79bdac217da0c6a867c5c5f0e32e39cef1bb91a21a7b67aaaf548b0a0bc7121a13e6c644bfbfda734a773e6d9fb4fa72eca83fc2843eb354168799dc40d7fd4d6fea6e5fb67726a5fceeb72f7059e8706ad43fb2b559f518acbddd675aafe4481cb1b2a1a9cb93f9fcae168c61fb2982e1af9c29e640f3bf2fe4feb0559bd2fafce9c26ec7c8eb99bf0868015fbfc5b46faa21a83a798664d9a82dd1673faf68c6eb0abd6b31ac186a0b0981df8f9fcbe0741d9ac8d17f4361bf8b19c3468f3e94be37c26f75eacebe3eb65d357551b78754b1ce9ac8fdf1d3ba7419556f2e844ee658403e1535f0c6a5e8de505395d876bb9fe9ce7ea35633ff67c74caa35fe7c3417ede96e42d5e61173e27d4d9f35efb86aadf7d5e6a4fef76471979726f3f3e13eec5effaeab8bdaae7d4ebc4d99c118e6b542c6e499f2debf429f5da6050ccbfaae754fd765c3342e3c7abeb61c23cd323f6eba3cb89d59caab3dc3ef5c5f6fae539d1f6c3799fd57260af2735f2f844f6366b5b7226d376fe08241eec5dc8a12ff7eb5b7c54bf3781fb1395b65d8b4fc9afa6acc3ba2e884f7df1d9daddb6671faeb43e897fba0831f174babbba781e3ae249215b17e6cfdedbcf3b9f93d74ff5fa242f3c4e4e2a1e479c18f88317caea8b35fd410fe89fc8c393ccd6e7ed3f7f76fa6eb5463e1bc757c7f69c7ff761ccea30f110a538b60ffad21b73ba2abf45481016c7f2f3f6d675d14ad6b048012ff5db9d0785853f0211b27abf1ec2bb5fa0c900dd84d9b076db93e72f8cc7be6cfbcf8770b97da0f5fc7cffddc1c9b3d3f5bd6d137282d79eb53ca4af0934e853b8fc3561e4b0093bac330f6da888a7be78a4b9ec8f93671763dfe8a1314a51a5fb351e0267ebe4614c8e6b433bbec2616d6c3302efd7c11a098039caf8bc7ab60e36ba979ed688af33797a364f4b3f96777586d7917637e12e647ab59e5882d5cacbb9cd09011ee94b9f37caa7bed864893da1278eba7e8a8f2955ea361cd6275c679df6151ae2d37afb6c83a6a96cc6eafd93f2f0697d17f3bc45de444f491d62e16ec2b5a89b33795de9232f967177481f72c1034fcab19c3665ceeb653f2fe36ec2d7fa6be939f529c7b5e391d57a3d6f6cfd18547d9c9eeb1f97b6285be9f82551c40d72b4339bb3ed2716c7bb3f9f21470ef5d519c9d71e54cb093c29cbfce298c44d6aa16a2e1cee9d9431e1f58deb48a5a788ccd14eda6d5feca3731e3fd5c9efbc531dcc51a9af8000731fe837f98cf6537c7c187bebdfde47e73c17d3bddcb9dbcb13fbe49d839e7daa2fd01779b66a6f7aaa2fe1f3f9ff4e1f9fb67fb76d64c909fd0814fe40a8f7dd70b9dc36df70b7398c674cb775daa2443ba9779ab5a7707713be7affb4bc17fa6b2fef5bef0d3410ea93e6abfabc2efb845f3e3d9ecfcb3891efe64b3c7eedf8f8b00e25cef89c50db8adeb9eedaf0393dec3be917b2e62bf2fc446ed95f1da3269d59a55b1dee9de941a76bd689dc7db3af5e9c0b6fc8e102c19cba8efe917e344f69bfc4e7879456ff26f9fb7a1fbddcbfadace92f76db4378e741ef6fcb38be5ee1b74f272b82fdc9247f4836ceb1bd1fbdbb1edb63bf703cd91c13bd7a3ac9f76e59fe4e389e4ef6f6a793eceddd8f1f9f389de45fcf37cebc7234f983d91f22f698db9e20f438ee7fcbd1e4e5a9e447ceb6aaab2c5c26ef9c597e6f2bdbe3cf7ffef1d71fff3a9c7f36cc737efcb9aeaefe0f99a5b384cc125cfc7fff671e66c1c6ff0b2fe39bf9f2bfe66156fdf1434a8b9bad707a5afacf3f300d6749f6d77cf9c73ffec0cbe467386f7effac088a75368bdbebb60b9aab349acf48f373354b97eb305baec2d9fae24ed15caf97ab6c46d6b3b696fdac3cbfaadffdd7c9c9ed3fabe664b33cfbe31f7fcc56abe56a5db522ae2edffbbc379fdfc4b3f8e7fa35aaeacfeb65344f6fd6d972e5cd675549cb55714e1c7babc8af654ed547ab371f56ff87c9bc2ae7822ecc7030a334a82aad98aa121cfff863be4ca3f95f6172537831fd6bcb55426559ff77132e375948fff8c71fd1ddfaaf7079e3a561ece1204c66aba2aaa6ba71b39aad979b159efdf196d8bca90aaafa279965379b5555e672fd4773227c5371457d345c8df27c96a7d58f4d52cbc166a0ab3f59256cab77d645cdc9f5e37fed8fe1fff987bff959b7db2fb2d9bae6bb385dcdd6eb1bbf0c53eef4c6cf8a354e6fcccb303dbd2e69e8379c9b79d5c7ded0709db5371adec1ab22cd96871f375e53657381c334a807a9bd26a70fc9da3b5eccf0f925e10481159fddb809936cb64a3c7a33233b6f45d6976494866916e2e39d20f64eae0eafafbc84b4437af968bdf1333a3b3e888970bca8de3bb9c2bd938bd30f58071e7b76c509b767d702cb9d5c5f5499d1937eca05463cbfba49a330afe66d8297244ce6273f6fbc75c29e5efbde7a76db3bbb13265e3dad0e77e64bfff432989d167eb358d792f9709dd6d3e97599f1b45a66cb44f3425a4dafb6d97e98e1cd6a3b5b7f8476e58549ba5cd20fd0cebcfc035487b1ada6443becefbdb3c4fe47a8d25992ced38f535613e4269a15bb9577d55bab78b9ba827e8649700d399d7bb1f7a16ed9bfb11fff8fbe7018038fce97ab300be2cfbc3cc3f853af1d67ca47df4d3d1ccd3ec2dafb17d65c744e3d8bc355eaad437c335f92f5cd4188aedf24ab24ec07286ebcd5ca2b5a71fc3a6db69a5dceb997285aa110cc2e99f28278bf78bdb07ce39ff3571fdcacb1972497cbf52941b68c66c91b8f8bf4f2333ea19a04339ace56373858550ae507a9d3252d7e86947e4df139502dd71f207a2ea2ae54a11a55f31da2e36238db86eb46fffe107da3b6bc459ad24dec3f9b6faf92dd600f07b30f132fe9a52c7c9db852a96aebf2a3f4cb55ec651febc0cb9748f8f3e795afccc32c9c27cbd5b5ed0b495e7dd9b56f2564965ff9ced25f7ca2a64a7a7ee6b528a361f2e1b796fe62865f9dc997d46925bdf192d68d4b3ff7d60df652cf0f6998159f2c601d9299df68911f7a7d35db3e97f2af9357c6d36b82f63975b6f29275dad815d7bd70d358b6d7bf770d571cdf9a879fa82ac8b20f0ff3f1ad8398c3cb387e5728be50c07ab6da7e62086ed6ebe06396f107ede7e31ec3d52fdc9065f67e97bf65a83f23ae5587a3f1f13ee907a469437830cedf278d67ab88ceb255f85e1f5e927fbc339fbdf911a1fbc24b2d13fe5c79f1d58d4d96e43903fa9b9f3f3dbabc0966cf579bf9b21153fee667f3e39c208c89b70a975515f38b470b7f96cceac6b47b0237e1054534db8689bf5945b38ac3fffba595f5aa5d9de7edbfa438745eeca5eb8f6c117d681b6916fb33f2c90da797e9d619595eb6ef95ada923c57ab69a87d5d36a7ed49324f6321ca4f576e61965ee256551f5f97f79f356542fa997ccff5aaee637f9cddedaa6cbddcfb0113d2f3cc6de3a135e7b167838f038e6b5c795c1bfdfa0799be084dfc31925afd01f77855e7afa7c03e725aa4a9d6779e6b54f5abfda11eb7570f3563f56cf8ffb0cf5cdff4efd88fc7c833e4a96bb2458b606df295135a78e9b6ccf1e1dbfb53e687881225d2df3e2f2c1ba58dfccf219f6fc67ef548f8e0a7eb2f67ece8299d78a914bc24d52ef3f1d364cc3e4e75f5be6f4cece5b2561325f5fdc3eeeac065eddd3d59f1b8fd0d98adfdfbdc12bdc5c64b5ff5a18374b5efdf7a0fc37578716d797ed32d03c5aa4b36a5e9f6dfd78f4ec164e37a7973fe3acdd623ddc4a6659b6f2ea2dddc3bde5badefb38bd952e6bfbf06477f1fc95d5ec279de18c86d9d9ed7598cce9ec270de7c159adeb628d3d4aeba19a25db971eb52370b89fcdd6195d9e7dddc520eeb7b26bf3f3335bdaaf9055a51c7783dea45acfb27769b61e0d89d79e067d90f220343eb0edde7452dc6cb2577f6efc707efc5937b0feddeef4c6cdde7bf5e726ded02c4cbd9a45ea1bbf36cb6c46d25598649e5f8b9ca4de32aa2660ab7cee7fd6ffed79e970733f58edbd6abaef97df8bf3816533739b5f9b753da4ed51c1f3a3839adbce0e11ea1f37eb22c9ea0dd3e3a142fbeb0637674bedd571b32e5bc6f576fab3276d173ebbbf2ed6676715785973f0b3538beacfb1f896aff7a719fff8639384b831dbdb5f379bec277b7b7e7d575f566cfec73ffed8ce12b25cddbcb3507d80ea6489788bbafe5349958fd2edf7e6df223e5d32dfa00b9a75e50d8ae7abe11bc4ef7c71c58a245957ffe2d97add88e3d7080fcc3edfd493e95dbafd4af51621771354d6f31b542149bc571e572b5623ea5f7a5aebaceb19deac66377e48c2d5e6d5deaa496b7bede77215bf45b4e7d1aac08fd0255579ffbaf09efd677b62fcdf95706fcf6fcf7c69ff7926f02ac19866abbdc0a85eaa54db7f75deb6dfea6dbb5ee1a3a76de3cdfc7761686ee27a28de4c6753511c9034c26f44d2703feed8dedd77e26884afe0687a5c4fb81318a6c3d174389a0e47d3e1683a1c4d87a3e970341d8ea6c3d174389a0e47d3e1683a1c4d87a3e970341d8ea6c3d174389a0e47d3e1683a1c4d87a3e970341d8ea6c3d174389a0e47d3e1683a1c4d87a3e970341d8ea6c3d1fc3e1c4d836ff99d609a9b85b7f5de46d4d4147b440dc7ff46448dc8fff8c1de0907440dff55444dd5facf236a7e88bd5bf6f696ef10351da2a643d474889a0e51d3216a3a444d87a8e910351da2a643d474889a0e51d3216a3a444d87a8e910351da2a643d474889a0e51d3216a3a444d87a8e910351da2a643d474889a0e51d3216a3a444d87a8e91035bf1951d3805c7e3bace6668f1458bf0db03992ed5136bddf89b2617fdc0a0ccff70e301beeab309bde576036022bf46e7b3f7a6c07b3e960361dcca683d974309b0e66d3c16c3a984d07b3e960361dcca683d974309b0e66d3c16c3a984d07b3e960361dcca683d974309b0e66d3c16c3a984d07b3e960361dcca683d974309b0e66d3c16c3a984d07b3f977c06c4e402fff46c0cd4d9f2e37446e2fefd39486b85e18ff7a3fdecddbafee213a77ec01a3d3e3982f80737e7a74fd3e3ae7180487dda373789ebdbbfb043aa76ef92bf09cbb57e03947208d28fe60f93bf6b6f7bf059e734396787d89d139f266fbf42d14ce113ad3307a8b9c6907f61c3a738a8569a80fb2abb96c200bcdef33d977bc75f14627cbfe7e59f68e3c3948ba3fb0222f3c4e4e9029c5040a0ba2d0ad9f683ffaf334f51d698b93e9dc8b65ce35059628743d8911ebc73ae3417133898ebf1f77477a9f579349a2ef704c378843850b594a38b1f00a21f4399199d0f61923efb092a72e275f5f462cb34411173e27c41e242c8eed8dcd4b850785641a8b5b32fc54d955790c7282aafc8d1f8b8ceb18a9cff536d31804fe62fdd08f240b8fd4d48f49bf6ac7d49176be42172ddd031e81b0ba1e2bfada75f4723cd4d73e0f2223011b97af6804098fa4b507f5a0eeeb50fad19f2fe7e391c4ba719eba855412a56ab33627b198a2be94b9906e1e649da9dbcb6664acc805e2b5743c5a3f8cfbf7f3b1fc727f4e1295f5c360e02b228b86c7b1ba68f3c6e5f200f3da7a5feee3ae6a0ff3d00fefe7d3a14a5dd87b18f7a51d81eaba6ad7f15b7a77366fd47d3ee94b16a9fb05ff391e811d5640e1727289ccf9b19d2395921128fcf0407bfb98185be0483be4a803d7d1e969dd9362f9abfa3bee2fe7a602027f642cc78abe44505fe18aae7fff6b7cdffe1d4a05720c16c7bdbaae87f0ae6af37d3d6ee7fdab1cf87c91efdbb11eeffbb7eccdbdb6ae877e349f35f5cc710c18e2a89bf1482a7c4ea5e33ef3e7e1bbfaf7730fbaf387be5a2028471e1428e6b57012839c40798d8b608763314466949ebe33ee1fda3c1f27553f1bc278717cfed394a83fd2e958a1f1b83faff88a439f293bce5312dbe163fb2de3be248e15b0c69c7df8bef3f1b90f2d667d46df8c83241ec627611efef8bb75a4fddec53b78e423d9218fe6edefcca3792bf2dc8f1fecf7e191f9dbafe09105ae77fb4364fed7283c1d1eb9c3237778e40e8fdce1913b3cf24d8747eef0c81d1eb9c3237778e40e8fdce1913b3c728747eef0c81d1eb9c3237778e40e8fdce1913b3c728747eef0c81d1eb9c3237778e40e8fdce1913b3c728747eef0c8ff3118be2390e5b742910fd5de782740c174b54c67ab2c7c0f7df3ca3b07280ef75b60c72d0887fb3ed871d5f00e75dca18e3b89f515d171441a8f8b3d72169f204885723cd4b77e8c52c483a245a4fedfbf135958ad626f4bb49a622fbfd8bbdf0825e47b1c2bf47ae2f76510ae9aff7928e1dd8fde0fe64efcf1bf458a7550c20e4ad841093b28610725eca084371d94b083127650c20e4ad841093b28610725eca0841d94b083127650c20e4ad841093b28610725eca0841d94b083127650c20e4ad841093b28610725eca0841d94b08312fe2700736af8caef02105695ddbc1fa3f42c1429f73bb305f738feaed76384ef83d4705fc9167ccb09bd1f3db62774909a0e52d3416a3a484d07a9e920351da4a683d474909a0e52d3416a3a484d07a9e920351da4a683d474909a0e52d3416a3a484d07a9e920351da4a683d474909a0e52d3416a3a484d07a9e920351da4a683d474909adf0ca9b939cf9cf9bb703527f989df44d81cc9f6309b1ef31b613602f343e47ff0e2f725c1ab9aff7998cd6daff7e347ef87d8c16c3a984d07b3e960361dcca683d974309b0e66d3c16c3a984d07b3e960361dcca683d974309b0e66d3c16c3a984d07b3e960361dcca683d974309b0e66d3c16c3a984d07b3e960361dcca683d974309b0e66d3c16cfe1d309b13d0cbbf11707363a7e96cd5f7d633b9bd55b1c95fef47bb79e3bd435a29e6eef724c66b80393de6fb12e3354def52e375a9f13a39f62db2e498230f2bf2c2e3e40499524ca0b0200addfa89f6a33f4f53df91b63899cebd58e65c53d82067ba0140551f77c7673eaf26933865fd9832d55fac500639e38deb48e9841a14f3d31ffd986658110bd297b638c61bcc4b85078504256ae043c0fbbcba9ac42a75a1504e6214b8bcb1c549b471a1b0f17923a8db140a12718c2de16881e087cbdcfafc7443145092beb0f03981414ec04ca8bec331dd20a67a6ed8c8d19967df94b4341c2a5cc852c289855708a1cf89cc24a9bf6be3726255768ff48536cf20e957cf41539f83a02afb094a712c6e7c083664b07ef020bbf37995192b62810aa16cdf8b712c67c8215b1caf376e2c6e49bf6aabce4c1242dd5058f80aa57e32ddd465cb2ac555bbabb2149941d6c7caf5460683fb82891c99adca36a0c0788e217cf0db976464ec26b4aa5bdafa894e8fef2f8ff58f74c6758cd42d9a71f114397379b5ee2f0bca8ccb0514477289395090be10605ea738316c4f91cfc60037e3be68bf67e9427681e3ba5f75d731169e020a5cf47e55754fe5e7e3f9a0e86bd7d14be468f327531af88ac8a22162fd58673c286ea68eb4f315ba68f33f6e5c2e0f30afadfbe1fd9c702034a0c0798ebaf563b6eaf7aa8ce7e3d917cca92d0c2d86fd690f4513f4a3073c02a15fb7bba97f2c831d564031e5e412d9c7fa1b1e917ef4e7cbf978289df2f6c3b82f55dfc3b98e41c772c56b86597d13504086953c208a3daffb62b07ea8da3bad699af70854d71ed4e6241653d4976a1e028eb4438e3a701d9d3ef4a3395182c2e749391e829ecb815d33bfa41f5559e3be54d5b5f339a14436d8108532332bb7489347f3cff1e838fee301539595e242286a5e8dabf282c08f097db85fcec7fd7d79e7fc3649a42de6a74b3f06fc5806a669cec309dff4935bf593394e1fa6fbf79fffabe6351a45cb711c505fc9b7e3305a8f659da979a0a8e68a5ce222da7fcf198f3d9cb47f12134ae49a5f59cce85ba4d8cbb7ea6dfe099c0b731699f374d297287640e0cbc6f66130de69fd287ddc35ef37bca732400902d20f8a439f9a42821ca3ef7386f0d08fd66305e404ca6ba0dc2dc751205bc3fc691cb6e58c98879fd3e5df919b34f692f067b51c145e4cdf562dcf49f7daa420fe165d52e47ffc60ef6ebf4f95acdadd29929d22d929926fc883a37ae82620f51583e244bbadc4295240ec3a604d06cb7925fa66a690fa8518fabcbef5433176a15c4e60caf9261b1248d74801c563e2ee268bf946bfff3e5156c3c8f02a4cdf4bac7ca43b48aecfa45716ef7896bf156f7f5ce9a4c272b73d9611856330d8de57bd5484afe457fec1f47a77cc9df8012f95c327bf2fc14e493b2f95ce4ba5f352e9bc543a2f95ce4ba5f352e9bc543a2f95ce4ba5f352e9bc543a2f95ce4ba5f352e9bc543a2f95ce4ba5f352e9bc543a2f95ce4ba5f352e9bc543a2f95ce4ba5f352e9bc543a2f95ce4ba5f352e9bc54fe5f07e59c2056fe0e479463f137982e3764b69d25d93b815e4f090fde24b7e2a762bd72cc8f1f0c7f2d8c46107b3f7a22c37c1f8aa66effe76134f5170b3f3e9453b9fde48f00018fa41d8ca683d174309a0e46d3c1683a184d07a3e960341d8ca683d174309a0e46d3c1683a184d07a3e960341d8ca683d174309a0e46d3c1683a184d07a3e960341d8ca683d174309a0e46d3c1683a184d07a3e960341d8ce6459ccbef83d4dcfc355bd330c956f86d70cd91ec904559f8f17be2b436a01af6fb826bd52defa26b75d1b53a09f401b1708cb235ab8306aa85cf89cc78b19c9391ca2273f730eedf8758910bcc81a2ba3f8e2466e64814737ae139123381a0f415ba217d71e73a6a899c7138a9032faa3b7f04120f0a65f51e6c8312befefe78dd044bbc0ff148a56464a45559e3be44daf2e86c64503f36cecb8bdbf7076981a0bef5215bd150745a9e92b388a39bc7d7db4e3197a77e32cd700c163ec766080a1182d3f65beee7e3445a1348527f91de9311dd21475fe098ee489fddbfbb7de3dd023906e341508cc3fbb9b3efd704ac91a3858f87c097f7a11fdf652e276e3027ae9139be1d0f862ff5cbf6b48f1e43c96f69ea7ec289bac5e1783d1eadabfed9a0a1185b0addd4e5f5d58038c6761c4a621b9c921cdb29b33e6f505c8c6fc7f23a448e5af8fc389c5475737483b89c8ec3dd7c56dc872eccd73e4f8e0160ed3c250a285c989747fe914467ba9cff9ca6627ffe7fff86c86be76c9dae665916ce56efae772784fb15efeef704936c173ceefb16bcbb2e9a64b7de75ebdd4705c3b315af44904d2f573c3252030fe6a91f934125d1dd46726e7c4ea8246023bd5b89683b604b14bb92c20c4e00ddaf7e38a61b2293148d8c6555fee3e0fe5b43e9bef2b1c6f07ea00dff8ac9db32f0487684d30bb7bf5306f2df989ca16e7a27053b29d849c10f0886a30c1c17925d69c476ab118f87fadae7416438a80e396f2460e3f27578fa873e25d4572a0ddb9e13e56e3e83228b4369831c3c0795460cf61af1491a8750dae158fc85a0ce8c4dc9f6147beec662ea2ba0d8879147c73ae62e2746c894162eec3db8b13d47b1c8faf174eec1de1c72525a69f6b3bec0604e220ffdded6ab346d67be21232d9d8455f9b41c2bc710f7e3fa9aa52e1498f1c8d81e42c7c7d307e4040b7f044aaffad651547f13649aef1f0f0187a0c0609659d6290b46daeda4101775087fa57d5608a95fdca593be1412675af7c758d1033f940a04d92d89ab7e0a683fd69708eaabb182b6389498a68d74331e19cbb39417a114d4dfea4ce784a36bbf2fed43b647632565313f9da3b8d2e225c62fa44aeb4efd50e25c28a4be9207fd986e5c4ecc3c2824e3616003f97e8e639013084a32d236fdf972312e24cde7f4c0ef4b74a6800571f6635bf70deb87d2ba7eaee4427f9ece5d455af89c50fa5c4efbb1b0f34d29f5139da9b4fff6ba20b0376f62344f1ffc44cacecab9afcab8afcaafbeb52050603cc8d2f188a4beb29b2327d8f9bc4eabbec031a063056cd048aac695c145af4e2df0104af309773f074a70f6bced4fc1e741713ae69379b5fe2ee76e5f5c2228af8932af2cb300551690a3976ebfe1c3ca4ac38a58596e159f156365383fa51b2b017561ce787d69e12960e1ed9e97eb2bb4e2058a797d3e96eb6facaccf9dcf5556a514fbfc78ee9ad2bae6b11894b890f6efce5d2ea02eb7def7cdc5fdac6c792944a614b89c5ed541515faac6bcfd66b54ea1809cf1dc75a60f900b1832baaff8b41dc3608bf9e9ede3e0bea7bdd2178e394fc78abc41f7a95ff3f960b99d70f9d6e5e4b5a78825192c7bda60be9b70fbbe108fdfc232cb07b3378747be673167cf5d4567719ccfebf9a648538bd56db72f55cf2989c186dca715ff32dec5dc3f198fdbe7bc5795b99b4fc07c6e0f450bf4ef33d4bf4f6685ba712b7e5a2ce7636aa488ab2cecdd7c5cd1f3c6d687a030e1347c0cef436d302cb472caea0bdc7b3455512d245cf1d7c49e27d3268dca86f4d97a87e03194023c92d61ed4dbd42fe22fcc899bf377eccc83d3ca424fc672ad1366669f0c90c996d5f8b89c7d3b561a7932818dcc9840d0736b8bd9be7c675f6f841c77e37142552f874c81ce1439c34a4e2febc6bc445d1e519ce855ff55edd8687d3c772afd537983172ee6248272e4d53caccd5d58c99a3cadc6a99903a7f3b11edf07c8891c72d4b5cfc9d1c4910a9f376833860279a8eb95cac7f06e4b78c24f2a1901d37212eb5bdf14772ed4572e2474f26a19bd3d3ff21eccd727f2ba9289d55c9c9bb261dbfd7b561b68739b030589e9029912f0639973215dbb505d2378bfa70fc68a346853d764760c189cd07933b70d8a432945f3f4990c69d60d831205143ea41b04a7f5fa50ad497ed5e771beadde47fddddc8de5b27a5ef130a965144b7d281633b3eaaf3aad51d0ac37cd9aea2be216f7a508c13c9899958cd3166d8a95d48f713d2e9ea39dcd0d3c52b75e0c16a49affb1be2655db0b2918cb599df6683caadfafd7c426d590d8a4434a8cf2a1a97f5eada9b0924b0a48702c37dff9fcbdd44f0c8a78759ff288c145b419f725dde78c142575ea168a397b3d562a992947a82f054831d29a3e96d76d99e5b97c56d9da5eaa792adf228e2e26f3e583ab48f3c36ed734dd608599d7ed6879f46fb695be9c828413f8df6932dd7d9fc954b7bcb3983a8ba9b3983e281e3e969104717a3189e976c24b81c701c62fda2c24a34a8bcbca09a7b21ecc23e48c6feb95635aadd66a806b6d812c70586733d9b930a344b9cbdabaea951317e231a3495cbff330aeadad7cfd184a89cb8f371ebcdb62455e21c7d84e6053579d608fd7b687762fd2fa9dfe3c3d6bdb63ad3933f3d7def7633142302d6b2dc494124f69bf9553b7957654afe45c4a5d7ebabd382339b1724efb637d4b14bafb0d6703a987236f3efbaf4ac2fd55fba5be29ed9f93ef253ecfb07cefb70a7df1fb84febef1afc87d41e43ac9df49fe4ef2bf202e9e9d1b1cedce786fdb05811f1beb9313f0cac6296b3dbba25bdc6f34b3b7db9f1ff88ab8f03894fa0a80a774dafe7ca1debba1457b427c76b6b0b7a3ea93dad1faa139f91d9f9e247fb08dcdc932894181b94a3a8f6fc7fdf16eb2a86cc9c3097a5556650bd33ae5628d0290ab362c91c91493c5fd59594801bbe6045c587810d4a7c1b3dd694a43b53d416f5794e66c65a659f6462b0efd7328cfe5f26d65efd47b0723adb6e59dc574a3f57bc5252d8ae50017ec2f5cb0c7bda67a6fa0b79b2cf04633c707fa9fe6c9bbb1414964505cd9bb0ad8b81cbde8dba6fce9c810b002ca096f04b83ef369db626917fdf516d2e1046dd02213da363293c598b9e8cf93fe7a0171708acc78fdfd3d7ddb5ebcd116eef3f6ee91147d76e17342ec419c9da30caa77e72f8e1172f4b557f197d3a22442768763c01085521cb6e35bf45e6adbc6e78cca5edef741c54f1bfdb26da7088a03dd0b7d9ee82c5640d1d8b24dbd7abf1afbf165bd8ceb48f4d86fc3f285b631b860ebf6b574423d2fcccb3a8d0ff4db70a359f317dadbf093cbab291e4d8ffc14f698f1fc90be748fd4100fed8b852d52c04f1f8a118139c58578efc67288e06edbeca1b34dda5df3828793c37e515d975ef4722dece5e7dfa416c8d1b7fe0851d4f4619d761797cbed845729e2684946aa70dcdb110bf46afd77d984abd39a664d5a643b3bd62930885f9ec98e8a87102485e71842dde789be742d3bd742d6230359f039a33f1bc8c0e5698a80a4db5ce6f8d4663c59cabd11c9752e187996ba31a25d6e2940d21800fc7e966b516ecc0643ceb2a98598e5ee815ff2481132c4a3e923901913e694d8c0361831b598796ec7ba4a4a463ce3f34a4654bc3c320a02edd3fe8a9053effb523fd6d30b44cf5e16842e54a9df17971e244b5fa189373a998f56cdf347d9d4a6803dcaa8669e381cbb45a31a35b49d2a6ae0c6603de102ea8f248a439673619e2245667c7e9c79d0a07e62a4286ee7e03b7c50cd93b3ef4d2ab921ae490ca2660d39eeede118249ea3333889367e22655ea26deab4cdccf13b11cc77c819672496d71e3402a288c504d26a5d603c886a14d3c4fc105db66fdf2431925978c6abfbfdaa948ca2fa5b301704ba352c26c02dc948e367116b110bac514c79c01810f0a9690c896a85d9da8f74194023800a6140143c20260f35471db9f690f322b620c3b1604056d6995dfea8a02d1ca6aa6105c00f4569c2cd392b4a6383957713cececd85213d59cce55ac81db005d78d698ab8605df14a2dc77ef3d89df0683d4627d79f1c0b6a4d19919f8d900d6da05a401fb9b66ab80bb032864639e5c49da11829b049891d2920a3fb1245e2dab4a62b2d0a0c9bcb6cdf06107002240eb5d0501ee83670a6bc6c0196d86421a5eec22ded383575ceb0a7b191bc3916176bffbbebfeb573ad5a775e1a975a9f09025f59b7737f5ce931cf68bc44cb8822ae508b9e6cd6a8fb6afdf8ac8c38e127f1199d0b85d233d9928ce82522f1053d56abd6a7fccbfcc6c91bcc4519e60dc1af74aa82b96c47a615d53a3fdc1085dc9ecbe2fd3e3665668dfe587aca90d5ac7106e87407a388f3d8d444b2b17c94a96026b8b419368490d912337bc41095532790b14c9e34598a1f1d3d7fec8bf4d1329cd92878c2b234990da8622f64c51fd101198ad0180a4fb6b9eef989b1c636ea79405d3cf06316db43f1e97cfd8c90e35ee8ec1fd68d173e976f7158eb1255bf33edf8e79345743efe673c0c36a8de5f7f61eda9758546577d5a309fd62bbc6afe2b79c547cc847b46b7f01479ed5dce9d0b5955e93517ba5865e7943e9773a83da73b396f2f102429e68d62660a1bac547abdb0c531deb673a8924d6dbd951d52e94d57e9143a51a2155ad0351ea68f2e4f147d64386031df5abc6a8391a16890789e99c58f4394fb232a214564712caf5d063906951d63315e59311998b2bef4e26ce086996a44aa862d1a1290f28625f75c2e338065ec10d059dbfa469d223e9f3f2d9f94934aa65ceaa831285d4edea17a6ed569f4b36a5e2227d81df9eb7ea33fd36d75168fa42d4e8c7202f5adaf887bfd9b6df5efffb1fcf8d23c3a996b97366f33bf8a2febc1cfeaade51a27aeab75c2e5c44d552fe9336d7d57f1ab8122191065ba22118aa68ea1d8501f3c0ef5c10c50468308013eb0b02da766a92e6c66cacd22a3ff38ec952e2f9586ad4a84aa3d3ca0b71643123dc25b9b09c626a51218cc7b134ebe9d3094358644b246fa2388d511fa4e1d386ef8670285ca0e68e48159f19d161ee846cc43fb777d44c48b110262e673065baf13afe829cfe8b8cbfade5ad32abbae577e7d4d3babb3964f2d3fd47b3113aba9e7a3ba9366b2bb475b859e455397953904dc12d854f016ba61daec02cb063765edb7c6e81bfb330870c1c6be2227efcca5b2d555be3a9796aea36528ce03545476e4b1fe49bddff2711d54335906c92ad0187d0413353529c950248c509c6fcdc19cf765c492c5fd47799dfa3149fdf8c5f5fbb85fb0e8895fb0e9ded4d7300f7658110b32d2b256b6bcc3dff64637bfc146e09faf07957c7ba13d996e566bc4fd55ba9b0d53e825248243cae883fb9e65d374eac8033830b6c0ce4ac4da85e1c892c1a7a546a59dc7318c0b64e4c669f6c0a63260c00294868522f408466386d8ec238cd9405380a02b2eeb2b44c371d6d714d9d56459f779fc9dbadb09bf1ef6bc7693c5fda97cfb4d7c74b9d76814ee7bba59bfde07fbb26ef672ddd5fc6def8fd4c5a4deefe8e557d99016e074d6181a16ddf9325a92243010201a1c1a36891067466a640ed0ce70f4c88f7795fc88a68ec4f80e500c2051240f19c35173dd514b63a4bb0f1ccb4d6d86d32c49f586426095aaa303374743f1c98f8cc94cc98cefb4215d9872adeec44d16c34a5fbddc6f8c1054d93defd4fd733e1ecd5e2e2f1508dac7bda397f663b97cebc6f21aeff9d01a9f9e3d9ce81aa49ad7f4d4c6d4c34bdd9166f5dceeb371c50f5effc0dbc50bedfb850b567021bb3eeaa3c3f205bacc8342ea439971b979fb2db54c672edb58f198e7dc675ea26ffd5aafaa3dec187c9c63753f7d698ed15eaef5eb7dc9dd7894df8d073db1eeb3ca36bf523f3dec859ff2fb73fdf438d66fededf47b977df7a93989141012882b7da4ad97616afdfdba3dd8c867008f4628d3656980ec356396ba69dbbd02465a31a5144c63b947985cb2233d8731ab7b89a13c56b2dd5e16763cdecd4612f41551b163616031068f61ba239c20f99cbcd54712f587bd9e3fd04d3336388d23e6f7da4b6c6323d5f651af381dd7b3390e85a4c643be30878fe755e33f9f2cf775fb27912872d4e1799b741d3946f0021f96c491763e5f9f37b4fae2b3ba2bba2d1ed538cbc0ef5fe87767fcf9613dfa708eb4e7591c6b2fe87d64ed736ae08fdedb171a3636f8d7f5bec457c4d08579bd277494654cdeec1f5ca7534c2951a73cb89d45066728e258b78c4773980d3007862e14246f6897530e0c2bfdc618ee580b4c396bc8ba50591680d1376840c1b454cb596cacf4a1ec580afa8514f2388d74d79241e0d300b9bcd49f46d993cd9211e1be55a7a8cf10271051ccefcf0bee378ffd5efe75fe9dbf2633630285a8f62378de1e16c7bb4bb993788eb124705cfb1f4cf8da67a1f479b59cf07aeac746cd03380e585c7c871ef35c1ff6dfddb36ce7fc97ed3bb6e649dfd1322dacd69df155bc8819b2b247f31588539d28aca447acab2dc8766a19ca3442b235440348978c5d1a2e866064b1c1802cdc1e91a72b2f1e97245e6fed8406264ba69a2cd9264f1da2b09acd303b37cc022403db7050884b796a4079ac256ff3e237ae67f5be12eeb3354e7eb2f7c44f8c4b9e7ec156bc3c53fd94cc78b5fec63e794d8760dafaaf5907190e5169f1c08e190f063c06f79c158a81e9b8055ac88965cf7bfe5084442686a988f9b43404b3445b9b312088c50581ac843934c0305d4145c83d40754f6175c26a5bdf06636b74cf83182cfdd1b4c470c7f943905eb10ff3619be2f1d5bd3bc4fa718d457fbe8626a0f02fc78423295102d60d8585cf557d2d6dfd44dfe244dbd698ef513dcf0a6f04caab75a9582e8942e39929065ee256b6658615ba6ea31ebcb79ff31d6762b1ebe88c079130e1e45fa4e19d9d57b52fac6c9acb7b4cde6067aed2ab1212e94fc0167670a43b38a286c60c191704036b482337ce356d640cb1352da611de6a34e0754eecb9315d3fc279ae39604bcae16e9618961611d688e55b2b52632f560bcc2e593fdead7c2aad75980e6d2efda503c37a899faeb75fdc6bf7ed4efa126d714202dc44ea78db2e351b1bfaeb76290a305ffb306c512c1684930ba480a8d6314eafade1557b4bcdf926da5ac59a03cc74e702f5f6515179c4a4dee3485a797cf00b5b643b29714f8b7543834b411f8031e0f0cee754cf824475a18140a94f9183770f9cbc79e0d6b96def7813489e39644aa48c59c0b89cc5de73b38121f836fbfcacf9a3ebbe799f5f7f8e78ec3b3c52b7b35194b9d088dec315ecf73fbe73ecceebbfcb26bc54f87c204ca01ca1d1386bebbc6a5d26a388279c00505f1c21a0e7266b0cb428ddce127dad3bc1c88d851e80826c44dacee27ac5844fa724bceb794e20108eee6cc842981016f0e8d1e084becf51c65ca8bce7043c48e42d4a886b25207854961cb4dcc2975f3a337c1743f2fafca9ece0e7f3a4e659acd4fdb2f112edfcccf94a59dca0bff3d40dc5181742e972f20629b478677dafcf6ff5afdb04afd65fcfdf44db604e0faa750b874c5be7556b7aa971b8c443f6c12bf51095600315559b14d9005a48d562f0608c526f0a85541fd0298ad28d350031e282295048628f501ff5c59d11091662d2120de504f012436cc4eabc9c4f1860924844469c2f49a26b60a84fa6df69db465283a3536838e150394974c675a6fb33d7dd0b7b4d0581bd0c2b72e1c27c8de0ee8853337bc2976d0bf3bef755fe228afcde99dd0b58c1efe1adaaee035ff14640fa4c5bd755ebba0a613e36a3e1cee572460b33884a12ba9c9e3fb0c6ad1d1b0f2471f347a815a62de453aa973e236a7820ff4216e9798951e8ccb2d0c3cc81f298d722768046083c3ac31c03e3d6046488e240476136b4136498d19ab962bfe4c37ae27830bf769dbfe045d2e25dded1d7c21ef70dfada4b756f27663daebc0bf355bdbe873deebabde7a08f6331c025e2c0c870f42151a16c48e6d0d81a9656788af0a8450c3b835932e525c7e054160e0343b30067d86c8e17e3120fc7bc1edb5b834d17d0d1bd291348d6c865352563d060cc6018c8333b2bf484f48922f2df8b5faae7dbda83e30b59f99a8caeed806acdcd8ff88037f6bb3e7ede3f7fbc56f7185dee2188e9b36f7c7e96f15d98b8d2834254eb2cbcba248eb6f51cade2a71417cc6eb2185ebd1ff5680b321844b936341e5d9b4efd98203fca355b01c9032326b3442e3d8bb296656436a76e8105043db9efd92518ce22d60611284d9a16ae43d20746dd1a430180480db4c8589a896c40001412b1431413a00ddcc27a51d778653feae37b9fd7ca847216b3018ef55b17aeb7b5ced7676b7cfebb3a648d11f83a66683ad26f7d28172e9f065e21d6ebc2c431521f825a87386f536bc75d8727724d7b5c4045bd3565e3518f2935611a9b360b1f61b006b11edbb25de8895690588e212086cba663c006638b0f5217a81eb4c1d064008f945dae2da8378398d5fa59ecb3146a713a40bc5160a04b7a223f125bb0be5587a874c9181493daf34fdffab140ddc39e636d137dc39ee3d57cd3f850144dfc8589a32f3c0534f1b8dec6c4ee260bfc0d3cd3fa7b7069e973bd0c73fa124136a8f9a5d94b2a5d2ea03e1c666d9d57c902970f1c83ca1073a0ef5be8e9d1262129651570e31e5ea027bb349e3c5967342e98c2285f1991bcb394547f940d19caead3340186c1e4923950532d261e5674170df3bee9a83b3802b6a104639d45a16fc92954d84783795b167c444f7be6bbf3d6dc7dc9a7e7737278cf07f5fa50efc1d6f533b96ef6caab65705f0cfd38b56034ede9348df1502d0d251f98307b8443caf966b6d413923e42cc9b8eac3d705966c499f1c0128e58fa038ee51231b9ec2b28b515b2f5cb003e8e1044b1207b966400aae55a4c427f1031de8022ccd6fd7e0dbf1ffc53ded07f5ff25bf91a9f377e4dd5fa56d73fb1f6be4d57d9523bb008162627f2d3d8283d7b28f8b1da9b42cceb969663c62d5cce98c2484801141397432a8000181cb37263f00bd8aa3ce154ce83eaadc6ab63ad44a90dee0597cabfac422c2d3e55086b0b7a21b2d31264539e6ebfd9963ae3b5fadbc2e5e7e4d6077dbfde1ee3673e5d5f1ae3d6d7287bb6afdf67db88bdbd6afc9fb5b3e685fa7cefaa353177233df15849d719c301231dd936f9351b50138c8061f03aef99596838d39de7e8b93154a95f64039375778f965dce1259d56463a733baa733287d8474871824e931bbb01d59d187c2138804de2ec4584bc6dc4cd697dfecb7f3ea38ce4612c531adcf115cb8cbea585aad7fa2deef152f61ff5f1d035e5ff8bc4427900dfc584ef67e63af95d39ee71ffdc5cc0b3c7e4573881f23047e9f2d109c666e9c072eb7cec848a507bfcb7adfe8193e63ed7346800fd88c4a0ee08d66d9cff6111024555fec8e788f4bec5f8d23a6be834e7d23ca977cf2300f18af8d20dc6247f8df85ed38d36792ca9ea29b67f88c3a3628ddb57db7c5b5cd25ae7d052c9a784d97dffdd27989b8435058f85cbe4650673c07d1363ed26b91b1afc0185cc5c38788dd273eb5affa761e71dfd5f84a773ffbd24caff796eee73f47bb798d457aa34fb10228bef4b165584a94e10be74c977e9117cf2b99cb4b750c23b7debb3ad55fce6dcb8fee3fbde663fbdcb7f5f9f9f3713ebeb5c731ad74a16ff09b31a89b80a4de9f6aeacd5a9cd0553a105244997006e75bc674ca81893e5c9736951f359a0eb44845c05683d9886853a00e3048330ba68cb10802dd921f34aa86da28d88138df1a54dd4c19714878f9171e91cd148a815f1a3b04f3c7476557da511a91859ed8f45bfd64b206ffd5ec5d68e197f725b837709a3b0441615cb4c98280796687d478b5f7b0b9fff3f8b7c34ffc7df889d7c725d821474d7d08364491d713e7b8f6fd9bf5c11e5640e135f8894a77608942d7b8c1f0bef28cd9b7ebaaf1341d6283810aadc898980379f928ab1ee6806e0e8c81cbd2fe6c81d660844c9f11356304586c0b1e8c45db1ba1d81c82a5c551cf96e581cfe3956e83b5c6566b5df0a0413ac40b04a09cf2d031648da79e0dd3a5fbbd78ef832d7cb11770c4e6f62f7c4abe51077cbd9ce6fe61cd7986c97b53277876ffa82bbec87ba7f12532cce9db635c0cfb4d7de294dff7711fbebabfec2c86bb069bd0e8244f8b1a33f81606ff2dac5bdd178d6c7baeb35d7e1771d4f5a51cacc6d3affd9ef23abe2589ed1623f7f2d85da53bbda09b9ee96adf67b39ee889efe837df83ff7c37de498de9dafffe9c5d1a790bd933e17cabcbf204d9606029e30285a2e15195b7203b9c3aea82705a0138b100ac64fac3710fd8820de31c6976b603322a5d3ae791a57b3036769e824c528e0517180a00fa23b149ff7184053800a55d46fc6fb24b4bb7b22f4c3673a110a07d6c98cfca81e2cd79ffea383dbbcf1b079f85ab6cda2fed37ab33cdbadf34b65e65afdcfff9640ddf91336f61dfaa39db7cc30bf3fab26f5ec2c9be602f3698b957faf12a7df405f97511f7a795c7950d2cf7b8333bee6d3fa5abf4dff36ff92d38f6f7e4d60b98f6c6867a5fd7d2be039bdafa5c54fa536bbb598d2d78d5193434b686432212338c3dd4a9591a138d550d6ba17ad352ed4300faae13f0d65036a7bcecf936fb8b0cdd5e25efcc856aba0ba98765b4f61964fa91fe648c48ee2512ef47f2d685770c56c0da5a046b8d551fd0c82d11ab7eabff536363d47894fa3cefcb3e71e177ed35bcece37e5ef77dad031c621c5fc47439e3d50f9f6bbfa6bf49014e748a3b3bed7f849dd6eab4990fe54d1d73efbd584a2fad6f5f39f3fac01a5feb43cfdaf9399becd1cc1c68a7234311d869492191a9866d75e9b23a6b592422166651420776210a78a8f5dc12243aab47a4243b83d9315664d86e0cc65a1950934af12ca2021aea6318195b8b23bf7c45ecd98c2c69c59af1fbe22d7ee74cf27336d96b3ac967f7e7518a39dac4fae18070a9177d717fba37a9ed96fd3e6a6dc39467368cd9ec61ffc7ed577f490e1eedd87feb7e48db8e6a8eb53c94edf9e7aaf5db315690823e620cc3e40c0e255acf1a4c794b91f39922fe3219437ee0581540f669161bb73a3f5e113303ba65ac35860c3dd6d8195035343bdd699cfe881d590216e52c0006d36898a3983298a14bdf2282b590b8d9805eb17e7fd4be9ed7b1eaf67a63a35f6ba7fa75def0f2ab6736ff63ededafac11afdb3bff5e7bf99576d5e7fb2feff37c6ecdf01875e8398636e15461c204139dc3bd294b35302081c94b12e172f35131b6980b62c02f7b6880736f11f1fe02ac001cb22e278f018f9026ab9c0180ec42419b30209f46e9766a0b942c02d72dc4ccb690668d88fb1e8ee53f61cdf884ef7fe3179b44fbbdae3a66d3f3584fb49c40b2f6b9b373bd67e7c3980359254bdb3588af6d9d4bdfffc4284fcfb56b1f7debad38badd3edd7fe219e76b72a2b39b3bbbf93fc76e7e769fc131a02ff82a67efe2c7c3efc11cfb0d563cc305537c024f5c1a5c369df533e8452ce3db43ce02f342e744491fa2be1101cd88740f2e0c4b97831cd9e4090e754e5f040ce867bfdc85ce798568cea03c01ecfdce968dc90c10c6b773cbb2a4f0819323000c99c46aa9014976ed79f1ce1ef557f6e238cfd1d326b66f4667efee63fc06dd28a6a5e7185b1cb22be4d046bfbfbcf7a9b30586f1f9798eb9343398409d29a96c0cd58d65eb0c6090e20d410147c6646ac9b25b4ae53491d8d9428a31744bbb9f251a932a064fedd928088dc53de72694d786c8c4acb4f16335d707c6c2e428670ec80497c3ad36d2b86f8dd3f7b53381c359e0655f7eef39dfffd37648e0c6d55c703fe203ff1d717a4337512969fcdddbdfad7fc475f183367e6c0b1386a6b6292e67115d420bedd0d0d8b891cacc1664e851c93679156903693ae153ce96f54c77a42723ced67a12b006af8e7c1a6c262c62c050784491c04c21f21ecdbbdc4e0cea295939a3b680a16e7b30dabde30ff7be3ce3e43afe940b756602f32de2c80b67432fecc15eeadb9fecf717eaaed693c04daab54d5e903ebbf63992547c3c69308d57c65453fb1e556d9804b63d424b648b9cc1a97dcce58acdd22700b3e281d57fd923e3c94f54cd1e68250a336802a2cd62706b3b92e7f2324425f9e55abaa62b461f2aeced2c263ce8678136180b1e557b3a90069ea53f10486bbff50ff1382716fefb71ebbf25669d0bf52d8e7b4ddfd6f5327c1dcbe84afeb61dbad394bb7cc2b18f48516dab94a7568956a692f136af66885dee2c30dd7a913ec04321259c0abc886ceda8c72025ef7b23f98128a2416c7d63d8e26416131b2424d1e4d4f16c7d6b3b1167f3818ea06a8078debb02f71e7ab0f7520ce185cfab0ddfc66aea87877eff2a9e6ed7c682ba4ab76bc721f312bdf78e8dc17e938dd17e2ffb0bf3f393f1afafb3c6b7e43a5ca5594a53a2305b7d409e4c0e1976223dda96fa30e144d50aef4a1bd0d42c914258bc42761a9a76bec49cd1f306aa038679e4f7d7a5a6dcf55c9b44405133dd4e4314a39d1121091562f2c0a7a966db2b2f410f559d7efc714cd3477124ed38b46bad7b7a6ecc9f9e1b3ff69fd9ec1f91a9bfc87bf33aacf1da5ff707aeebdac76961f6714baedbdb5ae83188f2845063ab5b63de8582001dfa6031c486761a1a45c6f9b1604007c99ac2b03e64576e29db66916d66437987956c600d59d51a48015c18911be770ca085b83d5979ec2ac3c3e957539053398f57d864d74e5a5f17ccf770f05989f66a81adf4ac77540e0f7cfe3235ee869752c89096cfdda782370e39c4e6a9b8956733c9eed3114e18b71252efcf1d86a3daad7c103f6e2793cd116171165c7581475ae9bd763f17dec5c631f7fec23188cd763957160e7732ac531b8f538bab95627f3133d9d4079ed41f29e4fcf77c5473eabf3247f42e02b34f143a6ade7ba3c3b78a8af4194e570d82bed88f47d3b4bddd888019fe65336627c45f86538606b2529d0c174e73340c10a8a26fc92c5763a06b15c1098151e3486ba92b2d6f0ae3068a07b0e01b613148f80e4b66304100e7b5056d1b7e2a292967f0b96f7a0c19cc42afd8c9caae3ebd7793eb8de0b7b616dfcfd3a8efefc7d7bf63be2519dd759af57350f38158f805e6daf9a579e4b59728015304534d035009e6c5ee635e54e302155a650e440b2142c0b589a6d240fa561e3c8e051c452c20e39dc170bdf665904c73c9189e7d1618e93396329a2a0d972318d49e2f3f2082b28c7d050f591baf5afcacdf271fcfe57e6eb6bf1ecfc186784a31151de1b5fed7bc697bfe4dfbbecf9bd3666dd75f39a73215a90059a78147926ab27b3c53de733ccd61ca09131548ba963dc3e8e50e4c972e031e4971151ce4ad4f1d44282c6040363210f4c2868333333acd1b08764e3c19687b91b66134306b931440ba264914d31a32b76feadf33a0699cfa5073e3f9e59bc76fe81585fc9dbfe6217b5cfb0d3e4b1bfd887b8f453abfa7a3781f53c3be2e6cc377cc5fe2edff7f7e40f7fd9d6b7e3bfd7fe6fdfc39ffb3a2bf9b38fbbd8cc27aba9e72af9631bac9d683962b2709ac8a565672a8cf302c588f74720791cb2638fd33758494b1da0a96fef727b282f1f3856d24a096843c3f6792336e4e50e0d54001cddc5b294d90aab5bf6920325e635860da696fef0c0e5a107c8db79baae8eeb5dafb98d1f64fff4fcee1be2be87d7da4f755b9a18c2c907f658bf677fa8e1d3dad7493dcde3b46f47d69e675e6747c5a2ab29f2cee0d4b10bc0c33412d67a429507fe9e3323598160c9e90b77eb29c1c060b247dd990ab68d7eb9516a982c00130ef72c5b088dc808498c0ac4642e89a2dc76240f2bf9d4e204de8477c223ccdd09234bfe35799cfee639ff319d427bee5ff1b7e814d7e6da6078db665dc253d560a7a53f24e1d4ce1cd78a0a2d52035c6a058cf1c5daf0b7e50b6abf456766f5f547e2ad7f1d4b7491c7eca44ff7ed68e3af5fb786dfbad158c091fe3005d31cc7ea2f0fa0a1bb5097d8ce147328206b14244459f72c0acc99bc2c4d90f2c64057f44860668aea422a0ffc58b03c4bd63c7ebe326d63eb29c6d41fa29db6181784459235a44b04d2071be8f2a7e2843ecb75746a477ed197fb6f8c5bbbcf29763176378778b60b26bf9ef768e63ac6c27b2fc6e9731bfdb37c27b439155a9edbd7ff9938c76c665973565ba83bccaa03eca4f0a1449aa788191c001ef1f7850e28f4a0facb1b048eb71897a6054c5bc9a678245980eabf667636d4a261e1dbea830fc8c835b389b520b1164d396b282c1f61ba9a463a9dd9f98a8cd25fdf9b6faaea93da16be4526bb731d63f9768c02297539f1385e079e7dd50fe3ef8ba1c7c985cb05c23bfb08f977ed23e0585fceea5cbd4dbdd7c6c0d54c66e57269df5ac8b1650711b28247dd51c7c8a13dcf911666654fd843713f7fded4611cf503f892e177e46a0b707b9e8263dcea28da553a8a6e05d6239087d8c63b389a173a4b795bd69947881e660ae53c4ad7fa402ba0adf328327444972bbd94cda923034c538a1644c35166c085ae99c3fc8930baa50f916645eace97ef59add4bdd9602ee840a716a38f49f4e5f84d018e49e317f35eeca6262ec877e817056a7d1a6addd05193c677cfcef6755c87e7b963ed5814f4c478344ac3b2faa26271d9606af7383b497f79505e41aa153a503568a3c26558860cd3dc8d8de871a83a3816a4070e8d660b9bf7ec1e6b2be39d9e48dc34229c3f00896d497d7d1044669c97be1c703efbbdb964312f15b5cc0d2bb95df3d39f4d3f8caf96113896858903367b9df0bd38bcdf222b123598992cebc755d98dcc386dc7a4cd35749d0d188c664eb0b5580301870e2c0b954406548fc003e284481f822d7288645ae4d682468cedbb95c7905f7e9c7bbead0e67a1b8b0176087164131e174539749ae2fa4d2ea8b3b6d482bd9040c1b4c09ab9506830ad3a157c4d7fcb06e7a6dccdba039dfdd7d50df7f2157f0e7e66335ae6d4ca0ca66adc7f0e21e537c66ef58e70d9d94b24064c32503f00bdbecc262ef57162b3308d83948c0a35952a40d5496d82963b2c3dce65dee11a6ae6d671354828507558d30e4c1e7716fe6a49eddcfe8146af9e31064d6904c5db8dbb9c97da9272af777c4bbbd363ea9ebe8821feb2bcfb9c4705e8e5f9df3ec5bc66f068585c7d126b7e8b1feac3973f930763b9f38735667d3582be7bb9935ede1580c67205859a37408e32cb264adf4ca8f9dd71345cc3ca86598cb2972eedfc7a67c4f5f303ec7a66ec1967e7df655f3f2c53d26ff042fafac48fc658c64c91b90dd6c20b98011d487d230dc24dd7a60bcf5a9b13287b2632520d212c0f9519a137b9a4ff839eb5a44b641aa9b74ba9b42fd16dbeb9d0d7b9cce8968c21ab66dc99a4bc1c485a98747f7a569d11762377f5cee7c2637b8eb00c6afe3000bdb777116fdda5ff8ebf6c9599df558b14411172e14363ed7cbda7aaef33594c9d8b0d5076f40438f95a92107c85bc88fd640ed4f29a55036024bc9423ba682c6089ecea3477b2187d8221ce083b13d08cc078e0e7cdb10a691ce10382fec21fbe001b236b83cf5d820d09cfb9d2503002ddd46a3cf9ccfea4b17e6ab37ed8f585f7b26cbb8505d234b3be47ad25f88ede672f9d68fed633cff4b9fcf133bfc108fe89827e0a5f3e0058ec512176ca51f72e3939cd0cfdb89b6386632a4c88dff776327b12f9459e7c36ce49396798ab8f578ed349eecf37c848a514c6050f1ce16f16ae09b071da96df7b338f64b341a679e424ba288098ee56ce24814c77a9d8fbfd693a0187ae19b67d96d2ce0bddfed499dfdeabb9e9d2b2f6b1c644ca3b3b384e2b29fda382ee7b6e7cbe70e319bfa31cd2a1977ecfbf10b74e26602054afaecbaa245b0771ab7ffb98fc748a564640813a80ae498237c9fbbfbd2fe2d7c8e543a61f9e677252aade5a6a372ee79de8067e38963708cf1fc7aff3734bc51ecf1984d8e99b770a26afa4c66553c7f29d3fa6a401c63eb72f2c6affa2e4eafcd4174fefe67f3de7f531e9417f2de7fe28c9f618c81ded72989f5813cb1586a1ab151ce6276886d7660f0431650774b6c569a2ec6bcc6a4aaa5b04f0fa5fe6b0af3e5a33c67b06d3068642453765ca22460dc28972d27b5668371614363e947c6c24c10ab25768e28e23f976fe86c1fee342ec8733e7b31e65a1b83e95bceeeaedebfe1484cb7efd8647c3dc7c3afdb642441a95ffbc934f54e2c5ce36aaecb6114385aa4eb538ef55c5bcfa68c5e9a507e70ed7c321bcab7f688285a4962a844b9f9ffb3f76eeda922dd1ae80f5a3714489ee9e544299048198a3a40dd01e50a424188a222bf7e3f1e72762631d3ee6fedbdbf8b7e3adab6857518350eef785f4d0e4839d405c77799c39a4cebca34ca93b4f25658f7fbc4b5260ca8750a7f2f436dc8e6b0e9e3a87940631471db9c08906fe31a9e8bc1beead53be5aa3ed5bc79df4b77ee3307fc53f6f23dfa99fbab939c01118236e168971a38cff4d56b7bb7bbd8961cd6e9bffc91d7e38ffcafe6eb4fecd27f7ba22eec89fa4edeba82ab989b85e041fba26bfd6fc4c05e9e3a701debac9c72904b073d1cf2021f9fe7946fbd203fc0d582416fefc3ef90deae05154b54c92972cc3b5a95dddc0d7671ff491eed3b7168057b41e20316f5eb7a07bd06e67b114748a122d8cfe17e2fbe7ebd9f2370a92d0c68bb8d995a85ce6020c798b0cabb0b6d64deea1370abb553618810b9629769c140569e9e555e4369b3cd7a59851aa689de2cb1eb99a86a1adff558583563df696fe2d254d4ee8c799d7733479999f34bf323a8d8c7fef737fd4cfcb5adf968535ef5373dd540dff9f87fe86b12bad212972d4efc1f7de60cd7993edc65bb6125226f9319fee24d7ff26bfb38fad8dffc0ac3bb8f9176627f36defa767fc2f11ad2c8d69903b5ac629bf454c31515dba5067ae5e3bfafd9fdfed89ffa8ad72dd687ebcc602b79c41c7f6f4e4e633eebd09eecfabb6778fe4dd1b7ce845ac791674e391b4887ad0f67e04b3ccf198dff9fd99326ade06e1e023577b14a0f778079c4f59c7fae1347d465791b9fa9c799736fd2b0c5d88e01ae9b07b2ffed7db9448aada5e3d9888225ad44287558cc6cbcc15c33792558a01e0c091f0062aac04058f39229e47871a6631cda6c796bf826ed999169c329ab7092d5d956fe233a4897c605de66eeb0ef683e5ca356b3488d5c1df36cc7710ff8e04bf1799c8d90cbe88c79eebcca76a98eb7984d74bff24612205f2aa6b0e62f99ee8549d598732a1eb081a669e50fa4f17b9392dfcb04c29e30a6334efb70ec71df0e80acb36d5a7a25e9e143a0351b5efd02296d95a497f0d67c3b8e3c61e2dfe2c1dfe7c0620e54eaa03cd35f71d8bef7b90fb9b5fca46977e2c43893cb8af5ae99f2c3bcbfcaa79cc9e9fc01b3fe84217c9f2b1191d74e23d4ccdfe6ff3e8c7fb4ada0122f39a5edb4b8ff8897ad65231cd61f724adc542f394afb1a7a6f831ff5765c76f7bcd768fbd1993ce313bfc1c17ddd8f76c59e8e27ecdd0b96f2a92e077e50cb587022aaa4a03a010cfb4ece7cda3ee2d2b469c46e71c56e32da9659094d5c614f44c2c28eea32252712a0555c811129c1241bb33ce9bd0a8dad2025f92db3854988d76651bec4bd580bbd9d90deeec462b8fac7f5cabf75870e07829febdb78c9c5ff0b3d3aa73cddde061fc7bd144f79ecd1c0b6af4d74a6c79a4fdb3bce3c47b8e826a5b82314b919619c2d86805038f28bac0f4be5a7f4d7d2d71b2b75ee077c8c3bece2523a724c0b54cd5dbc2036437385067ee161e1e46beca05b59d39d24b062b5bc2ae6e1ffddb9bc3fda0795f2e1e31becf727f1f3ec631eea47f1b3e06093546ff0baef9ee3a91e78918d40546fc4bc4211298796ef3023a0f9765e5868ee5a02d7c210bd3093baec4899f507bfd08037a8083456a2cd147881d0cd9d1f0e5d6c04cb84fb7d421b3a57f60047b4670e463ec1248ee49a29d6628dea5ff42effcdba34d90e549277ab53efce7e1f952204db543ff013fe2bb9fa24f25b51b355eaca46b8f861cad1fe5e6c336778e01f396a887ef69c3feadfbb9973d0a2b005b7061a670045731a98193573c11bee6bd891553e0e75b40a75dccc95ca43c54068db031f787e524d8c54218075b314369a6023de26ce6a1982d2084a60a52e8a045d698cb31a958c2395e3ffd3b6fe43efd4d7dcadd758fba75ad6343aadfd4efbf8de4f7cf1a861f382dde251ab09036a92e247c27323e41990547056a052ba3099450a875597b04a74c82eb77e389c2266e549c158e83c18ac563b4a87b7b26e7209104fed764b74cfca1cafc2630b8ab130c3ca5ffa9c5df51e7867bb5eb85cced5823f3f3f9ffade87b98e7eb7c77be7e44f7fce2ff79fda9bdfecdf8aaf932bfcb27f2bbedc37a110c8b2a599c215a5a620a52aa4e3853e5d6d38959416b6818870e71c05999e1971a11602c626765927a389268c588f69db8530cf93716cf022f752e61b4c633788411e6b432d7544e4d75e822356cbb1b8aa36f6d9feadf03fb4576a2f8f75da8a28df1e9eeb6b5ce79187875ca177e0ccd887f8e3dcfbe48837b8b09fa0090c1684367684e14df8584efc5ac030fc05e6ae75e38fe50dd5f2913fb668e6b23ae379cb23cc530aee5041bb9903c6927928d58602575d89a9b7f29dac9b8d2510d5f046387022809cc640397111771995cd75f5913fe6d93fc7c9a04d5aa15c8e401b1ff070075df2f73d30dff1737631475ff62e1dfd96bfafcf1cd7fbc877fcfcf73166b9ac9ecc2703c9b52519c3705e6a3dd33099d7e22125a20ea3876ece058d4b4f434ad1d44130d4a09ee9a00b4093e03ad350fda0fb8558b1eac14c0a686266457e8f2688de2f53dbc3196c101dc3e5ccd92e519f4f62625db5af53546a958ec02ee666fdc46971d4c9b8720fd3b7ec02ab0edadc5cec525dfb9778bf3c202aa1b205a8b26ad81ef7c39be7684f58b28bf2be84c182db8cc5259a4a9b6d90ee3d6494f5a8a0ba6fe7a618e338e6439d57dddd545f99ac400f89120c2f8637126446a8795c4034458ef4e468b898d792cc2858d08275a93e59e2823dca0825993ed97206a7fedff74c1431470f82c345baf73f2ad649cefaafe208b4f890bffb21e6071689c34efc2c9eca22a632e3103ffce1b90e3c3797c60d7749818a80ca2030e01d57f706ad1f7404d97a4e3c97539890aa6b28439da83c455daf0e98dd49adb5129e8b942296d65e1ed4f856da6d81c1449bbb0f86d4e2257186b7c1aeed334d24b28e4150496746557ddd5e2fb44a75f3383fc77e3df5c636bfaf6f5552c91138705ec75c7bdbe7ffde0fddafd1081ce73a04bde07b5f0937b1e17faa9b9ae8cc949fe79b57a92155561df2cdaf38a2ff8893db9fcb031fc0bca2ed738e540db48fbd1da7337f9a8bd451cbb77abf7fcf237bb10dfbc33efe78dfbd5f9b7f81d7e0ed98fbb3558b28688f3cc8b0fd11af01374778d13a7ee4595c89b10c875b64788ff34a5ab7402d90d3559ce5bbccd91a31113ca5cd8e91dcc085f27c8aa652fdded04806443593b41caea4eed10494ba7085864b75834b40e60cc671d96d188401adaf7bff652e6bb33ff3e7fc9feadd7deed1adfd4da6abb5700f7b6097b8ec52bce71f6cea192d1e676888c82be208a9ef71da5eab7fa7db489ded621df6227ce1ae3df33cedc98e5c743f4b17ceb8eb11d4e71b428710f56846a27c8a6c8608843de54383e9f12029db4daadd9ba29703ea409daac0f0c7224495b7a4f441c7b0dc31871a3462cb9835bde4dd2026fe5602db88abd53673348d3b6af2cff02e5c9ae34579ea747d12e1eff8d9d7bad757a98b1a79d21679f39af897f7d0b1df83a06aac0ce43a57fe9295ca66b4ec7c9e4f0200a12c328db3404740b184b0dbb01433a6a98e8c273d8ad028e54d8c466d371f2b2423b1ca7ad6c85acd30350be9de6ba8ce3181761f330c30917da6c3abeb8bfc80c7e95dcdf68bbbe22af84994a79cad8ee7ef50d779f55a3bf1525ee47bf97e9113664f3ad45b6b0924410562498d57980ea1afe39580d0ca1c78cb61b3245ad9490a1c5137956f78a16496125a9e870eebe79ca95ba006346c23a4904e4b8c59215856e13b01bd861636f00d79fb4fe46c2fe6aa79aea1ff1b1c35a7dadbee99e7e1479c34c251937985edd0c80b16b68b20422cae8613022d88216c646f7598d36dc6038302c5d2024d848e9c14ca3a2e7121cacecd0c791742a5b0e14d42a37167d183ce98aafc312c674c38848b640e2de4477942f59ff41a9df85c0c6ca62fd8833ff888e739fc8fdc5a57a9ff773fd3dabc80afe3f8efbfe1e9281267b84c38cebfd276f30f7cc3fe35fa383689aeca389a9c7a399ec6d7fa036feeee22fb614b5beb452f1f2545318d72872934a3b6399a5336f617ed2ce4400b6a36a00cea4cef26929bdbb05404d1619115d60af7fe1655688c34314e882c30b5b7a26eda39f70246d50ab97810946a1357ab4e68f2ee82bedb6fedd7f9eb7c5a7dc29e7ce0757b95071b79ff7326df75ffa49173e8e5aad8fad4f3f63f283c8ba569b21dd8cf6b9ed5659b39f0097bf33ffec7d8fde9f387ef3f3da7769e7fee0fbc23f59f7847f631072e93c8dbbe7c8e5ee3ecddcf4607ddb83fd6cc5ff4653afb1b1cb3bd88844a6bdc9f9ef384dfbed4ee976dc2cd2afd1a6f7ea59ea9a7f10e777533e56a2daa5f3ff28d5184a748635aa61eb664d1de115b20e9e45a46878fc8119e5f362a2eee07418fc7016b02492680d898332ee3b0b02c5f6b7a042d840db84b0beb961118f93678f0c36132736532572a98bb90652a5741e56d02f0f7b9abd429db430dea3bf1c9e22a77ed2a09c1017b981de7fcd56bed8881bbcc3f3291833684233375240974cc136e3e26148f249b0ca88dc67ee5f949ad5ce64a98326b31a3e6842e8638a62643256304e40583e526eb054f4a89f05840a2108c39c39ce6634e2c97949220de542492c105dc953ff38ffe8fc6befbbd229d43ecfb15167f7b252cfe9b318ffe59d74ca3231fb5bfd34ee35cd4df68509eedc2fdde1d4332ddb5d8d75821b84a24840586563477724b969e71abb1501476870a4f472e6a12add9c96af84868ee642cd766107aaccaf31964ab70ac7602d06d50b188ba4ae345b9616e2332deb173fbe54b5d27dd7b14076d07d867fa0b36f50fb8cf337cb4cfd8cfbfd449ffc053f87a4d5ffa8fecef72bf79fd4beef527f7c3536ffbbfa1737cca1b1ff7dd7edc4bf58ebb29cdfa19edd63e6fabd0f9b5c4b03128f544404d27d5501342bb9b8ddfc5c9df5e97dfebcbf3acc7dfb1bf2b8f18d9afe6f2d08774bdb97c95837f3dafaf9ee7d48774c11c13ab9cb3fc8e6a70c01c914c0db14b6de421800151d0434444d9677d48976aae7175e432793387af780b2eb6ab43b07f1ec14ded1b1c94d7a9e3eadd4672ace4de0f760f7d4eef9e433bfaaf97f5df69219765ac1a2b831667e3fb8edaf02e71008b0d7b10527399b956cb7466651ab092faf70e53d1123e14712f99881ebaa0887729119670f000f76ac34ac5b8ab2c02651930accd4ba662865062fb035ff7373feb1d6ff4938f7ad27cf03f6803487ee26fa80783131fc285e7ec0ccfe597feec15701a1fc63df85887d8fd10c31fc60d4efeed65f90daa3c1800ab4f0ad9c87038880bb609812a324d4ca8616d7169ae33fd61838877c7140e437da2cdd56f90ea662c81707ca3e1290734d5cc82e8c20d76ed9896782bcad586113a408e40a2f707bcccc73165abf0ac7ffb65adeff45bcd3ce5c773f9bfc79af71f7539bf6f6fb39f9def43ff2e58c71ca8efe075d01570e5afc73cdad9e3be482bd88a503b8d73d1d92e89512e7d0d02d6a3dcafe52c56cd248c18e2b545635d3e6283f92c1c82a0dc6e24f70a5ec62601f9023bbf06a28a35d2e726ab7f83a08ab7820b3273194c81daa0c8d6707d6f08589a44971883bc0e22840ff89ceff4d69ee3b2f99cbbb0bb4e9ee6fdb8afce5af4943b0b4e3888cbb82333ae4649d56ee312f864379c90713c9887ed2a19e3ce1f0def7c0a125c3deca8bad7f968384d29c8fd5d5b8765d0cf176d24b5b2e3756387aeea650d2718f87dca7eeb69d4aca9839619cc5bd9c375485411568d493fea04fd4113eac3ef3bf64656ea27fc29dfe422b7afc48d767cf653dc79fa7b7f162ed57004f92d601d73eeb5449789d80d496a4b5d54de0db6f3ad001e401ab4281db66904c3d06ed673270f79a9c6a126181b975d5c7b3cb1cd991cd341a081881115649ab790050ab08d1246f305ab73801d35f12ba07dc4aa9dd14dfdb11697bd9e914bf54fd026e5fb988395475d2096a7dfe20cbdbfc6b96bf7fb4df05735f8a38dfbf8fe91ab7670196655605260442b01c28a4d44218ba0f24684360e77f229d57077db7bcbe0a061d2b5b4f4f4d8100e266c141470c2cb36961039014376e2e0d5bc5037042863eedc0f521b97692d5a42876aba5b8158c71bcccf72887ec575520adee573fe6efe9ff942ffbe1e3f19ff24be18b629877bffebbddeeffbbb4e3fe67aae71d78136decfd5295ffeea758b16c73ce425b69711c985ebdde2cabc15fa2f6dee34bbd0b5e8bca6db79e44da82dbd94e33ea5818958b3124011cce163c007bbb06c6fb093db0c5aee8cb723e6b02aa5c305197bc654376bc19a75c2bbe5ad36e4338a5c5f0f0cf6b1c67dc11a5daa21803669646dd243fe1ba8942b4d7ebd56dd474eb01fafd5761f07a675d00a0e1ae962952d4ef6f8cc731dceefeed25ab757fa065248c1d1ad81ee7c868d8c358f998e7056b35d66b320e4e2ce1f0d4dce4d92f0814ec3e10e8f514b0ca685ae605989acc46e405ca0dd8c5880549325d518096a067d0845aa4d4c1faa525450cb80f7791fc4f7cecd3ad6a136e520cfbef25f46578b155e8d795a83174c727b1ae78238dc9ba6eea4f377c328a94489e8704d28ce939ad53e63230127fda771f837e74954aace0cbcc9becc03d12b69adeee74534c2405a6a784ffef4ebe7688f3d0197d999988269e67a75d23391d8de6c4eef7788e78f3357ba723c59e231dd5123eb30f4c2306abaa0967e36f6444c548b2b2066761bc85a68b202eb98e4640e4538a30de2055ece4b60a3229ff985a7a70e0c33a755f80baceba5f74f6a046de67a9beca52fe27d7fd4a1e69655b0105c807404aa6cf73a8ff9a13ed7c6bc55538e9bec736c24482bd5494edb77bc807fd06d3af8706aca45933ab48d23bc49b92a3ee5dbacf352ecc081fb45386af75227ff7b7dea1f704117a93e5c26fcabfd7ee010bece7ed7dbe6845f39fd7dd26cbdac369348c373124ddece210b7d8d7929c835b26b4d56527d46d90269ed2a89f245cc99c57431a274624a257a520d36e9ae15b28f4da1791105c80efbc3f9c0a4c2b35b433a33b781c4897b618b593a1a2ee74ecb3efac9dfaf87faa3c1c5f8a2e3bab0c7389afc5b39e9e37af0267fbe379f5fff88330bc95d9b0b075573650d6260a9305c6d99dee9b4f676d31ead301077bee3d9a867640eeff5d9d8ee622327c91846719d0f9091274129a73e675cdab842356a66ae57fb55f7902af69801e1132a90a8f6768c197fdfdb8b0e365746b84947a0f91293175e2b673adc891000e9a8d594ab533deadd7bc778e3dbbd307e083451401672d925917032025516e101a5601570cc18c546ccfdbf9daf7d2ca48910ec4404411279dfca435dc337dfc725f2192bab76279bf2e1799e7ac62ec350e322d444ecebcddab7c136e4304e2ad5a7607ff6722f54028646936744def8b59784465edd6a806485a2898edbd0013d23b8f5abae20cef031ab1e36b8cc5733072c111303c28108c2b692d05bd2d1af3ed5dacf318ddff15f8c030f561b475efd95cef119feca9feddb37631ee7ffc049c5e14e18f1a5bc6f471c30855c84c385d0cc490aad928e21c70493a4ff3d90446d03fa60a43d1c4c0dcc698463d44b8aa2669540f5202379c70ccc13608d708427c2150ee2a843e39ccf2b36c63d6bfca8992107e3b8cfb752eb44561ff253dfdaeb87df16a16d1c7da9b56b7ce430fee93e3ff063f799038df4f51c9f9e637acc1df797ed6f156268dd868005ac64333c966508adbb99eb2de372b8a6ae656257d5b1861d09e563e6b08894a89e933ca2636fc71d34e0f676c05cb4a415c3e958dc65e56487fb6cc968b38bb9ecfdc8ee101587ec3ceeafdb3b7bc44c81a588ca977eec739c1e7aaee20aaec581ebf218bb7fe1cf3d241cbde5cc0eaf8187ba30d7617866e6e2cd34f2f2b4c29bf4c061e29dc16afc53587fb49b479696ee0e7d8865aa6bcffef0e16efaf3f3fd0cfb5fc06d6a2bdb374a335b0c57d4c9f5843e74d2f0e2cceed49c310f6b30f1159a10a528e6709b926c33b36d332dbb203594ceeadf3d2d571bcc2c27e3039068ec26ad5524804a488d42099508995c489a0dc28f3c86ff01ec3f564f18bd2fefcbbfcf8f94fb7bf1a0eb7b1af7742f5ea0b505ac388205a5134338ed9a51e1608e7ca103812876e352167327fb565de57bbcc357d2363ec33b7ceaa5b8ac7f14dc0fb80b03b4fbd5c54415196f073cca767396f7596f03514c7452b651505b3687b0f4474310ee8653eac292f27c102b2b9f91524b1cf326a910f495e86864d999de558850c32f5011028b114d929402e19fc560ff38a63ef2ec1ef4982ed7ec100e3be4d70eb884dddeb73aead77fa9e5b5bb8eaee59fc73fed677dd866aea7f6bec81bbcc771fc0b7867e59439182515f688c67454365ea06191449e86b4a6ce88bf2157bcc72ec17bfccc260517db2411fd6ef7bef35163e1dfe8f77e33e6661aee6d15db4ef9deaf87ab1ff9ef912a67dc0701c74dc6444117ed6d52218331b89851bc4ceca69839664deac99670f880a9e7ca1237619d0d329745319fece6ac5925a3769de8b027ba99d0510b31c0161d8b1dad7fefc2bab94dec2699d762868bfcaa7c354974f2a93978c13d9f7a8ad107be07d54f393ec4424fd8be373dc8e774cadfea99ffe17b878ba462857c8a839f7b783ff0d56fe2aa51b111bced253eaff772e43b717faf33d7db486778e0049e5662b5f719276f3548fe71dc6aea340f71e42d2ecccd3cedcf0317adf83aa77e150d2371d0943a71e356c1eb73727a0e6d3b3df0f55cd60346b47c10d2614ea12a43a7bba5351e532eec9089443ac2981aac22e47e9929f1888ac0a4a59acc2bd44e0de14a00436e0b0d95c320a3ca61066a7d95431279b390328d81898e5c247cdac1500b76b284771770a37c1fe33cfa5097fcb6ad4bbec4a7efcfd0a0bf969d4b8e3cf4a7b553fd941cbfff023facf72b33baededddcca64b042c96ecda30d372fbb6970551f9cd5cd97f99d7d93fabd58ac8abbfbae38fdc657f9f033bec6f07a8ac92eae4abbdbc3e72965dc60343c5ad0f581d125c877cbba4769ea484f6896ef6922127b3e9322d1921d1c42004eb33060ba14d0cdac77da83f6c90921de1caa1b4d906a527e6050ce468a5a3ca4b32f8bba744fa734eb744ff6512664dcfd6da2fc0dbfae4477e5925a2492b9d5f075c5e7ab0d7ff0e46e9fcd8477fecc0d512e1cd0117589987bbe1275825df5644d8e6464668225543fd9235b8ea12c11a2bb43d26151aa4b4ed251063cce34102332304b2c63dce6736e038a21b1f8805aa59c4f9f026d11b3375d578eed06d587a5ec2bc91cf1b8ec68ca0de8ad859ad8f8bfa5e4ac14573c01dbbde2673d84e3a67eef87f704df6fb6d1a59bbd4b05456e3463cdb9b73cf75c4eb5dd6f7a7f5248215a7eda35f75febcc288eaf180972ac1e190df8206ccc37624b4401785ad23870ec2de33908eebb4b6a641e48db0c37618a82d21811e322562bd59273a0e48091ea9b3320322382e2783db1e9150efe2ebf6fd3dfb35070e8337be12f97b7e92c9f8e04b5d7c8ef7ebf6a52f71a5bcedcb784fe7f5886dba58a72352c2afbc1b59e148d85e43348653d7726829133466bda8adeda7f1d2f7e66615474a896f73b35c4bdf04abd481e67b2cd899e7b97cde08bac9aabc8d23a5ddf67e8729eab24af6d91837b1e1dd12237f48dee3192eb84bd0e558e232e1a2fa2217a57de434fa592e6a3fd6712e5525163fe907d0c0cce9dab9dd9280e011a9953f5fb493d0066c5e757738b26a7fac1cb668952c444238ed65d9348923cbb9dbd4b1219319141b4c599052e807a07167b46b332e78aa9988d0762b5dec718639ee05c0b0fcaab6f8235be11ff5af2ef55b9b6cf1d20ffc2597f8dfd7daca249ab442ef36f1a1fef032fe899fefb2d89cc965a6e476466588ec361665ebf2a8b9230ea0924a9e10c898262a69f83deae57ac6518108dd4867a2639775731aeb998330a27091d01ceebf17bb969845b19eea90648517071a6e842d5b12c9725eaaebf2131d6b0f2f5a36ff39ec4699ea279ee1aff37057ba3786c531cf4f0f3ec5cbf83fe28c36e9aec588977d627b15d2e428d1032dd4b2414ca40a4a73c634d32510e7389206679225bcf138d58c79edad38c5c8b73d87dbf963a2ac288532f1995723c072e1e0445065a7bc349332ee43077409b37717f4d77ec38f60fd0127e0fa2f3d91a36b69bd5d6ebfdf60a63e8bd7c26be56487dad1cffc7ddc0bcfe39fb8682edb0b9890bcf38dc616840e1217b28c37bb98c1bb346a129f765e3856840178cb9c0e861a9a20a7bdf5ab2196659724bd0c63056359639b102fc691dd8b5a2e59a1c68121f4708cfd8058165bb41ba1893e28b5dd757d4a7556eff7dfe6badbaf49c2e5de7ff90a87b13df5c8fef5dd901ab811fa7e4f9c6cc2cbebd61f5dd4d37ac44853e962202baa43202394b3b219dff6792540bc244ae881ca9701c02dab6323d3577a5a0d1f316c1259b33b464d9745e596572b8d45d684d240c7143fd2de7acc6ccf88353896e5bd26f8b092b5ba092a14e2b3bada3fafb324dc6c5e74f89eb9c2ffd8231657ea3d96e0707f1ee7f0c95ff59a74317c79ef42db20236b25a25c65c5b7725dda157c6790399d9a3b6ce71f7a625ebf3ef6857cbf47cc6e912e27c2cea752fbb59db96232d5277a528922d07f0de21e5bc41e7a7f19b75fa4a971e4e3bd42bcfeb5a6c6094772912d1d4bcdf369c93c4aa42f957282c28ae6ccd3a59e77880e40c6ac87b81701e18d8d2a4f085d3aa95d021e295be8dba5ef8a4146180f1d0f114d74c4c98cc411d1bc02600603c00b88535d3ca40c7b89adcef4105d9a6f646b31021bb1f87e8c8746d7d8a71fc63dae4115b4a91ebfe9f5d98f77919f1bb640f6b0494b3561cac2a90eb9a4f90dad552cc6932ee108ddea682dc7783c2f0390a96c494abf937a73c718a2c4f097cca1062e873ad2e00329a44e7b3598ea436fce739f8e59400b38b935ac074ae144127655fdb254378b57dcaddae5f975b6ce22d664d5973d20bbbdbf80fefe2e52697dc4fc1df1ab2fe34fc964edef06fa8535c44752994156f81d0a874ea27c6d5eaa9e45b91006138c59815fd18e942b4d8c2544601fc328935354c4a518250ca33955f66def19b2d276b28f97197cd8a43a46019105addac7c445415c759ad4bcbbacecfe09eda3577d90cfda4757e0edb85f5fcabb2722bf8df9814f248f8de0eb1c0eb95ffb23b01651ae5da327e5ddf887739eed401e1f74f0602147875ce8605afc6ed38a0de4a5712d2d3546659fd9f6561a56c2a184a4f6ca80582074bc75e262858afb5e8e51c746bf3a568ac98cc3d8afb0859815503dd629cb4068e7b128d824e420cf98d5262acf59c578d2e31003b98e23b54a596c480aafcb3b1ff9875c7eb68fefb8d29248a837f5d80f756401d20a1d78bca6877ecde0b546f907edc2c4816f73adef754eab3ccf76a09f73b048f5aeffb286cd0fdca907be9e37cff981737bff5953091d1e7ed3346a5456fd7a1db39dd58079ab1573fe37bd70e9a8756658eab8af8f9f9f9df9de97cf3ff1f67ee3bbab733c3d1feaea4ff8bbb775f51aef120ed49bb579dfc7f1a45bc3cd7a5aefe339bc396a389afbd87e7f07e659fdeeffff5bfb11fede4e8be04ff1d11b4de1777ef1394dde3a89f083e49375ac0fdba971c406a586d74ff5ee3171e02efe3b5b75862bfc2d86e25fc0bb3707dcd3c127dcdf6d2fe3ff081f43ec25e52d8c8dbc214e374240c03915da9c7af58c60e58ff3bb20427a46a4c3a857079145b37068f8b56a03ad3343ada931b4fa39f746989a5cdab6c16d84319790bbf9943ac335deb5ad542a9c3bf71b62abebe2631cd84f2364a6dcdbbce45ffebb378f7bf305b793d668fb8407fa7c8fde5f0363fa8203e2669f394ff5e08fcfb3dfb3b34bf59e78e30b1743a24d3a9f7815011e98479635e7db0d2216a74a7841a94aa6e01d058c610027f3f2419bdb1e892ba5cdc6f0865670372fa4cb9c7c89a948e60486b1ce44a6a488815504a508682427730a0b9fcb0beed7ff382669efcb68e90e6cf7363b897023bfec61b5afc4bbc8fa43ad3fb2f6774d231da51f7199e7ded7ba1ff030e2401bae524726618d73c67f99295722a8901fe839651c4e48d5dce202053cf23b56a9128fa525750593022e79944f05833436b01f707613d0e104b1664acbfbade83d4f006b8dcad6080aecb171ded0dafa4a23f207b9c173beca7b3e9e9f62f94e7670745d9d8d0f75ecff6bfb5d4779e6d056e8c3fc1b1c58ef7da61fc610a888f77e15979b383ac5106f9ee3d42779196fe4606a302f713cd727de38d31bd32f1bc87a69cf226b12d79e8a99c8e96e7897d9837eced17a1e0998425c4a4d0369215c4e44842aba0b99a5522e740c1ac528e878a1ac698fdc8caa8470394d4bef2188b2cd05b9ef7f2e57fd3497d1b356e61336f43bf57d700dbb15eb702b5ef5ae1c7dfe7c7ba84dfff9f94ef57e7a0957e32eb4214fa8c4191d6cfcda7b9491ba919ab2e63c47c4c9357a7d4d83ede95ebf745d56fbbdfa757fdbe43ab8d6d378a7393ffe4db2b57f319655d368011bc1bc0a91c926899a8297d40878e7cf09d5255593d0c63e1b671a8f9a1bbf54ba5f6df544c3398f0494440d6e0d89828295bc843b566e07142897432458e1898067866f8b82f54c206eba5833bdab6a4995d622e69e4a47c362bf26532e764fbc6e93225bfb64f25e6f71ffbdbf9fe74c677deaa8b574bd27fe81535ffdfb3b033e3ee943a1c589a7fb5d3cf8a291f0679da9a7decfccb07279b2b307adecf79c9ec7bd7ceaf779febe0f31e8abdaf2a71aab829bc77edf68f212c3efded983433ee3342f112a52e3b9560fce73bc9fe66e74ecb77ea587758e1357657ad7a475d0ca4af5498437d9e20d96ec7c6f61c5faccf5d42b4dbffe4c1caf3203021179e6cbbd1f9cfdaeb3b5e7f77350a995080f3d04bb79f8a425f65a97f6c3f8fbf8a678e2ff3ac49823b0481d58243ba06515539ffb237295ea933673e04e9c6cc871cecfcdc7feb35efe2a7eeb8ff8f50f3e4e9deee38bf039ffb19d16f1078efc343a72e289c35d70ffe91e4a380059b5ff27cf5f3e7ba6f6f5a4077cc0bebc1effc39e78cc76c08c3958bd707fd8e7d6f731d387ebfd9d12736ff572f7c846d4652b75a525ce10c811387c2ee1c2fc7cbe3b25abc1f3f37fe0e8d8c7b6ceb08ca3e79e566d5ad87bdbfdf1735cad93b7faa2fdf9be1033972edbc57cdb1efaaef66bfdae4ef0be3fe489cb59bee87c6ca745f9f1f7d4d62ed5e53ef6fcfc2cd5c7dc47e6fefea2ff97b5f2547f386a8b9cc963d6eff590f7df7746f7f895be7352a34dba38f6143f73eb1e3965ced98bd35abf3e77c187cf1cf2dc27fef197399a9cf9edf1e080ab8eac23e7cc41df8ebeb603fd85b5e6277bf6c2b7f874978cccc76cf777b8a6a8b0b7472edcdff7ffeb6eef0fda2c9fe3232ecdb16cb243ae681f23b2e218671ee38c675fe6e2d8e268df9fb898f631ac88b096f02f6b59832bf1997dfa0c6f7c257ee2903ac4fe4c3be0baf731c5e5189c91000d20901141db1b5975fe140896d4f71bce27c66c2c3925139d2ada0b4d3e0604350915ba70d176da7b0bc2050f99644cfd36a4d30ca4d310dfa1cb10fed6fcb12aa8d305b2349794779b79918f6704aa0bf0587fe00c7dbeb78b5437ab8467873e50e9e2e6c93f38ee67b44ac24ff6726d291179dfd022791aefaf787b9fd736733ab03f4317ecaffea33ff077fbebdc33bcd95f91b5925c36e9e2cdfeea7fc06dcab0bdd2b3b2a1a85433aa8b82e8bf001ab3c784c33ba94d0c7f0c414095e62f86252d64949602a79a1cb36adb4d3586328e2d527aad042ccf2288d198e5dcb57619c0ee5ca1dcef951f1218cc231606753eb82adeaf7e353fbc3be429b3057810bcdbeee3d3c95b4deebfc582ea9f7ecf8ff72b3d7fafbd3b337b1b7df45ffe68a3b782b31d7e8787229c69f17b2cea6b5ffcacadfaf0f9b7fa0fa377389237e7ecdb5884273bd1c7fa70fb654fdbc7ded5bf8b6d4f31c8db73757a8fd01fd46fbcd9dc950bbc183ef0c29a660edb723ad8c69ab94877ad430a11a7dacac03a9ca4103e08e37e93d82a49c782c7c45ae0220054c13b62c807622b73e674183b1e0874950b88fc40f3d6e1d81b63a5f6b19686b87755fe1611a19de008642f7ac9dac77bf314e7b85e7eb481f4ea1886bfb1dd2ff1d797dc6c57e845791f9f1ef3eb6fdf3be51e2fb3c9c68ce09232b5892366caaab3e33ee8b963ba4191af1841891c679d6f8859a0e7b51c63c80cf9c06d18f82a5f06b5580b470c70615942535da80defe2083d525b05f3eac10c6b584bbd35e212093cfebd61054aaeabbffd3c077a12a1461ef8f93fd4d6afc0a3f0479d9a2bd603819919b88975a8097e694fc8fbbdf05137f8c5ee8826d395961a93977efdcf7bceae8317ffe3f86ff6f2fb756c4fe35fa697563e187e3918306ae6681cefa46e6f424ddc6137d850fba10f19d57d88ecccf67bcaf2b14ff3c7b887230ef3ad28b7bba057210a5b8b11f99838748b0be1d29275ac040fc86e800cdb192772902e56ba70d496b17f824fe852ee8ecfcec2bf6aa3de8f7faa939ccf991db079976a0e136b4775100675130b0ddf8411b251055c6137b588c48dd0d94d48688f6ca4b282f953439884dd6f132dbf61a3e16342279aaf3761e20426676c45a8140442d3af9b6d569a6d0a8241c6611f6852e3618b63da5e70fffd50a3f482dcfc54ff702fe5698d9a6f6252cee4e37e1443bc19f3c00b76c41c3e6197c10f7a82169c882a29a84e00c3be93339fb68fb8346d1ab15b5cb19b8cb66556421357d81391b0b0a3ba4cc9890468155760444a30c9c62c4f7aaf42632b48497ecb6c6112e2b559942f712fd6426f27a4b73bb118aefe094de21fd4c2feb4aea5e01e105f6b37bdcf35feb42f78217976ea17df8fab693fd0952e538d19c2152d82d658d09516f628a474b0e3a5bf0b946241050752eb2c5aa28e5700253576667bdb4d1f76b49a6ce7aec55367e8d0ca1c130d1b196fb65237ad54871be45a2ab50783748cc2b0c2baafcbf0babd3ca07fc3ab7b957eae4be238844484f3337bac9791b54d0d4fcb76275cefbf1a3b7df429d2efdd2d57e02606074edc74ef0f5ca69377d4bcd1e492baf74b5635483ac0422588fd426e02829da01490d862ccd583467b1c679cb904e46359c403098365524d7a59ad36b456790864e0438b86868aa4037caa69db78d1e602328a23b1c87a18600e277efd794fd10571c6477c97f13e5ffdd9fc9fc963ff64fedf8eb9b70f87ba453602c73be0d4b378195e1a0259b63453b8a2d414a4548574bcd0a7ab0da792d2c2361011ee9ca320d333232ed442c0d8c42eeb6434d18411eb316dbb10e679328e0d5ee45eca7c8369ec0631c8636da8a58e88fcda4b70c46a39be2e07e9dbbbee99a7fe3fd3f7f7e7fbe3699d8e75278e36e92b4eb1cff38c57c1adfe71fcfd79fe733d45eb7f80a3d185b28a5b30d1129e1b19fbad93c5300fa378270a58137a3f48ed219750e2d01976418fcdb0171baa61ceaa612139b0325d8c33de2cb96376095328710092c0dfa4944d88fbdb60157b48dda0cff8564f6dd6fce3bec3ff4dbd5e9519d64e7ca91990adfddd75f085c7baf9314e3cfead193ff04b745f6bc6a444101518a4bc7532072c7129bbb912d34c1b52dfc5339f35bb5b83a98c7689a82deed3e162e6d065a0b19a4299df6ac341a00fdd708cb4b4ca9b948269c8e12825b89d1a22a7b5753bd5db1dad1f76d7cd75c02235bcf54b2df31c2ee0f899296ffa5736e93ccee0730c43f7419bf29fabfd7dcb0739aefb7ff31aff7fcc6b1c7b92ec2feccd195cd1cfedcd7ebc63dec238e097f30307dda53d619cb9920a47f692650ece6ff54ccb462d0e5db166bd15ce198ea70071419b11b6b58dd09046280c496f15c465d42ff302d376cda0a5274ec351055d11c15da04d3699eecd52e3f73634d04d4aacc74c871123f802ccbad7a41fe3878538f0ca7bfd09afb048f860f3f2dea186fa31475fc15572c42dbfc110bc7a7f9dd4fe5ffb4517f36a45a8939cede65feb07bec7adfcd4169cc63bdd551153595db6a7efbf4cc349437612a12d330220cb7c225d8938f14456428c1cb5c0556b91711ec6e53de0548e52d58ce2bedc123e5cc95a5489dee2586b76e96e98f34a5994b11525a8138627682f6c54c703acfb00f76c4c2354cca2abf220a8fdfcc4d1619edf62effebe36babf532eafdb9c7075677ce40fcffa79eeec3d26e787f5f757639eea825a56c1834d13a1761ae732fcc6dcf1665893b394ec6d8b27a46265e85a9e34623364f24650cde4365ac5e57020f5a1c55ce6087b08116820aae5848cda09258cce9c7c436d6d392f733da5edcdbc4630e3793d27969b291bf0b1ddc75c34ff048efc07dc652a333c151b4f35c22fee88dd7572dd59c50a7958abd3597f7e7dca995db676d3948b2919a3052ab32555b94ec7f9cc8fc4ce07b8f379eb4ff5e1185772ed97a6e036d332f67b30d5b67d66b779069985ec6c106b82c77ce8f80031bf9ff4811668dc555bba1856a2529bd0014be994fa14e0fcda75b88f755abadefb7a57e030ff0986fdb9befcdff3feffc5f3feedf53b832bf847d6ef07675eeb67dc5c87baa898f13098db832e5074e357be31e303332d276668e39bb4b7d609532c8beef5b9ab3ac64d33d5e09a46ca648675c71c9c60ce9a40470f33db1b49423b14059a347e9bbc0235ab044f9c8189a9b7bd000ff50faf1fd312de7d9583da5d4943e979bcd3babdc24b5cccadb364352a32962f913d1c67e37840c1c356386d8d69cb13126f668e7af4fbdfdb50f32266379ddf7bc154c7423049a921a7680ca339c3839877339fb330a536e085622c1cfa7cac6ca48988ea80cf18b27874afff1339a67d1cf313eccb897bfe6bdd96f7bd083fbb634fbcf687fbf589e3bebf9c2b1454490d41d05333d602233054846ab6232a9ffab618492e96bc429b844a7736b60ce6b240f22646a4dcc6da043017afd262b2c5c4634181c914488b2ad12530af846a567ed9cd04f09702c092daca4bb8b6f962cdbe11f38a3c8efcfd5cb459cdd6d251ed971c8fa38171951a6005f36cb77f0d76929b5ac2c1d1de9d7b9ffc5ea3dda53c29de2e64bf3516e132d086772945391f0d3738b21c027eef10f4bcb852cb98a21125b997705821d5ac110996b7bab964b6d2e7444ce62cbf91e1aa47111a201761614f34d9e72e7259804b78430ceb8131f81897cdb998f8abf8a5481cb84ade68ca7ec0f517a93304fbf8fa750fc0b13fe483feec6bedf0971e83333d0bc261b974eedfe2973ef4f5c05e3aaa9a87cf7d07ef7359873ae0de9ea6ce301723b0cdaaa126f891afe5750ff2c7fe82679e16fdd0a3f1c778ed0ff98333fbe415875d913ae5fb5cc0b7ce436604ed510708ab69c476476ea367cdefeff48c5e2137f4e5736ca6e1b08a23a44df94197a814210059559e7a65866b71e86fb47fc29b3b155a1b899e2916e53a558d2b4136c0b5a8e20a4e900663aadfef626dbbf4f507204ae0ce154381914741f9d00b18f73191d1bcc84dbf8a3792d95b41d00829b99f67dbd7870411fcc8a06d8650d0901e393bbe712f3cffdeef6b07f957d2d4785e8f83364a16b13c3ddc17e7de3fd5942ebbef2bdf8078c687784ed4a35fc287a0a29b70ac78d0979dd4ba36d4bc7100e84668f82e2ddb59c0948b78de4bed971194dd34297e9ba1e38310aad9bc5005d6cae5ad91af321b8f432eed982b8dd5fed6d720a5c5bd76f0b1bfa3a1b6b70123f01ddeeeee4a31ccd33a37a28a5feff3fdebd63f6a745f94e39adb0d4841006eb5ad3963f98a17b9267556c6ccab500907bec2356562202b9910a036d46e3b5eb32aa54d13179646c6de7edd82a01c267101b7ac34eb90e7ab8ce255402c457aabf00d39920a1669d40cd0175c9fdfdfeb873ec7aff7f8e21a7deaa7bdfcccbffdfaf57e4f4fd6e8b23ae90ebbd889754951911b09c3348964e257f94cd84d156bf92cd1a9c9ed6195d6b20d941771276f056dd1ccf51c1f6257ea603c05504b7b4410f036bc6cb788a32685cd62ee3677882b4a14c699f6b0c49cd957ee933e9c85d4518ba92efa698db4380a3eed830d9cc33aae123ed988da5f4bfde56e3fee5bff83b6fc81df3cb2f2ac62a7fe89432ded9c1f70d4c92193973bfb7d8ee9d85f5964d5b08d235c24a34f7d856d72a893bfe6909d1cb95afe1ef3fea37bf7549fefa50317a9f3a28dffd49ffa790c7715fdcad3b96bfa541f1c38c9e2aa7be166d0f7bed0cbd9f8ec797f8437e5dd83180d0dbc68fda42f07216c36cc465a0ac52ea6b926aa7bc0a16a92523dc6bc8b637d65643a64d26579aa903da71d9a3be6248128c614df66341fe0b16c333019e0b105021d74a9d31a4989f8cccd75a9e5c66577eff3bc5cb02ed91afd3dbee38fe39f6286fea997f9ed5a69a7f12fba8b79a07782546d90f6529bb366e7db1eca94176515b409c3b7526f26a8c25e4cf362aa4f3641a52c041f7624b20699dd26414d35c4e19233b1f01d7cc76a89e332def975c308070fc2c93aa6373bc69b9b800eced6efbfc60535fa8bff6c9fb31707edaf94b39d78ddd3b2f868b7b24a94f11b3bf5e1bb5eb84b74d526bccb5fddb327fb625f810bc8defe4837f4b8fe2b110995d6e8413aec63ccf091abe77d7fff4fe3d83363bfd888f418b7f5898b55c20727dde2f8fb9c2ecc1299839254cf745c434422e8d2b07da0459ec8089688b3307eafe172a9f6cdf137ec04c7dfe04cf5af1ae364152b638eb457e7f8e939daa39e847d91af9700b54d0b2ca686c853db3709c7bb90a11a8da5c6cbe196536f96021c87baa4332a05b7c536b4079b442927dbb52bbc3ff7baea79d8fab1e6dd61074f5909c48c088bb98d3eaf5124172da4bb5f5aa803203e6230bf9fd3bc9493ef383f7dccc5bb3be93b7b3dbbd65e3f33fecb7ecf7458bde79b388d7f193f7f845b54a272ae8225aaf31e3bab5d4a72826ae6cfa098cc6dd30889b8957cb21444cd38c345c041ef17399d8df19639f60e51794b596c268535e6c49af99187664e3e45eebd2e0c6f8b0b6f4479bcf46b68b0d2fea63efffe77e2fdeffafa9c90f81ad8c6c3ddf7e6ae3be4640e71a67ee9f9101a5ac52c0f02902dc958b49221136b5ec298e7063a56a10d2c646080cb6e4108ba0940b316a552bc1cae135d8c13da74a992c13c625db0f8b509391ce35e4e52bbd5a5ee21e6b2a9a8711d13f428f97687e0396ccf97bef7cb6fd6e1a33c6236b7c9de1759bce69ffb704ffd7e999fe136ab8683790872e1e0dd6bae913378b603e7c6c10ef16e237479c23ffe99bb378e849ef05f2f7c44eff1e74ff9b3b37ec933ef0f38e397bffc76ce7659f59acbe45cefeaf37e6ca50e77e98143ecf4fda3b377799570b39c72604e2399bfbdc33f7e3675a0b69f9bc93bfdba779f5b255c3ec81168e721d8890802113d730a6ae7f945ac267de6478e3f72441e6d542e5ef9d682c3f6651dcfe0126baf12ce9b9ecc0f3c3b997ea89fab675fd281af6ac9e7d7fa23bf8bff91ffb9c64d5a976dea7ae0e57357e9d1eff6f72d5a5c5c4739bb8f3ed76af1af6baf4ee3beb55b4065b5b7c916daf607d8da4da08b6d6c203bad709d96980b5d7948f70c5cb696e4839db07f2d91733f40ae18a54e1b6540aee78be11da32b9356ac120563b81a3ae978a2f9514e13daa910ca786a08368b9a258622ce986273a7b9935a5e5c94273bfe3e238ebcf5995edd33f37dbd7cd961be23996795b9b75dcf79b377efb7279b70595f4b0f21e5120475b69945508b7bb89d024939c12a232a22ccf3028a96c9a29d3007dd8574d5257ca0111683988a9c52dfe425f2e4d82ac3426eb3822d421e6b29b4b6a12b2c097fefe691dc32dbacb35e3e64478cd877efe2eeebbce487f8e8e7fe8f6b3fcf6d76e0993d7cf765f85a8d15f3da1f084d05d8f5f8dec7c1bced39f50a19591d89d4806a79cc5d6f42b42ea475cefcc5d04e38e2b3713698511006ca0b67a37612f71e6046c36464dd653d16b4c7b7f3d26b833a7fdcc7f9419ddb53fd5c3ef22b1e124fc9089dfc9c67deeb4b398eaafd9d3de56c7dd8b71ce5b19e7f85a5d0afa4277876eca32d3ac75777e242b92cc76960c3eaa7208fe61c2c88b3da51da89b0c7b3796d2162782229c183b0d580bbcc9375b9a3d4eb894df5d46940aae3a9acf09219fe26362c332c1ffa00088fd5d6c4b7878d4f735df470232b0fcdcbaec4a537ba2e9e4aace22878c7edf5b98ed4f77280defca0334df6f6cdfaf5bfa3dfff7347ecddcf627bb54a47601773f36b8df0dd07aec11f9ef3d7631e629b2675b66d56c1b5d0698b7e10976674b899d178296cc052eaef888316c8f616ac16eb506b060c5a8f81ae2da9f2b682e01abbcccdea6649c6b2c54caca63a7ee40c01bf1c969478414cfcad5f0eb4d4804baa6766124df4a4823ed31e768c219e9df5bb7f8cb3d5d2675d80576bf1dc8bf6f7b99f8b7bd1f67eeed1df34e2e8ab582cb812f780680e9a4dd1c1d73ec5636f9ea33dd5f02fd4a2f3ec19c148d8bff458f31a54521381dcf21d310a885a4b031ab746eea2e8be635079d4ce73e9fabdaf4b9884c325a9a189342f0a6d18cdc7390e6d8429f308238cce1d7f1b56ca9e39e64d5cd9fd8c4b9d9cedb7f8d2567ca336fe67ed8fa73aa2e06c3be5ac931cbee6b0fca8d352a35c54f4491f65f7394f235269245476c8c5bf70781e756fffbe4fd22797f611bdb7ab5fe6d3aea031f666cc838fb28fdd9eefbda386ee65da621cb7b3c807d4cd8cb0f2b7d8108873af4fec813eafd043a0d926ad244edde606b326f60d61a6706286117484f207dc414d5c758cdbc3a950994e7505c2c2523e410a4395a4a0e128926556311d81df3da9e555f53b44d5e5d2c54f3ec39f78337709dfdbb4f8f5fdf797fdf8d7bcfff6bf01691f7af0cf6ab6db57c0c3edf711eea53b79de43fb3bf2094b72a17eb63657d600bbea213054430acf0829d4a8d679a892c56c3cd960de74bcf2bb54373d64839ba9bedd6650ee02def55417221cfddaf152152c6c95af0f2dbf96b6d4bd9b90c95968c8dc2f903373bd07b4686daae4f2803dfd56bcf66a6f7cae697c1d8eb6e7f10efec47e8eb58316fef1fb2fc33394701330d8488ecd5b6302a821d6d4c8fa506b4cc487fd541f86a1529379eddd2495bd91b66767919748db7c60513688eb409f93fc2ea81bc474f4c88cc972e6740d2b721817c2247a6ecca04c10100e2f58322f3ff725be1307a4c6a4151c1e6bd29fe30bfbab685e56c3dd94b33cd6ef8ffbf879fc53dee1327cce63c65445dcdf46ca7f99b25426e5f160cedbc8af632308573b52609c546c2c68096e357c3363f92ee6eacee7aa4e8bfb4eea4d138ea513174aa7da30920a56a4c62dd56d2d1c7b610a20cd6a2f4e225132d6b4d7d590feb33688bfbbd41e0d776908caf82377c899da2fbd4a1c971a5e7bd42bb14f6bf9fcba3de6502f3b3f299974a44011d101c48c85425fe941a15c620f21821e60dad011c564409cfc6116419773364b6dd921286c0ed92aaccb9d74ee7799de8d88a2036cfc1ee0a859a5402544570b5e3e1872cc54aca91d56e8919d3d3f5ff661f7f3bd3fae2b6df29a67ff43fe176dd2832e1e2b8f396696a7e1eb1cf9070ef3f680a98db09939ec15ffb57dc8ebfe7d0df7f7fbeff98ebfb4c92ad09c72bddfd113bac63df77acce77d95f013e6831cc7b90c3b190f84d6b5b77dd085e1af41a24b4049b0497b68fbc0f342e8b509540eeef1362d4d33d54d5d727b89c6d62ee308a62cd06e416cf891ca798146684c8db9e32d8486fa40178f14580d2a1898824c97e5aa631769b15ecaebd06ea65c34d3fdfe0a879ae4e63ad6db4da0effdebe101679c44e8b02ed9a536a4f6d7877dea5a270cf29798da6bc46efdb4f654ccbb6d1ce18743ecf6f6394e7a2bdf8eddba2915981af8966a802765bb0dc8641f0b3dcc5c34a2cc6b1911cbd9f82f6bf33552b2626bf93d0ed06b605dfb2396e1c89df26afc1327927f91ad0d2266ccb8ad0551de31c3ca675432513df4a8b746845937f35aad635d8c02ea45331be471214718c811a7f811d9aa1786bd8c353c95eefd362102cc7853f0b1da528ad79921fb98c33be6489a521b64367b94e763db9de02897ce691ed476419d4ec5115213976d850335115a5abab3f67e99ca8ce05e1ef43eac4db6b0f4bd1d8846936f9eb33ccf34b5ce0cbcbf6f496c784de60667f32ea9611d70f2271cf399ff7e58f3f4adbdc77956cb267d851d887ec499717fac4f1fe213eb10af1c6a4c6ef76b32dec7bcf64f786b5f743d1660ef4f95dfc8cd5fc547783fee71efb2756ce0bd6fd9c6873c8dd65dcef703cc900ff5206a101f0766a6c503ceb760e6081200f9ff90f76f6dadea6cbc38fc950814afd1436909144b2a211bc819902e29048a2db6c0a77faf6e74e8d039b4da39df67adffc1733dd6e93031b973efefdfef0e4548a75a0762ae56d4cd634a1b87386042748f4a8a7adf06954fdb863ae33dd6349354ca492a2582121d6718fc52ac51e5f582d97a404dceec72ff739ef3df9cb931df1f7b6ce6dcdbc61c6de611fe02a6ced5e6183edbc7d1ee7ec60573e91c831f02571af0462ac190d6d63e6f5a61b70576d6ba30d036a479bde4fe0fcf582a39f92a8ffcb5f28f6fd63c9c5d2da2e0157f7c7079cf2995288e020dd335f049dc259a32fd3257b2ecb65981b7929a8f4125f594af359fa079cca085f44643301e05050eb18baaccce370848bca092675c8865a4460b7b4ce6da5e4765bb5b4eda3e54de22d13b3f1ce455f1d13297b5d9effcce5570d12eeecb7ae6edf97b6da2bb4abfe14b7ffe8903e9fc7b2fb2c9c495f9d295262fb29e385b43aac623355e90da332578d8f39af94b768825b02d1db8125c24a10605628d1b5639978e2c9795b995cc5399912f526635d2a67baac1fb3bed578f6a14313b5721409e5f4b147c923fb8b0165165bd7990f76de6402d99fcb51fa8492b71ee4d79fd73ef78719ab4cad5e1ac4ef375b377bd3c5fe72d1a3fc52ffd241ff7e89ff60d9a332ffc2e759926c2b77fc78f6478b5fe0f70c4d5c1f72a2ef6fd8ff20bf671e47d619e8e5e09d7f32d5fd8d13778bb8ff634737119de6740c79e0008073adb27b41112dc0e01f39eb0f1b0414c3c3197f6a1ed09e1362b0c6e35c4992f07a86705ba090aa4f3b2534bce4a3f42d305cf9fe20addc743b9a38687965403545938ab5a7759e09c0e2a498dab62e71ce4ef387ff2bb4feb5877ff69bfd2c3b7f4e7c1f673dc64f517e29cabf826675eb8092893c81b5e64e2f73ece7dab97e59610cd3b16c132715a981ae2d12fc7d55c0783af2945fb3114bc2dc840b5658467b4ec388216e4c4eb13e8195999c704c247c104c4ccdf1327dfc4c41a49cdb4a52d455ad09134d414b93eb8d3c02cd3c6f7e8babab549abf2b5ee02fffd2cd06bbebebffaa8c395f8c48f6f207ec66d38cb40d66b9ddf8f4617f74a95b9266c5bbf03961d94ea5150a607a4ecb2daea9625d3937ebcf1fb718334a688824d56ab8619ec2e9c5a3339a82273d51da150f3ab468b4b68300e43e1e4f6dd400d1f3c6852490395aa48ca368823d42c2ec1cefb429d7f79e41d168718f8375fe1110be1c77a61f48fb2541f7cbc73dfea1fb224236ffbe79b16bad21297adceb9a92173c64f993eeeb37e3c1c62bfa35f65786b195d3afffd227b1fe02163f3c8bf5cb1e1531ee8c9a8bf0a36c59b357fb56f3f6bfb7971ea21bcc8f7abe84650aa65c5ed2e61f229b3e1084f1f805faf87206c17beed6988798b793f5e246563d02ae859296698837e19c99128989e81669b4c7188aaae593a7b3d58b5c672f56b24266d1b334c02de2e7c2abc442b0772491fca97758afdcf784fff5bb2b4fa7436e314db5e216ff7bcde736c70f85aeb4efee465393b518932e5e32129ed913f9526eadb6d40e08210eb11d3cea24ab43c62dbf9907528ca9b907630a97e0d89edf914e22289bc9a52f389db6c9a16acf675a0d122a744eba6acf236a266b94ff3bde0a31e85e338feb03ff1db3a2ccf6a2f5f8600a4d5739ee91f3976cb249abde15df5dff790bdf4e4ff9ec77ee1027dd7e7927079b88f375884ef6304a0b24a2afff72cc347b81a43eac021b9726cfb472fcbbf131b18a8492b7cb4c55995836fc508d587188a8dd00f71f067f9ab63dc30faf99b7ae6043ebca9e7afb5e39d2e2ec450239155e1a90c324741e65a937432b690f2b505c9273155774895bb807a744110648eb75a12afa2d3dbbd2c308c6b11042a8f301fe7b4802c50d63c1b50430b3a64762390c6345e6d41a8c16948a89110c8fe0d0caed9f4524c5db9fbcc562ec2d175f8ddf5f139ae1b6b73521e73d997d5ee668660722f610e305023a9abc76cb0145bb5baafffd2ef403ef3a9ea58b91d09bbb9c79c15940b9af2f62936323360b1261c64cc35bc5e3ae58870bccd98a5256e3eca606326518396b5aa17d0a3296503eedb0b6a779fe7c102f7cf37376eb2df73401dfa60ae2570d14dca611f1b4d9ef4e3a3af3c8f709372d6bfe911f873d6a53af5949db9a5ff9cf7d13f9eb13ae2d41c79538f7cee153bdbda577dc71fe44a84cbf6a9c346229a0dbfebe01fe9d43ff3b12f1c7eef31129cb12122af8823a4def1b87dc46dcd559bf08ff6fcf1cf671350c4dc2c04ffb3dfe2a3de45bc9b47873dbfc61af8b386ffce361cf4f1f3ec529b3a70f4c77cdb8f7df579115ffad6fb9823256ab69d73f119e6de71260c5d2176cb2a58082e403a01d5090bfded3e8e39f1d5857d8f4c3e86c05a84656c2c38d6c212f2b4522cb5a5cbb45c6063dd274a8ed854f0c41eed90a375a4c29b58adfbb41c0f98c69b582b3bcc719df13d5896284c5c7fc76a8439f3f44ce58574f38d8422e68a6d9228ff7b4efc0b363371e06767de5d09e7701d9fb8d60effdf7ecbbf2cbc5296bff64c519de8ec11016fc3b4c6cd2ab64e2aef8650f888eb5b3007624edd5b2021de334d716437b31036733f1c4f968ee7d01a57075f23201e61002b7faa8a98e296d558f0a8893055ab40f9daf2139e9c4bf3cf1fd5385f74e515f267c73edd8bb90bf23ceb419e19ea29eec13ad5c79b2f7013fca95bbe657b0fb237e7a77ea539cf77a9de1e73291f7eff5c57beec3d2ac78722c07ab359ba3323889449195c2c791b2fdc668ea0a54b9bd919607701b33a69d03d52cc5916701b1702cab204be818264ca663e6fa3a5938d88ca3d44bb41286fca8b1cf0a95a2440d9bcf456731d7c1517e5f80644d5e55fe04ebbe2598b6d7ce24f7bb5bea67d83070f2e797bc72663ecd3f691415948d7da0b4d594217840c96160201b8628f89235156d84662402a3940e95458a28e074c15491dc690011316353b6e6387d970c66c3c45b6799f6ad98ed739f335a6a73608de63fb7e2f7ff4d5bbc90cd5c6d578fbb5b7f0f33edfe3fd44c84cb9b74bdddf7af2f73eb4eef239331010070da901c15ddf9629651e2f671b54e39db44d2734ec1dd2f0ee0eacf792e01d9b5a37a136be23d57e48a19aa35ab8d290c0aff2c7d0f537a8c8ef316b56cc691a46a91957f23ea05e1cabdb1d36444f076bfe6fe0c1cea6c77ad93fe8c7ebf10ea54eb38e236ff51d795972d87f013be62af3a427595179568d5ee4e4b4feb738965946bd30e3a596d4d460939666542e840b2d325841cc10c706b2b1d6b040413d1994624c2e30f0844f9183357cc379ee337d8c90d660cc599b569dce2aa4cf818229f77ba999d1c2f6a67e8161aad8f06fc49897ce81250eeee73c3f9cef4e185e9e8687f3fdf4adff898bf0cdfbfb68ed830f9a97d90aac930869e9d11fd58e18bbdfc12e4ca69660cef8ced799914528e7057ac20ad3988892d8631b19a85b4e5a28743c4593f63ed6d62631a8b1548d9dc2609f819c503b9f65052a969c3dd10805590457acccdd7435de6155eacbaaa9306d636c889bf45bb3615e9ee9544793f3d9ff338ed43ee6edee4d3c74616ee88333df1f623971c4803dbc63b08babf57f54437c7fcf99c3fa583f62291ff6dba6baf778f285beb4ef6fd51c29f5f458e111753a576af9a33f088f96718754eea740c158311d310597f4d7b098b24dc2fc7dc8fc6131f53b5121c26c336670662ca68c4b5b38bcf0f20496863fa01bdf69cd85dde8c809f4908f36d4f037127c47463e7c13afe3e84b7b0d4ff98ae7f9b608a994c3c3b9179fbdff0f7096bff7fe0f3f33799e1f0783e0204f6bdcc4c6c9eefff3fe0ebedac5fabd88232f48f4ae60fcc1a0e538a2e5d6088cb847c00ba483d79ce72cd3d9360ec74010ba4bcaf626a958cd6a11631722bf543e260afba5e7a685bae365b3f67936423ada232206198e1d0120595628a2c319fbe2473d728737747bce53b07ece9bcf62d4fd7166e40a31ea299765e5598d54b67ad1cbeff673c4160f47c345f148141889d3e882c73b4473180e326400972c6a38e3f976e1361b1cd10d71ba1c13cbe351539288e9b142761259a340797ba28f34c67363011b13530463f2b05f388ab3691e077a73930e629432a5211b3504365fc5485e2f234b6595faaceff65a78992feb1d759cab0e3aad11936ff92f05d5e12671f3158b501e46ac4b2aa1cb0a311989ed5c135b7f08fab088c1d2913e81aae7514ea83133330eeee61abb0bfb962c1cd4d341b421efb0988c73a4971bea500d4f2d2400ea256c02e236ea4e87d38ffc97cff2ac3262cdab79d23ff9bc8eb939c955f92c7bb3b718e897d9ba97f37ccf47f8b28fbfcf2e5e856fecb4d6af766e30909c66162fe6190b9d8660e819a8920926ec8e7059c7069e05157a6415dcf8d3874da8319e40e42514dfe0caa40be69b3167751add8e10f377b1f254a0048d0b8c992d725a9a7b69afcdc46022a6e63aadbc05a6e34d5cb6abb9f69539006b2b381c446881cc39d824ac6693e31cc06f7f619a3da4c6ec2171549d38ac9faf6e1f88de95229a3dbcbca9da7f483934672e3bfc2e749c2fa9bd3cadf02e0d1f9a99a39e660e52598df3848f1e625df5b1c18ef8b2698554d6ef1fa49e37b1fef09044fe43a29b3ba98f1ea4f3eb21aee843e67abbb8ea0ef6434bb8ff349b584470faf0eaeef4c5c42c45141f7e6e27fa23feef7a1e3defc1aa0e7f8370981673b5cdfad11b99882bf5f451cdef20c7b3df98faa7cf97d9e82fd6eb8e9c87fabf54af3bca2aba8ccba35852618786d7c5fd58080745b8329bb0ca6f4212f4771abca17d5b935ab62c6aeea9260a5a22cc23691e22afa0f4ccb9d63eca288f085cef7099c3702a506ad81da9d40da1e30933148d8d7844067ccf4b85fe9d78fbd27addf39981d53204a5e02297bcd3be9457fef90cc7b3acb4715db6c261551cb1edb1efe51ff6f58db90042224b8b0db1c2fa2f7d61c32e26708ef8b8cc8a404b389b4b7dfb439f47b59933eee50454075dfbe9bcf37b4e8deff9a21c1c39fbe75c1ccefe38dff6ee7be45463bbccd7118a33b5a6dcdee029c441d9dea4b558339a8fe222afe228df66b564699d0f82622b2ee11e4da981896510db6cd2c15b1180e669d508ece42859b522a1b043051c6525701308370bae62566d01ae9b9a5270ddf980e79e5f7eb69d7fafabbdc8ede1cc52fd551d71720d8eb9f87fbef7e2b7cc74f9f2538cd3d995e65a5edecc368e1af3adec1ef7719e3dbc6436d38b523a0e18cbbda4fad5dde96642ec6ec2197e12b5dc4a656dc897e5eccb39ea4bf1d19a3462fde17fc973afcfdffb0abb3f6617beab2b40561dfe97e7d9091fe18f7d68e71afb576da6dd267adea008f5893ede25951a510751a4dbbdcff2d59202c6c27677fd3ec0dba7c564d42dc24b65dcacd2833fe77e89cfe71a7ec993a8ba46e8b97692ed97f5cff5d34bf0c0d1cae70d128ec0044223acc51da62d0c61a60b20239f7b55f2373cf00bf567aa9bc52b9df9519f9a9155709f9ded867ff95dac0f31ce97e69baf8293a49e0e7e7c129de69b5fad7fcebd0597e567fbb18e7518a3c958a48e3d30a33109453a83f09e43a5429aeb191dcfa563764185c152e159e6367bca9a9b20429b50036b5e78f33b8d3d05952284a81b0cd02ea44291c88a4323cf918385608d4723a8ceb9b7aff8214fc9e77cd4c3bc78b8823e319bf35936479fac1f8d2e9b416cf8dc504080b897511321ae1055a8e12534b18bb198b44f4b17b3b46a1471837dccd142b899b970da39713d5d328f2fe96ce4bb78a025bbc7449ab2945ce8709bc0b54e4b330e740043a765a1e6cd970efb79bf45641d71a5e7d5a739ad0f30cbbee71f670e2c853b7b4aea637ef1f5e7b3ec5e1693d3816ae154b5215fefb3ca1bd152995989118e18c06c36426557a68e6462500ed559b27030a07ca60780b97ea5c2acb4075402c1149c50c3ea991def78c52c69089312d6625b02520b8fdada3e28d5d67f3fbf741137c4a5b6f5d80f514990f2afe027d8d7d22fc39cc35e18ac3df1f51de3973fbe77aa017fddbe1e63d211751ef6b402dac236212ad840ea465f32d6325d7a7e846f7c1dcc339269a92d2ddf01fec2ee04afd02e8c9a39311a3b998a591a792225a8f449be4185f5143aac0f86dc5ad0b65d38ad90e4c1585682e0caf43f9943bf4e0df84b6fcd3fceefc79167cea3af60865ccd2f1de6476c1dd82f43f0821bf2c17e2ef54f8fef8f970052a55436883d7655b98c989b703c0822ef332d1f49c7f310905c300653a3a9e96a5c23c32b7d3767090782549dce9507e7dab6275c26cc69a225c97a44552578e70b260a4c3513e9a095d073f927bc6417f6411d6435cf0eb17a946b478e931316cc73bffd55fad52fae071fee4687dbf43fc5127a8baff52223bff771aefd5e36ab231c136511dacb823d3182fc54674638788bb9511aa1d6694b17e78921a8e4709a016a6245813f1963ec80322ef3c532fca5cdb506d01aa3d0852123b33e1d507707b2d182299c561863cea6ac96f3bb0175d925b3845ff5d1c3dbe3bcf5bf3f8fdc3d260eece30b674f4ff7f48538f72a18444739697ecb47f92dbbcdb9b86353d927868583c20299830761e73e06b297553e092b5188ba59900a1a9ce2451829ccede6c6b7154fa8acd0c0ee17369b50bb25c215865f7bce9dd6b9818162648b64e1e2222bd0ca27ca8f41d37dc6677831e76d089ab412bb3f305dffa12fe863fed7dff776ca5f1ffdb0cbfd83328eb09af3f12aa958f1e95c5ff88e47ef7bfe72e4b727cc21b08bab46c54670f2e7deede7dc2b7659ee9a51bdb3d994f6c8953b4a6e47311f27b86ed67e3f4e5085d60b56ee309331a6399e6b30a7e5684ff5769e11acf96563f86ad6fb836f4a88e2349280556381b4ce4f6d6f1a97632f751ffa3452c15cdb8365b5ddff7fb057ec70576ae9e297f9f94f6bad57c88fbf5ef359871c6def89a3b3bf0cdbc86e33aa8c00d04eb0d928182415659e272e5319cb8b85236fee34e0fd1b399b2336ee37ecbaa8d9367565235cbc9e73b4130e6d3367dc7c8e23714dfd2d40ea7446c2b1964cc0190bdb3ac4bedacb9dfcf33e2fd5f7dd9cff32086d634cf224010a319d751961f77743a6a3693920d0b07718735fbe8b8beb43c3d73869832bf557bdacf7ac1f4fb24f82cb79ad09737d17cfa5ed515caa9618d04ecb6ee257b98b4a6fefd7b00835e60897ed908b1349146293f10c952696ab719d38b9e90fd60e11064405aba5bdde1107cfd0a07ce2fa7da88b3e2d1e00b3bbf992da46a0d855b1acdfbef5d733ad3fc7de3fe23a5fde7f75b88f26ad9116f36e2bf8992bb882dbd4fdcc9fba7df2fb6bf9dd2f587b4a4cc03396c3f63407fdb7ff7ec601beccb61abcc8473e6f06a4a9dc775a1583db5da0e5683e202ba85a2b8dd8239fca88ba0227830092202775cb1de15b0db996490db6a591f514da9986ca314acadce536dc87d47c6205c6092c070ae413a6e8deafd7e0ba7c1f6f314fdef85fe19ff3746a788e6d93636c87d59b19b39fcfb9fc5f800771901f53091d6a4924d43c6a5476e42cfbaf6ccdbbb59ff5e093e032978ed245086e44e4ed8e7cc317ccd5f821d8b2723c0ab967a35aee12f7b6cfa692319d798463460abcc61afd9fc9ff1ccee6f399c22be5597bf09439dacb59678ed69ee7772e8ad31644c040535532552369633b859699da66c09dfc26a9919968f9406893f824b7a861e5cc68f0927a3d822a640ee28962fab282b33852764019f1ab319b0f689e39dd6362e72ca931a1a5d9605736be1def137e419cf6afe1f71ce516a4dc539f7116a0fe4a335147f9606d5cb1fed9077bf94cb2cbe7cd48d005baaa123dd305c9e992772473b0c65c4b112850160912948c2f15d6a49deb9879361a82eeceb09e78915ba48ef7fef45623ccf3d114e11058766a6fcd58933aa96f75a29a882b36491dcfe5508d968e7981aff065fd7ae483b87c8ef0707fe355f225fee42bdddd738ffcf3d717eab23357499f51ecfa3a5ac546335adaec8e56e37beea0fba4c66536857773bd33b3296c4935da2f1d78932a6f584cda56526f2d002cb2ca5c1d62c3e594c5888b7b3958b3b4044f7125ec652d9e300550bad0c6b481e9f0c9ccee156ce2177db0535efae0e7e8aafc8c23eb8423729d1cc6338e615aa3469c30d43fd88f365c9ec3d076be622e85a84e23dc49fd57971878b4b04d3b741a405d99301dcc12fbd746e8ebbd28ca01f3764dec19a0958c16cc4b442422ced436e42d4175a3a8e3eb8c7851668f4bca9427b55c2d989a221b47987afcdfc8617c27777de63bfa4aad0a5cc5c7880e76908d9edfdf79fd735f02bdc8dec9aa9bb3c136a86676688a77d28841c060e86ba8f31d0f539bad169376830bc442b0ee45a512528e23e9361aa71424c49a2e4b942c6d614bed1758b8d022406a4b074fa812f7731003cad5931fc9c7c0800ebf2ef6d93a7e8b0331fcb8dfebff82dcf7f35cea7f841d70d00fc3928355aaef9ff5c5f3e76f61091043364995e754a13a8bc43a0d7fed7985ad18e40b5e07660a55196a621f03cf6653c6086480b33c4841602c0866a41c972c6ceb0c063aad9b1dd2671a2bbc19e3fb5d6adcead88062312db58035862c54155f5fe6dece28bff426fe3caeffbf20877ac41b140eecb30a9a5f92c1ebf8f76fd67dd67dd2557bc1f1193fec9c7bbfa0070ed1fc29a4c8492a6107350a7d1def330883d49150d44d4e0debaf3d705f3c33338ebca7535eec10cb7f854fe93a7eda6936f93987f2f27effd8cf39af72596f034f1452f16abc0d1db0490d552e5ccfa45078a121ee037da4e129dca41ae878d8ea59a41e13c5aa7840a3256d353ac525a7e31121819681a64f6b88a9d110e1fac3d255f7996294403c5dd08e0740d4c431eb4f6697bfe427c791d77fce3d792dfe9297f54ee7ae9f65f7423c0d3f040051b3a49aa83383ad630a26a966deb142f01058750c105dda7f8dfbbf743622fa94e7f77a7d513a1b9d673e8eeb5e9e0bd174ea8a1b619b2356cd7609632ab1719169a29050dd2c5c7f93d8f60fcfa419e611de253a7bfac27cea7562abda6fa533de086e9e7a1d5f7f3ee5d02fc461f1ca50b12a7510f475c49665db90086261a0a924b73a561658305686b4b9f71d4f71ee05899d2f90b3d5e3c8aac31a37a242bbc0c074c1bd62698ff79c7a5a66077da22184145a2dab4c0b74083290eda8fd0946da577c9cfaa8b7da4ff5647fc448bb42cda239623aa427fdf878d48f1c6c8fb317477e86cbf8ee130dcc90368eb9bd3678e42d16f4881f4cb8eb3d49821b3e5526d1b71bbf604f197bd0120e885f997b1909ca296ed37e8c316b7659249304a83ca478e3eb0d97a577cfecb187b98489037d62a8a740f9e675f3cdb017c69f7390b74fe84faed78a0d99eb3529b7bf346ff10ff36a2f67fd6a66edf7f95fde1ff098e9e3a739f780a8c4a7b92cff5ab9ac1a1d71a5241795886627197ab38f733c7d815fc28c8711e24c5f4eed2eada889caee6661e38da81e3631b3928c36f50ffd92d31e2354240e6be3106859058f76f0d37cc411ebea0ab83ba7731b623d5729b75be97af9c9ded0df67f8e1feb413afde65ef721457de349cb232008a21168c888360e2e42099ca59583c8c42980336a02ed3ca8113eb8680c6097591609a1719944d08e92eacf39b6488fb05f5fa4c87abb90e5042732c9dd2941a08ee86070d312f10049df2135fe0357d3e0779ee3b3b9c55728c5785398f8e3efc4e46417bfcb94a559fe2135f0b17e9e27d1dec7933a4fae83827fb1b1b513d09fdf0df81718887538369737ef839b31175798e21bf8c9fd1cdb9b912046ec30a6ad46d6eee86dcc8a6d009064b4b0cd973bbd9e29fda209d99f273fd711d4c8ae35a87b36bd5328acffcb217d62d22b50957bf34a4d0623ea839b5b55da6ab22711b8cb4b1ce5de562a8e618e01c3bdd9c50390d7857fb8acd17761b2e097e8c0bab5cb8c889fbed9eb9c19e33f5c49cbc5bc0879eaaa60ef4cc40d00b968e2c3ee6c7fc764cfd5e6f4f66ef7131bf706fa9033511216d1ebdbeab4f7187afe0eb77b974d82027e0e5f71ffcb70ff673e62db9ec7ea5cee89d31db27006fa88265a0631168a69668c06020c7cc063033e43c2bc524d1352dd65b4c34c01327ef125ba19040c6a6de9af0f5c6e7aa119a5a0b809294b09a39a0a72a9f906aec322e7306cb6e695ff57ef731479b984b757af7a3b3cf109ff063ff73be8a4ec9ea33b9b87dba8e6f795ceb60cfb622124f47ec924bfb60c276c5a61e08a71822dab998c8f55c1f0d221205edc703e5dd1db7d13e8c6ef525d74604c83bc41947abad8e343c647cbf230eccd9547661e95972eaf5cb4aece2f017a0d473832a1f61478d7c8e919c7a1b4aaf8b739cb99e4a5d568a106cdf624dbdc36c3f7359a0b5e06873b2df2f1cba3fed5d78f027476e904b65e53403c881398f3c9545ecccb3f1f75eaa2bc9ce476b1f65e9c48f05dae52b2ce7437c78b16c516113e5397e054452e375c8bc081379bf70821d9f4a6b59e21172c61aa5f9164dc6983b1ef081bdc3ca33825214429f6d7835b663c64a4473831474900cc6c4868d1c323d35d0e20e88dcb74d18d371846aef23d9fa941f20a9e3df3a83cc3ec2b7dea57adbbccc3d4e3ec4793972029cfd973cabcc732ef5cc99b2fa80f7ab62b978e5ff080edbdf3d35f107d8d048c9638fe1789370fa825bf4bb6f2778ba74de3275c6651c9d38ccfede4b611bf362760db9db89e34cf1c12779fe5a7bf9fd976111c47da261280835528715cc65db98624f529352b71c685d6a42ebdcb010894f7f0db2a45d62783587cd22ab11bed33a87d972c6ea9c27158aa9eb7748ebd6b16a38d65919d0465fc03cf123ac270573a4427fafcb5f70def30a6d53dd54c2612afb2417812623700d5ff0e3b55fdf8359a4cef84970ac4474db9ed7fdbaef4cf0e362327ec2611bc82ad043bb2169e94d964e1ea79a5aa56e73ff53fee397bfa1c6bde4661147f8b3bca2767c17ab1fe715b7a98ef34c7f783aec35ad502e4f35ee8fbe7f383bed82f99e6ecee423a3e68ed82c24035edc19ebdd1c889a1ae58669e62a2338f92b3ec1d7ce6e97399e4aab4fdffb91fbee0ab9d86daa8ff77175b0df0fe7b37af97c29fe6537e7b8c6030a7c8eee449907bedd7441c5745f97b99cb4fbb08c771fc8d767fa7f240f3ec619c3eb946bb52fb5e33ba9b33ed6e12042b01191fa1af6facf6700b6a9215556a13cd3697b88f54ef3a5eff7732936cec97e673d71d6ba1fe1183b26c7a5b84f48ce7985873b807694371aa5fe201cb94bb4b6c476d6a70cb77e74b0eb1af06d9385b677cf159a480071e82ad38771e797f63e54d8458e2a846a70386947d455eb0514d6bfd4f7f4e7ece157eeb497e13396e327faf94abd4fa9eb81177cc8437cf7faf3919bfb522edf66872a7ce74ff13465e85146cd93d41a4207b4679c45290f76e1d4aa84c2db04e4b130649284adca0864810e3a1ac969326915719120404d2528cd05818d5f8a3c99e2b54f3d48281a2117d2c496ab4c571fdddf67efcf8c79b74d7ef3856857e2ace82e8eef39dc88109449f4d93c837fa5b81ee4894e5be1a8639fe2abf5bf95a711037204bbed7dbb5b483db78833dba112dda01297c88efbb4923782588fcb426a71ddf478ea19018b37e9a01c41cd9920b82793d60c07af1553eb6eae8b86ea7197e9761750bce62e6c50d8ee582def493856f8bafca383e04017d1ecb72f7e158ca587ff798ca557f7fe01cf205269f479bd01adae53d7cf74d6ca73dfeccbd724be1c278ccf8605c39398612254ac2fa9d7c791c51653b5475ccc056fa15f693b52cb27ec8c0b02442f1974e860ef64c590d0f18d6456919663e40f18a112194b988d92f26197ba398c09eb836a6c0bc60c49d82c84f882fecb8f67489fffde57f5a267997c4aea4b6705ce6f3bf2fad4f84c9f1c3152ae802bf466cd83bfd5c6bc5573cefaac1af7672c16fdb218cb1f319e6f49450da9ac79aa039cd87e9751a1521bec1263b6a3ba3f045c2ee21aed7c7d642007706adb80409c48bd9d2ca8b9e54eac7168e529ed46614947c9d4aa93693664a5662237d725f0a85f221e72f3c7582c29874fc77ce057b121aed28f01f2b482b578850bf1c73e2e9ff5230add698c23bd6d9141b58c6706ae8f78fd4c96f92aabba241ebe84037c90895a90cfe5f03ab9a5673ec3832ffafcb5d65d5e57d34619911c738942956961916bb12e3875cb91186e4d52212c4153c6b5747004d7221c47bc6a7761d43ca6ab5f03b3a52d0d7c1f00a5715b8e0282ee172e0e96b5552c4b34c58ed4efc06d4fa7ccf4a7561296e3fb7f6776f9d21c3250d2c977e22b183557e1437f59efa8334484d7a98e4f31c32146fb7a2f11a73ad8f8dc4c18a57ba4a311054dcbaaf1222e038d717b4786e0df9921bab0d735e5aac8aa232e6ef119cede2926fc39cededb358f6fa3890defa027b4433c7c5ee7327e69e8b5cb3adb71c80a097237b30333a6a59985bff6dc1e1bc4364da13790d9ebd19258793a588670e13eabbd1becd81ae7e68838e806e90253d5f40b57ec9269ce7d626db09e5b41e52d622de7c9c08cd09191bc2e37ebeac8d7f6d267ed7fcc9fe7a822d5412e9d53dee294eb9cbde58af8cf78eddedcd907fe9ad51cfcc3afc895bf3afc1dfecf7db657e773f4db5e7f3ee6b32fc4b3a7ed1ed3ee51d4b20834cce2420582ab9ab97e9f52ef6ea97246ddc692ecb64f815504a41c2d68ae16d0d304b9dd70c6aca4ceba5009256cbc960ccfa9d3ce1285c4b2040b5f37f7c1a0b692e135060a863afe37e69dfebcdb7fa9d7bed9a5352a12a76bd2aa55597de90c3d6852fe392e11fab37ef03d3d7f58eba8e3130ed441bf5fcc8b1a3dec59351a6586e5dd19128405bc47ca37846eae6206eb05b446c9142f4899af90d692909a2d66729e300b22e8cd89616d65a51ed355bb487420520e42016ef585030a34588f7ec956826187d6a8cf0c99537ec9dcfcc77e7dca557baedd14a953fee9cb7fcbe65c3ab37ada0328e3cffa3ec291f68e9bf5fb77dd0a67f6fbbe395e1def7c1a5cd88faded4839a6a2ecfa0c581356b119024ac3caaa332022593140265b8deacd238ff29c123892b6d6851a709242ce849b6f83aa1b89482d88dbac97b4e1cba9ec91eb25586b2cbefaa5a74e3b0f74a551dddf910a7c802173512d56bfb0b7ef743e113633e7dddd7f8cdf5264d7f0070e3271ac4b9ff2b6a73b3bce1d44fe19436e665c98f3f312173e053a1c42a24c3c6949a6834d16b15950e7946a0cf00a633e6513c9e0131d3c1e0f722f19c434dc8e965c05884281221625ae55ca020b32c59c1056a04a6d13ae0403561daec64fa1827e36951fc56b9fd9fd17797cd16fd3abd5e1bf73f74ddc835e4427bdfe698fe2957ae03ee0117e7eab7fece75b1c818f88b2423ae6269cca3ce582cf0d1b848e6c531d6e7d9ef594e64ea8bc3ea6632d8d1ef6616d79196f4789edadc370bc0d15dafadc4419b435c4731e479e414a46893e8e30576d5ae1044138f7a1375bba6cf4093fd07fa5679f12fedb57fccb3b1e4e989b3faec1b409379b677ff0747f2f9fdb531ff0653efd923633a6204c5cd551bb63cc91da82ce463eb0624944e41bde08d9409765ae53c074e68c77c2b08c549336010cdf19caced46c1f426f2727ad49345406da2f4312bce653b467bad050d54641e915197fd8337ad57eac934f1f02b574ad3c7df56ea253bc6afc30a7fb78f9fb3edc871abe80e7d6cf0b7a8d777d90c1e6dc4ff36a7ded58574597bd638710f544141399f22601653e5790fa46aeb8b20d51014434af469519910adc850017c2407782433f33703007ec1e43b1c706ea111dafb993afb993e962d576d25e8f2457c91db0d8d2696da6a33a64b92fbfd85b9cbed3c7ff5a6eed38af924617e31a777326ea2462bda8a5252b6064362c175cb4588bb5a46236abf623f1377cf4afe89c0a6a323ae2e81ce2ae7d1c799ff52474e7beb39fea9ea738c220abe076ced12e8dac3cab8e36e4a3efb707dff2b2b3433d5afd32a48359e82a23adbd20332c3dae45c8edb28b6b2b887f7c76e35270b0fb02c7eafe2a6ff365bd83bf75d4156daa8fce7275d97c3b5a8d1fb30827b26cca64b835fddae26919f40155339fa83925caa5acb1426d9cb0badc2d59d049ce7c54c11d5bb5de722a739f779c2ba471b7d1317fd80b75ab2d4baaf914db4cef36ac1acf1235d399deed9617f445270e1c426e0ed281db14a222abd4fea4ffbe33b783d6c7fe3707f6bffbd33eea93c32aae59fdfa67d0bb9ff9674ea1170ed077d853a0492bf53ba772e25afb332777ec053ef5d1d1a7ac62edf2374f41377febaf7f506fa44fa8ff20f764b0fd918bc4f5db581f6f4fb59cf3cfff59033ebc73670c62fde1773eeba39f39da4f31c45ca837985b7fce41d56c7fc6057d4a0ddc884a9dfbd78f7d2add5ff0945709ffb307f9c536b6cf6fea8893fafb0d5c252e5e7c801df7652caf43dc73bab35d76ecf91d6f53e7e0c32a5dfc29131fcea48f0fbe4991eadd567074c2c93a61801df7981eecd265bec3cbbf3b9fd3ebff560aee81cf78defdfe70b7f18ff59670d84a9e38decfeb6ae7f775912fd10abedf24557cd0e51ae67b409d5147a3070dd58d45553ec7ae35896b7123a2661044ee91d67521355be18cbd64c803ce6e01351489a31ca64ce948e1c4b71b13d3d6f2793e049a2a5189bdc4911e7371f4514c90b99e8a75a83dfffdf8f4b7bde1cfbb2f4e7f9f3fb9fd753ac3ece1ffb8fb8723a7ce74af1d67ca436b1d4742cd1cfb2175c6c63c42eaf03b8e7f37f41476c6c3ccf50e71b2ca8ce39d3c483d57e9ca0299ceca130f9ffd408ebea5f998f5964a6bd164d5f8e9c81130193d845170e4e0cb2a76b0ededc9f70d1e967c0c662edb0bc3cb85438fdc7ccffb4c8dd9033aced9db4fb349fe8f9809b252475f29e5ac4cb8fd72c7498406c9d9301f3213f5e5f5b85b5ef2ec473cfcee8a6fe1885b21aa2effc27bb8ce5ca403873917dbf8f4265ead7ff93ca47470c8089a62d0f4096da2948b05d6c536d51e4648efb88ce2fdf571d42ecd13bfe8e9f735071d7c2d67f5f31ed8f69ca71a8e75850b6a83a7dc317213608dee807824116e0322109fce8c54b3355c7a0ea69d13802641d0d7b80b15d6c67160c4fac2c5f44e6f56be213673e099316d233ab50266b72633704b2042be33dbc41c3366333daefd8eda2c0fa7decf7b095efcc5f79cabaffb45fe72f6605e64d7e8f57cf6570ef2fefc758bc29171293f78a64310535ccd81950828eaacec28516a466bbce78edd25cc6b421de5827b4d08ec2e289b328370cbb4873eb5912ea21c0bf80050849ea82dcc709078595b40b8701568e53e63b923ca719e6979b9a4a68d3fe407fff8fdfcc32cf71b5fede8b7fcee8bba2c3ff4b7fbfcd0d7fbfb7cdf3b1ff03bf1ad8140e65abbacc6c3315e73c6a7feabf7fb39dcf7253df9275e1fdef0a49625b79586a6b7234255134470caa778c7683b08407b1c410b1bcde02b6b7f9cf16350c455d3de8106328d156cc0449462c1dc99262958f00ae4bec34ce4c42075a49f55edc47760ec4388d2ebf605beb52d2fbeffcfb9442ece2d56e3fdd73801ec2be43ccc5de61ef3474fa961bd709b5e62d7e22ad827ae20a99163ee3212eba381557995706de403e5a1d556bbe23de57175d06bf17bdeb7afd4e89ecff614bb9ccffae093fdac267077b97ee8530eb749d47cb17fccbf528eebe0d7803c75d4cd9b1eb2f7fb39e7942fd301a8624936303f1b50246dd4645a1e655345fc52b225c9cb8cb77bac975aa0045916c88d23d86022d4b2662b7f4a3bbf646459e3984592058598a252cd6305379c78415acd76290d3406d42e2951287564904b667cff65ae80b767788e1b3f9db7ba427de7ddbaa79cd3ab7b0659b53fcf595d66c3178c258126c210c292d45ec55ccb15c3c3c6a76a11f2ccf4b599be2ce93e663962a5d8c80146b8963a19304961634a40f5987635a2e3cab7e17e0eac3ad63d2207ec933ad7099331e10c0843a2003cec834b6a04ffda6cf5330f0ac80ff19cf874fe3e38c5393f7e9befd63de8e567ae96368ed09070f974c4500a2fe29ff62807da72ca12ce1f46730dc6c4158c46a80fa3d8c8066f8ab56fd7c1bf39f7f2f2b736698df682a32ff07d67d7c865bf9c67c2cd21730e7b38bc97f7fb39f6305cdc8f6e1b99cd66c279e89676eb055cd225430cebd227d1c36ee94a9bd768430ac8c454280194200582027a11820da2b609316414afdab534ca9e4036bdd3bced1d402681b9452ad358aec68f4bfeb0cb22a685e0134ec9ff2decc5df67ff694de758c31baef8a69a534cf9fab3d61de3d5fea2dc962622d5115738cc68fcc4b04150a84d42728729692dc86dcf280bfd1a6e960e2803829f88136fa4dedc131b46c2c86f02201352a25166e36e41818e498e529e47a49e6d42921bbee62dd054f1e5d4d73911f175b1b1b012957a3ad8feac1aef45e469cf7ed6292f6ebfcf0f576c9873b83ad89e98a35739747b342f6edbb4622339799be7f97f11b736d5bdc7a35ee0ad5a7e4d7eaf69134ef395075feded3eda53dde132bb4e6a66618618010c6555e7717b5c85767b83a76295410bf80616728a46b26a16027a1e0d5b47b0609fdae60ad9db110333c3b7518edd7c2da9594be6f7dcce36586f364b0a0c62340329589218d84bb958ff2b7eda7b79b9c0ee98ff7fb2ede647b6fde9bbb6fd848f28e85c47a3347a004b0e772144f70c22332b91293465e30aedeec0e16ff2845f9ac8776c8d56180a56ee90ddd619673752135a3840332b1043851c719e77a142db80a1d6afad7962777ca9ac47bfea7ae47817cccf7e9e2f160eab0ef73d8fac3e352c95d5b811af31b1ffb403877f13f96dccbd837dcf6323f8fdb3e4e1c99f802711e51f6167fc15f7f88f9ffd6dab8ef3ceaf6b7cffcf6324efd2d5e10c833675d4201df667aeec03dfec2a79df77eb9ef4dde86063b439ef0ef18f4a5767bb7d594dcaf4691ef2a81c65fd384c1d34912566526b63aa830dd13012ee83160204c2486c530d3d51a6eefcb22b83d29bfa1c0e9ce09974c49abb52f98045896efa316f2d061b3badbc9bc40dfa903786af691d8ea0f383de52f3d4b761fdfa3f136bb9988ccc6fe8b9a758ff42bff755720ac7b58efa2cadd0a9dffb326ce008bb28cfa628625ace32e0dd675a6ca6a598a222033ec8f305fd3227d0e73e502dfb38b2f6279b38bbb43eb5cb5cdca4ba994b67fc594e7e3f2fca6be4e4dfac797c1386a51dee318ef02e5b69e7752eeab53610f4b69c3027d0cd7546f023ad73ce9835c70e0ca5e171a2729445c8cd7415a112dec901c7e190afd308b73eb18c60b0cc0c3613e26620a46abf98b2052f41bf20f626e341476ba1636a1a62908f89f29c4fb0af2ff763a3db731c71c63efac84e54709013b0159150698dd6d261a7bce00b5774fca7de3f629c9d7ddc3346e79f3d01562f78078443dbd47d65a756effb3a4ebd06a0481c5624fd5f719d8cd4f0ca797490cddbd7bff34a7c100f97e7b30ca1b2aadbc53c6833d7dbc9538fc4e73d54ef71d1be97d7fac7f58f71dc41976d531d9627bf01abd8c0476cc2f3fa17f9c33155f7c2b00deec8ad70da0999aa229bb2c744b37729178b20624d32580b5e0b1e536f9bd9cd9a8260232ab6cf083238856d0a6098d9cda328333d60259086a4a926778c5903aa58405d5989eaa1cb087ebad33ef2873fc53506d2191731379f7ef7ba7e80d376b8ff3f30784ef1daec6219c826e0b05e21f88963fc4b7ec0cf7334fb23af7985d499c7fc605bfefcde39eeb92c3f9d0dd9c0ddfc9e17f82673834e709c70d6dcc82aef7065eb3212381ea02e01cb7d7bbb0f2aac85aca929055658adcd907b2a2e1f3661d5d621688a057fd804c52da0763b23f698a6539c2765d6051558644a24e9251cd65fce675e384b685879acb7b9d0e909e7f6738c87abe080650e2c12fd38ab7ec2463dce0cfef13d121f6b9b97e5d8b6435ce1d6af463d8af06619e545a2d07c59cec0729a6f8412a3d406a530d08abab33dd6db2436e42cd3ba7d5cd97aac798f19459a4fdb6daca175a8317d69e75e0cf0c4a782938819a9ae1e7931d3970e1b210aae8a2529f4f1730ec5fc187fefd5bbe08737ff70c6cf1fbdc5297f8ff3f7ec9fb52f7c95ea54c7fd08e3ef05ef63e22dd17146f4e7b5ce4bb9a7dec9c3fb9e9f5735f9bff9b2671cd69fd7c8cfe7f2abfdfdb5a67f835b64e50f8a0615a454171cd56a925570cfc883994d5915ea6c8389d7ce35d3484bbc8bb531cf6a86b1f2bbb92114e1b25cd62c8875f39e105f23444ca591470ba799cdf56e84b90db2d2db618731695010da39bdc0bffab86ff3ad4c1ceba32fd82c97e3d8ef63deeebe844f467eee2b640edca4fde1ceac3cd17f3de3715fc8d58cd7c49e8da85b6a4bd51482b001b9aa5cb0fc2635ac4e02a1cf0de5922ae73ef5b60bdba429459d4f32ddd772150eb30d8e24676ebc491de60abaef7c0d3f2553cf1095d7a586e414e6d390feda2f0bacc54c1d73f75f3acbc853691db4cfdffb8f70dfdead7bd6e1bde0a636e7e777fcbdb93197120f32e0ed298b4773fdd72688b2118fa026549350472ca89209e7ed2ae1182ef81664b5b59debf9d4378416daf94494b2f54b552544740cc49b581fdb586f7b46db248872e86bdd4e4ed9263650983a0f9bebe6d1519e3add90445865d7ee17b9302ffdcc8798f5208f0ff6dd65da7f355bf8f1daa77778e4703ee7e952bd03f2e4b35d86934fe3bd64280f6d931375bb59386c40d1cc64ae95a755aec5e0a1fb2bd6e77f89e5f7fc37ebec334eb163cfee75de275e1feb00afcf5c67e691f7e5d23c321f3fa69c2d7c17967746b94f6a748323bce3241865851588c806c29508f3d64b6d742f89c088c79acfbb2a3190c15d369750f5892377ccb5fcb4565eace5ad5f6096b8707437309a71ad0fb949a4d6ad311117f855ff1a97e9e90ca3df7c319fe955f4f33ce79b35cf3af5f08e0efaf6650ef7c29e7b97eae09e4d3d1897791f5273220a456821a7d866bed4bbbb850d21a9b603e52383e86a130ef8092b654982eea543fb3bad1144093d312c0b33d8fafd9812db846129ecb9912761d5dc2ca3bcf6b576c2b4f1cd8fb9cccef2fa328ff11f70539dcff984d1fefbdc4f9fbfc34dc5a51deab351cc1a841d66cf0d9c30c337e934de64c4ba5b5060243adea23a47acc86952992e9da22e54e2ce9f8a95b0419de8de24b53bb6b05529caf11046c85916de840db0274a501fe480946cbb709b2088c4ff02ffef3ee1e8199be6f3d9ccd515b0a3dee0dd1c75ddabcfda09a7e7b2f7d2f9b6b65b7096846ed366856549dec54b6619a41249526383afc661a09a6d5c8e867040531c793cabb6c087411f30244222274b4ef738122ad184f03515f8d4d4fc12cf24b17a11b6dc57cd2c8c2c94182cfa77b87edfe2107c7906ea393e7c75f642575ae2b2d57996e98c1530eeb37efc98eae610ebf936e1e646449e76b9bc989fc502fad15fbf0e4ed1d3391668d2ea578b56a3ce0f2fc426e2b8a72eee12bd25a2b080a81f7aa143151344b35a3909f566c2363d01f3b928984f0a6bcd6c6de42b1487048f58a974413c83b8722186b21704223615adaf3716d53a8094b8473a733989372907ae88d477f02d8e5c00472e65071672f2d60ffd8837601ea15c546f79905ecf06bee74813db38c2837467af398abb773399f5e9ac330397f308a9ac52a7dec3c81b7ecf69fe991b3cfc3b08128e36732e8efd8a7202c041ee631dee9feffc9cef7897dbcff4f153c2fd36aec6bb347c5dcb9d5d36af78dafbef9eff6fc4ba07f99e474813133088c86b62de35cb837c7f696eef1a76ed20f360904ed0663aeb93733f68561fb1f6feb2bfe7f9b78b7427ccd88396b9d2a6aea7f91a00448316a31e62c4a2c9c036743516b18610e262416d76233474efd7cd1da279c5a7961e576ab6a0f92aace436ad95a2115a2c88982f2b33174420a6051a32ac2428582e15eebfca43f68ea7e53fa853bc5df3a8775ed787be558f90555b6068f554353b9fc18438de13629e8f81b517fd384aa9c2a8605d0a649438c80df57817174c654eb74974d8f3a9d52ea2f52873ad691c055acabbfb8cb1811996496a2684f66b60ca3333a566d46862c4ff853cf537eb4e87f33ce65027e0e84b7f3e7376153ed77d569df4ed9c1f6ce2edf1ddfcf1bd6f60ab0a4289a523957749e93df976be98036609074fd221af79e1ddfd15dbe07bfedcc5f639ab98261df539dfe4b5f09f5d4f491737e739b357eb1f7cb98b73ad1beee27be4fa7be2ae771866bb90ae4dca7194d8b042fd7891322ba22cdfe07ab6cb56e32801b341d6cabb1b2c7de1c096d978947088a9d6dd6443be08aace948ef01978d82183614681c786d84086f2437daffd3cd76af522c25ac25fe3408357e7f0f399941336fda8fb939fec327900dbe3b947b33671d83673be60d3c22bc56abf65a44d9de3fbeae73c57a96bbdd8b5bfeff3522ef5531c1d97db3e06b7665a7b390588e1422d7c951b2c929da89b6d40c596505370bedf503d8773106fc2699e2f22b64827e31d8be0c48fb21ed33d4076b3f6edf176c93c22a67928941461818a140882200e09b8edafdb1721f2cc085ae1a84aac5ef7acfda34f74415ef25d7ef32b31fe51ce9721582d9f73a57f8bf3c3917e45d931e7dc33e5611f8758ffcfef117a392e25158e1c6e8705c36d567a1d2eb7a394db3ba48d7ddf40f67235e6cb0897d26e7a7f1a6873005958e399efcaf98277ab056ffc8c282dac95b784cc9010de85aeccb3c29b64116e02829b004822f55f6658769b6529dee3527eaf4efc3fc94990b9de2ed6d990f5a79ecd532c007b617c09f3e9e77db986d5a73a5299e19ffad81d55243dc8b34a3ecbcc3fedefec0b5ce6d7f9fa18303ade539e6bc2f05644b73ba4ad8d3b838d08c0fb9061c174e8d269b60b78bea385bf09c2edcee7d4ccf4b65f566c8bf57227607e83993265e58d24f7202e4494169e99b9a86076db845ae3e06ad4c59ff8755fb305e3fa881df899de3f9ec715e277d7db9db0349e75fcf3fada19bfe6b23e37eaa899b4bb6d3a65be70cc794881e193db7d186e474bbb8969c16a36785802291210e8096df498582bee288d976d3e0739ca145a0907d4be31ebb963e609c7370b0641ca833d53564e222f49edd864851a8277582497d41d826ff8cb48cb2aa6e6b5a7d2a8fcca5cc2e80aefe6e0432b119abde0c03cbd9537fb38f7e73c5c363f3a489bd77244391885ba097c1d8688043d0bdb78610b33b3cd9bb81277779a0f3884763220c0f4265a3a23dd27b48ba942d8c06b0654c821eed81442c4c777b2ca36a9d3e431f1eec3aadcb04ae88136c68b4ffa73bef23e24079fc528c3b56294c35aa7b3666d36b91483e4e8dff81234e69d713b504d0c3eb34ce904bb44a9424eb191b9b1b6a079c329eac45485a9e303ae44990c16bf1b72b1ac633d51331054ddc607384c99e5fb5c68a85074096ff7210509d6d61b062c87116f82abdcb8ae7f738c0b7762058ef21773edf59cc0bb9e9854370bf13b37345cccb9665820ad55f1ec077d8a7d72859a9ee4a619eb073b7ecc25bcac7fc642b97036240f33e03d0a27de24056bd3496bce07e1865a1ef0caebf1ead7289b7a42e8f63e5496265c484356f6dca120d5f33b6a0766a6433b2c1b9fba62bf08db05d5bc7da6842e225172d89871653efa15d217f6188aa9f57e36e4dfeb6b039963ff577ec261ada33d9291951fefe2529e3b9ec3b07cd867431e70bb13731d95dc79d0518d17984137adb09d956a4eeaff1f7b6fd79ea8cef60f7fa07be321203dc6cd51094a25969017c81e10af2204a44a15f8f4cfe14b3b6d756aedb8d6b5eeffbd36e698d6a289c99933e7ebef07675ec77a71e09809a84c57cf81d7a10de67d372e2c8353f810726f850cdab8195dcdf3c7c6b7cc907130c6bc6e237bd2859dc393e22c4fdaf7ebd60294857b6e63b90903ef17c6d3edf9b3beb0f7f01216913ecdf25be0ee3687981eeca6247c9ef93ded3a7fc16a224d34becd561ec008e9e8ce1db33cd68160bc2f88924f5ec116bead6d5020ef98df0f93c019d2dc99319d65128a890ba113d1de8ae42ce3d9c0923605d158dcf963b948b2c71587b01606f3226ba9331d9fe6d4afc03d78577bf2cfea496a246740f8a08e386a6303a789bebe6ceb2c6ed0436c402002a6a6fcc0c9216dd845079938f3fa017bf7ca9ee299e47046754b1745336523761f32246850ddc7fa7a8bacea8e59dbc6d32c3da4722933d68abc095c3028136aad087146d17810516e0ebc2e5dceec5ce3b95879caedf111f3135e5b5e9e0e9031d1229b3db9dada3cb551dfed6ffc767fdffb87bb35c46672b4595f72861feedd6ff4e40a9514fdeeadfff841973c7e90ddc717aef5c35a0ed29d3db0f345dee7bd7e239f8634646b6ec300b782f79f8f39cf4204ce2631dee0537e3c07c30fb2ff1e4f32db7d1fc91b6def5b7f6d4d5ec6fc80d1e4bd9f83f77a56e4d7cecade8f2d62c3a9c3c0abe5eefceb284dec83dc7fce63fc1123f47b7af3b339ec6dd88055a1beaec501bf449b06ecf9e58e117baeee6b7d3d8042baddc4065cba23a78e2cb6415c037ee6b4d2409c8c269d1f242db5588a819808e0b53217dacc8283c4986c635be8945a408c0761dc294ac7749b944b43423414907942af1721d7b6d1a25f44198b0849cd2fe7a58a2ff48b2f6ee19739d97e6d8b97bcd375fed79ca005d665e3ebcb8e52279f5bcd82d8f526e6cd26b26b3dd1ac9ed0f120620cc7100dfdc21c46b678bed71c6f6e275a58b8ba5b783d66a321eb2c2075a8635b94224847424759a8d7cb1054fa3c902665ca23b7c5f0ca0567db2967efb896dde1494cf170671787bbfa3f075ec453dfe117befadb7eacd3ba7b03b751f0f3d85b015ef03bb5635de8ff1ce34457e6a49decb0e7681df91f72015f8909fc86f3ff731ff5632fc2b7cefd6eac3ce4ce5af8af3edace6e3ef77abde789bcb287c753a2f2c7b941ac5ab1f1528b35f339d291eb2fea3553c845a5d84654283e0a37628436547beccd731420c07a74e46ce2022da3b6d69925872ef1baf998d9519e1257c78ad972e5ebfd908f55cdc7d08cb972c459ec824b7eaa7a8eec3d466cf739f632d292423d0bd0cf05473b3ddebec3e238c523d622bead77672129d82b2ffd1b4ceb3fcd193d5e5d7fbc97355c25e5cf8b1866b7c131dcc90ecea3c039c4427e8dbf93a7ab710b430d2c2591d9b44b5b61a72b1fa64102f2556ca09d6e237332b88f786d24563a9d76741571b0b9d79aade0b06356d88b0d06933c6d63a8561278dbfbb67e8e0a654a8af5b0930f58e5808d10880c11cdc6b0c6eaa63c181f6af18e3ed9e206782ce4f15b3868bb7d1341ba9d96fbbecccdc13e328bd886e5177287b7c92f7f3a879dedbed35fac970ccd6d52f4b5d8d8dbb4cf7bfc47637f7776d7ca91bba8b16bb940743970697fcd79733fcf842909dd10e2763e471d66c88dada6480ce584b4b90f69a2e1dc6a930c9b749422a904f2156374d82f58eeaca83158848513c5d005c250cf61ce0262ab6dc45518b19bca512eb8a8e282ee7b6d139bb5fbbcea3bdc0bf7e31daa8e75ff5a52bca93ff37bcd1e378b9b6a3ef66ea293dc614ffb1bea1cd75191a64931b93216f1a92c9dc1513ec553bad0536b4c6fc003f601336577277fd83fed65acabe49ee5ce7aaacb6751a07ba4f55552a0a9471462055402c8cecb533b52a136234e37a700081b3d5356e972d8b76497aa7939c888960aaed274aa2d4d94ffe8c9f271253adc431913be9ef688212dc61f755787e4aa5aa5cb72bf5b032d6ec13629541d05b89205fdb4a77f276f2fbde6e1eeee1ebec786398339f3b676f2a48e718f311e2033e6cee61d9ec099beee7d3f8d0ed7c71ee8b7f36ccf3d7bd0838f6f63e4a7bde2af7852ea393106ea2d9eceec4c9fe9290ed6173ebb805da2ab327ec72b71b2563bd9ace222793ef4fbf70f75f9256e230e545c789faecd4b4deb079dbfb3af763670baf3a9dfbdffff71bcb2cfefc0535ceaf7f2f277609ba96e5fbbacb3dece8e7b33feb730cd5cbfc691c6b2b9addcd89a182c67262eb1e91589896cba9d59fd41628806698279851c241037532369e71c8cc8584dfd425a748ccc3077205142f3880c3d00a1d05838b76a2fd6cdf1bd0e74ce9c5e34ecbbfe6df5d0a7d8547f5abbf30fc79bdadd596a3efef9fedc17621d72d99de9093f83e179d1aeecddc2ae3ca32bdf61b4fe9a8fd61c6a5fafe3522436d630ed0f5d62b522effb32505b2f50eb6947b74c39dca78e23a0c00420c6a8c4feb8ba47e3744875a792a3c766ae9c3429970606781969cce665ded002291e3801e7c80b35c7a6101afe580dc20e96a771e0dfe666ff31fa2cb9b4d7ed81b3e8563e44327ce32f8cf73ee6d5b8233cef3bf3c2ebcd99e8288303a42f7b5843248683311fcb12b1411153ab8903a771adca43b6398eec4780ac26f5b55e37b7711af97ddd87cc9224d112ab3658963eccc74811e6ea28a02dc9551d1b088700592efccb7194ff22d9006662e0eac0db736daefe33dc8c0b188fb7e0bdfefdf8c7f8d78b9c8154eefb3ff126d2d901f3f1da3a44f67315437947c74e277431bb070c2616262ea03d8fc1a968fb2c5255880a80a95601c1aa275763d37b43cc30439b843a24b11c8647a88c03aaedf1d6ac7e17a93488f2b07139c63e608de0a0700da11202afe83bbc9c4b3ec4c35f6dd7de9fc72ac2933cf417ef9d973d39cae9e73c1c2735267f2a272f78ed27af69e0d02f7555ad5b2fe4487098529f0c0611803a52ce80e815740df1105215f2a2a6b3406e90d53ce0c219fa40614cd9739c8399570ea609c72cc9739d7678c6468329b5d4660a2497f912488b6ef888b978d1a794b1c2b5d9eaa6b53d2f31ef2356d5eccf799aafed6b6d053fd499cb02aeff26acab77631ee399fb739f94228d8747accb2bf838087126495b3fcd393038ad2da2591d0d286079d243d46b90d6cf1e5e623217f46912b02a29682d4a67131fe2f667ecc4b3353737e8f9fdedf8077d1a4010058e9a72d1c6baf6dad378accdb98e338aa5856b9b8120c24f7476175181a45f0f92915a445cb1b000db786ce9b4cb37c9706dc84e0a0e7f6efcdc99446387610bb3682cd37b430c48a94058b246a82a6063a198ff6383a1e2d84016eea4ef6bdb8dccafc16dffab712b5ef6e6325ea84b6e82c1fffa9ea3bc1f6c33ff25fe749d6d15717785b44a442cecb1226fe74185b12602a2d715cf3dc0337587b41f2d2fd27ac6521432dc135605e7569d26ba523847edbda142bee807314bbb50af2711add72e71d2241b9848a515b770cfd5358de6e9b31bdcd4ef3bc19f78c9e5fc836b717eeddfe1ec5db6af6e8133fb4b4e8ffae0706fbe7fed5837709ddfb50d177dc4390813030f2243753417bdd97850913c6fa4256da2a08373ab93450d5d4d36c862c02330c79928fdf1cfcdbd214a5ec2ced3e47d180cf43949672eb056c8fe61e052ea49c03cbf40cf3c933e0f72edafc002b896676a5f53bf8f7db375c4ebaf614afd39f6c9ee3d7b7b5ff0a68a0eb8c11f5f3be2044dbede67c96b11ea89312ff1936f89c8334419b2811d12b44eacc424765f7dbdcff20b1c9776df1081938501522771d0efd8a1010231bfc8f1b7bd511df9eb782ffa5772a00e38c2d7715ace6cf6e442a5289504e57d250cab371ba1514241c5468309cfe0ea86ba528bc6ce467279c0342d7bfb5ed16fc8fda59ccbf69477fabbebec1de5dbabf736c9d765fac0d340060b17a88006ae413314cd886530e0e0398113dfb20cafb00c3c4a97525525520c220edc39afefe710724c9c2749060eb79d716cc30985837504f215d37a86d484776f4846585a7bb918b836e4a814e20c87e25fa97fb4682f775fe92bba493ce738dee1de90b6aa4530b9b6a77bbf2fbed6849c3c02a6d730210e770b672a82c70db1fa0f2e131587e2d9cdeb31e754a35099890673cef1531c3829a78a2540acf898f64887d3d85ff7ee3bc6c202a658df36094f37c8868d47a1e75b2646962461b1b739be64cbc90055a2fc421fd0b0a7dde24e3e8e779473d6455c98471ec1eb6aa51935e3fcb137b3ad4e14ee46f07a8433b876877d4647d0890d5449aa9ee60c2f919e0ea54a39a1a91040642297ba1c3d9a08a4a5e4cb96d1be8b6de620ea8cdd4233a60633e61cba4c79ba281ccd33249d07d5a90dfe49bc21e2fda7435c7ef23f0fc43a8bc17a0b1eb9a41079f8b7d549ecc6da9f8742d8dfab7b6099b38c0d91cf73b1207a6ea0b61f84bc4aa906c2a8731e88adade696e90806734201f0325985fad2088bb53e2ff21667e9186bb0177199c539b613ab9a84b969920295735a5911fbb99ad9e643a27210826a9ce4d657cf42b53b6fe2927e690f98317fbe96aa4e0a581ceed4e3cfc4bdde17a555146915e2453dc09ab029fcd9f200865ca55e988335a14e9918e91d26a943c6ae165bc0e1c31f6ddc0ddc196343d9a98729c8bbb813062e934d44942036dc8680dd334336619177918e7b3e1be45e17b6ccba719f88de6cc2973c6f7ba81bb9b2f6f1d7be1d9e798ecadf7ec60d63cfaa0b39ccaeaeb52cd9f3de7f2be03ab6d917e246939bd87092f7eac4866dc89bb5e0dbbdfefdf0dab106f84a0e4fbed558a9229a3dea042e37b1857b5c611f15554346e900e7b4a5ddc0c17983e868a27bdc794ab4867b14f77c1b2fbd453f732dc912ed713527aec9b8184504e5f372d9237a83251bd47101ef890636d84ab1975f91ab785beb03d75fadcb7fd9f3aff5067ce22f8b82b5b181dee0437d94c7cffb25121b6a49c176b2b03e99ef995a25694863faabb7e120b37fda2b51a0ddf701f1f81043f8da9abc8c79d4752f9cd1c3f77378fd4e50bb32f67bae97e63507de7ec0aff882ee3fe09c85252bc497b8d32737e14e0fb95053ee0051bc6288bf9bc794d07d4dd1757cf6ced60568e38ee434d4711dd37a8177fe2d357b94a1fb24930b0c0461c51ad04ec18440fbde186c43e56c50f773c5394bf1385dc98e596294cea8d55b61cdd3c3a27ae65c6b59c93c4951180703c003517b203ded21fbf7dcfd6f39775f3e1bc75a9b4b67e356f85a87b371acf771df9c8d97791ce3f657e641072963c84e004b496e02df902baf504fb1b6f39de0142dfa8a10c1a3c0d1e76c10c470697839c47382ad7b3d1dc9e251f332b1f669b28ad5208f6cc716b95ad0615d324b0e43c3c913ad9fb2c0dde2451d7979ff1c66f1a5b8c5ceff3ff69afc3ce49aaf8b0f75822390142ffc1d2f38c117fde68f3c43dfb36b7596c97d9ea5ea62fd605f2487b8dd6fe6a5b5071c8bab62b018b1e56646e47398f76728f03664d8effc91a8397160c8511129319686330a01aa10f5bab0c43ee99c31cfd2adc8e0d4656c86c0d2f447ec1e11b98c9460ae8277f3f1a4995b3f56b800c3c8eaeb98d7779e06ea2ff76e1d39102e9c13631f8bbac11d72e4bb38aeeffee71ab53bbf8c5e65c751bbafb0568968944efc0e0f99f563131245452622dc215df01f1b8fc8889548240a0d50beecc5656ec6c5a4f332c89372b092b4b79a67ea011366889c82642426c86ab208aa28d159193158867965cd088ecef7355cea93695ae9832ce468f982d3700667eaa6dc15dfab2fb0be71660f7bf78ac575b166e90658942fdf99e34a14e13b193acc433b62cf5f8789c64703673eec8ffc024de674d20b3b6c46c66082353590796312433ec4baa311ff474f0c6b4a793d10a3c766aa3b302aa4e78f9d222c2ccd65622b02d422bd0aa786d763fc71453304f948298fb9202ce82a5250dc94abe194eba6fbaf70dd7cd89b33f7f2af797ececf749bd8cfcb7c5aedd7cfe4c0a3731daec5a49b313c0c19264285fa9c3a6d180cd86ca4b6888ba9e035740b6d434af98ced7e468068258336edac8d2c18123abe936c90c5791fb91d462847c61c26bd287fdcc4e3148684b55ed1b7046386246ce2437c45eedca94ef8aef6d8c1bf74fae199d773f231d6f0157beab86fa09376bfbd782f0f6fbc7f01d262c351eff6f1e535f2f3fafd6438e3a518130acc592036c26236359072bbc19ae9ea39d2972bbf900f5e29bc384b0d9a2b2d81d0a73a3423db5da131eaf0d8eddc8e81486f56a21498d2aa24c37e200b3021503c21a83299391d0270442928bfc883d389c0ab43bdbf8974a55e72e65fc81f68d3ecf116ebad4d39dac47a5d09ff68ebbcdcd367e775b08366d7d9414a406732b3c1d0d758409470580ea68257b3b864f773bb510953700a2a226c4467c3fe4c70cd9ceaa08e0dd47389b30d0d9ccf4683cecdfba63b1a4c89aaee92a25f125611c4412ae9ba9d1aaa2623b89045a37fdd0e4a5558c067d11e7a9c436e5ec212b899ef10d96c1172b3dcaf3f07695cecf36ae75eff563e27d2d25e923977bc1c0869e33ac97b4d42f153523ae1142c9b444d9a484b7a78fcb8127abdf53b3846360be340848921eb50a34d0471e029295850ad93020ad9599b39abb6482980616e20a034593833d7c635be860ffdb27ff16b1d8efed52fccf50ff987bfa78eeeec7cfe067cb493710f3af1556e0f7d06dfc24dd38cfbb6ce71916aa1f1d8b91ded2475d284a41686138d94ace7154cf3ca6a844085899ed60c4227ce53284662410d2714b682f3a01ac93cd922b0d4106442580d89a06473966a886a9b394fef66365b85faa4b9a236ff2fb459541917703de5ac17ed7dd8cffbbb4ffadbbec7c15709dd4ce32150735b69873d7c378ffa90b371afcb5329768f46caf6ba94b9b4df93a072e7965a30885b3c166e5c841ba4b0258c340ab5754f1aa93f1b579d4b502f193f1a73db19a36cf02c2c671d59668b8bbcc51400ac9c8da078e3e73f0c69e025d59a068d1c185d886b7fe51cc536eca2cbfd0eb7c98feb4d9ae88f7bbd7a18f75bf882e58c594d644315967987f23ea10636c20c3f4b0b8db12653df402953e88992b02772a7170398c900af1117c40d04e0c4eaf9236450c3eba25c98b8c46d643cae7c63b965191ccf466c802c607a1c5b84e72dfd479c93a60a75babb13bbe8efe2327a37e63e9eb68e3852530e9f133daf8fe35cc78f4bc18870b1e4e4a7e6da88fbd0d3f67851b930850145a898875535f5ad7e89b4b5e1ea406350ded362d24bc6ca7375712732eccc6d0f50a3ca31ad30ca81cf78b2619af34cb4a627f43492563d958103c96db110d2b844d5cef69defcfcf6bafe9393e94f4d07fbdfdd0233b399bd78f02b716255bc7635989315e4ef7581db44eec7e15bff695ba37c2c2b37eff197fd6eb9e45365c477bbda232e183fd7a3dbce64027fd77bdfa57cbfdf99ed2cfd7ede27df2e775a3baeaa65c80d86e8c88632d1a82039e6630d8ecf4d84befe927f33cde37d79da579a9ea98d095f4ebce33106186b266019c859c3db10c59b8144b4fabb3d8aaf328a844482b26693a988d904fec6a817493482a9f858d47be2575d74e57f75a2d90e6208f371dd3d91441a6442720cb4448ff0a0e8fab7119d1262e5436e5cee6725db075ca5dfe3d7be1ed9887fb4b37abb0058b58efd7537218e7ba1a8cc6f7edc78d47522d81899194b437e34d1bdb354316ece62ad55c8e1712a027a66429a96c63def430915a18481e533c8cadbca1967209af432f48efd95836912d3bcc19f5c7d593db090b5154fbb6c431354f71debfa0efa4ddaf23eed689de2811fc7c5f83fa11b7a0685239465ab278d75bdc5e6bdbc7066b77673ee6f012eef1768f29758398f8db310ff6601f24c5eeae036932d48ee35c65a7b0a89069326635d39b05e1e9ca2be41d1b4911e92ee02c656ce4e9381b54be417b54936142068bd0901ee2f86eaa3f6ea9dd3ca1823dfb257c9a67300a4bab8d472c080328e2d2e161290302249ad3b0c39967fc1535df7b7e8febeb8ddfaf67f00b73f0f3f3faf319f9bd6676ebfdfc35fee1ec9eff5bed0e7b609a59e675b12cb9890bcd98e7fd914fab3b2f9758589395b4d38edab075ed5a488a9cb952fa1c56466c39e96c24cdc8ef2361573a02b84a464e36676241ec2588bb4186d560862cc6238351a94f3aac616bce58cfcdf138cee54dfb245feb065efb2c7e7fbedf9f89f7d87757eaf06db2bfd7c29d8efd4a1de92d7cbeb763eee52019eff7b598eee4e6506ff9650e3fd70743a24312668e88f5863235f08405b94fb19897cc0e8d411105c91ff2979ec76efbbcf6cbbd499ce3d00727ff236cb6b7658eb52627f3d9afdbd5f1fc7445d5638f11184479658b51ea261abe774b85a7860c9891a6b131808906878cc05014359a59d62aca7eae662376ef51b94dc65e830ad4ba4c2e4527a63e7716c8eeaf181128e15bddcbfb4ff70603c9b06ff83a3b577f7831e6f5bed6e680b5880ef56ed7cafb61dd5ad0451c54b10d5fef8b4b38a937c0977ee969ac135dd5116fd2832df9663f3fccebc8537b5d6db5df6fa65d8a91e5ac11aca61e1b3c45591a88c071bcbc0a3cda4c231d7ab410ad2cd20267e96aaa4d5a57cfb5b8acda183a4feea25fc61dac6764e0c4997cc6ed8f8e5b9884797fe30eebad24c29739a284281f6b007f35a6fff2fda5ae72697f814ff616d833bfd6f6e813bc5befe36b5afb8d5ce93331e00411950b8a9a1943be6f37bd84c081ec1e815f981a1a27ba6f08d73760c00ab542457f3063d52a86a94b72f5108f6189acb09d070e7529e021c34f5e007556ca5c142c4246628414e97eee1992cbb33dd897ee95aff9b3e77de117bcd3d758c71b1ffb4f73aa57f7907c82f9f4a53adc3feff1f904b3eae08b7cf2f7637dee753d4161c6cca470d6aee6843eaf2661404d3a765608d02d558e080113c2ea6952938415b0893507d38e6e3d0d4157ab879229e6422c686e7a38471ed2218f3513f1d1a3e15b358d6c8ca8120e1da132e268edebb7c6e8bd1dcee06cf80667f0cff31cff709cc117fdf41e67702f5ffc88777c9197ef0635269f9cb93d57e6ce3fbbf4ccc19ebbda27a7e3d4661c52391e343c405450731a52f1203be423dbe9f9411510dd5c50f2d821000baf54ebb84b9ffc20d542dd994e356b9368802360ad8806f9d41041dcae8da49b80c4ea43970ca69ca1a790a1077774867bed4ffa226c5644dc54d360b726039594f858aff28a9f77820df801b3f1d7b3247946bfc5d5fcaff7875fc2f1fb1713f35f4ccc7f3131ffc5c47cfb3dff1e0cb94bf7d229d66095bcd60d5cbc5f6f52c3f9464677fae8cdf8472ca0abfc11adb907708539ea45b4597b99e43850b61caba1e8724d909f3da2c14e969681151b0a0d6ed9d8dac8ce31638adc39adef8586bdc4500b2f673356e20102e98852566296f67c30d8c479b28a032168992ea75ae3dcb476736727b5a09b73b088f5a6bb35d6fdff6e7bef34df765e6f7d1ebf3bd167dfcab1f51751c1323904555ca2ed7e0ead766e3ef5118bf3bafaacbcc9a5c51ebccc6adc423cd092998905cd78f803b850f82c57439f634e699f30c6c694a6777e867b9e428b28f07a6e50f961e0dc214dd2c8ae215695e93227134cb50ca88cda6888d5004b2d353dee3642fb664fe23f4d4e02a48581f3057beae74df2349fdc559db4612bdfc5597e3fdf6ff9072cedf1a2b7a2c1404f72c771a97808f5441796dace21f30490233a66333e16088f9236e4d00f19c332830a8fb09a0268ceec7c1359820a3218320e2c940db6530007a870962e877a1c308fd96216959033e0dc34d6ffaf7ff0564e4e75dbe977bd8c5586fe9cc7ea833ff0a3fee8abec65753fd6557142ee15db8dd0cd22d49606d1591b6af56046010f392b998186be259e58e6996e894c12b03cd44dcc4ba14d356ccc6c7697d8e8c1872ae2b6b5f1b35c275daacf877589c68f3a626a1a8dd307a961168dc22e642eb8edbdccba6980373b598d38a8a4adf4373cabed193b7667fb65d2dee91cb05b97fc539e9bfdbdff364f7d1213fa142ffb23d753d2822ce4cdfac03ff4beaff8ccb3bfecbddffb30e731a80fcf7fc49a7effbcceccf7f1aedf7ef67318a02ee2f2f9b856da794ea02fc4857ebf365f388bffa7b0c8bfa59bfec5ceff173bff7f93bcfeeb27fc9ff513b6c7fae0bf09b3f3dd98aff9b06478a83d3de6b2bf5c9fe0faa0c19c613f605d18246dc4fb19b3d58213781f0529e663368bbbc7abf3a1875ce6877bbffd2fe6347fc727791127ef46f99db3e3bffa6edb172c8050efd73b1b438edd63dfd597ef9d66ca0636611596bc76a40ed6330b7724674b1ec84d98a7a6300665fc65cccebf1a231981c4666dc8a5fa4addf2ec3635516fc73c9c9d60a0920296bbfd9892c338d7e5d0a44b03ec128a3698aa29b2992533f1800dbc227a9f90c0ebf0b0de246460ba3aeee616003c60962ce08c0502b051aa70ee0062838266838a3375e75b6e2348ba4cc6d508a9aa9bdb0ea02361f91cae091537c516dbc9db4e0feebf3f677514604d04934ff9595ffa32a302be706bb6a7d8ed87f1c39295bf7ae7ce3df3815bf6b4f766efebc486534f394ea56dfdaaa568cfe44df6dcc72a3ff54b4e3eb316015ec63aee3ef79b4015f35f399093faea9d4e788d2984fb7ace93bfff863bf6b06eee2771852b3846bf51b3fa4ef64fe3f4e7f8652fd712b53de3467ca46958346abafb7bc1d2176cead3d7b5c31a5e172b8061916e66d65a8b72b5f02dd88b4bd68b88dca091f390a8aac48b7ec42c334b40f5840ad3f70dc5625e2f89259a9985267e80b7535d98a848312f5914b39f9b384326cf14f7145b24237c375ff46b3e4a973153de4d791d0ab4490a5acb0057f11054afbcc8fed9b353c545aa7677c57bfee413ffbf4a74d826053caed53127f0f1bc968336d6914a0cb78ef76777cf499e2685ec7e61089f7bdf297ed8a4ec814ffdef8f1cbee5951cbee599bcc697ec05b61581930a9d3d9fb3f5131d16c2070bc94571d09517394e6ec0ddf001f76c5fb3ff6e1e35f20f3c1fd7d8f758f75ac6aaa19fe315b71b8134b9f0cbb44834da9beaa6eeeb35c38c36b8737b6107bb88f674ca7eea21511e1b2914d37438b3e473324619d501f215dae02c7589a65a394a8118f60d3ac69ba8541db212fdfe42edd30df4d6995adebf27cff8920b0d74ac42bd9fbf60199ccee73b7947f03c05681997c28a88b07ddb59b042e851e06cee81dc4485b2e765b84aba14510b4cbc02ddb1827942b12db62a57ea7d978d064b39826b0495e1e568119174ebe750179441619b2b7facbc39c3de540777b410d7f4577c0533e6f7e7ff6a7b7e7f3e35115cac6bd16e84b17f90b912abc47863371e7e3ff6855e77ee5cea0cc252b404541dd6ac8e333c62065cc4fcb141d676cb296b5c8b8d7d8ac2a96e0ee342ac8412f771264952a69865d0718d01e2bc22f33c31e7fe0f832bdab24ce5cc8066c2d72db5fac6dc6e16ee48e5f2b6dcc6e76da78f5880e5471bffd0d3b9b7e5ff3bfc54bb7ddbc686a3257bcc8d6673111ba83db11dbfa91b8e38836377e7e3ad6363f222471fe6a319073cdbab74439358682095b39e054893b43f91059b267acff06d33f395a3cb8c6edd003a2147d3b9826bd2fe5891b1ec855dbe72c7562bb5c69419b64429b4d9e8e706c3c1b35b0e1aa2399d5f602be2fd925bd29ff9f5832ca5ffad1a691b76532ed6214f8eb2e0dda8bff7da9eca830d794177e8d32cb9450e573bd8d03bfbf568bb92f0798fe37c552eb61a4bae6908a80ae5f503d18485495abbd9a493b6075c1d6ad1c851719e669c3625d1d0133626202e2498d94eee53e853bed663dadb48e0209961933027f36d7344757312e60846b6a5257a7f4183473067f2a6b59a21aff4a3aee89de6c6f7b8751bb1c74830b378ef8fe237fd97deceaf3aad11b3fb7918a0e5b4dcdd47e62fbb6f9fd7f1cee9a3b7fdfcef65f077755ec1a19effd7e77ec49a7eb557b7ef3ff7543f7db777fd0473e60b77a43cf89b67ea42e193bca0f366c3dbe05ceef67c67a7eeff278fcfe85a2c5222311e396bb4a8a79e42aed4c315d200e0bc9f854aea540d726250dd6dfb5aa21cc5ac06b8796d4bbd2e43033f4b3e69c2806df0a2162e9322d4b5ed8c224a886c64c0bad070ee120e065487ae6fb91bbfc3e7b048bf5f7f50c04e0e412e38db4e396b243f70e0bdc6424ecec0110f54474bc1413a0d701b06fbbd79c763752a7f9ff1cabdf69d9cd46ecac0a9a6bceadec9f6b738b27ee102bfc4d8cf8c754d3c5e25767f210247cd8bba8aafac49fc44f6f7381e5fcb2bd21b6125bc1b7377e71f31358eb94642afc7e8e58e40857842443c30666d23481b5faf6c92632c69658ba06a7c1db75ea06c612925736845016c99961a546f1631756684a65bc4e1ca2d42cd85837a665514970ab90568e6763d468559465afae012584cf5e68abbe02fc3c03adea367ea5838d844c557f7f5f146fbcaea58afaab739e30ff3a867dfc08b210c3df1a0ca98663e7864a0a40627c978b92541bae554e8524ff439af4c979a63d74835c1fbcd3c0b3504c5286efb3eb5e57392591bac49ed5e5799abab7b36aef0cc62c0053827c4d2a80e8d5809165309d19f632afd765ffec52af9bf865572b46f4f63324f89de7f9e06288b6c56873ed09202eef7fb22b6e7694cf37b35e087dc5b17eaa98ab955cbb1931eecfd3deef627f3d39a6f6076cd0879dcd0917a7641fac4edd4e145af89ad66196922f5763608603e65e913d3538e2c673005ce3331c2de7c2cca24c04d62c17046d503b2814f8394cc47d08fed1f9a1cc33b11c0853b460ff1d80121ed9bae8e2fd5a2fdc9de5dd94fec9df689fc75fdc4479be5aabd09bdbc5ab0119a21ab5ab292d5dca25bc1fb2e23caf2f42a0b6968ba79ed9212d2988a519c274d62873d31666c6e89b134b0877268a1c25c456562860439c256beb4b61d268ee16a951551ba99db7927f3beba0277f02b7582efee9d773ed5496eed73ddf701d3f26ff4696ea657ded53e5cf6e76f8389f9aedee2a537f3b57f5bd3bfa12f063210533676a85070c6a9e984065ed00c4ea7408d199c34a8a33a365446c7a844fac40c0bcc67148324602db2a58e0a384d681a86fc514760d9f33920084838cf1866057a907653b0ce6979ce80303cfdb6f9a88f76f54e56e87f4d560ebec8051d45dc67f7cf6b99b53018ec71a2a50db762cf956b75d7e268bac3be70b3812781e3305ee310e011d573cda390246dfde05133e2a56ca855a75130187b1a339291b51510a2281870a9502401639e9e6f5d966f885eaf7d2a4ddfaaedc8525954f4b3a8ad2d5f3787226f06b8bc75fff907fff67779ba022bb1d3dffc85bbe337b85a765f8bb8dcdd032f79bcedd9f8722136c902a890a3e5afe73eeeeb8bef8ab4ddfe4ff9ee2e7b33fe997cfd1bbeb5ff39f0ad85bfedb7fccfeffa2db9b914c1ce777b796e72ca0f79a67ff2f879e024d6c5d573c44195186fe6be38f3dc6ffa2c77cfa3f64c9ceb952bfc3587dcfcee39f9c22dba7bee3c06e467d80c6fe77db2e6d24edbd86065347ccd5177d3ecf14ace8a97b3ff731116eaf945175ca93f54526875a2abbb2ff0c1dc2437206dd6c63ee8a2a03aea9237bf93c9be06e7baf880a52706abb1dddccd69ca7d2517b3612d625d080471e012abc59dd8bab918518b0d70b15e21a24a9fa989cc50e843671913b59650e019afd711c14ba2a4a2d431a83150331bf9249b80f968e013833d13daff2bb8f77b7f431f61177133dfef99e12c65702d4f0156f3b157cbd73ee9cfb1de4e6aa9be6517bf1b73e7bb682248b569f0925bf87995bcb83e285c22373e09758fb152e47024f3a6a07a9f26e067ef5e6f3202ad3ff52d9649d10742ff021651dbebdd608d5ec6dbafcf0bc7f5fe2cb5bdde156b630988efa79d68669619c6b6ecc202ad300b9b7b0d6f429e6b42d13f5d9b2ae6ec4dbcf6b3f5096f5443fc6eccc31aed74fb4bcee3985bbd8e534fa2d0c02dd3bcd6875544c6cc896db48ced1aba052eb8552d91b66c7d0d3b338a8d78b86e43ee789c27db384006a569413468529674515e956e30108889428e31f1a919495a67dcee0f5d4d8ce7c180477a735a07f9d7d994555ce6f5cedfbee063187b0cb33faf37d0226e9a53deb4f290377c1d7f4a92e73d06e1557b53cd38fdb1f50d51c6196bf9b80a126bbb9d13e4d3eea79968608a32a9b00e7194e53d77c49e626b6deeee08aac35c944ec56c7437cf9b0956693a35d28c75b8f69953c4bc19ce686a52ffc78aead27561d8487ee63ef87a5effdabdd9ec7ce1d3bac0bf27ae24ed1ff5b9facec33dfe9bbf1db9aeafab33568d9bb1d02b3d7d9e7b202e075e64372e53e918e7bd6eaa4b9366934d42fb56a8d533522a4ab8a7c9c2a9dd4e4d18870f118508c1014ac840112646538057f3f172c58b2a4f7417209e98f340dddd03d5b8a3c115b9b02fdfe9fab531fff8b57710b42137cb4b3619ba1126d371eff671fca480cfe210273c331f0d1cf2d9576148e888fd34a260a9f31133713069424366c210786e3b0b3f480cc6d79dd0fa26e2d811631ca1b163c982b9094f5b6155debdd654532deda1129b7e3798613e59b9b91ccdb9a93c0ddc475436490e2d0fa059d4a5dd1598fe5ff0f75537e52688b9f38b03ec46bd1db3eb6b7ab4d860d917381d9adb9cf73e088f76c561dc23ffdb75f19ec02b1f7b2cc801b31a8d00e44b4b35f79ab675db7ee76bb8e51672fd716a601b359221cf2d5ccdd51ae58edccd2c402a292aece5ea4eda953fcf841d69959a67ca9aeae95a046ac0211e62ad3124a898ecd4fab6314873938cdff9f0cdefb1e2cef385edf5788037f2c5773f7086ed65e1b8c6dfe00dc33bb93cea9bcfeca8fc469897afe3ede52169c17efe5372f8fc2b3162bd78ec193c8723cc1c8cf570eb6a5a8b0832a5d50857c7933097336c388384a8c6a769c0586e722b15f108de21438ab89024c9d00325ac1707ac9ad93f5a8fc35ea2f567734bdd45052c086415d39c8d4b6f8bc516064ef9aea7fa24168d76779f267cd08a00822870d4bbdac1d3de914a14e1db1a9d53dc270e57c2072a299dcd1b0cf6b3984fbfc7e7de7dfe01871b7d8c1b95ea572ed2ff3d9653581c9efba0d75ee5e1204fb84a0c6fb38f4b14d549bc488eddfa6007812e349ceae57c095b7572d85f447c5f17d246c140bbf07e6d775f25c6a0dad91cb16eae8ff1c67c27c3537d77cede3db33f671fd66b37f7cbf3e058256347853ad404f73e9ed7efe1afeffcd74fe2c689cd54925f96c73d0e5580b2a450db43bffdceb69c3ca3f6ca5a92315a47fc528dbff5ec12ef26b5827bfe8f3df634ee625b2d0e5818deb5b5e2615ce41da2e6745e5425091c4304c24cb4947a1a6ca5d558091ce8734e7b73156e5c8b6a385022cebc8e8e920d32a04e03e9452335c47a3d11815c9080ad59616a61a1ca98238a0c27e7233424c50f5302e7fe06f9c7ddf77d96fb1c9559443ca977b225c7b8badc63b15ba3c75be476f6eb1f977beec16751a8721a0c5a11602de2879e8b833c9807dec24254628fe9c7b43de6eaa1aeffea1eeb391c18333628891ab8b843950f9c5e4cd70686b2bdd7583a05e82e2945e18ff1132e3d402c678d3258469dc3bc3cd9606b62461a0a6951e9f7466afa8c3689625a5c4093d80c3126eebd02213e4a2397c8676c7f3dfeff5bddf6d93a71b4141caddedceb5964b32c6acda7b75cefdfec75d3be550f394640da6a7db1e7b7edb5eec75ad36fda06fbfeacb17bb00d0ca645bce9a6c47d76afb7176bdfaaa7aeae18b7b62b17301b95a98bf87a4b2db6f4c14e0e6acfcb913e6d6b3fd2d84362573e33d2de7c34317cadf6bd02d41e09b71e515ba1f599cc4135b3e434820ea216aba3dcf1e9b8ea5c9518a4830f37b517cb832efb75df3fde046b0efdae56b11c281138d617e66526367b77cf3d645abb9fdf70f0e33fc39ffff3e0ffec0e35bf6077461eff33de3eee71eef6fce13febbdcd346e7e4c46bdfe64e41e6a5cf96eaddebe9f9e7bbf7ef6fd8bddfb1d256debedb3c6d967dbd767afb593cdc4a675a8a72ad4d797394a6e13737c3be6fe4cec7343475d31253fafaf0f66e95a30b6093b05a426c38457810469ca188e3c0eee084736cf680f91147bc4d165f9d8b06002e696caa2200d7df67335b39a679ce39296833523ee5606ae2e6dd608bbe9224d14d2af5341f01475ea21d6d94df1c976f75b3c663b9bed2dc64a7b2b8c95eff8d2873d112ab9885fb2fffc5bf8507bb91005eb0e58766f7fd7b6075d71556c4513b673e70755238b4a13ba4228700c97af4192b389b49c01c9eb5a8c591e59d2f4729646796feb7201e73c4d3daa9689de9f9232d7e72459f9b467ba9a2a124b6812e46614c00ae9b5756fa486afa738d1ccfb7f02afe8dedee5384d4a279dfb7bace12ff6a7ee7d1b709b7d647918386d18e4b5b47fbceb55fd647ef5213643afb3990a0c66304524673b3d3ff5c164c5a17ae016e4748c03c9f36d3cceb7a4c49b08ee747cb2621ca4bead060c78bd68ec703770da69db9f2015ae5c0bebfede77b64cdae5c68c6adbd886ae508fbda4d07aee6d7915aba405fbb326ec373dd7bfeafbafdffbb7becee75c99ed34f3fe3c0ef66ecc9773fb7a97d6c771aec3f85ed44a168df061f54c799dceb394d2dc0173880733e2983c77bcd8c02da28f2ba6a718e98ee5ea69c4b899cf474cc35a3f75b9009e2e15d5ab9e1754c8654e4532e6cc4b910a4b850c0a254a0624a846b4b8851decbead37e8c2931802ee129db51fb8f1b5c4402a29f73c3b37b08727d7cbcc5e3ec59ef3e7424eebd0cfffe7b55260678b89431ff0eefe7ffbfb11ebe6babaa9b874425e4a838f1d6b0abc8daf5235e7f23ee178443a31e36ad99051a8fb63a747fc7e8474e024c4d9501b3ec75a6f8b33f84cc68f5d3c96f724a0ba17c87b4e4233b27135b7a14d691fc44075845710f9fd917ba156fefaba290788977b7ff11d9ea5bd7d511c7000cef445d86c21f9a59cf26467739a7f5e677fc07ad9f7411cc6ddeda93ecdf2ebb85872d7c0bc698555a57e617a610ebdfb0ec2d8c04296304af44927385aa3405628778a8888a1af300b3573238d9f7a68882eb1936da4d2bb5839d4d7f053ecf721d2602e343164051b50281029d0141b6842e86dfba20f76dc2b4fffb567b24a0276cc619ea96f398b4f75839cc6c9b83b7dce9ea30002f1ab97ec7846af8b6d486aa682ab16b3819ec02aa0babc9306f2b081995b569c02dcc68b1f3d3262cd54536a0eabda1f0d943f12c42349e7e960e011c690250d021c3a8770c04bd7440c0fb8d5cc12cedc78f748fe03085015ecb6dc3a5952aaed2117089f85ddafdfedcde1dcde28ef75a5ac04833c0cb09a7273236d5544fc2257de212e7f033d9ed8389536ade3a2af455c54479c8b73afd7070e86ebf43ae74d8ed4724b4b35e2540e5181563eaf0a91cb07aaf56b1fa64f2e9748506a84cc79986718e1b60e09afeb2848877c849f1837cb24972151ea0e19d2f335a79676df421678f60aabf5b809107088afa7daf41accc1cb32b3888d54bde1a038873d75e48dfe14f3ea1807959db4fbed0b96d599fcf62b5ee79cc3f6655c777192ef3cf8d2c181fb33b6e1dddcfffcd9a40559e4bf97f333cf547189b490376bc1bd7a5f3b5bc0753cce5f732be770baa2c0ad77f7c7af9cd16ffa1702952645eff5738fcf6f4f791ff73de4a9b4777e23787fc7a91ef80d961148dee2899dc3f6d2592df77ca16ff351eed9bae1b98dcb2977d2446779f48aa1f697601cdc900344a9580769bc387b7effbf573cd54c6bae8c259cd513a73db96819f2667541779de951f996ee3a9ebb1ff5cbb8fb78ecd57de9d872b589cef4507369fdc099638b31ba8b296e0845e38430ce167d40281cba59d2f9b97263fa63e5ead520b61f7b7c841b3cc6b9b4e58866a8988ff182580ccd15eab99983859d3e631bddcb92b692c08295b7c662d863737672acd6bff0f0bde793b8f71e07e104b7e4f87c7278fe6fefef606de4ef6c978b7eee4d300c5e7ae4f7318c979f89777dac924eb673e6d0b95239a3681467eaf95e0bb57b4d2ed15839788c11e528f54b5473ea5809c004776939d5fa2acaeb61ac639712c7f16d3173750721bd620970c2b8c09b047a06d154c8742c12ee36a2a86a969dcdef5fbabbb6929be61ebbeac3dd70ed1ec543b00df7fd93601d5eecc9be51afefe9b807bba4d8d6890ddb44a7bb7baf77ed99777d60272a9d4e35588499d78a311acf6d10e10c955106d71e11a6343ee53ebe325f32680fcf78f55e4687b7b535afc5cf3de20ceee6dd0a8e763afd2b1cd637e8013dc5f53b9cc393f9d4877ace2f63703553e660979aa6280786ab9b28564a97ca6d7cadbe17808d438ad16cf425be5d20b9ca2fdc5fbdbdbdf2e7f501fbb10e6bc02a31d48e9f7b552ed1263af093456dc74c429f263dc9d3486662e4160e151ae37c8c2651f7b31769d488d9609de4ce0273ba0a3bd4ce82c153a8334e6d09124b152457cbb0c3e67c44813f0a4d02d201291d1632042451cae7e6f4b436e07c4dd8e13b7dac5539aeef95b6c77e9d8241fa829d7281fbf016b6c5bb317fedd18b3e3a62fe5d97f77d103608e796d54b72dc51224562993ccc6be217f56caeb0e1e6f98a762c48740761db1c494b0514c03436d0cce328909600bedf177e07695456cc27e2392cea320a209cf3c79e00f259e82293593a4874cfdce7321ebfa013b2c7fa801dacd6c20759c8d1f20bfd52dd4deee4b363ffa8a746d8dbd7650487daa750875964ef638bddb5718b7894ae3d8dd5c4462e67d512d9e6427273c64b813dadca5030d0515bfb9e21d3d9d8da101bb3f92805486f3a66080f5b759dd8fddccfe13d29e5cae3e9bdd7fed8084b08344aa7922a18f34a1323ecb34259c99fe3701891ad2ed7c1eeef90c99fef819e56c73ad8e3b8da21e6755d2ffe905879c7ec6dc360d2d1b158a36eb0760dd5b820d7919dafc2406e25489b449343cee42a322092b6b9e0b66c09f55673be3492220d5cbb0698e2de3caf52ced27194b300f17e19068329c901f4351345855adcb60e56752248d52f2ce79f9f70267f5207eb835f7b77e86ddc7c78fd8f6b25ae8e2fe92a173b1dcc9b2a2e2eddf7eea9eff0adfb5e56e2e0bfaff7bc5d3b1dfa7e1ec75ce195983a25aa6390a6f118052cc7081b6c3b874b40b39fbd48b74c513451545415198b09cb61c0697f2a6d35252405518923664ccc10388528e0eade600413af77aff51733abbf0879132663690ac6aa39c51652d016b78d419ec1dff86f62277ed8a3534c8677f85617eede3371996fddbdef31b5f698736ff9278e3d1ad7ddbd0b4e44116554278061d74e994beb279c9b160dd83d2ed85d42eb3cc9a1890bec88400cb0ad9a44c98904681d166048723049462c8d3aa740a3811793f49e59c224c4a993205de14e3c0bbd9e90ce6ac4a2bfbe026ff7af8b2bbf3f6fe778a54ff0473eb77b6fb2bf2ae6fda75ffbb9e78c7b8fbf451ebfd1530548a4d45d08e48c68d6560472e08f0777ae057a0954b62c65894af5342770863bd49336db24c1524723cc3dfdc786aa4119979366aac9b11cd655d8a1ca57f88e92144a82a8b0b40641944adde48c83312617b81b6eb23f97315ffe86385b95b4a090bc591f75567d8829806dacabe703e7df055caeefc4e582ca8cb906ee0dba4a34d451204d3c520d29a08a54d8614be89185a6a1de4c85adee3887f72c60138f3c76346f9ec24c3e53838de302e79e968e653658466d3de5440e0985eb0448e57798099ee898853a87f09f808bb75bbf3d0e756cabe77379e07358a69fe7893e629cfe1177e9cbbdf5060bfdf5b5639dc895f5d28add215a59f7062e9300036c57281a4b47740c6025b8ab632d614b73cee07d0c2b2e4a4bf3c9cf66aaad01b5e113626c126592cf030713add2e7053428106bdf183c8439dc8685b05c8be5a854f761bb6ec48db9e0dfebb2436c67761e4fe3c239fa347f74828d34513dfd731bf5bf2ca3af184a1762bb37ca7bbf1ff32d17d301cf087d23dfed054cf7016e992d30516ae673a4856ad2f86d5f60807d972400e5d20cc1a0139d5cccb893b34c59328020c970293391fa069c701b2e5126a399a56adac900074b4099c88881d742256da22a28b9d4d06db17c4e6cb737b9b3bf5d6662c3c9a7816cc33d0ef48578e3e216fc507293145e2d0d274df6356d6f7fd7f6dc1aee753c3393f9a25f27b96944019ed1e271e343369096b661cadb202626f7862af148582c9335a775e40578420c67917429437aa353e8ea733b3430ada684865bc992c6d7aa513c1a4c50f7b3111d8ab0c1ba7b1d004c987e459fefd77bb2f6fd9d57d7121b4901b7c9f8122fdead62c53b39196ce7fb73fcf2f311bbf1cb3109ab9610e119afee90e634914a7ba4a8052ec5c08570262998caf1cfde9fc669767a43f8a08878a3a61c6ab10eaaf0725fca47ce9eefc56d7676d3bebe7a1f3b4ba5ddaf23beef51f9cdbcb4834d789ddc0f649e6673b6047e6112515abbfd26735eb55e514f66810a90ad195ea056b3e10f9304f9065b9e19ebe65404743323b8908683621da998fe682985f73887ebb8302db2a8230cdd152faa01cd180889b5a130dcdcb8bfbd9681b3fbb70c03b4fc5573603da3b3350aef6a9f7f71a79dc395d7551917703de5ac1705bf3831cee2737f5ad3fd5a8700ae3c973d61277558c04e705c5de4bf38b54bbe25771f6a2376f2f6611e2f7d5d57c999473573896965095e459c854634a25bafe82fc9e8a7898389c90ae8082e5a376f90c7c38e68ac4e2cb48af27ee57658f140614e61c8187ec20c6a3cafa8af23dbb568cb684da361bd4934ec26ba9c455c33ff0afd7aad8f3e1fef64f7527f867723bd9a6a3b9b61da6a2fe37e8bef8658b56004561e4bef3964a5c7d2e719637e542870af81201a2bc6adb49385d8221d6492a97ac63161b49ebac3fe282a71cb02697b416acd46934d4c511096d84d34f98473958ad1c0f003b411237c97283cc0a77c37d7dc77da9567ca0c79b38ebeca47f4e7bed5eb78fb7de1701deffbb3bf7386b44eea781c711ccd030b506bb29d8d70482c4610c35b0290ef1164442a1dc4960a084f414c9c152d903eedbc86eabd5670805d1b9b2180011ab3885b8d8a4a399545a2e300e96181d72cdfaeb05230343ce3ab39a6f909c6dfd9b8f30d7a90d4f3611d7bc7f8f2755cdf2c78d4e65c8e9981805bb84614209be9b4c703da70de00bf000d2bd25e42d76da8352151708028ccbc0e61513863520e10d2057061de0b17fd3b97882db79a675ca6110f4410d95e278a74c889b2880d46e89a5e943fc35dbaff25f79fde9b0bcf76d2b060eba97ec04e17a5931e78333fdbbfe4d925936797fc395ecf6fc6dfdd3387b812176dc881dae3671dc6bcae26b5f49a39efe75ef9d8308ecc88338f30b462bac9909d7a094f8d84c825d6f336ce85ebd246790441c6b7ab84382e0d1e1b940387eaf2de1dd67748c7cf31973a1d292c2db5160183cc920f11ed4f5ce6647ef075bf2e295823b96acfda32f960117247c5c3fe32e27219dbaa8cc6deaf1a2ef2818bfdf4fef919167021f87613d96c9dd8ac9d06228d6d958701de240b50099b3d7fb106d99866d64deab27eed77aae2f140250ba087bca9840db5d898d411c72a2e71250aa592c58ffa6bcf692ff3bbeefc67484b3a7947180288374514c8004311cc9563614dcdeef5e6d9d31813360c8581b96f5525b1274d92cbd423e289048ee6650ac6941a6464f544d10ffd5cc11964cf53cdda442331f30b31a6c1cf8d20f01e5957e68a7f2b0397cea6778bbbea8dfca832b29b4ae8e98177e1edefe465bcabec3f4135f4208d546750419f02827538a47c02220d5b8986368985f388b17162c06d18e0adab8b87d8cab5fbce99d0ddf9b501644a3eb3929954c703af639069a8a140066c1c6e233ed15de03cd14ce6cc72f22b7234af3837e774ef75f2fb8ab1d59cf462eff998d334b6d76feb984f9e894ab796767f25b8d97da8b9fe4d5ce73b75a41f74cfd9fcc2e41417fadbfc52efc67fc3ad83b4f9de2ed38ee39dc8d4e533adbc2dcf733d02952f205ecea032fd32e9a806169c6b1be9d7b3848bce0b529840f9e0c241310b50331bf6d58ce0603e4e1f123898ce47caa619b4ff7ff6dead3d5565db1afe41df0d1492677a39500a4429435107a83ba07c0742418812457efdf778c851136366f6dafb625dad1197d3823af4ea87d65b4b5d3596f69063dbbca7e17a90d6789d51314898574c8d899e9df521bde4ec2ed713aeefb1d33ba24dea0c77075ccc21b60b5ee2d3f93bfcee7bfb7fbaff3f72385dc26a5fce572c0f7a52e773fea3deb213567ba76d4e7bbd3dfdfeb99d3ececb57353f2d09db6acebb6d589a85d4624d42c9e7a3e17da6309576dc09bd69a6201ee01aae17149607ee28de1558498732e9f8cb762e3434a1207f4c34b49c6aca09caae9b734fe7b5847e9417890e19722d450df69147f18addf8c69d7e7cc70f7bfda516b03bef0f39eda5081507befa971ea6530dc2fdf33667f19153fcb46ecf9c59b83fec2567b87bcd0ffbefecc83b1f72f4e72336e1d4dbd2ed7d872205e6fedef918375dde53e1c03cd7adfef19efa782e4ebee2fbe79a91c339e9cfeb9057ef262c4ac8a413ac6429ca20c20ee5683cb7d178c194e673219891938cc226ecbd826a0158947834b7077d6c583da69e259537c8c6ea8e68b24665b6a15a3e0995b2d8f8ef6006e0dd4c533ab6a5455c346795e79edd4d5ffb8daf7377d08ebb14173fdf2f07dc7f9b56b03dc50bdda997ec276bfeb4f7c3bfb9deddefafb7f9262e787d9e03cfd6cdeb6cb7d9588d58559a094758568cfb3af316fca1a754a1d8b0a82c11bb6ad7bfb4b9799eedf42a75e085fe9ecff2c41f6b813f9db3d7b18ffeda8b7eebe79a585fd85f3fd435013de66bc8e5b5d7844ab6a2345d51759b70fcd748a1d065f1e7ea1e7e3b3fff2ffc4ebfca55bf443f72f4fc8e5f7283d6ef69dcdbfd13ca1b9ed4b2e4b6d2d0f8cf8050d504111cf331de30daf642a73b1c410b1b4def2b6b9b004d8b191471d5b453bd814c6305eb3111a5983377a249aacf79a5e7bec34ce4c47aea483fabda91efc0d88710a5c6c778f4b7fc93f7fbfb8d1ed197b6e52bcc5ae0b01397dc501d79caf0ee6a7de5d02ff41b79884b631ff04ac7cf5daf38711dddc60f4a18403ab63151db148a0759e75830e9731b53590a10965e198ec51647a84cabed3eee2a83c8d2d2883998594a405bc391d7a1c8ebb18be229d0414035e013cb4b6c3327bd17211677c21edea7259e2d9cf6fbfccf5fde215e9ed4f1ab7e14995ca8a11cb903def1879e69c7b03e733df5d207bb3bc392efc7aa53e780c97cd125ffacb75580fd7ad1b7584a70aee1a21fceeb8c8b7ddcfbf0ba3f2fc4305573e8554df9f6b536433ef67cecbfa73769a5da38c2cf78df137e23f80cbf71d4a6dbfb295cdfc784fde4bd86ec8fe3b7cbfc1017eda376debff2f333721a776f134f1c189af6491fcb553b289c2194008394e020006c86ec754f159cfbaa19fba52718f5f2852bfd8079e38c352de18d868bfd9982535f794bdfcdb7acea3658794f8136b4a5011f33573e057c98a73dde0adecde7ceb6a76553ca02d5f42cf7fa5b7650ef9ff938fc70b0bb2d2e93eb147879ea7e2b06ef8eb1d36ff9082f63efd7f3e5fccdf636abb898cfb9baa681925e60b0bb45890176861344f03cb4db7106981d73d34a6cda0780d9fbf1b1bdd5090b00b1f5983b0f3ba6a12731562ce8bd7e51e115b261441cf1281c390f4a1413c8f254e52236ac5150b6f75497ae3cc36bffd29ad66fb9cc4e677d3418bce377fb789f5df069d2efe556761735b27e7846d3633ea5cd76dae9776f5fc74c932beafe5db1aa41d2d12d54eab15fc84d40b0139402125b8cb97ad0688fe38c3397e8f95816f140c2609554935e56eb0dad551eea32f0a145434345d2d17daa69db78d9e602328a23b1cc7a18600e27fe1916ea465ffb45f3f0a8c31d83619b72f624bf77ae2e6b7aff4b6cda49b7b44881de0a6e6ad9ee2d4eedec393faf5f5df52f44451d7f450bdc24aeece858cc67007ab2f02a9f4b148ef335d185c67438490d3846ae9aa16a4830143c05484f29ec4589baa46ae3b4860da7fa434a7583ee862da6b99f8d25173c5fcb31ead2b15863ae3e62675feead33dee06ff97c22cf0cdc88ba3ceacdbff4815dad49fc56ffdf9f83debba3aa4538dcfb3caf3d6a47bcc3c7cfda637c7b5bad4118624c7436cf60de33c3f328411672601c689d271c6f4dc696865d5bf34bcf9df55e2c7bb959385e938ed5834fa09e1a59e7bb8d467bcf9554e48bd21c89aa5966354a1037d7536006e9983d62881e9382517adecbf2655e7b3ff7af58d3fd1df0b59ecbdb7513d5702701dc09875deba7bda083ffafd7ac4a0dcf8823af14fc900b7afbf7a9bff8c6ba5035bc9ff622c2632ba7f5c320ae651daa8741e6b4ab85d37408fcb341fddf5dacdb5d52941aa279247a6b13ab06094de502aac8d72d25fb3fab980f56490f31194b8fc26642082ae38245b810f7742c06c855ed89cbeacb39ce5c6fb370cb36e6b8bc86fdb9904bf8614cf4d9f87b5b66ed522337671c96c29dfc486b5bbaa52181c9c468e80a86ba50c763bf6c368b1aad5194bb71650e1837212efd2d0183ddcc6802b9fc679044b92981da52ae735e4b9d19628e81394a81d2c2c233922837580d37a29631a9593e771e0027f12e8567f5b72bb59ecff7f81bcec78fb8b2ed718eccc7ec73aea90b6b7dc0a6ac133ed988da7fca00cad3ea3aceeb1827fd7b5ec8cfc7dfc7c0a29fd5a888b959267bfb771cf336add41ed5be61a1b05af77195e9a9ca9764f4cf2ad04b10124f8525bee3257c4a486052474cd372ab8b4a3e50886ba15b20a8824d668b3905729a016c095d6ea5cb1c4964978543486b71cfa95827aee809c4e3f0066ea82b75f803bee5c0e97f9c072d3ee1ff8eeb7a16ffed241f1c782b8edc4adbd71c7d3830bfc4277d3ad615edbd8ffaa43f8907b48b631fec69b6337be940eda0c3371a6837ea5f89d4cea701b18ad40d76535dd40878456cd82be636a1b01b200bdb8c7bcf23351c51036d88d66d7dde2864e48fd29d18613101535dc6b4c87684a2522a6a660476cc6d3ca6e12ab1f56aaae1502a380d7bfc75fee3024ee280a7e15d132f0fef6a7c83d7e88029ff05bdb88b631fb8186bff4902b84e76da69ac9bb06183a0f63671e403a9b0c67aec862ca701cded54a3bd5fe54fa4f0108ad44a6868cb34b9942c9f5062ebb264288b263bdfb046a8176aa6c924d655cf4b3409680710b156d20976c8850f3852b3ac104650e3cd0dbad4576cee1776f0142b9de7a10e76ba7bb5cbf1350ec73f19504fc23d9c935de21efbefaeacf9f6d730302e6ad20a1ff64b56e57a76e8bb3bf5d6913f3fc053682629199d137b8b6d330f99f52474f544ec2e103c5b1120efb20835f38821e4e824ae860c4525c8c6394114df1186398ed094d75e2e41b90aaaa14d14e34165efb0934f330605a302108a2ba1d32d2a3cff0a9ef6fc7e73d15dcae12e369a3cd90d0f6763161df42cbfe7e7ffc259cb8ca68d23af58547035037b9bf8a7958e6a4f7efebb673ad5957637f2da7b41e1c571dd4c983d0009675e52098fb0d84c9c8ec740048c4c40d67b20e642301d16bccc236ee7f70b47e5543502533cc3912cd3b1bd9bb3c6143ddd4e81d87016ef9212d5d2f53aaad920a3a64e14faba2ff5fbb9de5270a1b2e501ab5ea4c07c12fc88897df173c2afcfd39157dadf9ce2de3e06b94ab97d1dab341a18bf70771d38b9b3ddf098738d509138ac8dc3fd993ac6da19400f82ebf94987d3b84de30b0d982630ab910a2a0d905eb9719d752193cbb93b0144f735027222c7e881c2c64f34616576f748484e31cb43a2793aa5d20fe8df5d42bc9ad756c11dec07a5da6530d7998d1fc2b1e471a57509cb5b52ca5bfb8d5fe6ff051bfa95cf48e893ff512bfcdfcdfb513f6da79dc6d73a14decedd321f0d9769d5105e0603a49a2ab3bd1e3bdd38e4ed9cdb0aa461fb806ad9cc79668411f4a7a06d71d5e2a92e8124689a55b0175a07534734d4919bb4cff9dc155c54264c888599f23bbf92cb745c6ac958894cff24ee728f9ce8cf3ae457f1fae423a7e5cfecd3f31a4a076e8fbc3887f10f5cac87f8eaa6ba93c5e70e9aa5861c09173501514f719d5ba2cf74bf873d2ebc42402b2195622990852815138cb969d82e056f5850d24d5c8b26ae1ffaacfcdba34a613a564bca9bfb9981ee17a53018298d99c1c688ebe3051ffe962d3adfcba3c9e315bff9b80f5ff4cd3ed6f28236733a5d80332ef84b3dd4bf74c7bfe7d517d1497feab99e38d2b7a9cbea840ff677cfd973cef63ec0e53cfc57d8952e2e519de816421a8e988b04a5f2713156217319c6063292b05de228d82611eab0eda974d78e433ddece09ed1735f47c88b7484309d24433e76a2b3461a14a2f68041d649bf7ac340dba1b567e3d010b881e7ecdeffb7cbe0699c376c9b18696a723fd550feaf27abdd943cf3a07faf3fc6e328036fb339572f8147379c2687efa3befb8de8f9cc8671cbe95e466211db539f487459e12237d993ab04876ba96554c7db8473f72df6e8403fbe79ae27e8c035ef4e3f7ea636f6ff682f9bac0bdf886f7f634a671a8cf7dac2dd42f1a576f6a9ed97f6b92ffad49befcb7dfc08976bf8713d50f3cad69e49f724b3fc08746c84d746b30d5c52389701b1081f87862a49aade1d27330ed9c406f12047d8dbb50616d1807460ce62ea653d02c7d43ac66ba67c6b48de8d80a98dd9accc02d8108f9ce641573cc98cd405cfb1db5591e8ebd8f9a529fc741efeead4ff27f3fb17f57f4627e45ff4bfbfc6e5db896ca2a75a86fc57cdbbed1cdfbecff6b9f9febc61c92c160b063a56987dadf2e19e721af9122f4af16002482fa01a410035a0def898d7519c13957cd86393910650e137bd87065e1000c8d69cf603a468174d5202c6083dd09602c4fa4ae344c90c9157c4c1cf47dbdb06ffa32e771d1a98f673438d384fd742f18a8480d4bcdb89ea715ac9ffb892faef597bf73fcfcc57f2d3ef68b7ce9539d7d2e5ff03d9fdea3affecdf1fe3dbd3fbd7887bd3c6774d45efc94a7efd338e8c2bd7fe011fe8ed6c2ffb0ff671c79464f3594d3bfb5e7716fab293a0f1d2fd5c3acc738040c065ab7f4ab784379134a4d6fb10d77b1210b5fc94da66440ab6e34876cce60b3e604ce32887906bc1801da73d594999357b4ce76730e29568c909ab941911b73f657cf74df446758c21fe7d43fdb5b7d0c865b11ea6dcccd5c9cd6ebc77bf4873ee2d9e706de094ebf3c6baffecf0b27fba7bad337690c9dddef17e2cf739d869fc6a0a771ff695f7481c8f1f77f80a32f538d19c2152d82d658d0b516f628a474b0e3a5bf0b946241050752eb2c5aa28e573a4a6aecccf77b9b3eec6835d92e5c8ba7ced0a19539261a3632de6c2530ad14c00d722d95da83413a46615861e003199ee524bfdea3dfb0dfc7774c4f5cfbcf3ecf7f3140ff2730403fbb072ec57fffbb7ed499cddbfbc2e7cff9b33b621eb611a78d8b1d530f7ac525547e46bd8758473a21b29424d345adc674373433db1fc43dab918e4ad9cb2dd6b61a29318d2b36f1fb5c85caaa16a532858d26bcc41b02e463ea0c07548396bf5b6be9687897fd5eddf57fc6b657aa4f8efdcf2b11a98f3ed08ff6d4c9c7bb9e273cbbc3fe4d9ef0d3e778d1e8cd763fdb33d2691346bd1a433813aea8b23ef7d158fa710407296866d8a6ab942a96d2e19d701f8c6cd9ea539deac8d9f658c32be65a30567617d67ffa5833bb8c42368f0462148d0202ab24c27dc8f316196aeebb62303fe7fcb8d6177dbb6ffabf7bc63f79ae73fd4d71e8f163ea87f9bf5550e246dadb4d5c979bd05e1ba2cfc79c76140138cb6c68a4703210ceb04f1c112d8abc443d7c9c13f98478cb62c28a98e69154e596d67b0bcdf2b4dc6e7004476135b448c5c01ce6c50ce818959d2ff5dcbd8197fb67f9bf7f17ab8024428d3cf48fb56a71bac76ff2e13e7ee7a067e5bde8befa9775bd9a6ca71f30d5ef7ab6cf727a48a59178db27de9fe754bc170dfa37fd03c6175ad3dfe0c97aeddbb896e741a3c378bf94e739d79a3cfdfeedf91e8e373892a5ac348dda48853d9ef9ba8749e12541ef8d3863a338ca0d62c33030609252fd51daf1607f4ec2c20be3c21a6450ac534d846989eeb12bbba4b68cb4849b98ffa3650e5b93225ffbba37156edc0bddfb9fea077ea33d79f0016fe9cd6c2fe7002f6084c2339eb29fde3fed11aba0f7073cd0c51af9553bd563d0068b51cb9352d7526a03c2feee10185ac816235c321f9728e1052608e69da0f29edb08a022d7d8a87d8c0b0492dd305c703863fa9f2d8578b660524b694708b19653004bc6309495d7fbcc8231fdbb3bab537c7acfbcbfff6fac375db037ffcb3ec1077fe7c0cdfff1b31fdd359a961a7fbb0c342dd6726fe13410dbde13a148639a70129bedb88b67018130eead3ea82d7d515855c6e39e8edadad71a071b8a2edc7c898b3f20ae95e1db22cc74eb29adbc0e8d71110205c2b19c65bdbdf15d1ffc1a87c7bfb96baa97faddc5bbe585c7e34b1e32b88c6beff4ec5fd4e9c3b37ad30ff936bcfd7f078efcfaa77f1ff12db7f53272f34990721372856720bf0b792e506d95d83197418def90861ff7673153e5d6877f368b5a0414687a660f9d046cc1c2656e56ca27ee0c36acc6949466456a6c09f560ce7a184a873d2406ba634475b18e9b8458b762f9f2f8d00b020b39d2d72990f5057dc5cb3ad9ff5ee3e9e2d8a739df7f3f8f0f3ccac3fac0bbbb3be9aedca401a5ed82aa09196c060c5a2071d8bd2ce532a8d11a2b2488ce56d9b22589b23402cc1d817f7a1fc42b56aa88b88d5a28b8e515ea5895194965f7648ccb40e5eda26e6aa907ab98fcd9cd79132ec62c0840d987356b3ee17ccb6330dc9de9a27cf41d76bfd39b1b73b4c9aa439dfc34ae661c7ad46ed3cf7aa291daface3fdd0ce873e17894f43020bd58854e6b50c36b85feb0252cd824251a67b6d948e0b1a4941b5a0e34e174a3c48553e90cb1a4e809d3e16c5149ca6a59fbb089128a36342a01357224b88759f57770c5373eab019ddeb34d6af40dfd8d5fd1253bcda7fe98197fdfccefe1eff688e1b98d6f2decad403ada068de57d0804a6b535a7c49bcec0d023cb7f7aca5413f6c2917ab612b45986b47bc8001e24632f627657a6a375ef3bff0c622a4be6782da2cd5254628b4b6189ddb09e1a4de353ba4a6a31dd8f99563fcf495f88f14f3dcf5fddd9a75ee87f8f47dc8ff5d25f8496879e67709b3d7ee88512be30044d7bba43003e2d9832c372e832a8a67199ad64653e51a60026568bb8de26c0ef98bd5ea5756e65aeb50ab40e8574bb8dd983261c6fcd4a344f354912276fa7a0bdc304272c52aba01a22d1e333dd842ffddb032e376885c354b6f7492296a7afbdd317b114f14123e384d933701e57dd2bef0d50d5e26b5de30ff83f7d6f8f0febf7a28b79ce17f0f7a8b75beee394d7d86ff9b66e7ef10e3f70cd1fb8bfc037f82e7f23bf00de8df9ca9bc5e13ae1f2e947da1bacd906a0e3a1016352a0106b5e1b02b5148e8816351c7382d769d540c987f385a23a1b5b1b4cc55654c16651b02e2c731e479e9e185e23ec404b6ae693de73b8ad37526778e14e4c66402c1d286292c754a9dfaaad7ea2afe47fadaff4032efd6fc4c817b80afedd1aefff7f71d4417daf91448e7abfb7c75c5a174796a28e8809818ce8a893bdb59953d5e0126ea4127773aae9b487b6d8ad35e67ab6040289486254ffd964958e24674b64e088570df6236f80ec6eb320d0ca4aaf1660d861c3aab2089621c1bb1498e79c7bd762ae334e982ff54f2efbccbb5f5c0be3856feba475f3d2c3fbe633adff441ff2ea5d292b58c5460c42d0705eb644180f5b540dd14cfb0bb086475909b5459103e1e438e6ad9b94c293a5b90b6d1b2c089a045adc059a7a226eb9a2b4ebe60ea6a1b2b0cf27ab50c32ca3d8890dbc12d08bd0182bff8c9bf4caf9bb1e4b3dc74467da5247ecd9859cd7c91e7d4b1fe5a28d7fb337deea8e1c35f6df6b1ebfb3dd5fecb1cff44b2eda72babf1b3ee60e7fea03bcd37a39d47dde3d8fa61f357d6edf5bd86561d6c33a04de288b100a3595a4ae57895aae25cf0684e6ab1898dba4f675a6ac968c6110f0bfab94dabd0fe91643bc918eb0796195be622cd3f32d75f420a53a0a0b11a13eeb098796af3dac52c76bd859dde7b7f6d63b7bf85ef3fc6b5cdb57b59cd3bd79e416fb0696ea97e2f003efe59143aa7ec37bf9f21cda8943e7a6b8669aea7fb77164b97199e78c3623526dc182c6ab6c2ca6011582173140cbe143622337d406ba1c2b8cab66192a38638c6e449f2352790e763c206aaf0ef51c8404e20c36db145af7692dbdb42fcd14fedd0414b6b7c7356f35fdfe33bdcbefc7fca7fd70afdedaafdccd88c484e5c6822a978dd11a03cf0a7599cfc9641754b0f77b2f11fd25dde9d3b8063653e7ccdfb88c8dfd355dc5678ec937ef7f7a8e13aee3569db66550a85da035161bc35d5c350d2bf1d2aff22ed4c48428e52f1ca9257d3e67cc1bf00279bc96b6afc580d47810ab3ca1143da50a353eed568b51eb6167f820a0b5c6f59f9d5f78062ba11ff25cf1b2c1546337c61b9f71a61e7272dd357f7ec1f55c3ae89aceda05be909faed1339fd4717d9ec73ff8f137e7e674341fd39d5f5b3d2d51b750f10a95dd430af41845b2cec6139d33d1c455f33087f2d12f9087981724bab5cd20e2143466a805bb80786d50362dd3643ed5da3902f10e8f854faabf6652b5a300309338adb6a89aef6be87dedc7ef7dad434cb3a8689b39504bbed647db26074e2da8c5e0efdbf5bda2fd007731c8cdff103f459e55e8e1a069048ee31ef2ad37c4667ea8ad62d08c48012b42f352907c8e226f2222354822ab0835f988a97d313797551f71f817ea0ee12fe86e01b83b62c5f6ff7bbabb6ed21bd2f439f44d4a71877b2b5e8c27068f64408dc01465334822f1c8f956f37b4f0486acb0ad577cb9367ce65919633b5eb10a69dd2ed461e26bdd84d84323d07d0d97dd3ca8ad351dd3ded79bc17c5cea14b0fb40cbc1cd7757e4d547ece8b53eb0c3fa76bfb377e4497bfe34b7279ce8690f753762023688799b05111a29338d6adb0d2e87ab408373a4bcbba45279a237c42f5848a072b20a21e9e269c6bd528cf31133bca7206c2b6c3ce808a83962d6d21f8bad2c3d57565b5de8f636288281b09b7506ba585643fa5b759accb07687f75aeacf5c1affdfb1de3ef9924be3a4e7d44a6e9efc8a2bfc09bfa1810de02eaba0398bd8d3feb70f79fff7cf71ea6db80d8b13dad25c38c37b06155b5084508d34c629c0b4a9d32ad0301f2aa9410f190d128ee8c8ae5d61d03ca5b0698312dfcd000a5164557377b289f589c60c1bf82ef267c69f6dc8db22510c626619b4472eae3d6f7145bfe2825d3dd436d2d137fdbb5fd2808c0f39c153bfd5b376f4c7cf8e7c1537e6c31e0c69eb861f298dc15c43bce90847f774d4ded3082b462097d49ccd59b9f56ba687359e5102892c623351390eb5b6461c3571d919586b36b2cfcd856a82296056dcdb03cc751feb569e8ead6536f641568b9b6b5c99a19e62d036f2da5c8fcef8027f3ad7665aa15572e4037933beb6fd842bf053dee5c5981abc8afbf9d832d138dfa5c033b9d3fa8b122709c03eedd1ea524f6e1ce14dca55318bd05a70b6fd4fdde3279dbd36039d12d19fc3fb7ff8ec471c538966de2725ee02fed7c8dcbf5b0ee53c0cd71ae5de5d0a543803264db4dc629aa98bb1a7cbca9c6611b3fd703840dc36308309a10df56d582c6a38f3217c4285dcf0704819b43be2782c04f091d7d6d6d74a53c2cbbdce71c4b4f4c0b1616eaed6f346071dda5fd84f6fc73cdc71ba748645cccda7bd9d3c8d73d37c66504e30f5a6c9582d131d2a0c739114704ec6de28504a718873e2b44b5a29d3d7cc0419624e0bb8cc8804ccc827749c8753a0c629c56650224df2bf3b6aebd384c935065d93e879ee477fb60432c609a2c2bd915fed9dd6c7e5decd1874cd2c3ad63cfcdd4bbd42bf50af285267f8245e6b21177af15e78db5ff8ab5ffb502ff1f4a25d6aa07ec6f7fe46fca516a2a886bb34d4cb38c2f96b6f0ebdf09b078ee8a3bdd8e90f2918ae5e38b1c28bbefd8370276de2a85e3ac33aab603be34dfff6b9cfb95ff2325bea0ffb3b3905721773adcd1cb68bc141db682d22bf4d81f7f8a187e8e36f1cb8409e7b84de8cb93dbcd7c73c7b959bc79ebc77f1e5591fd733767b1659f96b7de2b2ce4bcad553c2f526335e753e2ee41997fbf39156eca0239f1958a5cb97f9bc544fdb6615d3a45bb671ad34f18251b9c0ffb03fcbaeb71186a732c3fff2bdb28a1deecfac16aff5bcf0225ff34ebce178f974feebc3779eeb39af9cd3ffae8e53240e5c27dfc2c75d3c8f3fbd334ee3eeedda49ffe4d3badcd5f848c36334424a56680c67445721ae70bfa8743ba3fa181bb6ce54bc9154b7826262f85ae31147bf9ff6e831e0ddc31cfed5328a35e1e23ad027bda8732d2e3b48a2862cc6931de5f8212d7111d642f76bda09258c4f6a36dfcfd3bec973bd70829ff3f31feb7767bcfaaf7a4957f3f85fe1f32a0864a536577c04e3905bff853abeac45931ee3e0c3b8078e99e5cddc41915f2214003d89296a030df52187d39876b3850defa82b1dbf971577ca2ed4e48094432038becf1cd6645a57a6519ea495b7c6c0ef13d79a305d3da5f0cf2ad4866c019b3e8e9a07344611b7cd89d0f36d5cc3b33aecd7b9b5d7fcc9e7dc871ff9e02f7de70257d7192e1aea22626ac6f52636bc8d74609fecdeda99c97fb1cfff17b0cfffed9dfbbfd43bf76dae81b882eb989b85e041fb9a47bd9adbfa851c8997a70e7c8a012b67cfb9ee7ddc7efe3cb7c654dd8cab25835e1b47688740fb24a858a14ace9063ded3aaec166eb08bfb9be2ec651c21858ae0840bfa7a7ed06fe8d9022fcf000568b4df8ffbfbe4eddf5a77f4b16fd3730f0d2be7bc9ba445ae2188785c0e278151aee282ae42adada59a68b2f67a3cce415c8b5d5c291cd6568f809861885749d5da595d82a42ab79962d3a4f4b789d12c49c502e2cabb856b0f92486dd33ee832cea24ff0a2fb67ccb3ba6c4574d0a53eccddb5baeb050d909fc59b957a8a23cf9c7136900e7b3ad88e63fdf593e73a9dfddbf0f01de70f8364acf05487362e98b3a87294ed86c53c5c03c64d2d2e039df03614ca3362ee0fb03384295189506cc40ba9f182ea9c239795f00e73aac52aef058413ccd7abac570445b2275acb056c76b2b7b45b3918e36a381057b59983f3b8e3677b79b370d8310f7a1cf7c0fd7133c7019d689205262de59de8bd8d702d488b7817979e41b50e30cedc60d746b1f21e935a99b8cadd4c6b9fe23e37b2d1b0f547ed038d1062916082a089afe22d1e33207beb29a8f0bdcff371580d93b4676d08981e5ee945bcc15ffa800ffc2aee87ade05db1b73793b7da7ce731fa8b8ee31bbda58fdf5927a1be4c8d5cbde19fde5d88cd3ec1cf05e7f9f0fd9debb07dccdf2751a35e63b90bbefd17da191fc637128e5576c0c4abd75cc647dfff66ffee235ee43b1a6217e6f17f0877803ebbd7aefa7c9e4095784444dc33666f1348bb10340e293196b47144d47421c0bb20528eb0959225b49308ee98961b1474cb947a7342f32de270e557b1e643ab9ddb0dc5b5427ea5770ba7755165d68996dffb045633d0ddacf3f031fff4dff8fbd7e2ef7faf0579a6f9fbe9593ffde6a7baa1c6e9dcdfd2a7a8523e7cfc140374714ffcfdcd3df161fc83aedb3bcce28cfcfde11ed111058d58542822e5d0f21d660434df2e0a0b2d5c4be07abfa6c24ceab22365d62f5cac5203dea122d058893633dd0b0430777e3874b111ac12eef7096de842d9031cd19e3918f9049338924f4cb1166bf4bc867d618f7c15572591df8a9aad53f788abddafaf70689b39c326ad3ff2cd5fb49997ef9e1fdacc2bcfb3f7d3aee045b5d3f3dc1eab2d6ad5a684ae64d8f681810833943d8fe03ce6ec9115c8c6b57808b4b648edb64ca246c4b46192e6d67c8c42e2344b044c22a97c120e1e87b604be93afa65a2b90e6a180773d036c862053a217901522a6fc57b48edee08fbfc911f4cb98d5377ec35123f3fd679ffb7ad7eeb9a8618b824df1a8d584013549f123e1b911f24c97547056a052ba3099470a875597b04a74c82eb77e389c2166e549c158e83c18ac563b4a87535937b9d4114fed764b8067658e57e1b105c5589861e5af7c7e8631bb74cffda4affbdce68dbcc57cf439a6f9fab9fcd4877cbb37b6337ef0393ec9a39f6cc2b7f4b49e7fe7aa3d00bf690fde63a0dfea661d7d29b4fca10f45a12ecb96660a57949a8294aa908e17fa74bde154525ad80622c25d7014642033e2422d058c4decb24e46134d18318869db8530cf93716cf022f752e61b4c637788411e6b432d7544e4d75e822356cbb1f80e47e44ff6d6598fca3166f877faab71ede531a0fb58781b9f62e16f71f3935fc0465f18fb103b5efafcd4bb7c632ea4090c1684367684e14df8584efc5ac030fc475fb8d69d3f967754cb47fed8a299cbea8ce72d8f304fa97e8f0adacd1d7d2c9987526d2870d595987a6bdfc9baf958eaa21ade09074e842e67b1ae9cb888bb8ccae6b7b8512ee7eb3eafcfc660f81403a8cdb89e67a367ed8aab1cfecbac82c5751ea383fdd9fd427e60177374c2263ffffb748fdfa475a22fe72e6ba7dab6a375837c5ddad46840e2684068eace8f54c51c6f24c74230a72b306d2d59a336a328e1a530d058dca1620252281ee7fca15b5016b0deefc3319b4c4137a2919510f6a74bfa7c3dedb341e8d8dbdf5a5751a9753ad2773137eb37fab8db0fdc2e17ce29ab44c576332e7629d0aee76e7f2737a98beaa0115165d5b03d9ecd77cf71d2c5bbad5f983058709bb1b8443369b30d02de4346598f0a0a7c3b37c518c7311f025e75f733b03659811e1225185e0eefa49e19a1e67101d10c39d293a3e172514b32a7fa9216ac4bc164850bf62823946460b2e50ccefcf246aea90ae531c855ccbdb5d8dfe511d44574d4c6f8c22e825fd2262c628e1e0487cb74ef071cee05d6cb43fc72f9b96624fea43ff0ab7b71f8e8036461dd1a677498f0b10c1745ac316e9a7e2945c09a79ea284c0d58c5150bb24a5a944023d4609340d5063a7bca2a389276a38500b9b4c08345210dbc6cfd546bc65303f5583540166c24b4d80cb9fc2decf80907b37f7fb44d81f9dae77bc2897ed4991651d01ef93c61fb7a6f5ec8639d3021318045b29f7bc0f6fe889670d47f5ddf6cd5228abfccf7a5ced0109177c8f75de40ef9f8fd6ab84b395c2751a36611dba5a3b77cf4973017a7b9e05d9300faf6aed8fd0b3cc5d9dc5dad9f8697f28e3fd62b5672a41f78d362ae1d348bdf3ecf8c1cfbf27e10bf3f0565bcc205dc05ace1814137d958ee92baa983b0157181d742a938abad35023660953ecd141dc8fd3e26701c1a2298e9d0a0b699848e799fba72c99c56a00a03690b6f510a440d85b9e3f9a98e3185def9fd71c10efd24c793b9accd3ef44edc546fbdb82fbf537ffd3ddfffc233ecd77a9d1a526515ca3340db0430337be64ff949dfad0be7dcf508eaf30da143887a3427513e43364304c29ef2a1c1403c48ca76936a7f4dd1cb017520a02a30fcb10851e5ad287d0018963be65083466c15b3a697bc1bc4c4df4add36e26abdcd1c4de38e9aa4f41bbd91dfef5d2c62dead33f08ce7bae2abfd0ab61de5a9d3f549844ffedadbbf3fed7ffeeacc0573db7b0c22144bd590a92e3c0c99e713f810da08e328361054141552305eea61d93844492fa3db9ddfb33ea8f4473e0e5659f4d7241103a9ebeb49244c52b2796ce0011a8b01a51df601dc47754666a0fce65ad9879acc7f808ba588b9ae52e7b0c7f77bfeeddf3fe26221e3c980ea78e4936c9bd632a27ddc33de68a9cdee314165ea601c44561eaa3c49b4a1e7470ce14adc8902ed68cd02c1e524a6b9ca0ca544d88a05b457ac17442acfa62c062cf24a027098b049870832c22b5c2c177cab876f682d6abfd46f77a12e10fca0cf0e37a1db94d86e07b14e5771097bc6bd4d687701a6182751b6cd2853be0b4ba423c1f8a00f1d59e0aa8b04f0ec18081f1bc8205a2e0495bbd06eef70afee906242147f3a31561c977ac5eb3c20040eb84237f640de80c3bb21c77fc90e25ce7095709c7f438f589b15febfcf11807c930055c647bdbe37e3ef6d507063ef996e4b5beb452f1f2545318d72872934a7b6395a5036f697ed3ce4ba16d46c4019040c7413c9cd6d582a82e8b0c80a6b8d7b7f8b2a34469a1827441698da5b5137ed827b01a36a8d5c3c084ab589ab752734797fc506dda0d56d9a6ff300ffef68e7cfb84a8fb993d31ea84ff5e2332cb3e84524545ae3e7ef5dc65355729d82c901232db8a99dbefb89efacfa19f79ab482bb45a86fe3e8c8ddf1f2db17bf7ff8fdd3fb04c77edd2ffde0574cf5fffb4c0ba962b9707093d57f5ebe87c26bdc7ca89971f524aa7fbea3bbfb1b77ebf378c73d1dea4d5a89cd8f7a9708d3c25e42e97a896f0f5644eb1c12e107e9c2fba4c05548bca9e093c1dcf6b540830975e90ed1ce668ad5dc7ed806044db31e0784ca2eab06db50d18ef5164ac6f68617b9c1eb465037ef58e4c5827acb5443b7f62e15a953b6073cc855df65b2f7e77f216ff1160f71b0fd6ffedefb90935b31552672d0867064a68e2401c03ce1e66342f148b2c980da68ec579e9fd4ca65ae8429b396736a4ee87288636a32543246f4bc60b0dc64bde04929111e0b481482316798d37ccc89e5925212c49b8a4432b8a2b176c177f9d047f2758fd8c7fe921fdae6b763beccb376c84f10bf3d8d7393ff827458fb65b313d19f8eeefe595182600c58c36b8c630d07ccc81f82488ce4ae85b48a3b9fc43b59e03ee1ed34abc52629f509ae612cc7390e99788849ce52fbaf995592f9b6a7986e99123e98331ddff108aed979efe3959e9e7d5ce2bdeb4f39b79bc36552b1428ef43c33d01b2cd0659ccd25cea317accdd7f9dbd79ea0ab98bac96facf726ad8e7eea71dc4ff1b29ff602e2de378933e8122026e9aeb5792d71a094454ab109809a50620f2ef6ac1dc76ef7cf9d39c3a76ff666ff42ce1aad5360aad97e3f18d626add141f3f4c2f39cf0ab1774cc3ee517b1ca05cbefa90607cc11c9cc10bbd4461ed2b14e14f4101151f6157ef5fb39b336e17a13ef3ecb99fdf93af70cba8de458c98a3d49f71bfcc6bf35ef062b9ffd94e7397ff31ced4153ecfbf37dcc03d8aa168e9704911530150c7c665904e42de3a89bdb6a9e18d6366552051142016fb67ec99c94ea1bce7d837176e7d309f02b0d041c970b3b33535d788ce56640bb48d8904ab781824342783e9e8f51310337da17de8093df046685bdfbe0431f780b2557e5e93b831377ccd736e2d81358a4c0dcafd5b53cf66f71e39e8d7b5cc3bdfd9cb431183eedc795a39f70e2ea212dd998bae81101a5cf8c7c89f870c639ea719993ccb51c52997db2fc47f7cb2167d09bc505bea363b649556eb032ee174ab429c31b52a17b51caf154432176ad2adc0d19227f3551eab5dfe74968a31cf36e76e6c75fcb511fdffd691fcf9fd6eab997f13b6bf5f2df5dabc3a25fa837bc1df3ed1aa5156c45a89dc6b9697d4a62942b5f833aeb51eed7721eab6612460cf1daa231908fd8603e0b877a506e37927b052f6393e8f9123bff0c44156ba4cf4d56ffd1832ade0a2ec8dc6530d5d50645b686ebbf8680a54980c458cfeb2042f8130cfac57ed8abb5edddafcde9cbb86fe73533d8367386fbbddfddce9fa27709f51e13c35a12daddcfb4dc47456e4e41f7805c7b3bd3fee9086b9ca4f0423e16f14c6b5bc2ed7e0ae4148fd1dd5497464860b228f164112190d1dca53d6ae958b48bca0c62d06eb9a31b3e37bd3947d3a456e1019ff8d9dc7ea74fe27762a6135fdac1cf7ce64eeb6ee32238cc5f3ed559c79cbf5a026422764392da1288cabbc376be15baa7230d5a940edb34826168374f0b270f79a9c6a126181b975d5c7b3cb1cdb91cd341a0e911232ac8346f290b14601b258ce64b56e73a76d4c4af74edbc763cdc3e6b077f1937017dff1e4abcd640bee3f30c7e65ae0fb13c2b8f3cbc2c4fc3d3bc9f7dae1dfa02e7b7ad8143e94023ccab246d54e8c446ac79cba0d4a758e50fa18eec2c5cef12edc033ba4e9937921502b8a47a504eba103633ee62824b48b09397a9fb602ecaa19046fe30773a5b382648a97e2fc27f5688a332d5d8392fe9d7f6bb14bccb17fced7bbee5a2b9e62f0d0f1a5ec2b9aa3d098eb1e86fd89b839658294e79b2377fb768798c256ef19318915cb8de1457e654807fb485d3ec42d7a28b9a6e179137a1b6f4528efb94062662cd5ae88a600e1f033ed885657b879ddc66d072e7bc1d318755291d2ec9d83366c0ac056b9e12deada6da90cf29727d10188c7ec2550186eddebf16dcd4669cb54984b5a306ea9573f0b1d7fda7e720b236e9dedf1ce92ae54a93ce51abed93e7dac700fdadfd2eb40afa0c5040e9649569ff74cc951daf9a3ed6e14e46de1633cb13e53fdb99a144aa50931602cf0ccff6817e2f233c918aed020d3e84355bfac6c4f45d368f972dc10c8d24a55bcad42628ca2de7b88a23dcd3db73f69bb442b91ce96d1cfdb932f77fcef3783f9dfbd7314f7bda2ce2e88087dacec8719c1bb8d57621e8763ef1370c349518b3fbb4d4ed9837bae8210b2a1cfa867f63ce65f8242a556706de64d5b57894fee2bc884618484b0defd95f7bfb1ca77e93dbce7b4cf559e67a75d23391d8de7c41ffee10cf1fe7ae74e578b2c263baa346d661e88561d474412dfd6cec8998a81657ba98db6d206ba1c94a7f8a494e16508473da205ee0d5a2d46d54e473bff040eac030735a85af6072be5ffbc01b39d2b75935dcbe623b2617f2cdf2803713355bcfb8785f2339cbdfe87902682b1cb5fbb2efaa664f49047571e8b178cb637119d321f77bf2d027a5d622d49f3985bec48d2c1c5ccfb897678095c949fb393ac6d8d772da9b14b4cdd5dcd03937fe0f7343c34d02d4f37e3cfe9bfc7942379cd11337bd91956285b566c0d8a4c7546db88befa786e298c426e61323045db370bc5c501889d2c341a100abd13c5d0e37535d19a85075a024a11a9ecdc7133d81702eecc14a6af16051325f14a8c4a5b99e817690e8ccba2797385c4ff3c79bebb5ae5fcbaf1de72da9e0eeed3c1efefe5477eb2b8c976e4c012c6320eea89b17d461deb4b7a2d41561564f363ee85c56feb38dcbc0400c0df8381ef804160b881e7c26970bf7afb180cd086beb4e30a16127061928075995ed52277f62bce959d9215cea55ac3c4f46d2bab936b0b76107cdef6d9b5cad0ffc5a4eef60270ffaf423bd798e29de7f76f46b6fc96d4a27ee185575c615c0b5dd89086a0b08516ac39231664b008b1befdd9de0507bc6fa2591f7ad9cc06ff8937b9f57bee00fd5eec84b79fe3c3fd394c245a889d807cd936febdb90c338a9549feafbf5cebd5009181a4d9e1179e7d75e121a7935d57492158a2600b7a1a3f78ce0d6afba8238c3c7ac7ad8e0325fcf1d7d85981810ae8b206c2b09bd151dfdd3a75a7b73cd2aab86fd81c7aa92e03fc43bf76eccc3f937bc4d66f86d1c79b55c9ef6e36d71961e30a166c0ab4999afa983039f0988205af9e35c9f4796151672e3477f37120a2ce15f03e981bea8ba07ce735d6ac34842b1a2b607a59d97b28cf5d8b0b5391477822217f1b25b94034d4058cc5dcb20501d35f72ee40a4eefd6670e34bea121b5fd15ecc069fe32c3cae5513be5c3736847bd82dbf22f0d2d7110962da35040520686b0f380f4f92e01de7daaaced8262530064e31a47496d29a69963619403a6ffd9652a2f1630f7e710f789ee29cab78018dec82f3363aab36956c13aeb61e713e6488e0ba465e04a2df0fbdcaa079e657d25a2f2d5e7b8548f02b98a2bf8240e1c4dc738f26b2e2ff99070f4f0ee3b57ea5659adb6d2f9a7cdf6e338c3f645efe73a3fc4ef70891a9e99b978338bbc3cadf0267df5e18efbe4d3e7fb1483f8d59e017e64ad431af40ba27633d005892b9ab08046a6f22d7198c9a87203f6b0a35a3ee70cc338b25ab4fb671010f544a0b559448267631486bb21a4b6e8d282ad70d43c2d98ac396be699ee699c298f014fc77d3ebb95f35838ec84adb8da57f00b71355671841f4ebc48fb714f7d043770bf5098671ce1a09065024c864b0163adab5356ead8964b0cd0e03237ff452ea8cb7cefffdea697827bfa912ffbc40575e479bf15ab1fcf61ded171b6f1b96dc6065c2da032fc5ac599e17788c73b549a33a6795b0c732cc67f3692ae37a16e7502c28785e30531294de4e44f8baa2930f178c6e016bb682d0aaaa37ed2c75a1b303a7429d01127e7f8b39fd61d5f756eff5cab5395821ff22dfb79eedfd65bafafd5afe8277c3afe699fee6de1f650ef7d5747d54ee37fdf4f145a4b85ad3f0a5bdde3280661a9c618aa26ab0323ac64e7ef86e8776263bd39f2e7be9fcb375c6e57d6836d677cfffbc73cf57fc0ef7c37e669dedfe8c89dea25376277c4581588c23289208ff5c92aac9a42ea0cc785b213904fe33e7f129ab9f36d3d4f6c36c286b013da1873d7d219804bbf5649eafc5da5559b67daf089ab3f2b4c250dd81f90296feb97cd5d58e5535e378094f1e0b7b8d093e8e4fb71fd15ab775abb734e54d5cf383ef8ec29f01e0547dabbb53ee39551fd875ed24f7ef705cbd2bce7713de376d9c455a362233861f5bfe4283df647bb7f9e32d7db48e7a8953fabc43ae6f2cd7b4ebebb470f1c4fe23a37f6af70193fefc903af4375e02af8f01cdaf6c071789b8fe0132d1f84749853a8cad0e9a6b4c663ca851d329148471833835584fc5d654a3ca2223069a9268b0ab53343b8528721b78586ca619051e53003b5beca2189bc794899c6f409402e123eed60a8053b59c2fb1ff808fbf76eae72781d7a94febdfffe3adef1fe14d19f767f264ebfff7d5f21f277a9ca563e990c70b8362864aba9eef5a11dac104073ee3677f4b6f8f0b0de29673b71158774d295fc059f4944562b22af3ec6e26fffd6b423afe96d35b8b0404c68a52634b59eead684579aee83f6293318c1b505a7c08454d37748d33459281c033942ba0f7cad7d9cf522caa8de6005a799ed8d78f4d0513758a1422c796d05be6e1bc455cab7879b39d583f0b906771e1b96821f7a4cb5f4106f984fcfb6eb3f50a7bf38f6e9dea9443469f731400c864fe9c106fea45eaf6d43864a520df54ccb0157c10e73e5a4b051bc84934031408dbc0d0d64b0124151e40fac973306a48b1c7b40988032fca767d5044826456a34aba456eb05450341ac6950aa8696932e51b186986ff850f25bfb5ef6ef9a7053cd226b971a96ca6a7c8167eb622cf00b7a3258897d5c151e73f822f2b484b3fe790d2e3cd72956f8f6f93fd4377c4def8452b3a4f0d6c46d4ac25035878dc74bba61cb369151b90a2a69a32aee5081d5dc5eef642f4b01cc6da8c15d506295955264b6a6a15209ced1635ab525b54d94286b35a73660a518cd47eb9e6aed9ac3dfaa6fbcdcbf07ddfe77773af95a13e579feaede8be7bcec3fb5d7a7f14ef669bfae3cb89dd73352c2afbc3b59e148d85e43348653d7726829133466bda8ad2db9d95e5fa8e7ff67e6641d47ea2d86e3e42f7c7c9e5bf37b76eb1bcd2e71f47c11052bbf873030e04e18688b1c55646573bf70f28bba1ac25195b8aefbf0b197fa87efbf1febb01f1a51c53fc26c2292afd3289f51cdd682d23489fbb00aed1cb1a859138d6d45ffc7c42a5e892806bcd4956f8869c2f35ab8f99d00c8e045ce538d41eae816b151827be5a711ac58359c9343dd136b215394951990140b74a66b792d4f8f9b6ca9d7a9335c5e8f557f055b5926d1a415a0dbc4a7b97d1effc47b7763cd4dae3225b7732a4364b7b1285b9747cd3d71742aa9e409818c69a29286dfa35e3ecd392a10a11be94c007659b7a031c81c841185cb84e670ffbbd8b5c43c8a410a20c90a2f0e34dc085bb62492e5a2545fd789be9f5f38f419cda203ffe40db551bc898f98fb6fe4167e25b75fa6e0943f3cfa6e2fe3ff48bf3b5264aadb7a42d04350c506d6bc9518e319eef31c013622a5199152facc81501a52309d3549a90421f22eab3a816d6d1b94220e9de69142b966fa4347abcc601c9602362aa4b84d887ac4059aa4116c28f17e4bbf5b6506d312def5ef72c5cbaf63bcd408da7d9c985db9c78efdb2bf61b387dad1e738e04ede8cafe9b7e57a0e7e362624ef7ca3b105a183c4852ce3cd2e66f03e8d9ac4a79d178e15613a9c32671f9ba10972daa95f0db12cbb24e965182b18cb1adb8478318eec5ed472c50a350e0c01c231f60362596cd96e8426faa0d476bfd573985cd651b9b256b811c0fc061ee6cfa19efd0bfee3463aaa4ef7e7ec74b65effd6b6b7f5a71cd68b614dba0c0812474ccf00e461e9afe68ea8d9b29db35a8cb8d38e99a37359c83ee9c5530a1a9bab06483a64a4946c41ac24e931cbec1ce3b180d86988ef34dba0964540d17ecd540a045844cd28d63dfbb7ea3b273d99173dd367dcca15cc7929236b2da25c65c5359fffb066da2fac999e399d5a386c77ec1b7bfbf771cdbe8f37b75b04e444d8f94c6aff6ce7ae98ccc00424952802f0cf20eeb145eca177db7d7eae6dfeb5a6c89fdf8845bfc1579a1db4796eab1d202328bb10538591d6014ec5c887d2a4b53012d7d649c13aeae40552164aca00c44ad54213eb9030b1a0b84e47ebadacf30e3131894bfd1ed7d017bd7c104adea5111db0314b7c0637a2ca5b66ab8730c2b76240545a056d0ae2cf78662ec4fec16ff43d9c8d7b8839b959cef8b07aef970737f63f682b19655dc24d2f8422a07c98b39a4d16ca33b913ec7cae0a12b6455a075a6034368abc68aa99633f928f446784d9c37eaa638534712f0b6925f6c090ca3717a3e1268cd403817f740a275d386ab7098456e852fdb76c7e0acce24d6f98760deb2cb8798a5daf6172274ffe6e00febded604f27ff62775aafe7f15b7fb9b777f14db1c58237f354593bbfb7f599261e698fefc208b10554b5648a51f86727089c873d2e91460d5e0efd2452220068894baf61b66e863458f9b50429f10cb46cb77c39dc085bb7104061029a874cb796a98b8da01cee88f335f6f666aef9f7fda8da377a4655b6d3f3f8c0f7098bab7a92e1a03bf09772532ddce03762970fe31fec5c3fe3f0d0071b73a41d3045076e66fd4944b9762b9635249861036d036219196c62a6b1795661cb77d924aecc07e950301f23cd37209df590e3f2af19b3bf3b61db3a85161185c0ac679310e615a2b99772d851477fe40ee4828915829ecb80992f78d7b242eac119d7cf4fd794f5b3086ff6be67c2f5463a0abc398bbb0b75944a72b338f4922c0fbd22e5e44bbdbf3c7f5fc339eb2d7c8823bfcd0cd5c6d5707da5ded3643bfdc04b74e4a37bfb9c671c6cfbef3e092ef3e33be97722f2365f624a2ed6a72ebdd36b7d2aadd1f67dddebef85dffd2c9ff6d56f9b97fab8cfb82a5efab8eb7dec8037d2555b119afbb8af15efd6e6423dee85e3d9dc66d5504b8d434cfb74c0a444488b23ef633deff58c87efed7ee6b027e1b0a718a84ffdfa1bb4122ecfcdbfe0fd3e8dfdccf17df2773eaded5e3def7ed8e24463c5c2517e6a4f0c563213d7d80caacc440eddceeda19519a2439a604125ad0ce26e6664bb05d7c7c455b3b09236759119971e244a68019171a0432834162fec364881e94e810e38f306c968e887dfe1f30e7fa2a777d0ceec175c5fa6a0eb3f5bef7777f1e8cf25eefdd75a2c37fbcc61e776fee21d6d3fcd7f8f7fffc233ec6dfdf979dddbfbf9cf78f81f8983354c87239fd83b510e4319a96d10a9f5aca75ba63c1e52cf135060a223c6a8c4a1db4c919b8f28f01a39fedb2d949767f5838175fc9068cce175d9d10a291e7911e7288835cfa1101aa1abacb887f5cd3cfc5f6a167e62efbfbe8f3fde033fcb7144fea1b695eded0b575a128923cee5d2e7e4a04b7a634e118e09e8d6426fa6d2812ced559b30358ab56e9c40cc629acf93b2717cdd12590f79c2b18d346824943dfabc150bbb5594e142da9d25a2c622da5f9d97edffcfdeb77527cabbf17ea07d9380748d97a312904a2c2107c81d10d7500848952af2e9f7f2d04e0f4ead7d5dff9bbd2f66bd6a7d4dc8e1393fbf5f184e46b55fea9a39032334d518db9acd1d1d66aebc554cf15f7a6def079cd36b651c113d132fe7faa2ce3cddefed3f313acf9d93d8405b19c23a35d037faf76f528ba33303e7075e1f6398bfd8696fe771ea49b8ee5cd03f1bc5f4322eb3ce2f719fd4e52e2c7984416065767ec06fe215a23330dcd2025bb16159aae46bee109352fe8c4b25b1ce0c493d8f39bc95b57445c5398d503267f6c607aa0b798325689f832a1fa9ddf0dadaefd7e7fe8bcb72b4432ec51f8f7bce6e703771114723fdb7e614bed4cbec75e617f33be690f0b7eba3ec96f4de34e0b2211075f4f1d72eab1ab8881a3364c84a6ce8272e2157c64efad4d1cf97fc0abc1becf04d38c75ec63b9ecfe36b60ce8ae9d57ce2184dbb44f050166c3733f45d0c1b84015a53b784b8e65e68e73645818991be5b149ea70a6f8dabd68eb93648c4acc5b835299b42899a51a6a53f4758129853c1e39d60a8c6fdc889610605e5cf04a8f9673be2877e43397a8c85a7d3f1b0488dbd2c92bb57dc89227bf6f7f7947e9245bf6584d7fb73f1ba6eae579c6c8e23c7ff277b183da917bedec741771e87fe2de779701eabfe7d5dfee9bbd9e7de9ee35d7d54227bfb7b9fec6ee90c8b63ed36fbb297ee7dace2d4a7b71bc04fdf7b59970817a9397ac3cf76ce47783973102a47afdff0af9dc369d699d135691db4aad27d12914df6f8ce0ff9872fc4fbccf5f41bbcf8331cb59ece4c0465e4bde1eb0dcefed6a1c7c97d873ffd79dd8f3d8a3aadf7f2091e31c9c3d7bd3fa7dbfefaa2155a1f64d2183ea60e2a921d0459c5f5d7f58867b006fff25b9cf9ae97ff7d06bb3fd6db7df2214f798057ececedac883fe9e4341a6db23a68e541fefcf9f20c2502c2acdaffcbf3bfdf3d13177fe17639e468df8effe94c3c653b68c502aeffc6eced73fbfb9419c3e7bd4e38e1bf9ffa155423ebb25586068933846a0c0fdf4b84b4be5eef4eab6af03a7f7c0e7bd1199671f49a4b00b3c2decbd5cfdffb77dee1c39856ae5cbe8bc5b63df6cfa3ddc758e3473f267349931a56aefee2946e674579c67f1eed52431d6ab7bfee5539e94af7f7851e18deeeedaae92b36ea479c860bdc3be76203d1ef36a9f1267d3cf6d5eccff9abbcd89d9517e0ad0d7abc779f6c507088919d70f8feaed1991ee83a1ecc8e35ee4deab0179cfbf7bcff3fc78affc44ff30dacf8f3bc483fb203de712eeeeda477f33960c5ffccc77c14545649c10c0a39f19d9cfbac7d22a565b388df938adf65ac2db31259a4229e8ce48838bacbb49a2a88d77105c7b484d36cc2f3a4f72a3c190529cdefb92d2d4abd368bf215e9e5b334da29eded4e3e0ed7dfe1037ce76386ffd29917633be02ce7e8cf6b9df6e39eea9b3c2877e0f4fbd7c774a43344ca20464a4910187c86ed75cf349afbba99f8a52739f3f285abfc807b938c372d150d20c5dec740f7bef61e7d37dff2aadb10ed3d0760682b133d65ae7a0ec4304f7bb295a29bcf9d6dcfcaa65405ae99fe065efb8f623ab07fcd7f846ffdbcd3de7dc5c975fa7f2fdda333fde7ffe11ec143ed651af9ede9777fc0e786dd048e06f7503ed188b40195584ca6660a6c404acf21ac7302d82418f940b84813308c033336e62e61f746f3e89b7235839e15b336629351c0edd6e2266929c2d877a6ab5810ce6d6ec4b5df319be7e1e4537dca69fdbecd5b7ad0a5d9181e64c6b764d7e73ec49faff97baeb3576ebd97f91cf85d7e26bb462a9233ee7a4c6a3417ccf262933cb202cd6650bb1c4d3bdc338398ba602eaeb131b5e28a883923308bf80e3bcac0159a652c8f63f1c7c070390805a4182ab42838e1157e504e57f1dedb89924369069f7b55cfc8aeffc065fa8e570f7fc4623aeded57b2f14b3dfc1dcedacf71ff9fc6575ef6f868d7edf5f2a9cf677ffffe3dcf13f7c20f642aae6410efda103b7aa94c14e072b0899936fc2aee2480d3b9d33df09a448ce59b8cf960c1d6460ab1cdb5dcc4266f83085781899e12983f67424b2af296468ace0c8842bbdb622875e274c037d11a571d4aaee7bdfc3a6f79f29d5ef06e66875e3d02127111676b70a31ec12fe7708c9f9e7c4771c2e9d91d7a068172b4ce1ec1e007f56363091b4811a792b577aaeafc19943ca9ff6c84989af389128c4e0da6592f817a0a286e12260de9e2edacf71ea99022e48a73fddb544e3350875a24b60ad16fe04f74c19c2e50a5b562a2db2c8a7c32a748ffbc1ea93d1bbb3cf9c7dbd4e5752206edde97552e692ed70cf837c20efc720ea798da715f33a783d2d0cfeff6951ee7715dfc9bdb612f77a10e8c90595456f821ed19c0a2696236348322dbfa111f8551b09b1924c4503d138d360460914eec0d61b093369a071534b9405dc66d80058a33d7ebb9adee9861f773d6793e1f598a7be3859bdfaa46f3cd798587b32ca3699b387c9d397cf73e277ca136e44c1ce56b4e955bc5ad4f7b69e04de6b0f7fb7bfcacc53fe0adf34b6ba00ccf991979e2dbed564623498b51412b6f730fe41ceb7c13f6ca8d59be6622af17e3e132e4cd1a6b99fb8ee7e0090f191b3e2823f7c3a81ca408d971cd2789402503dd24a8aca95f62471cee5400e3fa56b522bccf2a5ea8c8ebdfc4423ed6ca9e6248641747075b475f5553f212d77a8d2d5da805ba098ec0c7d8dbdb18f0cb67278cf2eb64ae39a7a4645c6fe2885baaeaecb80f7ae1586e50e46b4e71a22659e79b721e1879ad260471532d858d025fe7aba096cfd29103528c4612e82e04c38738c24fccd6c1a25a5a618d6a65b4665c624926bf37bcc0c9ad7a86ffde39d9648606a9393dd38ffbeede7e385f239d5644a7153ed303f64e9e1b49841be50c7757f086759ff5f07ff037fff9acefcec1c779fe1ba3f1924ca7f21ef7de7c8ef83ca681e1d72a9f81d6a18080191cddfb40735c8c287147131fa238e8d134a9fc2ed0799c39d2f74bdf62055b059c9949956bdf8e0d023d9471899309b957115b515d9a0b67b0c2156932c43fe6ae2efa35df93c767cec6457cb31bd4d5ff74bf1eafc20639ca6ad7a3e95e2feabc266ee365203052a6cab0525ad54d2da3c6c3d40781c177986d37aad6584c46abd06dd8cc689aa008fa447b4b39d1928b0e13a87d1695bb453ddad10a6ef824efe2084f8849e43d4479685e8ba9f926a6ff759eec632cf8a76bbfd7eba71cffe935cd9e0f71c7ab7a4fe23e2cf13c00ccc02e6f1320b7a9681d62a23b5eb63d85c156d9834ed4d39512bca3a8a9321477d4980e64d84e88500137ec1535f3490ad4d437c973e2e896b2d68b99d762076c5485c2cc5e6e12d30b1785772b2c923c3686bbf4f13587722ede7cfa0e7ccacc97d83e3bacd1bf7344ff94b3fdff97b3ffcfcad96d56e936be74b7c79ff268ffe16eefc73beec7b176c73ef55a5e67e34aa62029a58921df4ac75ec99e6cef219aaaca8a7ce4591cfdd9302875587a360d877560121c70efc177b0af78b00b1d8c42c362cc95cb44c746cc94ce226f123c0efbb8b436d96434cbcca6f59da68fb9e2d8beb6d792f759c4755697ff23dcf9d7f18e7ec429c73aa3f6f53ea1c013e2e83e430ae0484e43979894973b117923464913977215b0ed8055de1473ed06959504956ff936dcfb4086acda1513f83eab7e6d62de3401473c45769f09b513dc37c8441a735b1598653080a88f7b7dc3bebd4f7e01fcc41778651daa3cd4b7a0c3be7dd28367f7f4c8f77ba3f8dbbb673ae9c537f301271ce1ebe36c419d3fd252b9b4025b56eb5044924b3bdf869132e64c478b8ae339cf27a9e33d2c5cb5093881a4220f84aa84506986f67615221bf249be4ce108df9bcd545570b6a89b9e446829cd724b4c8f60fea7f30d5425fca65cb33a333d1d9b7b7df20d6c939be0acbff54f4f32ecf5fd2987749dff364b859cd1097ec465b6623a37d8249ffb91dcf99074be68fd99319c904a3dfba52585cd41c67f0f6660db67769b67888fb09d0d6220452c868e0f31f7fb691f800008576fd9e3b09295de840e5c29a7346690e437f4dfdedf89639c7bf75f6d09e57af9d146f8b8a767ed87f318da3fd74f6f9ee9b8bf6fe6d39e9eef7a3b817983b8b45c02ac76af9b98d60617649ad9da5485f6b8d9684a751c18dd23357333058829264b7ae8e3618602b97f0f72827930489c6140c3f62e74651b9acd5d06789738caf26db56394c73ec5b9acf4aded847fcbbfcfb6c26d7a9b2fedc5f87afe02bfd7cf69d95652abbbb99bcf7de6f159ef15b8d7cf73618de72cb717d5af6d5a69c92334c0756e659c3f2fc470946a642db8da52484a51729d305c24937c1cd40cfa9403ecaaed9c37ad84b2e255fe3c677c9cb9d7fb5adf8e4b8d6f8169f33adec96638f6bc9ff83dafebdf14adc80cdc09670d28c05b5ce45414a33231140aa16cf0e3af412296bd3f19cd02ad5858dbbdaf7f6f24d29a43421558039f2b8bbb799eda834e72af0d284fe69cf319e8e2390b4ca2154d796c3180e46222bff6b7cee88b130eda655ef29b6077bf60ac1dceee0bde5a7f1d56f7414754498d60d0332b068119983ac235df519dcf7c5b8e95902b51e14dc2943b9f8c4ceef2408926c6b4dcc6600ab94bd66931dd12eaf1a0207406d58869d92528afa46ed67ed9cd25f45712a292d9da4b04d85cd0119fe54385f26cb7bfbb70a7840592cb9c60db5991dd22865ec502f5b3fdfbc883694d9a541ce2e8e73e6ffdf1913bfa1a9911d49ec726842b874c2818b68181e2993144992d1fd8640a58a91f13d1e601f0c8dcd64d2c6243540388c7eb555ab52c8ca485cbdc126e03ef7b1f66e61f904154060531e77606141f3941d43c644ece99681ec3cf7c1317783e3fd4b19ea911fbcc8bf85aa3faa99ef22327d0541ff8fdced42c1eb171dff5a57dfa8ecc339334b27e83e3fcd10e1bff7e4c4da9b3aadbc4e2885fa11c7eea157c1f0bfe1003e95e6218f871605dccf154a8576378c04e950e6b55e435a71ab3136fce776ae66fe0035f9cc75e5eecd72d688f58ae44cf22be4bc2436e7d9b1a964eeb17acaa2bb992405b8750d55870be7065284a65f23e7754251f63f6c70c784e938957d0f1ba4f0a5e51a6ee3883930552e3b0c0252f708ee15e77963bf938848c8eb40fa60637e046da419f421f62a7618cea29d7c43bd58d7fb117dfc66ded6f84a357c511063371c468dcdfab586c8ff2e2f3e7edb1d6f13afc3659e08e51bd6151692585374a6c4fcfc01f8b97bee547ca4f593b0e00e63343d9d4b066b44492f47c9999ea0103cf0f8de576cef202b35cd27a69c54079f7bb7690ba233b00ba260e6a1492bd3fc1238ea6038ccef351bdac7122647519a7e0a30dfd9fd6b69155fc764d0f785afebf6ce7af7adeed06a63080f7606bcd79be16450e94c1cb987b152ed1c0d7a4665c0e54a5120af586d96d276a5ea5ac69e26204e8c4dbebd4202887495ca02d2fad3a14f93a63641dd091a6fda8f04d35561a1569d40cf0d5f6dae99ebed44e7f253f76fbe7bf41cfcd715f8f185a3bf0fe3df59ffdc701bcaecfc9b3952d0b090363eeaa8623d228b8dc25b65586952c42db5a49aa636ac86765c031d32a4e1ca843000659196fb9adcc94f91b16918d0f7d9355c324347fc3d8d06b51798345f90b269ccc39427df8d822c9c8ade2e4bfd3ea804fd7c48fc32adb59bd7210f880d7b4fed07ff2bc97a7a9a31f6786ec67b57aa33b0fbd83fda7f8f9616fe1368ebcbddcfd1b6b3fa3674f38abbbbf3af14c6cbb824d6c7a9b542010bfd6e59fd7c599a3f732ff6dbdfa8913fecb1cf7e9de357d6a0cdacc3cd65bbff66819ba5a7c8b87fb063edcf16c7ed50ff0464e7c35df1fe5c6d789136c148857d4595b733b4f524826cae94456a1a972e412f35c26a2f1920aad858357d8c4398f088c854589ab7d1ae5cfa1935361733bacd1746107661ae1706e075bc5709b896ea58c66c28b7ca06a35fd07a7c8c7e73bf4c2bdf43d7cdd1f993de35bd8c8ff18ff8dfc78dda3f76b9e5dd1a377587311189da4551ba4bd020bdeec7cdbc399f6a2ac4236e5e45e19cd1457c48b595ecc8ce926a8f408a3e58e46a34166b749503380055a092e1f7d873cf05a91b88c777edd702ae0523a59c78d66c7457317b0c1ee4abecc3ca9e3bffd0ff4bc5dfb17aff8b506e51c56c44e56a4f88001fe0fac04d8270236a983feaed9a15ee522ffc869efba83ed9e193990423f5f3e37bf9ff1e3adcecdfbb1df9c99f591f31c2f95c39bf4119cc6fd7e4f27437a1bc366237be9640ce28c29726fe4e11c3530130194dcbb9287eaa88fb38a97f1656ce65b615c1ed729f2b4745e7062decfe3475897a295993300221c1ab1e8267306cbacd454f681a950f390213da6d59009bbadf944bb82e74e66e7f399d14852fbabd4962be60c9b0c962beae03105a40ca1c4829646c0c99daa9b9e9bf18a707f83edb655429ae7f9e54ecf62a0ea83ecfe4e8ccafcef71947f8eff5777443897157b2fdb8e312cf3ca5a48905239916ec3ee7b39c80059f91518b05e423ac945e8e673054a23acf9e3bdc12caa358b016ab37e3ae0933f204324f70bee861a89b9586e03586e69817694e6cbb027035ca95d66c7bb40a3eabef73a05e53f38fddefacd17625534bed9197ea7139c830ed8fb5dc6d5b95980d731cf8300662b3a91ade2d822c04b38f7dcc0203ab4e1089b0492b27ba414df05b07996a5d6a21c3e27869c24ace952ad8245c4bbe0f1d7261468427a354dedd6508687b9cb67b226754cf19312db1dfe8c61fd65cc24705ed777138bc6f8db6bc677d3f7bc231fedc7bfeb648e76a9995b33814ae94ebfecc58cc5a16f238fcda04d9d612d8d137fd4b1fff65caf65ae6ad9a4bbd71a90337d335fdb15475b919de10c7d7df6bd8edba5e6f46f6fe899d8ccdfb300cd38f29ef7637cd9bb57c9e680571795ad32d07b5df7f9bbeb3822bd7a5dbf03c644f779ce5d238d1ccc04b40e1c3111d79919fcb59d3fe75af7b6f373fa373e740e936a27052adfd8a427def2e33e7ecac91f6c6059c6bb2f71367a2930cc2af6d20fb1f71b5ef363ffd8eb5e0a68fcedf53ed43a7df20594a39f17215c67357bdb877e013ff8dc5e5fc0cdfc5843f46399fd6edc57597db83b82efb26ab83b70235f5bd7258613598f8a0c9067e9a86782649db0d28c6be58400c1b4f04aba5b8364f207a8d25b2750f5dcb0ee6660c8c35e8752c80a73eea440aefd22e8168834d4e1530eff6c9466d6a26a6daef34e703e48caa1193a985c90d1fb73be4bbfc309373ee6476fe2577db893efe5f69bcff76bfc782d6eb3df118e6ac53c73d6eb4e397e978d8711472590916d7100c390a149622c57212205057ae60bfd8c6d28b0404eccd164ce9b4918055b692fcdcc9dc2b8d41576ba20b373238848e0d7dacc10994bd33713177d617b90ee72fccabe9dbfeadaaf67353b606ada57d77462c08b45ed0f24d001713db1d0c18a88b617cc2b5434ea68a4070ce4b170bd29055dc8ea9cfb8f433b1158cc27d960ce6018682f9c8fdb69dc7b909b0d57d1e821eb89643db95f945e1bd4f953526211d4b93d333ec5adbee657ac38cc5ee200af3d12c185f8f93f7016beca057fc65ff8e1be9c1bfb60671ffac30ffd6675f9d227de9ec6bd72cfd436db0d636eea362ebb95af912fd81ad0bad95236dc09d1e0c421de02e5308ca4e56b34ce408770d53d29312c4353967b593333f076c19a7b1f601172b90d27a38784a2a9aab22e35e5238d1a5fda721c5ce0b6ff7ecfc45e87061f7ae40f7608b8a01b9ad4d91e79232fd6cf6437e2847f37e6e19e25a25b1fb92d953ee1065f59e78b1ed25e3bf706c15cc0895f76455c9071aca59196edfd02912029717b0fbd307318908040627a7709d89a29e3221d0fcb446baaa8f72091bd638eddfb136f8e9d6197405ccf85dee1aac92952f7bee694d7a3af719abe1fbf04e92ba620dcc5c2aadfd4d11ceecd85fbf82cc7b03dcafa4b7ec299bce04ff7ef8d6d77d439efe6d11e78d4af94979c79f69c122ced5f460cbc0697ccc2301ff98e1c07543f2b1399f766eee2e84fc791f6989de7caf57bdf502809872b5a230b032f0a6d142d2639096d4c18f728a79c2d1c7f1b56da9e3bd65d5cd9fd5c28837eaa43bb50ebf49ddce1bfb1d4cee596de627a7c8a399f7cdde3d9984cbfe4ea7fc1ff984518a4a6f70657c3bf84815fa50e023381f3d8c8bfc52f71032ceb77631ecf4f97abf18b4c07a771ae8a399629d53de6231383a6f0edfdfeeabd7c98e3ba29121b8fe6dcab99e8ee16254fc4041b0bd18573a63b52493a477991086fcd79fe101a32c21a378a2db792dabd64448a6a98f0829bd2f5b42a54e003cbbc590dddfed95df2b27effc256d925622f1fe2b7b2fd020edf5bbfea224ffd077febe7fbbad7ddaf7bea6290bd7081d32b7974dc2658d8c44a6c6c256cb053408f14c27e48651df77f7633c09f32de14be183e8794e0c5e370edbba3282bd13a83b812eccfc6d78d1743b692146f02ea99c4558f8b5247b46ccd984e7b52e4bb6412af08f2a2c4fc579efacdfe7c9ddbfbc81df9433be765bc836db3df4370e0a5da5ddf03ba28d126e0a8518258f7e61432533e3333eb43d058580cfb99310c43ada78bdabb4b2a7ba36ccfce222f51b6b5e4513688ebc058d0fc21a81bcc0dfcc4cde96aee740d2f721417d2a2466ece914a30948e2878b2f85cb7722956bbc91ea18e4f7cdc5fd70af937c9fda7e6b4950215c9717d5fc73ff9a157d6bb359d10d2cf26aa4d7b6d849126b2c8ad04663b55a8d17defcd31424f92611d52b622eed212ae9727ec579708f53c9f2033a9f41403f9388f24a550194cc8b972208d2999fadadb304e7699ce1b55112e2a78ab1af92f7043fd0b36c7709786071cd1fc720e82dd242e999a5e7be48b3dfa656fdeb7875cf795f722a5d38e1638a2064484f3501a6b2328b44bed21c2c8831c0c1d594c07d4c997f308b942f0796aab0e23690bc4d7615dee94f3679719dd986a3620e6ef01899a750a75420dfd28caa5a9265cc740ef88c64ffcda7aae085b6985574914bcc53c3b53d3356ce3136fdd5b3e8a577edc4f313478a8813b607d476f30f5c283fcffda4e30bd36117f71bb2ed692dc429fbc19f3a85386bb54e853bc0e743fe011157347f969b8063e2b3773a7ad15b7c1ccf8d591090e439687a9c82529339039d67c2186cfaae6f97d1f6cb31a15444086c7adc03db262beec832280d8cc1fe34a4d3280ab44e320a13154e130c2b59cf9fc22d7c5e7fb55fbcf072e0f77f43d8efb9bf40dc97e567b3a16ddf695ebfefd3caee74564923093dc33004552b6db804eb7a9612de72e1e33eeb59ccad57c7255ed6e9519dc388b7f73b676e1069cbe357ea9973cc89dbfe39f6a11aee25685231565564cc968e1a228736c8b405e25856ffab68799dbdc2d8455c8d21b053a1b50811e31f05c0e3c499c2508235c67615b10bb058bc9a8c135b3920ac7f368448863f5cac479cc864c42d206946f8968aee15979c52e4cc75f9d4dfe1c9bfbef0d8e72e71b7c1c37b1893e8d7bd0dd30ad30d8df8599f00e3ea9ff039c8c05d31b55a23bcaff8079849d39d26b4cf38a011c8505ef95c6be12a889f5682010ba2765d706e5f091bb7c9215232c0b344bf86893d90acf99d590aa6904f3267125f3987a4e3291fb6726b84473ae89e75fdd43f8f73963b13de49367c25bc702af66d15ee65f8adbd8b78adb5c9ac7e18e5cc2553de0b35f11dff143e82a13dd292d39066ded8ba695765b1067694813af4396d70be15f27630d0ebecbad7a8a65fcf733fc6eccfdf9555afde559fd51cc840098ab094161c13a5ca0551895bbd0e10675ba1d763a48ab662c4dd92645d0f9a0cd19b3cda40e002ff231469e9d19721b3a6b93c3bd2c929dd4da5a447f0614fa1b3a898dd0180eee4def9e95d62ab5bb19be801bf0ed78653d8269f4fb7dbef44b5ff680b77b393e19de82b3e930d6fe2c9fea298fbf7b1d8f5967c6516e2ef8d2f4cb6e854d9984cc02b4b4768b48c53e6a20753555ae5712776fdff04a94ed48509e10d02c794d6ae936cfa9cb4319e101ad60904404f9088fe8ae7df00bd97348a692b534a49e4999772b3e812adb597b3b729d390824e3f7f8499fb0882bb94e845abe8f7d7de61d48ab5cefcfefb1567ffa29aff97d4cdee1736cb0bf79e233b9eae3bc6173e26ddaa42e0732bc0207ea53ade757678edd8817f23d9ef4c1fe7a3f8f1306d4753194800d3d0931090cbe4d582315fcdd07dc7b26e69f15e6f299bb6c17da9e946ef348e06f8005f7558f8cacc07741810d51767a2178e947783217f9735ce187b82f37ccf4f08201c8f4886455eb2e0a92b35e27e9ade443a5fb9978b9f36fb0d42fca082f4fc7b04c22efe3d93e5b1f7703dff42023f6fa503a7a77c498783f8f530dd295bc137c9a71de49275f11313492c27b908fc336ebb127b9bf2182af62f00b62578310793e2f484078b9cbaa3c54a637157647928a0bc238f5ed6e9918f676e1aa3971892bc400ce5d65053de971d8e2d0c50fb4bf1d1f495a956fef27fcd69e5dec75b4fbcffc58ff65bfbafef58e55689ded40e7ef06836bf56f56e640dab6710f477650ea27c9b811d0b2cbea51b728b991ec862b7f376c30e09a6ad464b56eb8c9efc3c968aa7a5d64aebea70c01bf6a405c22930b144a27b7ef7b66faf00f505a99b8d44552b6411ce166fe3967f143fd7be0eb6a65c5fb57d93d1eec3ec694afc4d4068b68a467429eea722ef66d6f67c5f4236ffbcf65a8f9f6997eb5efdf8397b17ed0b76de97b8323ec4eb7334347693d1a2dec6080a977e7037b458bd1584d78481f7f6d68d5dc2be895be964e68f336abb5b97062a86a9ca4ce1fc00ab94ea27c8dcbe94a99cbcddc0956a9408c01b4a2057242d17a3ee86edbb77d38e3dea53af3ee0cc7de0feddce3787fefd7017fe49803b8ce5fae6445dad4c44f01fdb3c56669de1bddc86716f69d06511b85bc825289ed06f7365c38daa3367f4a7bbc0cca2ee00e6eb24a115a593161f8198bac4f2312ce1179a0361671d5564ad85de88e745a4ce10ce6c5ad723a71e4ede2a86c95b05efd88e81c8ee0e15ee9dd7b5de79fe70d79d3e3f3867be10c57c2071e89f3356ac7da763afdda9632bafc13c7c4cfe5c33fb8b6cf9ec7434c777e234c8744a8bd8c38c4105f5fd383ed36f8014ef59846a38a4c5490391a7177344ec7c311d63e98d37c1c337d8f75b90998c7e61423ee788f0bea556cf27bab0a82e25a0681ce232286392b100ff46896f5b86105eb33bb91187020aa350c019a8494990945fc3b38d56fe7ff358f9bda5cea739deffd9d9bf8bcc3932d3b04335a3ee36b6bd0f8d4945c6d15ca21817aa00cfd94f523cd1f5bc3377e19f7309ffa4c77bc5c0fa4dd3c10c10b26244b45fb1c9b9915f01848079b3340960ba71c5041d6191f81c4cd07196aac246af0a2d6f51c792c65bc27bbf656751dbf33433f4bf7a0c77689cbfb99f1ca9bb39d15f6393cb7df99d9b471e4158b0aad66c65ee7fd6e95a3dbbf75a1f6677fe390074045e2f053cfd4c7dad8f31c1fc7bee203de737fe0b58cf03635acbf75aabbb398ab1ff8d7ffcd27f329c672eca13997db5ea7a6d25985f3cc601f71e9ced552b489804d7c6ecee7bfbf9d099ca715d6a9831e5387bdad33feb42e073ec18ae7f2f8ddb37995cf3d3e7c978e5fea7ce13a8efe2d33cfdcc75d2cb096355fcf84bce4b780bd0d73831a8c3aab50218584e9185627bfe5dd3c66f450530daebbafea2984a37958c6e65c10109648a495e6a9ad5c0e7249cce52ed16ac0275224f660831dd0d18aac62bddca5e5b0272c5ec5a0ec88207526b67051e23071fd0daf3111dc33329d17cacd570ac95868be4aa20b38d29f7308cbf8933d7c365e7a035c953c3faeebfebfe047f68f5f1183f623c1a97c906269b2aa8dc252eda4c89fe2bac181689c6cc236bc6c836cc201774751c8631096f95494eb6e06bc415cca5039f12633f4c8d738e20edbce05ce890385425a2eb442a1f0c6ac27773fc752ff50d3722e4ff09a5ffebaa62d71503f13a85f08ab98897c931aeda53b71e64efee84e1cf8a48fb957bf4d9ce126310f799f739f5f9b0f3bf88b82c55bae476e52b583ac50a345a409639695c03f8345b906cc958030d273d68c988b4c457f1b9cc93b5f748fb8e44648599fc1d112b33f5d02d540f6f95cd825a42eae588993b9cbe339b356829124a8a69b343a5fd3725c63b98e3ff1ee9ca919bc497ef1c0155ca50e3ad4a8bf19ff84fb7865dc3bd2ab50071b46d12cd1248a4db2cd1ce50542550cfcda2abb158a373ca9f29a46d30e1b6dc75dde52b13502210d1f708f199de6547542f3bb14e636d164142262073d995363e8ce6033e01423557598fd035fe1f01cfb7321bccd37621837cac3bce75d7e5dcfbff3f8112e08b3bb2233869d0ad72be94014f2667cdf4b909a644ecab69bf5ca4e776de2bb0ca430d82ecaf6212cadb56f7432eca5414c652aea2d9332efeffb7840014f624d9e12ced15c783505682c1c2f98016564dadf869febd52fe4c10ecf6dc591f78dded78f3dbd3f97070b8176e9e38b1c3f8e7fe292bd9663a10bb4d725943c29aad83d241d01569931f4e0a351cea0743340dc50f3318be46a2e38e7c072992ebb004897b88d4cec2e4a0130438d9014f03975a588cd7823186fe3de33a9ce0641e9efb0cd9f7984afd68dd29db689a37be51cec8376269a6fc8de9be0869c1dfb78b6c96e26f2bd7fb191a697a7e1debf38d57e5c5723baf491662958f632525d66a0c4372c872392e38af814046666a2c13de0b5b47d700f864558e80745d59d28c99a4f46bd403808ed7ce71bd892c222191c7599f04468abe7993174049577492551087357d54dfb29fffeb5cff0184758e322d8dff5b77814e7721cabf49d8dfc75cdd69935dccac82be401a7abd3d90e6ee26af99d5ede5bc8af327b84cbfddfd283cd09dacce1bbd8e0cfcad16b19f96d6a784fffd8fb73f36efd1ff47a30e619b12603e674ae02f993df4b8f95718775eea750a3587303738d16ec573f9ff055c2fd6dc8fd7e3ef13b5961ca6d2be6686ace275c285b3aa2f0f20495a6dfe33bdf69adb9dd18d8098c500c56ccf4570a5e570376fedc7f3f8f75f0cf5f6baa612f05ccd39a34b179494fddaa4fe0e8bfbef4e364066fe3c3bee1e3bdfef7fc7e940b8f0db4634ebb8e215f62e83d70e8cd30c0865fa890b9a44c905ef268ef03da1b25189c19cd6c51355a4269089b74947a1eb599c5a83726c6c00a75739f4c503d9fa8229b302333d986548a30b32938f407f1e7fdbca4bf0eeb91396897197cf70dd9ba3dd44ffef79ad7c37766d128cf6aacb3c7fd393ae8b34ff399d1dfcf38bcb206360accc4690c29e20d66390a7b1572484a1e35828b7c3d779b1589d88a3a5d4ee8c8135153d2881bb1c676128d0681f6b6d418002e72738e1a8b308c62fa673b77b4e0933c0e8ce62eede520e51a601b371435f5f93ec1dcdacb91445ccad9de8acfe575bc838fb088463aab74f923db40601a8b76b9703c9e19c853117a92b53462c8a1aab61b526d7b3cf1ee71c1071274be883cb940986685ee52b6dc10d6cceef767d2f428aea0972254ce0cdb4cc2369094d8be0d6b667a40e891bfa8d82a669f6d83aff3451c2622f8b22f5a45bc91e30fbdceff95bfe575dc8bf1e2fe2c7ff40fe396c767f9d5ceccc3f8ad7fe45ff841ee287f628084aa97b528190c4b584b0383d0f68a44cb3ce97f0fee418b7895d350687b51ca673ed1742e909606dcce279cce0c2f94cc13dc9902c68913736f9eb9e47e2e5a28049a278ef5484bfe9018de2c7e1cbec192f8fd8d58f09b5cc145ecfff83fc783cfc7e10f3ee675f535025ba424b3ac46c50cea3286ca492b7d9fb88d8727d3551035f4de50736540be28879454380c2092cad454316f1cd4e526341ab840ca178f4327b4f91497709351344fa20653e0450b4e0a55e40fd81e262183d7e2ccbee43adab82e5be9f02a8ef8fa7f852ff9bab6c2b30e3d671582a97b9053ff98d7293ef56d9c27bb65006e95838db8541b5ce4a34cd85dd8f38d74a7003b5a87a65a5da71f759b39c39d1ac36affccc9e57e9b9b604c27026e53d3033321f7ba75793c9b1f3ea347ccd2ebf4a2d482eb2513f68a4c1009caf62eade592b37c1017791547f93aab154febbc978c8ce2126df18499848e4c6a5b4dda7b8f14e2595a359238394e1e5b9930d4e1020db212ba0942abb9d031afd690d44dcdd8cd7a435e6b8e52312c95e8f4d7b1ef17ddc95a597b9b347ccf1fffa58dfabace5dbef80e96d04df4f6eb395bc75163bddfefc33caee570ea66cc8b52360c38cfbda4fad5dd1b5642ed6e2c387996b55a2b3d5ad12be5471af1ddfe5fe2a0cb7761fc29c7fbd3bb00b36aff2fcf33e3c04bfe611ee0e0677dbf37d36e13236f7084778931dc24951e3007336cd83b9fe78f0b06390fdbcd9572e2599eb060be1317be0106da9b3ac7bdddfc77fc532df3b775971f421a17e8890a5231d611051a232cf98cb03cc2958a788f1e65b5be490c3e35ace28d1d762e97676615da66a7f95dc0a07b5fc3f975efc5c71ad01f9e456b29a3fdfaf9c773f83afe0963eebad8cf6a664a37e67fc00cea754c71b4a8350e4cc9181bc642702f746547410bd21a8da5cbefb89d6f17f58888ba1965463ba3224ffc72bd22c21a271ce379d4b8cc187aa4e23843f96ce1d84022ad45a94926b87988fd7cc6813cd5c75d8813ef06831bc8b9e7243c9ed7e4d02be53fcfaf5bb37bfe38b49450c2aff91def7943b94713de8c168c002682555ae7800beb49b20ef80e2a6845cc39cd5721e876aae621aff5783e19810c7a8802662e22e9f24ae5a99327587b7361e396b07cc5593b0ecdfc1297ef67fd118d72e990ddacbae84bef6e94236a32e780f5f59cd4c773f9e6fd290e755ddc82f50c8413dd8662b9cd2a6fc04a6d6525c124e290f0e900975d993a8acb5e3bcce0c9dc219089a91140eefa950eb3d2ee710925d768ccccd18edbf146547ca44c6931ca5b622b486be9311b6c8352affd7ff43927871c9757ab13aff7b764eb2dd67307f3ac523015af7d561f3f3be53382ebfa7ad068e923af55937c4e680c3360dda95af394ab3aa4082c0adc86a66d62a773033a6ae924f7056f8a14e8bb100cef88f3c7081db81302f472620f923edea665aeb3d21f0454cf529aaf44c406d86c2a06e433bdbaaf47f7c7be25b45b8470fb82a3ff3fc86becd7777feff3ac2edb63bdfc414e7c9acfcff21c0d26dc9332f28dcc2696743524862e338399d4c4d3854b1e43aa225e714ec4f04ec2e946f66a2727a30117ba15cc5a2bdd84241ccefc12d64293276e96a65f704f567c4d1d2e62c0f19caa368d4848e0cdb8a45fd744463990c23ac8e4ec0346df97f6ecfe0e1968fdb7cee4829c7fbc45efc07edf709e3add6b9fec87799c70d7afeb1d908e85b3086f55c19f39c57e6a7033ecbdf9cc2ccd107460e1923c312553024d32c82ca219f4c743421c58c6653e5f84bfc00c3490d504872e0a399deed21e77f7301bccb926694508117cc26b35bbef71975d8d1d7078eee67f26f777b038e9d3c3b8a7bafe2bef86ae421d9859d56e199b6e55342a33834ca9ada2ac96cba06caad89077b4b47205b54d4b6d319edf2f8a91c72bedca2283b4cf51a04733661043f5de8e3cb63e01b81713e2882207b139ede3c2b6a883938c925bdd8d2209e1de0edebcc356ff1a5b66bf66651c113d13c3c7a4e2c5f7e21fd3ff6e3b467e2b1d0464083771d5e8d80c5ef4ca87f99ce21ed7f590736674369fb01d76d586d1df83580c1352374b7f374c708597735e6e0857316139990194b372b065463bcb28017ed998be9eeefcdeb714c2711a29c8aba1c4a0f353db9bc4e5d04bdd3fbb34d2c10c6ce1a25a6fafe5e2393cff5e867d8793e0f1363dbaefc77cb9277ca09c636fd3699ceffbd411f214c0dc173c9cdbbec91d398d450e6584e2b8cfebc5638bc32b7dea6c072b25bab53274a99c3f6d6c0c4b19c26d6ae8cbdc2f9f713b7fbe4e355fa7ae6aa44b96b3139e54e60c9bb47e3da75fcc139ceedef77df0b4573884399aa36625188c64843acc7ead701f8339f54da1d9e05f36e177ced0adb861ff8ef7727e8e67e727dcb098655b65b720d0c409057cc81879a6f67497d89911d4bf7799c033c264a9c42fa05003e70cb219f863508d8c99a196895bf6bef30be28857b19083f071e84bfb8f39679d9ff5de4cd6def37cc219b55b2ba06accc52d7bdf5eefcd3b8c8eafeb48f7ff9f7ece4cb2b705b43cf50ac4a25b5fe47a38f0e8dd46ee26e2c0c1b14e1d5e1ef7cfdbcfc77ab14bfef9f723feceeeba18ab4ae6ee9f2ea97d3314f6363178c1c6c34968838d0fd03801a83df0a04115288d56b8e6d00772bd088738e90390b99a2ad191ccb1a6a40f0c0ae05368ab3888461ead2c81115a0a8a29372c14805fbb45c16fc55bf2a16ff0ad8df9a97e792f0f8ef6f87e7f0d5dbea9d1be8811b85ff3b4e2751c914655ac5d547c977e2b86731b59f779ec97bb6d696920904452cfa24667d5af6bfde76e263a41cddc8bcbc050c670994dbc2d863c924c6389f81c3bb94baed711cf9903fe4775918775d8a6af76e5fe3500d7c9f7bd4d022c5cf24928e4721ee580d864cd5cbda67a14276ef394997a15ba18877ad9cd6d443307450b8daca09e02c13d1643f9c4237917b33c5f303222dcdfa5906d7cd06e53a75986883f2984435a695b19e59614a3e62736495af336ae8ef8ea5fd8ece60d6df66725e0a38ca62f7af5e57d8b77d7c76af0044d122157b2977a8e889522bc952e6199c37d5ec24e693c265cde719780d0958895818927f62a73ac646ea3b92a7e6ffd09c1acdc021fa219b3c93aec75414c39cf26722eb44a38f3d671a96211e583f4023eec791d307c4c2edb7cb7bbdf2fb55a2faf7fe21709b2cb18717d033fc6663358d8fc9e55c307e1e087a426653641f733a3b3b2096a6935d82e1c74976aaf9f8fdb56316f29212ab2ca7accccd16631e13116f241f5a3695ac2e7b892f6a296cf8441a45c6413d6a0b4bfba6fe0bc0cfe3a3f79335fe605d320ad71231df672963fcce727bca260e36bee3284eb34229d327e7589490673dbb243a781cc550937e034b17fada4b1dccaa2ec896897d49e4256a968cebd444632125caf43d1525c379a39bec1a91765f6b0645c7b0ae47acef504db2422cc133f911b7bf929a36f6161c19bc8e4682f53f8e0e55c9fc63fc521d955324355dd8cf7b6c980d5e109d92833860147a10f70e73b1e61367f9c8fdb1529300fe172272b9dd0721829b701823198d0d16451e264614b5b815f70eea211850a2c1c32665a3ecc600c99d0cf7ea49e021339e2563de2877aeb2b6a4cf7eb64ea36ae8697781c4fbd303791efa73af8edcb9d78797fdaabeb781ba9a99aa4ca73a6719d45729986bfb6a222a318e6735107568a741902b98da167f309e7147128781ea43030e794705a0e4b1eb675860283d5cd061b53c00b6fcac576939abf0d6222399f9420e08da90a5dc537ddabbf3d01eff2f517f27ad90e1efaf6a5837659852ef689df5037bf1bf7e5ae1db00905c9b3dacb17e1293e7385af8b59fe1c32ec2495b4831a87be41b6194241ea2824eb2667e6e8da7c733f8b749e5583f6052fe25b58a5b759a363bfc18b9ff412a7ff309f93ef74652c523e31833fce8c6e9a8a76b310c120ab75c04b3d53e5709216c4f645bba11192f7a6ec16a279e24216be995ba14902ec1049cd1ce309e945ed3d671cd185c665d6e3c1820d779c139fdbbe45919cf04af969a5aed7b9c6fff84c1a6fcf22fef1195494cf25c28e34314c1c84836a380f756cf0b20da48129777374ed1994d1457ceedbc5ba0d3e90279f643feeb5369d1f0283b9f24edad68057d34dc2b94e6c526440160ae9bbb9ebaf12dbbece0ea8fd5639c39514d6377a646fb20e4f7b19951aad4e8fb9deb7ef7fd4b7c62a72cf855cc780f531e477a1a171c6519d010cfd897498cb2c2e881796bfb671c565ac47cbd01e80a49779e6a87be5e82a36861385022baef0809a2319d4644b26de2a00c0608677277b328923def3dd3008afae516f0eb2253d60d35fe21c0b6e819ff474907102ae0f77ae3ef45bb5e98123df0657e3fa1a2d0e27ea41a0fc1e43bda3857e487a7fc360be4b6b0612fec75ab0e1eabe9fc2b446317674cb7aef3973b9c191b653f16bc3184f521399a26a65ccb49df4f889d7724c21790819af89c8736a0fadb4f4e8fc66313fb493e6b13eff1d7eefee23b607ef33d76b5261bfc5c5bad05f7ee4068b6b5ec9cbbe777fb3bb631c7039a1aca4ce0ef1dcf7f338f1215e215360b498fc813292039fa267494b83bacb0171da2a19b739434d1756d99532e5c0cfd5c746ae5361b7caf5f2e37a5ccadd1ef0986fd00b75e26d33f0520a98cf22b28ba3831f79cce3fe7b7ead3f1e5c7d3f168ef718803f50da5872cad9dcee0a22f2a5127fccd05e0ee6761e2b9ef559843d1f96db45394c48d956a2e4d3d81c4509cbf90c348345b536fc428fb31ae7f1e3b0a5424f59449a79a4301baf0778c243e6b09e57ffa835393d977a83b1f0cad918a94639f94645c1913fadfa0657f1adeaa6af9ed7df737d9eb3189a494496a9c94f1c7dd6812beccafedc6e26ac4749d13aac10606e7377dfe76636414ed08f4062aa9db09bf59571ce958cb4715916dca4dee430d6e13c1bdc528fa0bf9ec719580bd1decffac06060b099b336a0e1b04f045e2eb46d5253c60ba66cc15a973bc84eed16138047a993ed385b0f42e859d8691e7d2718ec6d90fb7ec4d4642485b058e2da0331f14251a989ec33c0f468200d2c82ef63277fddc7773c538f4ac8ea05c7e5181bfaba9624751090075ed3b767fd2216e50d62d25dae1cdeab317cfdfdfdde9d99cf0993f23a1b48199cdd9bd36d02c98a695406069101b04002a0c9614eb80d5166aa5956ca716200101b2da1008ac4c9bbc4d638a488f389b7a462b9f2856e24d04b097192525e7307ee98cec7b41aba5ca89ca3b25b5ca8cbba02b3368f8d3697c60bafe32baf647f792fb9915e8ac91ee5f97f9661c7b1f672a9d3aa1afc484fdc1b1ef36b3ec53683d456081b7f366981b5aa309d9998a4761307e6c8cb26d24a69fec0c1124a1e1bf77d6c121777e978e8c702316ca2fba044c0afbd3b590df359cf4950aa71e2e67612fde9a40d815fb5e4929d7ac51eeda4e8a074587bc46378eda1fe84a776883384b0481c5e24c738d7ff39aed5a5bdd475e21ef9af8e733961287e9d1fbfd1de9e1bfbb0d7e7b8515bfc83bd272599b332dea55c3f2927f7985608835f03391ec618a03be2fe01a94948e86cc10ca238ae59cfc2a1c36a352615aee3c7364901c9b90860e8aa39a618329efb81d026eee526038315afec2d2d794e616664fa4a6e0cd118271bd99815f6394ef6223586ab44b02fb933aee6b43df023bcd5f17f71adfcdd27bcb43f074ed70327df7093185affedbf7dcdf5824bb9dbd419967174911b67ff3be6ac98dec01eed36f2d0e7713853a7d7e0f5f7afcbcdc7bb0410242933538717dce5eb98114f318b31b7ec595d02093a372c64e2b35fbd2a5997985e2d5033cf6a4cee41e7705b4d799d8ba4c23173fd0e836e19eb46108397016b8c39ca133f2246527047697c6d8fde3a35489e197f9e63a3dba4152fa5e0dbcb6bcd6e61139d1dfba8678f7b3eabf03a352c2d1daeb3c31eb0ebe2a0ce7230332c740f47869cc869a8f173507a8304e59b5078eb45f96b705d6ce0e53c58fbbf3fc70602dfe81b05b7c881bdae49bdb7bdace250c3f776adde7e4e83fd7dff761dc9deaf4c349fa7a043acfc05e863bb9f8b90105bf750cde3da06a2bc2e67953ac34de6783aad2ededd5be1a7ac5363b88dabfdbe1cfab6debe3fd5ff5e5357416ad2e3c017f85e9679e0db4d1754dcf00d95ab71bb0dcb78f391bbe56bbd7ca8a72ea76f79c0bfce4b9cc704fc1ff880a9333465e4157184f54cb47a11f9c7f5fc349f6b7b660fb5a3ae5f764fb84040d8e49997d2a14639e0ba29b35d4b53889e144213df20756ab4336913d7af204b29028b0969311dcd39cbc7143634a815612cb71674247cea8d7cbb61a4274d6cc884b13fab051a59c924bfe4c77c3ebbae07bfc90769dc2856b4ce6af682137258eb37ef4f3cbed7f91861f5cb90f6728b6ddc32a3818bca32438da96f8eb8e4aa95e3e1d47764c59d6e25505e2bd834f706ef7cce276984880278796f703f83fa41306c0a5a5abe2877a4424becfce98292e3c0fc03324e96c4f0fa845d67c32c045aa78e7ec5defe4eaf6c2ad04a86b04ca24b3c18fe8dfc409827063bd4a71d64eddff14f5c84d7ed89ecb123f9ef9d6f777365e423ea4c37b8c477b82425b6e35d5aa93b49474f8b4281b86e7664e299018f5769af1dc9aca9a46447c7ad15f65e2b27a3fb99211b66c45d66d85dc0c852b8a8c161bbe1b57aa0e150939b7195609dee7ddebffedec7bdba12d3e2cdefbd3f1767f6323e87cbfcd37bd64bb1f7e90fb5502fafdb93ff7a3db68598f6734ec6312754ead858306f1747233e9fe82d167226458bfc0a6c68ad9e89332c28943bc591c37a7ba32a8ea541ee141f156939c47e4f302eb1b940d92029ff6c52374731e5bba01ada927353513e0dd1a75e867fcbb3f1ef8bb8e8a7f3acb3dadb7cda8bcfbaa5bf05fec5fb31f736f6e98e45de2e35a7ed699ceb3808fa9c274e37975419cc6e372947cba0471da9f89a8ae12a7b1cd2b8c72309acc7ccf8d5a74506522e8380729fa3c64cc0d4a25517cb82c4cc412d75f37b42f3a5efa825eef18ed2122c5c69321dec0228bdb4beb6260de669856af9ed1eb79be8943616d62156f3b7bfedfd3c7e90d3b468d8225ea8554a15c42eaa3190779c798447721ad7de5a54feb99edf3758eb5fd72fdd26a700755629ed1fcfd7e9f5de5609aeb455c020a34a10a170a833101639880d29985b0e64ffdba215260a36655c2b87446829c36124aa761346cd53faf8abe7b6b295491e02a881b0d520a0f861ee9260518f8a458927c451c63dfcbd63136ef993511296c3876b6bc352c141e20ccb6fd886dd4dfc90d7f18e6bab9c7c238ffda9d770f374332e692ad65daa1b4ee86f3336732a2a2852603d9209e171387cc0d77123b689c0bbd4f8cba174293f7e83dedd77631e6d045d64d5b08d23521ce30657f7e96f5905efd46e1873814d61ab2d99e83ca4ba9bf5a3989acaa7b5ae9392b3b0c82ddf411bdf5565168d7659ddd8312532ad733f3697a6d42814f574a0aae1728ee2ce775a37b1d1382ead2244728523359550dd8cc73baebd3c3678ff96bfea1337433d6a0e9cad87f5798d03ed3ed4d65d694f7cf8cd8b36c5f4d97ffcc437ffd333b04d04deeb3570f23bdfbe6f4fcff603dcac764b58f7246b550480f0b8d08114bae6aebf4b9977bfd039676e3352fcf72e85a322a0e560ce723d471e90f4f74a703e4aeaac0bb5d4d2264bc5c98c39ed34d1582e4a38f70d6b1bf47aadf6f63bd42834c8c7d8d17fb42d747bb13ef8461c0bc7b10ef2e8c0ed7bfaddebf2c29391488bbccfec72a54c7eefb35f06eb559d565ece4436606ebec4b6350f9da91942ecd10a220eda86d90cb0b27dc89cce4844f37c0fac55ca759b72af669378900adff49de58e084f735b8699e9f5caf8bfecbd5b97a23eb73dfc81f60d01e9d15e364a404a62117280dc01711742a068a514f9f4eff05047adb2ac763fe3fd8ff15cfd7e6ddb268464651de69a136271013771c687d83f9b70be71878e3ff2c0fdd4b60135e57871b46bed2ef6890ff7e8792eb82fd677aa99f7cc117e56a3205042856329a42d026120ce0ca124dd2c11447f13a50631b3bbb98b914f5b84ab472374f020b5bdd5dc612629bb5f89abee58fd606405def252de05ec718daa6e196aa891101553cd6c33e77cddfdf81c7bdce5f7347427c60dfc91b79ad33b1b7158db089b99c3fa23c7c0165dc78d7f17f2bc4b4b94675a69ce69b0a4066a130382d0f6060c2228595352f600829ae154f95b56f946e6324c99bd9cb9aaa1636671c200d3f38d70638dd38dc64a0dc4bd685247359cc940688febb46c3071ff1827dc245ff777bdec9f0ffbf2ab9cd7795d8bff44ce8bab36e17b9c7b9f39c3a74ca7cfefe9c37c7e94f3fa8b282ba4632ec3b1cc532ef8d4b041e8c836d5e1cae7d996d2dc0995b78de9504ba3874d585b5ec6db41627b8f61385c850aad7c6ea20cda1ae2398f23cf2025a3441f4698ab36ad7082209cfad09bcc5d36b85673fba3fee4257cd46d7c27b379736fbefd737bc0075cc977429b09531026aeeaa8dd31e6486d4627031f58b12422f20d6f806ca0cb32d729603a73866b615846aa499b0086ef0c65676ab209a1b796a3d6241a2a03edb721097ee463b461bad050d54641e915197fd8b0d39cd70fb16fde5e7764cad92073e0d3eb5a3ff3876617f262fb77d79c6ace9de5dbb8417f0868d24ab5bbbf3bde0dcfe31ff3ecd7f587e05233d3d2643cf2c2a08490c006b3311a08d660a48b96d0e148f4e28969661b962d8d75d98715cb898b343a1a32a2619ed9b2cf0a769fc0fc3181798daa789945f86ee6b2862fda8045f9124359084dc5c4fde46eb8a88b32b951cf23d8f33fa7d1d57c49bbb8a94e22b615b5b464058ccc86e58c8b166bb19654cc66d56620faabe2a6a738c220abe06abaf35b232b3fd5273b1ba7df601dcc5cba6c1bf34dbbf3dff7daaf7b3feedce7c7f8fd8afa1f3526fab4979a806c328fe453a6ac3e73c5422a2f0e095c64d02aaef3c1ccb570587b198734b9511fd6cb783bfbf894ea58a57cf874ccdb80ebf454e37552438dd7e24e38abcd8c781b5699b65f422f1cdb66b8d7bf864940db7bae84393514f523a6c858e429889761f460c404ae986a8884f92f59b247df1101721b88c6d0c650ae1220d6a1d38448c9556a34b7d2532d1267b84c38ce5f7003dbc139cc4329b807c4f6ed77e2933ef24f3969bfd4da7ab997de6a5a9de87d652e3ae8bbd79e4aa3f2ad5e9971aa2bc85a79c4224fd4004cf7dadd1f63650432d75a6735eef767d319bef9fec71afc5ed3742df95bfde88fd8c53d9ff4d3eeb9331d562f3df48b13ddcbdd7383ccc1b974689b56432de1a279d5603bf2e3ff5c07f1f55d5d8cd5fddd9da5df28563f8ebbb33158c535abf718ecc539feca8b3e5d2bf8669954b191d69e86f9065067d0d1e84143756351954fb16b8de25afc1251d30b223748ebba909aad70865ed2e701677f00351489a31ca64ce948e1c4b71b13d3d6f279de079a2a5189bdc4911e737174e2d37ded737ce36cbdbdf7ce716cbcf7d33fdc97479bf8aa6b74f6f7cff6047fc409dd5e53c9ffacb7fd0b3be9874013d063be865c5e7b4da8642b4ad31555b70ec70f460a0590c59feb7428c30f3aefe7fcbfcf78eeceecc71fc536c798f3c01b6a9feb8fbee8a3659a5c52f761c9aa06490758a804b15fc87540b0139402125b8cb97ad4688fe38c3397807c2c8b782061b04caa492fabd59ad62a0f810c7c68d1d0509174804f356d132fda5c4046712416590f03cce1c43fa9b17ceecb9cdd9757d518e913da9ee0236f5b630c07c6591ce2a57b3b42b9e4d0168b61c02bcc85e1f9cc3645083d2d8379ee731526b42d62ce16096db14fbd3be15a388572e257dd58566c40398e11617daa2c674e57068d9a8de4b88b4be4f92e8c7125eee3084d84ab66d896576b2f7fc4fcc9c8da7349675b50a47a775a5bfcec1d9c6a03fff81d9ccee1773b354eefd329398cfb03fb8f1325fe4a1dc7611468fe384721575646518c9c210b0d5433e2c18c42775efb5bea5acb94e09c32b5482a6dc94b16618e220451854b93660506849a49caed8d884a4d146c25b46e9b68934dcc1e369482f57734707f62ffdf6be19dd3ec3c7b0f7c95c7794a0deb5bdcd43eb941feb71a6e0e1860739db9c1736fc9357d550b31b61ea542eb3984b164a8480bc41347342979e8392df5bb3eb84d8d847bbb67d48f71d4d7717d35dca61cae92a8d96367a57389ffc1bf517cba5b5790a78efaf5522bdec5aba7f3f9fc9efd8a43a66249d6333feb51246dd4645a1e656345fc52b239c9cb8cb71bac975aa0049917c88d23d86022d4bc660b7f4c3bbf64645ee3984592058518a3524d6305979c78415a4dd6290d3406d43a29512875645ccf4bfbeef941565dea050d7636e40675eb93710f719fe1b531ef9a79455b1979ab3dbe331c5c8745268af11239b4ccb1b0cdad507883f56c70d7438f94aa9e11344275037d07c684092731b28e69c290e56f8dea5d328f244315f445cfee456159d96818081d2da89169c43607b20411b781925c1a84a2d8b7e1d7f1dfa9cd78e6a96ce308f5099797340eb553edf71fdd1527e3eef7baeefd151c69530efb4c5775bad08ee37d3fff1032d84af70170a51e67a3a1c5ed4e670cf659a97464f8db4093e86c1eea656cf59419d66e6e97f3311f31523fda7fcf9ca07b9e9dcd7e0eefd6e2653e3b1b6b5cad4f46e406d3bc4cc670106aca12009b143057681d9a8f8603a9e124d3db99cf58892a5673a666bec64aaa328d97202025b319c3ce9d9e1b73e2f98cfacba0da2ca9a17c6ec3595acb5f53bd3193d1b093119eb2e8da1adbebf37f0f4fe1fffbddf5bab6fd87b5eef7da0a576b9161358fa02f4b11cdcb6e9911369af1b699d98233cd36fdb1c7309b6c33de0e528e2de498be58b446520efd80c97aee3663069a5960e41becda2689049cd9a04da09c658bd69bb9591f94036dc6c4c0ef85402abf151f6029b868d28ab699ebad33876da5a3d41bfe9d8febbdfb372adb823cae919655b07893c7e966a3c166ca4d3577834b38eb97f3ff4d8cf54db8625fdff30bbefac33cb4ee3a7bb3f7496792424801bb67146c535bc5441793d0686c54791bead25e42a5f946ae27a559d252e13b4d2836b656a49a68619f47b4c836810eedb993035249407b2fc6dbd64daad62491bc9fd7688658b394b66a4595fb5763ab9f9fbb7ab6ab17fb276ebbde2fe3eefcc5e7f36ee699811aa10f8eba8bd7f58b3115ac63236fe76366c67c38a1da9052436d0343d521c54eacff5ed21a35b12ab7a4d43631c1a1b099e2e16f2dd46527a2c6c0359efa91dafa80eac8c845e2c23baa7716d5b56d66b78f048a5fd479dca6ee448b2ff0847fbfee8495a8d4d3cec7cbaae146449ef69caf3bf02fd81f38aa0efc0b530e17bb358e39d2de7c77302dfeb469c506f24cafd9a94ef43137fa11eff7eefedb9f8db779d40bfcafc3a7dd999723b0dadd6f825fcad3ef7ff306fcf327e3eecf73ba004f220ada3dcedd614f477b7e25bf6bd985d0137392f753e0ad62cdd3316446087292f2f61edba09c8ff1941acc9355b70e741373fab8250e1e05a5dfc51112c8ce3551e5b1d469cf985ca66597271aa4bcc44f71dd3ccab1e72575d613026146c527da92c3a7f82227c4adea42fbb10e6b5821b55b3774254f0676519e8d51c4b49c65c0bbcfb4d84c4b314645067c90e7334a6f12cf49c3cb33d732bf15cf1996b65bab38c297f1d6a3817913bbf76eccbdcddb4847add30a6a7bbcf5619cebe2b71e87292c012ed153e2da5aa2bc01532c08359cd35a6e5969c624823d3650c37a618575a6717b35481ca0a5c4de48cddfcc232b09cace405479d9f80110d5a0ac28bb3b03963ef37459b299d43323a99a105fc05b5f65efa23f6df26253feecfdabb37db123b0129150698d1ea5c39a74f1b656725257da7df7e9b577f6232fd03ff765cf9ffbb23fea57a586574e23b98da33f6f7fb3bf602777e77695eab09c46d63635b08a0dfc0d7e8533f3fdd9f9fe6cfcfd99dfc579a933ccc5687f2f69bbbb60cfc1400ee35fc7ab0a3da2cb0e81bc4e1dbc0cca8d191b7f4052b5d6540715292148f86a4354a3b30a8e52d7ba4b20a277ba50996bf712282be5434c6beb2ea9848b4a2850240de60cdd14b020eb85a2d03244251efdc8d6d2457b12f75ee03d02d2191631379f9ecf7e5404a738f8333d95877b77720953b5d96ba354487d5b93e516bd53c65ef7fa29d6d92ae6de6a5fd73ff9ece8e35e878fee518fe2b93d4c90db6ce4182a011bc1eb464f5ce8c44400a960e147c260dcde84bd35122ef6782531a1f02e299417576c118edabb4497535ef966326a47fe7867bf729f00bc420efc8b7b384aa9b965aa595dabc99539b048f47d9fc59e03ea720fe14dfaa9373147cb984b75e0d9d99fa58f9fb5683100d7c6ed498f16c2d1b6693101d269cdb983fe52adfd15146c3073da8ad5f98a705c67ba176485e526a029a496f7c4b51631114550355d60045da87745a0e7531c894168ab82d9930e2b816424d7096f12bf1003113d0072334e50b97e8e0967a758e3c33abfdc9b2097117e9c46789de8ece95d9fee191e84977710b16dfadcc3189eab6d7acf35a0e3d98e7736ec5f6ae76f7eef621d513fe5e1fcb92ff18c59986eb5d7ff27f127bc9b17cff1c2ef150d2a48a92e38aad528abe0869107331bb32ad4d91213af9d6aa69196781d6b439ed50c63e577534328c26539af5910ebe63d21be4688184b238f664e3399eadd00731b64a5b7c60e63d2a020b473fa9dfac9bbdaed57bad1b59527faefeff0317737c8516e62deaef7ebeec065fadc774daef4db9cdc0f8a3c9813fc8b5748a1c8d7e63c30b9dbac33171aac8ed7732a67098cbba0da0c88c26d60d81deae33e74d8d45fb4500241e5a25d092a1519db3d76cc47bf96555cc3b50422e036f2486ffd422ece79741e67b7c77371539b72b0162e5bfda730bea7e3eeee242bcf2af62447a04d750c8e5a61576bad60606f31936106219f8d86eb3b0d1a33a83ae988842bab22ca8bb852cbb85225266a89226f938e868f418f7469e793a0126e4a3c4f54a59e31c9ef74b4c6b65c668a4d79090798203f350290e8a8a755f778a7dfca27deeba6f549845f736ddfe0e67ae6633fe6dfd6a9cb2e7261dcf03d9e19fbf02ea5f3d0eeb5dfb8b7fb5d20af7f9fdd94c61bc9501eda2627eacf72e6b01e451393b9569e56b9168387ee23f7c385dac691a7be551779fcb6b7c9771dd76829a2f2e007bc8c7fe49ebb2eafb84e2aa048617562d49abed3f4f392692928b5993bd950877588638350b60c79372606d52961151ac395a8da5e821c8406165995d729c01be29866c8d12425138df1bc9b8f5680b9b0f54bf5440de927f6eedf5fed73ed9e771347de377b06febd97f9fd98affb6f6767f6fc948771aeb423a82520d862ee4db252cd822a3629981881862171e52a2c720b5373e903f884b46193682b2d2d850822da13032b7fd1de716a7259b59b80329c127fcdec6e8669e3e0d170c0cbe6efbc5603d1a369a0e4fdfcda5ee6faf08c8718f53b9a58ff5edf3faef3be67e77807befe99043fd0da9076a84f06316b1076983d3570c20cdfa4e3789911eb6e468191e87885ea1cb122a74965ba748cba50893b7f2c16c20675a27ba3d4eed8cc56a528877d1821675e7823d6c32d5182fa2007a464ab99db044124aee5fd7edb4378196b7c0b0d4de36d0fe57e2fbff9b3b6d7cebc5223b0f36d6d3de32c09dda6cd0acb92bc8be7cc32482592a4c6065f0cc34035abb81cf4618fc638f27856ad800f836dc09008891ccd39dde048a84413c2d754e05353f34b3c91c4da8ab0e5be6a266164a1c460d1b5bdd399a39e2ee940a1c5ce7ffb9023fae1faa6d5ef637fa8b9defbcdc47ef2afebf92a336569196f97548f37928b815fc95c70bb67ae67e24a8d4207cf428ee3508f01b1079b0462341b7b84dba53687c29315dd4aad334895997e453bc2023d25e86fc0902f89e0a4970a8352bfd3418b75665ed9f355c57b7e4c4f09e74d3dee2ce6f3f9bb2817d57b9ed9c91b7dcd53fe67b18a23dc4b77f2ae86708295acf7ebbdfbdd721a219555ea80ab88bcfe6b7c34040947cb29177b2c861c019056ac8f75b879b65947cee993bce12ed64fb8dfc6d5709d866f31e5930bbed46e1f825e3a419be96c9b1c3136597da91fc53fc492b7d99b67d7ea606f3f9d5f7bc0d95f974fc0118c916b19185a5b394648d2a1153036228c6e98b3020998ac3947634258459405e7951c93defb15166c22d4c346565e138ed5242e9b3a754c5330d893a2d443a3798a39d50993361acb0d2f27208e04cd3ee160ce5c4fa52e2b450856dfa8fb6e6fe297bd1b736f67dfe6858ffd53d7c51eb26a8bdd5a52d5ac7d0613e2784f88793e06d6466c87514a154605eb5220a3c4416ea8c7ebb8602a73ba65a2c32d1f5bed2c7a1c64ae358ea3404b79779f31d633c33249cd84d07ef74c7966a6d4841a4d8caeed5daeadeda1873f68f76bf41fd219ddad75e6b0273102fb187bbf973f7ef6135d07606f6421e28c37a3b4b02664316401c76550fd1e08f0b80d2bffba7bc8f5947471739ad33973d7df02e7b3db7311d6127ecce5bc8edffa9f71217d951f04b9467adcfb76f76baae168aaa9bb198325d3734b14d99a54206000c68926b65363b2667a1bfa8630c370b591459ea70cdb7347e594217f5efb03527aab79842b02653ced25a08ca190653aeaa549ec7685dc9fecbfe3f3f26eff5eb3057814bcdb3cdf07ff016d954d56316d8f695980d5fe8e8f266de2b055e6b0ed8b2df8629efbfac7b5be2e958bb0f70a3a564f59050905cc99d1c196bb92490356f3aab370d521a29448472d496cba668b7632736c53527335d5872ca3934ef61e2463aa85d5c386e89d49152a67d0ab185077be8ed64cf91a83de3d1d7bb7d2db3ef8071c37a28adf6200b65fd6b68eef7a1e82c5fc39a7f1957f77230e8ae31932a7dc33a5c3fa37e7eaf533429ff6dc6957bd3fe1c8fe4f3f63b8cd4aafc3e56a90727b8db4a1ef1bc89e2f867c1ee152dacdd61f07da144016d678e2bb723ae3dd62c61b3f234a0b6be5cd2133248477a12bf3acf04659849b80e026009248fdb71996dd725e7e52ffafad6daa239519fe01e3e1a822d9823cabe4a5f3b33de581f9e9f919162242fd01d7859b585fb571e4d5cf67e7b3f91d6dfc957859b4968cdd67103e4a476ee37298fb44dea16d0be6f69066b6a29cc91c833fc654838f2998f4779abd9cf650cd22b4ccea46a5b66ca63a8ee72513f3482ce62e5b601aeb4c1f6ce791d5c7004f13dadee1523cf91c5ecbddbb5b8f7acf57f02d2ddb7fc72a66aeb71686b75be37d1cf33afe518ffbaa584633a8a326d2ee56e998f9c231a72105864ffe6cc2703598db4d4c0b56b3dec312489180404f68a3c7c45a704769bc6cf329c851a6d04238a0f68dc9963b669e70fc6bc6204879b061caca49e425a91d9bac50fd1eab76ca4db6d93dabe0f429ab58fb0d9d8d6e5a3cdc602ddff58a1ed6f3dd3c0eb5d1d9751a1106d270228d1ca7513e4d6bdac76c02d0d86377e061806bb52175b310e5e332e8594c295efa068b12250769117788c03ca4c0954e1e71e6c5cc85d4a714a45aa38b6dbb4a2a98fbe5f02e095b2e6a3126c01e5c5d1b75597bd1ff3b8d177fb8c6bbb1f6b601a4d19f1ff52a105726f3b0ddf80039590f839dad9dea8d888d409386a5a3b19a244c8d331e98b4ea0ac41a2e9cd5862d56031e353aaa9a10516f95f488d20a04640c2b398e4de6e6816f2bc44b797707648015dd06a57894b7e2ecacf63eee5a2cc0ce96aa986b6fefd0137c5eaa9b85788d59fb4bbcec99cb9ee607ddfecb3eeb2d7a2376efb05645aa1f78afdf8cdf1e787aae8b9938f47a5a35a558b47f1107ab3ba35ca3524e43682571ed39d33edff84ad531b1eea88bcb8c618f132f1684ad13bb09f058f531c57761d905b2fe63de6926096a6bcb6aa16485635eab455a3d6e63231e108d95fea107e5dc3a6ee24b36e75413fda7e761131ff2d42073ec23f7c475eb96d8ec2e1c5bfd0c5a3181e53ad6719c8c635dda26a4543e091b6f43dace326a8e5194b759ad7a5e977d42d8d8d78730d5baa7984811d0612e462b43127b8bc2f657388613a27296520913c37b8c0b54f84a6ccff00afff43c1c723821a8531d6a6f734c17f033dd451f723130a745f0efefe78003efb2ada64f8bf25ade40cbe7ad93d15c251aa284c8625e584038c39633b6e6d48c92d2537199b7d39e197345d7dc85db407923a2a48a0dccc3b18543ae66779a0963f0b8c12e5688e7fabccc8db89e0cee408e532e0175f23ba46449cfdfa79de40c88101cb8110d9c67faea3bb8b21be45821101153530e9ad8f0d6d2817db2f70dcf7dae1db053d7e55f6792c319d56d5d54dd948dd95dcc90a0517397eaab0db29b5fccde748166eb31958fb2605b5176910fac3aa3f692106f9cb85642b969057dfe38734a8d976219287fc0c72ccc786b07656e2163a2250efbeb6b2bf3139f65b7cf77fe6db5ef0d8b82567253653aca33e7b05e17b521ff5d7bf8cb39ec6d74c4f63eba38f40d6ad3883d89081571642971e4c6bc72fd514c37ebd4808ffed8dbd9a235e21a080b6f2b0dc4c978d28751b6a536cb3110130182ad2c8536b3a19519934dea089d521b08d78ad35e51ead24d563f1a12a291802c107abb88b9b64916c32a295842486eee6b0aa7ebbf8dbf952fbc819f58ed6dc2363eeed7ebfc4160fabae70a034e9302e1a0c203e2787ea20fdbd4193e2686e80392d7c2860d63704535ef2e2dbd47510d9681b206a2c78bb88fb7629cd358f3229f30238e842d2aa9e636aa631d15899e17bc16a63414e6ccbabfe00f7e1b577dd0fc00bb384fa555f0aa63f331df7d78fee6f0dcfb1ea1d39c7ef5ca57f50137f9913340cb2ab579c6cac5bb75e2ec491ef1baff7be0f5f9ba07e1338d9caffddddbe4202a968b37ba7d82c3767f0ecf7d4efc1fe4223c9ed0dc445a37150cff42ce7096566d41ecc7650a052163a1678e72047bd0a77ad0a7004d666e3366bd6473f867bbf3311367b5940abb41616bbe91035c3513daa352305c275abbe63037539677730e9a90e32bb1b4ea2971d8ee1cf4efeef78f35a4faa84f0886a5d8fb902f3c3cdd694fe99e33474bf8a6150edb6415db6bac4cbeaf2fbe5bef52386afb8db807dc6e1fe026abffec6dc7ebf85a7f9d86cede861484e700e9fe7ae67a65e2b4130e65cfc3769d69dea350c8f4eda6490cb909edd51a856d93f2df4be25a2a8e10c545be96946d43d75b71de1a6cfc6779a79b7f934801ec8a0269438713467d832da57a1c641c3817b01fdfb62199b38b175e390d0ffb61f28df725d5dcfdf394b93b5f6178c019546215f38bb9ae33f6e74777eb9773389ee95a44f9665aeff1f3eb031ec3dc73e11c7a07fd6bf525b777c0de043dab67847644ef446a37bf50ad000a87c8ef91171b0852ad5b1147f473aa72623739eeb113106f8b5c15cc6ca0b312dc31c682e96ec7562dc91c6f11ab66457b56cfb9b9c04cfa49643509cb9b5bbd67e1b02ae1a63af412582aabf19127fa25de3dedf13862c4a4ebe587feeae37749f6e48fc09388f28fda64d771529fe993bbc88d140e3ab43de10afbe91efad01bfbbb9deaefe7b4af2790ece90cefecc5389095de6aaacb2751a13ba40d5556a169401462155402c83e28732751b136235e3fa70008073d51d6e87234b4659fab796d1544cb0557793ed51e4d54fe1ec8fa61297a3c400513a19e0f88216dc61f745f87e4b4e67826471a9e5bb74ff7cdeb7b8af07ab777120e1ae928fd4d1ee463cdf775dc9a3d1d7b56da7877978cdef6299fff378903fb77f7c6c77be930e7c738f2dbcc506d5c0d576ffa9fcf70d31d7f77b79775b87aedef78e903da9eeea58396fe1ea3a1b3c197f7de613eaf7dc9dcec3387bdedb31e9ce5f2bad4c379764e27bdb86fb9e6ceff9be77b7c6beefb8452039b99439fe45e1f9cbd7d279faedd33eee4831dddfdee5ecf38ab83f7bdaa5771a3bd5fe7ef9cffb3f3fc518fd5ebd87b6eb468cf6d5c8be8e1a8d5f0032e2a622f296f616ce40d71ba110202cea9d0e6d4ab67042b7f9cdf0711d233221d46bd3a882c9a8543c3af551b689d196a4d8da1d5cfb937c2d4e4d2b60d6e238cb984dccda7d4193ee16ddb4aa5c2b9f3b026b6fa0e27fdb9de86cf7dc46f9cb1f7df7fc3737f8ecfed2257c7677ec2c3cdfa32cecce13d9fc0cbb9d58ee35e6fef93b22ba5cdee83c2eefc4adcd39a99990dcd74f41bf85084ac54a390634ee99030c65c4af35f61810781428b240a067ed48471e4fd429aa489d342ac1ad3675e2198da32a00aeaa0115616965a6e06dcef84f631ef77c6de7f9f8feae84f5997b42d6fa5f7fd32de5b5fede07f5fddef96104dfd12e3dc6435c294da4652e46e00d08ada32967a06a823da80c036abed4da8fe6869291f9331d58803a7a44003e1c0666a8809a318a01e6f4243f2993d1c643a43b48f8124de2ce4609d0158502dd85c8dbd7eb5416d1cb13d3637d55bf50d6e87ed8de29d4fc6ffddbe7b471c823d76d9192e05df733d5c8d5da3a376c58c26c86a548b72b064946d30f47b46728bd2b69e02f697ab073d6590843553bc7aec315d2d656942aa0fbb40a14da098edebb29504f7b8502b62a0bf1ccabfb8b03b01e1944550a53cee65c53aff0287cdf735dcbce26dee63f675cefb6d5fdc37f8af6ea4bb6e7cecabfbf0fef69f69e007daf9839823c1614e43625909803a529e45f406fa86b88fa98a79d5d25924d7c8eeee71e58d42a030a6ec292dc12ca8ad69c631cbca52a73d9eb1b135a5b65a4f81e4b27c04d2a66b3e663e5e0c2965acf21db6bc551e2cabdef58a0f2ee59e0eb8224f8ff9a57776ab3edf77631ef30dfbf3b395155c1d392faee16e407e99f7777a63a69114a186ef0382b0248ce3fe01e0b16d10fdacc6d8cb3a4eb9d8a6baf68229fe163e6571039bffc9f8c73be07036435065d5b03de40677beeb113b711db63e1685f5c474aad31aa979a51c12d16510fd31e34a358c7b6de6741d52be3935fe2c9191199ce5c1546b46a1936f19c536e3b91187ad1e50d394dc031917090358178caea71a16ac943db6338396ad3f3504bcbaceff6cc7bf81a7b8097799f1fc6fe8610f1edfdf738c7be59ddbc4db95112ad5b022e709f1ccb9822e56f23ed15582c72c99458f06e9bd24713493db20676e5e86251b843aec13ce9cc0982ce72c4fa640b6dc4545a2e54da86f3abf825bdf2d75eea818bb0f7d4a70183a83ee66f6e2631fd48b5f1b7f5dcf7f795f87fdf9ad1ad22dfca4e7f7743833efdfddf11c1dfb88aed38474266bc2d46eedb580b766063c673ece3709353d3fc22e2e4d1c5261f986586282dc8c6028a9dd093bd685966fa6db5617a0e9320db9610537b22e07a440f8aec76ba40943d61050bb2952f56850a54ce45c8b49f5546658ebb4462a75d4f27b3d6bffaedff7aa6fc356096fd5d136bdffec8033bd463f7cc939aa91d16849993bbc44bad061802bbb4f5dcb9dd16e2df89798e86fefef33dad46fe3f3cda5fb3133587b1967fde7363caac6cb78cffb1aa49c6da7e4cfb598f381e08f1bce19c6c0d789ceea8c3c0c7c0d75842beadb79e2f3d56df88c9c7c9b1aac3e6af3fdcf010f1e5cb21d97b87e3787feb15bd88be0b89641bbdfa3dfd79c3ce0b988b5f0818a68e41bb440c98cd806031e9e1338096ddb082adbc0e3fc51aaa6468a41c4813fe7eddd1c428e89f75712cbe38ee7a60e9c5068ad12502e993630a426823b4332c2f2362885e53b90a35a080c3ec1fd544c4b3838e527ffbfea857819efe0534b47b547bcfff5dae25a1773f20098dec28c78dcafbca9881ed6c41edefb4c341c8a27bf6c5dcea946a132330d969ce3bf69e4e59c2a9601b1e42e1d901ee769b81adcf58cc515ccb1bee9329eaf9103bb80c220b44d8c6c49e2cffa772a06325d55dfc06c6e6e82cf7919efb886116a445d1efb7cafd3aa62443d85e387414c50156f872ad190e3f3cd660a58e053b5ce740542de98cc793012dbd339142884aa6615aab021b4d9b834b8234152788c689d2d68098232dba6245bcb489a31ed381b8b2aaef158026c1efb7ccfaca128bf8165e86fb3077763edd7ae128e7fd47abe6eefb1c27b4c0d51ce4bb1207a69a0ed308a7993530dc449efdd13475bce6dd3130c9684021014b289f54723ae56fabc2ab7b8c85dacc141c2659196d8c9ec661297a6492a54cf696327eccf72e698f7992a410c1a372b3f3bbfaacd2a587d472bed16762fe1601bf3786ffb8eff7fc4b35e67ff42d52cc3122489065d5c8a808e3d91b13ce1d05a10dea1a092fddc6de0cc567ed6e315a12a9ef6dedab73726a39e31a3bfd79ca035aaa523b7c366c6941f4756c1681349032e128296c2cd3deae0312a3c1ade0cbf2757a9fedcf3991d6a7a5fdff5205decfde03c753a955eaabd8737ca45d5ec69bad7d082abd461abbd7ff5f1b3038fd975d80bc256080a93abc900955d32d53b7b0e1b4a0bf137a39b414005f495bf09a9f009fbb345255c2435f25909edb99d97893d59c7bde5b2084dee8cb29f3156057ad90bb7f935b3872b1ab120e5661e9643946a7842a9772bfda64ff0806f6a545fbec7437f705cb34a1cf592be386fe058dfffd7f3d6c77c177f784054e27867be9fc794d0ebb9e8226fe303b4f6c7721aebb84d69bbc086a8636a0e2843775921171808c2aa15a0bd821981ce9d616d62e5ad51ff67c939cbb19b2f65cf6c31ce67d41e2cb116e871d53c71ae6d59cd0249519c4616e091680390e3f3bd3cc79eeb433de8d29ade4a8ffeb0a6c79a94ff664d9fe7716d2fe67e4d999533869c0cb09c9426080db90c2af537d576fe039ca2c5501122781279fa9c59510a1f8da084784eb07da7e763593d6841215621cd96a9b2cac4f11c51aa051db535b3e52836bc32d386398bfc0d5eb449500e3feaa35ccabb2af9ec4b1ff3dd5ffad23a2be43e8774c0a01db9442e62ec6fc2bb6a20151b6cfbcc5bb7b759355247beaf73f3daf98f576b0153c292695f1a69e5dd938269536db3ceb4073d65e516735888aae1d890db40472421ccf6754fa3e5ef2d068f83cc89bbb0878c143299d1071016d4489c8633e2e1799d6ffd28bfbfd3441b54f9bd2cd9725e2294f24f7c9f371a6c5fec7f635af84fe80636e5ac2ed076d05fab97499da1c25a2392713e097b3c62f6ef754c14158548708f74c17faf0322135623912964a1f27190d6a59956933e2820cf6a6b29e960392fd43d26cc102505d9584c90dd15095449a6b33a61b08ecbc69e119c607572877f1da3bb1e987294c77afe8c93d3bf81b37f5913e1a84a5c8a8b6ec593f4cc6377e8337df76e0ef3f8115f92cbc796371f0dc7618526733a19c43d3613c39a604d59b2ec4c62c8fb54f73412fe1e88514b296f2d317ee8a6ba07934a06a1eb5571656b3e131b11a12dd29b786a0403c61f96b440908f950a980fe28a2e1305c5ad34fc3fe8123ef307bebeb7f0fd18fb5e7a873dc5babaf87b97f00f68711267fc932d3be87fedef99e3ff6bfa27b8b88b672e2e7c93d95ece20aa5821cca0f6f20cd2c12cfa0344d9aa44a3db341ccea46edaa98eee59ed014a05f1c3a12e28a885db00eaa027a2693db2353d30e480f5f9df70345ccd6d96a3c81ba51a562c9200d17cc24e7adccff860dfaf7fbfece9ccc0ebcbfaae7f6ec433f0bceea097cef0a0ed7af299b6b91eab08680c1a1d6b00cd89d2531d43ac502f88bf49a16cd2aafd7ba73535d13c9d3a8381049e275d0b5385f239cf8bbb1ef799867bbff781e4ed2ad1854e19bc13da66cd0cd18676c793028bd888b7592f710020faa40fa01751d0c6fa709de84a3ddf97dfc8e96837e90dd099b6d731d3dbe6a0d3b49bcff17e393b2f6d3b2d826b7b089480de64e68051a8b18828e1b1124c056f6669cdeee64ea732a6e01434443888ce46c399e09a39d5419b1a68e0136f131bb89c8dadde2f87a63fb6a64435bfb26a5813d610c4412ee96a3b35544bc67021ab4eff6cad13872d626ed6fb67e6203ff405fc07f49a0df428b897a75576ec09804f625f9b3ef7f9b19e77dd1a2f4337dffa7593645069c2015b52c00e3bcd36530f6b5ec02d2de012f7b93d1fb5756258539f669a60792b55de4b1d1498c04706e58801c5e655b78d9932fc7068f2fa8fce23667392193cc27a5c0e36c201f605dd8e2bee8b5cc5157c125b70c0bc8caee0903cf76fff137dc127e3be7f972f38b99f689b6d574b618b47e9a0c1cebef8061bc5913dc0360e916d82b9ed29697bbf825e26940e1f538671c8cd09e6811e2bb4e50e6e70a47e058670fdb14cd01833ceb14ff53c62918ae598a1a9a11ee745ae121d2dfc0bf99533b15f2374334f4740cd1d75296fdfdfa8576cafab15f34d2ba2bc9187f57e378fbd0eefe84aad2326585804262efd0123f07eeeca84b8b9172b4cb312ebc431ab692f2876e48057683a73e58016f9afacb7fbb96b0d90912f701f6fd20a8f52279f65a568fc9221494598eacc4eb5e61e19524b20f233126c31bfa0697de6de4d1dd827ffb17ddde599feb0b7ff8771b5fe07b6a89e31bb4b1ca8e2baec513924d4c0465ce0276923176b320f0d943385fe52120f44e90d52000b19e115e282f891009cd883708c0c6a047d520a13d7789b180fcbd078dcb002bab331b3900dcc80639bf0727b35de4cef9a58a76dcccd3ef94f7150be1b73bf7f5709476acae153a6973fab515330265c3c72f247f31dc4431868fb9ecf5298c28022562cc0aa9986f6b046dacaf075a03128ef68351964ae0a7c5dfc1205f6e64e00a8d1949836189520643c5b33cd7b225a37107a9e48bb9dcac883e4348efb612ef6f0cc9981cdd479d10b3acf955ec17d8f453afa703f9cd6b5f6673ddb824af26e2575554ae76177af963bdf26d5d5d3473ec19ff766a87eca05489dce4838d6921138f00a44d67a772ebe85d5bea98ef5d7f379c66f8b9aad525736c2c58fd323f741e60c9bb40e7ea4777dc8493666ca357067d065a6a19e0269e2b1ea480555a2e21edb424f6c348df56e2a1cf58b7378c7223609c8434fcbee6f5cc8276a3037ad701968b92b0beb31d9b6534ee48850b8ca8054618f99e0998e59ac7378c273f3f9997f9713fecc87f8c0b9f8758e5fbb4dcee0ed987b5bb04e2b554cb9b74e75ad3d8e735d5d1a7a936434b4662edeb05e6e25793053d75b25806a41847e7137e884e319546f38d325c086d7a66e0e91817309448b6d6f15121884b44309c8adb9dd5069c047612028189eccabc71e95010874301100b6a43ac1ab7cad5b1be175ca55318dd04a70b679d7c77272e63fe5e8fc32464d0db6ddd9d894c34b38ed3daff22df2fc6fc73ce4398720ab76761de4d9483b8e73d5fdc9924ae699cb5aa6770bc2f36550c95f6c2c45a2fb80b39cb171a0e3c26a42830ea826e38c588bd89001e2f8d7547fd850a7fb8b2af614d6f0efbc80495cdbdb74cca2388222ad3d1ed7322240a2398d7b5c04c6d5bcb7ef9e11bc68655f5e73fae493f216e7e7ecf8a7ebffe6efc89fbde6edecba7711a5bad922a3b90f3475372f3d97723cba33f06306ac3c2bac258fd8388c1a21eb3c917a378ac98331e7e59a70fc57169226d19f6d6c281e97dd5fc47f6f624d04a4c090552d60ae5cf89ab4b1abd87cecd95837dd5be1f85eea4c070cdc7b8cd329efec9b357bd18bd22fc65f86b5ddafdd62f76ebe83a1b80187d8bb31f7b67393eded62bcbb0f8f580aff0aae7eef3e6668e12bb54e21e6145a65c08487a1fa25a928324734b2bfce67dff78f55f27f85c3f6f7f0c57cceadf01147bc70a463b5f77b8eb99cd3f9fca4bf173c26c08b6790764c6fee70150c888becb0f04c1a0e0d06e420e6c30d8e901528da71472c09c9ad3bfd7173d73f80b0846ee65a9a4f449115304a9c4c0f35b5880bbc4e00d5490457a8f4ee93450b64f4672db5569de418beae137fa8b91e6a6628fc46cdec19671da126e56a1547cf7eced79addfe68a0dd203774c471833ee1a0491db85ffbbd2d3b3faf63ac701d5e686ad8eb19b4b5a0da68bc6c2dea347f6750aaac54a350498bd8ed326656286a4f4f1ce1cc9cd53a28267d42f0d3bcf656b47adc4e75b9f6b966fab67a42bae94e7b1463881644ffbdb9332c8094a70700a319f3dca306d3176b7df0432fd78e6fa2d17d3c03597b8c0bde9c8b97cf7ec4039696c32e1c5353386c9c11456899afe6aedd05513640b47992636ca0b2d589dd760c8826e9c53a202a49f42e26b6e911bdeb448f1dbf565b36868855902625eca412867084e28534900ec7b26c6c64b03a39e577fbf21eb8e0f71fef853379cee77715fd798d9347defc391efed6793ad3137b99ffe02638cfe777fb9effa0decd4b7bfbeecffdfd9143fb3a5c545c3033abbc95af7971c89b491c5193bade1201baa1ca13316042d8034d6a92b00a76a9e661dad34da021e86bed4832c57c88052dcd009728403ae4a966223e7e3042bba589831155c2a36354271cadc29be9f7fc1f6af87e8dcbb9dc7bfd9fd002fa62af0a6e96efecf067df39e0ddafc3f2d02ea46eee300ea974ad8e47880a6a4e632aee658f42e47883306a22a29b0b4a1e7a046015d46a95f6f9df30cab558f7a653cd5e671ae008d84ba2413e3544946e5746d64f40660fa14fac2967e86fccd0bd3f16ffbfd45947db01f8072dbbd3df3de16838d3b7b6e7acb84deff4071e909d6df930a73d0fab312db2eb732b4c8cd2d1b04e2b518485bc179157849a6d122672c1659469de04570d47e3729b190a498e8b54c144d6c11abbd94044cd26d68613ce9a380e87773322ee67ae18dce999361fc780d3f6716e0f0d0cd9232a504e7bf67fd52fbf5b132dddee6c8c6a930837b2a25f69d83ee701405a1db55bf9ce5e07dfe081c8f3f7fdf81ff7e2f15efcbe9ef8b3edeff73aa84eb7e7e67ac70376aa5bf89c8b7c9fb3fc82dbe33c0fc0614eb3d3bbf938a767ce0bb01491eaafe0e2788a23b4afa9bce65e3ffd375fdc9540bd7b279faddd57b63e425a1c79da677c58ef7c8c531b71bacedf39ff67f7ce8ffc8c3763ff6edf71661cfa56cfdc0997e22cadbb037089391a24b45b0585e438528e74d548f4a526c89f01d1602f6bdbc08a8d840637ccb5d7b2f7cc94227f4edb3ba1e12033d42228d98cd5d842201f53ca6accf24108ac755a66cb341282d6f9e354ebbc93fccfd7fec437ee886f9cb1ab78505ef67993d66823becf87749e5fe6679ad32773d8f90667ce6d7b1cf77a7bcf1b5fb818126dd2f9c4ab08f0c03cb2ac39dfac11b1f8ceff0b4a553205ef29600c033899978fdadcf6485c296d3686bf6805b7f342baccc997988a644e6018eb4c644a8a185845508a80467232a7b0f0b9fc588f3c67efbf9f4bff1617ce65bdd3dbc5d49fdb9b4b7edd71be3fd2f2e46e9ea48b1667aed80665d9e17258885e9461640d18b36aa6a14052339625b051efe531f372c6a0ee73662387ae69540e9270f8881556beedb19406baeffe59536aeb71f5d0c5916825b3a828cdbf191311bda5befded6201635ad0fff29ffd97ffecbffc67ffe53ffb2fffd97ff9cf0eeffbbffc67ff2ff29fed63c06c04f2b446cd7f88dbe3dd982ffeda4b3efac8fffeed1a96dd6694294a15c87468f8955ac70037b12abbb05203ca7240aadf83ab300dfb79fc00b77a7c8ea446eb74018a5407ade0a6f63d1da61be53ccf8ebfafa77ec6617eadde47376596435883256f3da983d5ccc63d29d9238fe43a2e735318569d5e5b5b8d2c9555b016a738ab33d8d3879b604fdf8e79d8876ce71be742674f728f917cb85687c025106ac406e354635ed86385dd58279ad4126db8a61ad07c2d58a686bd99135466468e24dbf35de744315db26020a81849dab5424d360953625ee6639fd341e25abf825e2499912f24fba3635be5a90d9c5be1b577fb2173864ffbb5e0ac4d22ac1df8505e7ca6933ad2731f4152c1ed2b8ff619eddc0aabb866f597faba7b6db637bec927dac0a9e1b5538e73e9d8af35aeed891fb438684ba832e6deeabddf7af29bad88f063aae3aff36c156852feea43a2d39cd8227bf1e7e23d26e5e4efcff0edbfaedbbe97f0e7fd549ffcf645df6adf5b95dda8b7ea9cc6c18113e3f473edf0cc3f88b130f71ed33e9f22a7f1e232b7e68e09e64e69a47db0258697082d5e738567b18192a4104fb46c4dc6c132b13b2723f938b495968d86d59c8847ca1ac02b104cf5413f678f262b3d16d77fb479fdb84ed9c3207180a0dfe9b9fa518c85d659455b19e1261d81e6e86ffdcfc1df3a1f3f24dc7c147bbcc03bed898f3ce62f7e761c79db382a8fdf3d8b133abeefaf751c27f5e04cbff7cbb37e86d1f834e63b8369799de3a771cd277a0bf58ff2cba773be9863a6079dd1dbe421bec725109ee3dbba7c0f89b1c778e9dd61a78d53581a58f7eee68ee8317958a7b59826804146a0ebf779e147a82185c0742cf219b3e88c8236b42703ac9b9b4c4724a5e08eea43676677f761e469339795534306d219fe9d47be86fb78f99d5cf357f1c2f9fdf09d78e16c7cfe1fc0599dedfdbd68bbd2c590248ea963a7d471992f62252a59a96dba6da3546f1a5c37fa9de10f08b350687bc55c09451dc1321bdf1157ae090c36891b74e9180ba979e3b82a0799dd58b2621073fc9468b9495d45e968d8ce9557c9133cc18d6cd719fe8d493d3872b07e7d0ebff6a1f73e9826a293dce0f978e416989268af0da1b2437cf8f6cf474cd67598119f7a565c8b2d014d8f35bbe70c8f990117297fe890bdd970ca3adf666e48513cd5cd515a89a550e22e2d24c9ea1cb3027abe6121ce1b322f33731efe36b8a25b56a89219d0ccf86a4beda13177ba853f56a564b7eadf004a3af95ab8fe7b5de513fcd05b3ff9c55f1b4c0bff427cc4369933dcee628e581fae52e312df5e76ea77feac6e0032d75a6735eef73da2ce70fbecef7f984f8bb6d7733f6791350e2211a6e3ddfe62f7a12b5468a027a4e54fb1d684b28e813f865dc861111a0d4eeddfeb3bad33e68e6fdef556e7d7d29f47b1861da1cbf1c366aae1202dbc4d4687a34c6b4aeca8b500b94b8b72490c619ca90b7c8d1573603fe56215f3ec35777811c7835feae15f9c417dbae75cfae733a81dfcf4dd1d78f41349fc84b657626f58e34aae6908a80695ed3dd1848d49defac5a4974e007c1d6ac9d8536999179c7635d1d05f6c4c405a493073bc32a430a47ca5a774b096c043b2c026615e113ae698eae6242e114c1c5bcbf4e182460f60cee4adb03779523f6b993f9cabb72f526758c6117a9c566895eaa63ae8a0bd60f73eea43ed7e7395ea38cff487a7dd5cd20ae5f225071eece297d373fdb17fee0d2ef0a3eff40163f9baafcec48967f1868b7fedd5827fe5b77cb687530e9c9fefd3dd7bdadd11bbffb6b3d1271c3797f62991188fbd155ab4d340215feaf1126900703e2c622575aaac921854f7b7432d539e627607fcb275a4ded6b1819f249f7471c4d678d10a9f4911ebda6646f7da9e9d8c581f1bdeaf8c038bead00f6d7f1df6f82337d1710dff395ffcacc5af44f4a7ddd9a003bff86e2ff85fd4348e5c413a7a141ce4d3086fe3681f97aa2ffb873ed8ba737cde2fda6ee7b13b20abcaddbdf076bf6eafab5d1c7b1c0f3583eff8a8e09367f9918ffa3e37f9bb9deaefe6d3a2f087fd7edc13a8127f1111f78cd99b04d22ed41b8794184bda38226aba50c7db20528eb0959225b493086e99961b54ef1629f56684e61bc4e1d2af62cd87563bb31b8a6b85fc0a7473a7755165d68996dffb045653bdbbbadfef23f630e5c3bfeff2b4dfb005e7e3df9fd591df8fbfaf23b73b1ffe152bf4f0096fd99f4bf11ba27a23e6158a4839b47c871901cd37f3c24273d712b81686e88599d46547caacdf6b611af0172a028d95683d055e207473eb8743171bc132e17e9fd086ce953dc011ed9983914f308923f9c4146bb146f5933ce295f1db653cfac573d2dff29c5c98cfce865fe829feb447fea23f38af559b12ba9461db070622cc50f62c82b398b3bfac4036aec563a0b5456ab765123522a60d9334b766631412a75920dd2492ca27e1e071684bdd77f2e59dd60aa47928e05dcf7436459029d10bc80a11d3ef6000beb4695fdbe36fd4676fd8f3fcf95cf6f5da436da38ff55ca5dc6ea5ebe5877d448f989e1fd83e6aa2d96818ccf8a0e74e1327b64ad202ae88932f7105ad00e07bc63ccc9d264a60ac05a5bda695792f8b7c202bd949176e02f66086f4b796320fcf211af8cc5ba53dd6b2a851199f6c326db8ca6a9613a3ec85fb2d3cee97b9ab53ffebe2f9d23ec1b4fe1bbefed8eff3beafe9f81939dcaf3fb07f7150360b36463364378fac662db7e946f0a1cf88b203bd29621a9b7ed9faa48634a5629c96599739f140b88ccd6de14a0307a88436aacc655267664c90271c154a7bd363e219bed6d809a5ebb953f6b21c9ef6a49db17f3fc14a0a0ed649f5d65f78f1f13fc1fe5ee62038d4503ecfc57eace99ee3d93bda818b7bec93daf0593b80ce7237fc13d66f73e4d178c9c3bdd48d49fcd3bbd592919832d7a342c119a7a6171b78410b389d02e53238e9504f756ca882baa846fac48c2bcc6714832c625be4481d55709ad13c8ef9838ec0e320e4802020e1bc609855e85e3a5dc57a6fcb4b068411e827bdbf37da5be7ead447ffef6bac46f075dc9f399778e082279ff8b7a8c16a7164ededba74e046ec6bff767f459fef21df361a0abfb002093c8ff116c7008fa95e6a018524dbb6f70135135ecb8eda6d9e44961b68ccc8c6f646408892c8e252a14402c602bddcf8ac5c13bd5d85549aa1dd3a89ad8aa41a16c9b6b543dd1c89b2b3f02d71991fe2a64fea1f2f5ab662f4558dc82b53033742378f5c7ebbdffb73368727aae176ca591eeb0fafdfdb9ed1c33d8fe7fb9ff3982caf4e9de1e2980b36a685fd843e9ecdd73e8eff39dfc7b1bbd772b57bcf2fdf5b9cf0f49febc338fe1e3da9ef26dc6c52ae7af9fabded99ef7d86e7db7ddf38b3d62ffbfdb506657ff6bdbdbec7f17b9bb3b6fb2bcc5ef876de276bae25aeb7965c3ebed6e9fc4b3a6e9a88bc761aa1667e91f37172a31c2c5659a5b599ae7e1df37c6ffeac1df4b7afeb5bcf518d404af16a5eab092b9b282e1e969c0f2b4e3065bdddf965a66763cf098005032a96773d3585a644e8c63db7f3307134337531a7442d53a7d412db8c04832309d04690bca0e5608ba2870d2d87202dc1fdb55a57d261033902da0b06e12b0cd08d340fdf8f7958e7b91bb4f2880df0afd336eca63cee903ef450212cc6651550a413479014e09e8e1f96a9837c7a1df7d9bbfdfa758ff87e1ffff31df33cdee19e79d6b1d18ebfff7d9c1976300d17bff58ce433ee7475a67b45a231ee87ad9deab0418e60d771eee126e5ecd997bf700ee31b7156be1b73e7571df45f9e7df74ffdaaafb8a2248a0dbc655ab00d6193109779a9831e53a7857e852b6e378f487bdc861af666141be968b58db917709e6dd2081994e615d1a04959d6276553fb9125101395743109a99948da16dc198e7c4db8f3c8e289de59e7f9eb7193d6659bba1eb8ccddfde7c3ddf4c3bdc54d73cabbad3c9cb597f1a77b6db9817edd3a36334e7f6f4243d469c1b6dc6da2ccde6ce60485b4fff3ffb1f76f4d8eeac8bf30fc5576d4edee59c5c1d42aaf887d51d8064319dce6208126262640a20d4660dae003de31dffd0d043ed6b9bb66c57eff4f5d74970121092995ca4c65fe52c21c3f3117845a8262058bb4670cc1cf70544ad61e6d5d414951ae174035efa274a759348e2762bc007babb2819e85703798bab1e4daf72b572086a1f83b02fbe20be3b89978cff9ecbc2776fb3378d87df59c3f53bb7e5f78d6c66a7f8c6e5dba3316c09fe533214a677c98cbb340dd1980c6632beded270291dc85b6c16e7fe473d5d4c9a9ebc0194732bd32f6540350f91eb88a692ab2891d993a000d27bcb58ac6cb15cc8a140b066f422c451ebd7be4e9ce18ca4f7204bcc52bc3a38cc3d73e94f2b7f611f393e2e7bb716636659c296b24b0fc89cff4876beddb1fc25fe204133c8881b714e0104896a7ed7c912c9088ac48d513dbc32280e51e717dc984968ec656608ef511c98081615ca351317be476c5848b7b666e49f65e9e5a505b1929194650a2338e7f0c5cb2c3a9329af1e634d8c7fb37b0243f84bb11e6a0f24f58e8e23b30ecb950048b77e07dee3e67fdf479bfc5fbecdafda5fcd2de2c9ff78097f260b4e31cdeb4c988ee1e396e6bd4fdbdcd59351c99863d8e454b357704983323333883db5163686ca69e49715658b394de11b5b0a3055203aea0d1828e26425c228fca50b10616b713095f00b2a7e567f9b286597f4b2e7482d15b67ddfb099436e84dbd377daa9bfdda1e7c688fcd11aef935b3f138e90bb1c5af9ddbc4b3703c1361aa0c2da05b96e06f0d8eab4dc794c868870cc1d2fc944c2d5197b14377b61b7b00a4121cc5281c2a77a648509811072fccefae037aa1078aa97a5fcfa0d2c35c7f1a8de85d902999a3800270fac6703f0d6f22c6193e8f657aea5f2cead4f72c961ba6adc73df74b7952fe981fe2786efd4457aa7c58d1090435cefaf5abfebeb9b9219ebe40365ff9de4375f41539e1a8f18dbe77dd87085ee6a178cd1f868ccd32806ff9c08cd68633fb141f0b76becffc0cad7da8d2a48d739c7d14c7d00fb3746fbad224ca8adcf174117948c25cecce38a526a3dd082bb21041b717517f638c5ccef2280a17b3bd3bc41b535404d723b3604807965069c82389e381126412e767340fa1e99aa29ec2a13970b27b89f0fae347710cdb71955a0cfc0c1588e153008ee199bc8dd9b67b82cbf08b6b3c54e99a30fbad9405105778ac5332b68aceaf90cd4798333cfe35ca683ef1e41a791617b05ca0cddc3c1b93f4dadcf4dc31965c954cddd16e6c0874e2e67165efc90888daca82a38d2b1635c99046d442254360ccb2ad6040b232281858757f345bd0d58c8fed20f757d198eac0516ae0596bdfa306727900d262e073bc3f55963b539046bf30373c5169f9664c4cddab3f270fb9b567fed563a31d73117001dced19aef8c7f7c4ca1e551343a0008eb62b8307aa99c78609cbad3b024b9bd7c12cad66b3d414267565071cf88ed5c20662dc8b869a6873953dcbf86ae6f8db9943b788eb0392f2c574442681a29bee085441aadbeeb8d81b148bce5ef9fe597be289d71cb147766fec891256ddca1762eab3bc6cafe705f99c3c53176db2f9629824d05c2268ae18d6e787f380c5250260e3ef294f38e2635878848f6300ac6006f93b079a2a5cb83dd389ad99a30b249fef80a7f1d1882e022ff66df0b09a8e766b2bb57237974be0185be2190251c10ea9bb7dc0a18cd8558c1c6b62eee9f75000e227ed8f0dcf2a09b4e804eef617b834f6ebb2663b6688e22731974fe76dfa29b80cedbca10cec5b0cfff36b6ecbe2a83ea61f7048d5ef6cafd891ace090404dd3d34503963c4e814646baeca45585c6200d46449aa5200ed2ded6804889601ccf5cbac4427fe2e4a910397865bb3dc9e068864788237c2a059e529842357a1463d116620b73d2e31bebec193e46b7085a31cef538b21906524220cadece21cdfca2f8cf19739076f11d55a3af1de3061a3df9e5fe55ad6cf2b1dc625166f15325369d148c90274f6c5e5b41857e872305ba63cb2330dd86e374ebe4d62650c0de17f10a403eb6552a037ed60bc63a343cbd9ed47dcda4feca185982cd64ce91e4ee5371ea72db50550c44e73d9c713de3d330e9e97ee25d8cd507f282b3f7f6bea81778fcd65a6267dd9f801b7ad1e6910762c1ac034fe6ba3375ee633cd05f210f95d08d83902a2bdf5bf680a20f8817bb3327ad23500c5cb5cfe105d01e79b2741d92584373092958a3f19c2723f2dd77948cb8668e80f9331a29778ea3d881dbe36daf107c68e950b1208288271e0966bcfeba8ef09467f1616651d4c614bc2777cffef7c799c5d3655850b2d64e7e7edde5eaf958ece71ad3382022f1713adb8041ff11aa40425cb14323f3bb994a015c2886b9401ace6373c22fc5d0a53b23ebcf7c286d9c85ac1a5032a2a15912ae30898364c215c85cd0255269cf7791e58860033dd30c52979f7046fd59b2015241428ebee1dd79cfaf63f7a508ea3c7a366ee499fc94494ffa247fbcaeddfb6a22b4f1a613a7adff177c0492d99e28e1584fed4c790ca99cccc0c3ca70c1862854c0a0d8fb0b93fac29627422acc325498a9fe0814b070b2be8887684172738bf6f24f382ed62eb526965a5413ce1567d0caad5487c8556620e5a73e578d31179bff2dff93b08b4935aefdad2f78dea52cf13c2f04ebc0537864f3ef3caff8ac1c5b4fda6d78221f667447a05b9dce2d7e2147ac07a63e04054ec18ce4720078338f72b2774784038e7e07a8e9e2acb7998eb63cb6fb3af2e22074e75be4ce05971b890667563377c403c71a13ae6f83716ccd40b19f3ac09d81d87072853a6a7fe68ea4ef262401a29f162fb0c039ddb6365a658dd47ed5dae8e91ad59779545eb53f7872caec2b50da109566017c33e729f7142bea97d62a8f552b26aa5b85599f0b203ae8c4cfddafcc01c31efd185617dca5265d6edd9c0ea14b066666ae6c58642825df5dae5fd94afcd380c444ae2bfa40ff1e2d2cd3aa2bdf81551578f1000ead9f004a394e89ef507a678a6466737a45d4fec81cf1eb5936aa6750e24d5e776c21e6264f70397e555ed137910acef01bb56762e5cda50f77ab577dc1b2cef6219a5c28ea07bfface56ff9c4f062ff99ebe7e3d8e9f56ad0d8c2f7daf90de28bb9fc0a3ffd9f3b1c3ac0c5d63d162b9d8d18067fe233edc95917db4b3ed9fb1e315b8e6d758e52ee39992a73ec91154ea3039d47b884d78268f258bb15158dce1c4bbb445780bf7791ced31d8faf6f97a7bd2cfa7b96bdb58b9e77c677a48c5959f297b04ad02272fe2727f304ee6442b7f6feea2b6dd4617f185380ed5f2d7731139d6c8e03401083e67b8d5770874158dcdbbd0b5768e6b8eb1032048fabce32a036381f7764a8dd0bd5f19422187eabc0787d6ce1a5b2951c9d05d985934b6126704cc889a3d63a15b488dd7966a3e92dcad89a364207fc2a7df90afdeb1aedb6f6c7d173d938be0ee88addcf2b7e7e3fd9f8f996c6812b736f0d763575eb3139cc5c2bcaed77c8e6d07d4817dc8ed71f8cd7113b6763f24670f8c31b5c1b8404801c399d093c2a452cd41350e869664bb16e70065e1bbc53e0474608d4dd7e5700fd5fdef08169359d64f1d6554db6e9c390b33711cf21378a60d55290d45d935b9be0e1592424f591810fd0c812f3cb171be61b7215092da5882236fd8bdbd17ebe531af3adcc57f57cecba7edb6f3130ebabcb176c3eb3f9cf3723771510d47e5660651620ef51473a41782423504f2d3803bd9cca9f86afe958fd9c9984e32810d1d3e5ce63e7855bf7f1e4fe2f53c069f1273ce6ce01368513cd6a92f285ca7833ee94fe7d7f08c0ffdf3fcd2b079db75946904d196eccdb503254472e4186e35b133022c411939cefcb93cba3c81347de3fb7b2cbfccef9f45b1b6989dca03051a705dbd1fe203aa23f0364e2a350444b15ddc23300ec8020d8d4c771107201c9b5ab07fe8059c2b86402e71aa27167457fedeaca79efcd317007455c2e311cd9c942efdbd25454397b787bee4f0b1ece43af081c91387521b4a9317f20fb7dfd2ada1b7e9e75a56fa8df13bacdbe3381ed66c874ff131befa1da9bc1f8d463d9c5a7bd721088f24e8a7956367d534a29668a4e9cadd030f0bba69a9d2908ca8e7f24a1c8ae674064d8f8c106fdb7d64ef1537c80b603b68ed67551e788a12c1790ff1648d04b4208b58c6c24c623aefd3f114a6eccc8cdf06704727d08c7d217e6b5ceb2e1ffdef8eebb36db3f15db0f8b00aabb44436bff0a1b9441d86d107c7b99caabba10579c3e7760866732ecc743e4ca58050656867068fc7bef8c8eb43228c7ad8ee1b4801bde9d815c3b1e9112a8f6c81df8682f538738b29112a391815c349dd4f2d9a72d351c5db2ea882dc4a4d4587816bbd65277aba170971d1fa85bfa9dfd7bf2f17906500cdd637b36db7c3a3fb18e6c62cdde9066f9506b03c8397857088b7e1d094b063227361158f8222e231f1b1678e67947a8150ed1ccf5afb34ce71ca8f1e45fad314f525d8cb2be28251342e1e7d407d4b2814b0071b24285b9b934ccbada60e2c0a3ffd3cfb34f2627aa527bd26b789016cb1494295aedff42bfe2c9f2281a64c3782bb22cc98dfca553f7ec9c7688a057e0355960f145a237e4c3cb90717c03686f1ca7768162ac5cf20a3064963380304395cc5056e654ec7e027510a0f2fe8c2cd50e6c3724580a998c3f9ca11b49e23e871a8c45b22520a2095acd14c705d94bf715efdfefce6cfe4bb3acb757b9abf0fe2b83d89e9790f26d527e21bb4fac9091ff7b23f9dafdf2fc4c4fa341550b6e4cdb40f5c475e02479904299a5a8ac2db29a251ae4cd058972317a53604c2ccb50aece99e3d264ea8ead52c954c7bfcc0fbb0acd162b67555ae67534b8d5cae0e3da51770580833b2b247f73b03fa9b50fddd98d8cb58eef7e8cfd367b1327e557fbe8a25afb9cd552c61357d29b7f45bfab4cb3b01a5773e4fa60e37da228fc8f658be33467c0f2b542539c9cd9cfe8c1c656aedcd1e51c1067b4bc11c5a7026dc6f5c2ae761aeed261c19934155f87bb3b0a975e73ab1421cd345236e672a664c040902c88f2d077d381fc187f33fbfb94e8ccf5c276ff4a7cb19f25aeee636affdafc42fde4590af4cbbe21f45738879d38bdc99845d2946b0800667a9248b87b66096b6601511a5b14d016f8f463d83d78d20d3c4909abc2548291a999a25fadb402d57369f8ab394971b1903b9250720c8cd144093c6d66761bbbd901bf0d9b5643e8d87f90d19e3988bb19b8b231eeed93d8e7b2106e94dde16517067bac5e851b472ec59bca5166630263ada03dea2081a82c561b09422a03c864a01513ee26ce76137e14ade55959f26005ab02030f274cbe10a21ca14d1e551698bf2773f55b67e8646c608a4664e1ffdbadca1ff1ee6ff139ea7d136e7c90bb1c61fcacbfe220ee45bd84017fafb2b34765ecf9bfce099789a5fe7076f615a0bbfba6fce3c20d8bc550315590ea5531b9a9c4fb59d5df791c55bb6e160de4c89e4f3f21eed4932857a0a1674443c85c70b2b270b14dba2a24155599a0b124c47b472f7c4b3bc25ef02b47044ab4414d798160a8184339fc4b67e166d5de3e69cd9d57fdd862986a29e4e3c52fbdec3db7eb4c967f80d900dce661511f518333e727ecdb5fe591ff31bd0a2a45fe1541203cf9abad97c632b4026236e03e86c6302a43d8a34b786680416a4826e15cc3c4b73443dc1fb1898c24e70154388545fb4dc62e2b8fe9600bcb3b962180e65cddc3fecd0de0c2c11ec1f059eb71c20bc110bf1541f6cbe6d2c4b7f936d4cc499b2c56316f37ff8dd617bbc5b27dc4d3ccb711dfa335a900186851f8da4157491307364cbc981698bd6763afc908f8ad8b4816c3e6b6d030a170a7ce1bfedc7fa29f9b14923c7319f3a667f8889daaf02687463f45cbf3afc9a8fd1a24cd2781181256f679283f251b37e9c0816f52cabb4a9473d53e5c4994757d3c1bde478e9c61acda4509026c8733753c7ca88a89ba160d2d0bdaf5d5779b452a50c3369e424556029c60a6685ec2e00ef3ba38dabf89b4f8bcb813c8fb3e65f1c63617e3ae7b3af7cb2ba73c14bffb8f33c174fb1ee0248d63edc56c88b8bcb3d4d7b128b1d793245aa52e34c9158fe9c4b4ce4eeeccf7df52c2052ad7c02f5180b200ddef4277ce6ecf397f85a9ca29a4f7ccfa448a5cc87f0aa1f1d16eac7b0315dc59c0623f068a9e027a4149ac29c3746fa26186db75317d45380621b820c2f74c37195cce0fa4ae8c9c34028be078ec12140251750192ac00d526011a57804a36a612d64c5a06002d4f92a14cd9133367327a3d5f40d2cd4a767003187a0f496ddfbb3b0663b8cfb66df68db65fe7c1fb0ef7739662710b8bbc0557c9bc600718a1f2e2870b3a22076650221960088352ca20c0f49e58b00850e4d5d1e4cecfdc36626141ca640b452a5670de7f544e08740d039676c8e8314e93e9c6d0947f7a130e3a25c77672eb09e8f13a571a8ee8ab7fd8c3f8b468fed357c4ff2e1ae6cca7563f831df1fc714d18814482924ec80d96cf1d03395d8b080c183b1fcdde575d910c94f38524a1b10331883cac82adb17fd8d39549c70a1d3108cb6684c172ec01c0185efa8e027e12a01ed918245942075079d41a542172cc890bc10b34cd76fd0defe9372a54b218bfda16ba67b7e34ce0c809e39a6b9c5933d71f48529d0bd45099d2a9437002d895b5418a06534562646661a7024593307c83e67ec5d88128b93b68e4332e2c868aa6a9b683112b0121b618a7a90520108716a086839a3a9648d76d56c8fde172bdbfc1d738f3f66cbff73f3eda60856515eddfcf57f6fbea7f39bbf6e6ebedd98411635bffef39f6f37691e54c926fa83449bdb34ff4741d7f324ffc78f758effbaada2aca0411595b7555d44255e2545758be9724da24d9457e56d11e03498477f2cca65deb490e43f96cd5f12554142cbe667deb67551f2db4d99eca39bbf78a12f7cbbc99624baf9ab2770ece7bfab84bd207002ff0f9eff07cf397cff2fb1f717dffb43b8e7b93feffa92f00f4efa8be36ebedd24e5bf49b2baf9eb4740cbe8db4d59b33687d1e6e6afbb9ec44bdf6eb47c79f397d4effdd9ebf3dcb71b9326797af317ffedc660cd8a227f7fffedc64dc8cd5f3cc7f1df6ed4d34fefdfff2e02c2ddfcc57dbbb1485329f7edc63eebba4cd3f64b7a5cffaeb95ce2b4bcf9ebfedbcd4395644d57ec08dffcc5df8977529fbb977adf6eccb2b9d3efdff3e2bdd0ebffe7db8df17ad1e347ffe7dbcde0fd45bd7fff7b9dafcb88dcfcf54fee1bf78dfbd77f9ae98ea3151ba166d06e6ee36516dd2ea23c4df2f276bb5ca56511e0e81627b71d59fc234fe67145eb7fe0e41f97d471452cb76489cb9b6f375a562c57d5f7a08a2f48ad7b3a5ce2f6b613ace651d5feb696cbee97115438bef92b5f53faedc6ae021a1d67965d5951c008ad29ab2e958446e5a174dbeef1721815c7df4e545657a59b5b576f184bb26edafbbf375de75f5e18aca7497ef357b55a47df3e7f2cd9d7194bf2c933345ffe912d09ab1c44ab326123c9ffc1df313e50b0af3e3089573fbe9bd30fb287ff7cbb214115dcfc75d332767ded43be3de4c980d026d989e330b34ae41d84c8a7c1396701700df3eb8202aca372011a2116980b9cd12d19c8c350edf368d4d6af8d9ed45f06d0a4e101643755b6a743cc83d0db6c2cf2060b940b45fd52e16b03c258bb48a06742b5cee3ac75ac638afc4190cdbb7e8d2f0ebd123f0745a8b68a4f98cb3d6dc06fb5f145d0c39c8ccdc559fd2c78f39010406b36355bae09eccddb00cb874c4fe43556b939cec15a53753e80bbf4ec7df6ee943930b7ed92b15185593f45b6cc02af3d81dfa031289167744064fd2480bdeeb7dc3a053247e4d9baf99eb300118ac5d9dd41a1f2bdd3dcfc521bc2419056dae4e8b9b5bffe8eeb31202ad89361c18719e5b4819f69ea9367874d3d262a132ace13961d1339a24c8971dd289c7c4da0c44061b4416fd3cdd72680528abcf93ac8cfbe3fdb75e0ae0f09f2daa05b4dd92658d417937af973522fd79150ec27638bfd8bc63cd6121977e3b6794c969bc744fa33c88d928c9b7f66ef07d826da80abb0070ae49d817e9d2791caa40d5241150abdf9c43e4b1e3de86dd898837e150a161faa603f1150ec7b462344560d7d10955687b1f7855d31c98afd4bdfd98c53670060c287f55af0432ab7813a1da8dde94070b4bf502a0fe50e013d107481c27d7a0808c6ea8e47023d7702e6de5947eb00724cdc355b1b4cf83ecdf9719e8ee0159a705177065e0b5c3e01585e38d0ea4ffa7e1ecc7c7254beec0b9b2bc87782eec189f66ccef327755c3b7a3c4918723c843da3f3768d9d9c2daffa7e0460e8de97ae04eeb703cabb04b79781e3fac51c9d3b749bec80f8a004bceac49bcc3ade38110e00152c788dbf1e075fd86d08b428c95852bf73c7e833270d3df3a1b29f344a81a7f32103a0728fc612b3ee8282ff1e81ba5ce1d7e5e8a6c0417c168ec2b3c0f7feecddf7f81eff1b32742bcdbc2442dffd79777f2ff27f1e4568e12042f377f77ffef90b22b4f0b200cdbd2040ffc91d44dd3fefa5defd9ff742ef7f8a007d2d3bbf47026baeaa842954af49d69fdbcb4e48ffe7cd1f37ff3a4ae92ded5c0ae96573f5bf4854443989725cfff5bfe64915afc33ff032bb9d2fff314faae64f98505adf6ea47399fe9f379826515efd315fde7cbbc1cbfc47326f7fff680ad4651565dd753704ed5591ce23d2fe5c45c5b24caae52a89caab3b757b5d2e575544caa86be5b0362fafd8bbff3ad32ffed974a78a76d5cdb79b68b55aae1abde647d65cbef579af3ebfcda2ec47f952a9e6cfcb75b44f6fcb6ab90ae65153d372555f16ce82551a32ced38cd1ead587cdff493e6feab92a9754388e288d9b461ba26af8c6b79bf9b248e77f24f96d1d64f48f8dd0f09425fbef3659aeab84de7cbb49efcb3f92e56d50245980e3248f5675d34c73e3761595cbf50a4737af31cfdba6a2667cf2a8ba5daf9a3a97e54dabb7dc3654c114986696e7d1ae687eac73c606db896efe54ab249f37ef9435a364f6f85f0765f19f37e1fa07eb77585751c9e82e2b565159de86fba410ce6ffc6848e3fcc67c9f14e7d77b9a842de55641f3b1b73429abee464b3b785517d5f2f8e336689b6c2f7052c46c92ba6b72fe9094c1e922c29797449024beffe4c66d9257d12a0fe86d44b6c18a94d7c5284d8a2ac1a73b71169c5d1d5f5f0539e9a6f4fa51b90e2b1a9d1e64443a5d34ef9d5de1ded9c5f9079471c05f5c09d2ddc5b5c40b67d7574d56f46c9c7612d7bfbcba2dd264d7acdb1c2f4992cfcf7ede0665ce9f5f874119ddf52eee2479c096d5f1ce7c199e5fc6d179e5b79da9eb785db0e5f432cff8be5a56cbdc0812da2cafaedb6152e1f56a1395ef29bb0a92bc582ee93bca46c1ee1da58e73db2c896edadf7a6789c3f7942aa2bc9817ef2fd92c90db34aab7abe0436fadb2e5ea03e5234ce28f14a7f3200bde352c87370ef3ffde178e7310d0f972955471f62b2f4718ffd26ba795f2de778b00a7d17b48fbf04229a497a5a32c59154199e0dbf99294b747265abe5aace1b0ef28711bac5641ddb1e397cb56abe87acd3d57a2630a71744d9457850f9bd733db37fe317ff1c16d89833cbfdeaecf0b54cb34ca5f79dca819bf2d9ac4112da2d52d8e578d40f9ced2c592d63f124a7f4ff039965a96ef28f494457d50846a45cd370a9d36c3689394adfcfdaef2add8f25ad182aeb3f0c97a7bb1d82d0e701cbdbbf0925ef3c2970b372215532edf5b7eb9ca82ea7d0378fd12497efcf8e02bf3a44ae6f972f5d1fe2564d77cd947dfca49b4fbe03bcb70f10b2d35dcf3575e4b2b9ae4ef7e6b192e22fce24abe2e5d34dc1b2f29eb5cf16b6fdde2a008c2842655fd8b15940989c2568a7cd7ebab68f394cbbf5cbc519e5e62b44f4b57ab202f8b56aff8d80bb7ad66fbf1f73e4215a7b7e6c92f341557d5bba7f9f4d691cde16596bdc9149fa9a08c569b5f9882dbb28cdfa719bf537f3ed9183efcc22d59566f0ff96b8afa93c24c7438291f6f177d07376d0b1e95f3b78b66d12aa551b54ade1ac3ebe2ef1fcc276fbe87e93ef35247843f5641f6e1cee64bf29400c3f58f1f015ddec6d1d3dd66be6cd954b8fed1feb82c9064245825cba689f9d5a34518e511eb4c6713b84dae4aa4d126c9c3f52a8d1a0afff7733beb87ac3a4ffb7f5de23878595094ef3111bdcb8c146561447ed1e0f47cb9b222cbebfebd609a3a9528a3d53c699e36eb832d922ca8705c3073e645c95d90efeb66ccff11cc3b56bda4413eff63b99adfee6e0fda365d6e7f242deb79e6310eca4a7ae9591ce03810b8971e370affc140f37a81337a4f224a5e287fb20a3df7f4a901e7b9528d38cf8bdc4b9f54be38106519dfbe368ecdf3939d81ddfc7711a6e4c72be5d37cb9cde365a7f09d176ad6d4c9c8f6e4d1e95bd941c333258ad572575f3f28ebf236da4538089fbcd33c3a09f87919fc88e228e8d8c875c175ceec4f47836992fff863c39ddfd906ab3cc9e7e5d5ed9365350ed848377f6e0342a39578b87b8b57b8bda8b286ab2759bbe5b1bf47e1bfbd3af6985d76db40fb685144cdbabe30fd04f4e2162ed6e7973fb2aa33b11e6fe55155ad0266d23dde5b96ccf6717eab5832fdf0ccba78f9ca2afa41235cd1a4bab85d26f99c463f68328f2f5a2deb120794b2a98af2cd738fba1938deafa2b2a2cb8bafbb9ac483299ba99fbf62d27ea15853cbc91af46aa932aade2cb309684282ee34e89d258f4ce31d66f77690b2d6c8defcb90d93f9e927eb20fbdd597ab3d6f6defcb9cdd6b44a8a809108bbf173bdac2252ac92bc0a42c6727266326a1660277c1e7eb2ff0eb474bc7998acee5eb3dc0fdbefd5f9c0b25db9edaf75c9a6b43b2a787a74c0a8ede21081fdb82debbc6206d3d3a142f7eb16b7674bddd5c958572d33664e7ff2a41bc227f7cbbabc38abc04b46c14f4e2d9a3fa7ea3bba3e9c667cbb59e7096ed5f6eed7edbafac1df5d5edfb3cb86cc6fbedd6ca29c2c57b76f6c54ef2875b645bc569afd69b8ca7bcb1d6cf3af153edf325f2917b7fbca2b259eee86af147ee38b1b522479d9fccba2b26cd9f14b058fc43e5fb3c5f466b9c34ef55a41e1366eb4e7574a25240f5e78dcec582dab7fee299359cb08af57d16d989064b57e71b45851a6affd58aeb2d70a1d68b4a9f03de5f2a6be7f5df978feb33b31fe77c3dcbbf3db0b8fcf7f5e30bc863116d5eac0309a971ad1f65f5f3ea1ff0d9fd072854faea0adebed7fd9a1a65524ffa8cad73d6b8ea58edee97f4a7f8f777ae75a73ff89dee9aceb5fdee95fdee95f9ce87dace1e49d1e407e1b8a3aa78dcbf9acf520549807e1603bb715cb7507dbb903c11e0b4a8e6cb9afa9a80e056eae0b66198a20451ea2616eedf57df97859577fdda622ddce6d2809a150b15482da989ba35cdf84f643fe9cc77153cf20b9fff9385fce1f13198522a8b551db96d5b5a5a9880f33b3f5901ec84598a34d2080541b9382a8f33982ca2218c82c5c94795527b21ba8743f481e7e6a2add6baab2d654d0f39bfeaaeefc2cc5f1bc83a09a876a3fc7b5cc05aa3b0fa0b40805be08333c6fbf7736f7a1946a2a58046a9fe22deb2b2b8b33b040900a08ce8e6591aa70be2d7361579f2f2865a8827ad27c63fb9d3a19c80b1ff6e67ec6da6bc68ba2812c069eb5d4062423505a682aa8026f969fbdf78055a5f621378f387313e6168dc6565f530fbf6773df9617a12071c88b394ded2741061664d07bd406cbf96c2cc738532a6d5c75a98f2fde5dfb593f8dece377ed08047b32909350b0244da559338ed1ecaa1f42d7c6989bfb471a909a77eb635d1ea0384fe70758104db52816401d40a58c32906aaad2cdd1a1bfdb7900fd66cc2536872379eb7b7a1cdaf29fa1a0ff44d0e47e9c7de724db6d502d97a140f2b6fe433ddd78aa3c256abc4163638eb27ead0d48116668a3d7dbb92e921867bd7c3278c891a7d7a1a8e593814c896aacdfd7764c7d68519c1b73a2c6541bc52e501ecec76f89a092224fdf5fd777188fcbfababe0edab16bd7e489b68fdff270350f077813f1621e5898203886175ed4d9a69d16cc4d38908f9128ac8f8a4991b39c9f85a9e7cd3812a8ad7da15f4d846aed7b564132b7c282b246aabe8906fd5598f0db700cf200f62ab6c6ea7e12aafd6422f071007b1ba4f617b8eee704d2147946ebb9cfc215f95413ad25b2f9d338c06e0eafbf93bbe00d0dfd9ef1a5593707e765660ded6f0619e8b550d66cacd9bc346b3a54dd3b6d44d724ebafda14ca0ffd737ea30de68fdae0343fd3441e1efbf8b09c5fb57fcb9e9f45e50c92f44e1bf1148b668c04b78d1e606bee3097a3f977fbe0fd2def1bfee70beedd8107b4111c52ebe5ada0027984e204775ee06d54c03479c8113497618d9997f9944528dc6f34a51953b90833731342ba46f575df1ed83a7b1c280b765f6def3f9efa7318ab1a79e6b6f9ddd0c5e5bed18c9744c955dd8f67e1fa93a4b70e21e0fc331891e65e549ff5ffb4f652dfb3e2e69e93dd1f79ea199fcdcf42e88b69178d7146f36528e03511943a4ce253bf6d890bf90304d0bc7874bafeb14807508789ac01c59a4d32bd0833a58eecf37753361e2d1cc9fd46538f111369e0996dca5c28b1b4db2d349ebc0e6b46cbfb50d8b110f4a67f58e897c866fd5bfa0fcb6a62739ff76f565c8cff74be4ca3cb3dbb3f98172336b6cd33ae701caeb73ef0a00022e9f19296d7ed3e46fb83e413fb6973d5207b288e343ad62916e54d98cde644a05c3090e3e7e8a919431681e1e9eb8ec7aefd8cae7d4f971e9fa7bf73ba6bf7646739bf889a18488cd61a3a6ae8e187533efe9723201af5fb75458d953828693df16f8c81f8f3aec7f5059effbc1888a6fbbf1c03712fdcf7fabcc471ff53d4b4af1888af1888af1888af1888af1888af1888dbaf1888af1888af1888af1888af1888af1888af1888af1888af1888af1888af1888af1888af1888af1888af1888af1888af1888af1888af1888af1888af1888af1888af1888af1888af1888af1888ff3ff13c661e2c7f631044d31e5bd4f315dbf3de110b7151f61811c1f3dcdf1211d139da089f1811c1bafe1511f11511f1c5973ec4274e8111ba08f6c896595e3f5f9ce5d36d51849ebcc1f96c1e5d39174e06adb3e87970c3151cf3f5fb7ba22af5597004c5697fcb9c7b7363fec396339cf52b6d409e836bbea8ebccb1fcf0ce9e7832c52dc47a3edd2e4f811983e5dcf78c36e0a13e94c7eb49d24f08a4251ae03f0719ad3ac7e816927e20ffa929acaef37e31887316ac911d9c97adf8dc7939cc940a39cbb92e5a051240add75be6384d3c930b059ee294a6d3e4213786a3dad8cff241cefd3998170707e30a79e6de87846a43ae73509792004a31ced3655b3f10af1cbb970728762cf4799c99cc917822b650f35710fdf901629ce5016bfbc9c6eb709f3988b6b9658a41929ef78de25cd75a67715037fd7b1ccfeeba312ab421f7bfb5414c71aedd692350e3ac5f3fda0ffdef1da4371948cdfb1b9cb032ade3eb78b646504a1f07e99fdd38b0b17f1c10fd02ba7fb19c07aab246ea8ee25a8eb5318a4395a65ae7a8add7dba62f6d1f98c3f581ce62e63c3ec9ba9410f6761e891ca38567e8af98e4d612c1def2716c529c238a9374fedde91da1eec940da86aab27e1cba4787eb131dc67be4e902f2b4e2945748da8662f33d78a3d7e9c9e93b376998cd96e131c04862c1258fa7fc8f6b2c00ee513d3accaf0315c44805353eaf8739f3830519cc6b63f870de2e8dc632f5c5d952ef0264c27c56b1b419362eb541ff2716faebc9655d6b34982f91a7d793d6d19d0f2fc6f4988f949b64ddfc36fd49b6739d93369adaded3ebf422cf3b19489ba08e8ff54dcff3df36f3af028a47cd182ae5237382062519b4e33119c88f2ed79f4e7239c6b949cfc7a30bd28971ddf2aa30c32767f6533fafeb3d06a1c09a2c90cd33c77b9de74a6d40a82fc49b67fa4fb107e27070fc86d35cf065ee0b6e7558775d3daf052c3cfdfe03fd9fb5890550930cd493ac59e726bd787e70f61f73251bf3f498ee6449066931dd16fdc7bfc781bbd14daa37a5cc43a1a378c971d2c7c44b81fbf34f4efcf317c54bf113c54bd6f5bf47bcec3efa3de2e5a9e89778f9255efe3f215e1e16fd6b72e5997c366ee5ac830cd9a62db990c9febc9279ce65b28ba02d5c3f79ef10d8595e06b89d07f53e972ae7bc9e879f6d7026e2c3cc38f673923c9b3e877ddba4be9f5b50da134fa7dad85afa5e1794771e54a79a9bd0934be4598d5cb308551087d94ed2c6a49143e65855f65800a9a68ee62453cae0145cbb1eb472ee52e7597aa63b4d3dec03c6dcb765c187bb020de42ec0a7d9f363ee4a1eeb64996e4f569f9767b581cc527835322551698e3ced282bfa22d813b55f214fd7d17039d7f70f3b6361707abb3fb1f79b71983de90f0bc62b1b3d01d7728106db561eb5e538cc664739565315aef9f610d27500793eb47b8f67c17817f37e1d70d8c8a7afc9ca019cdd6903bc351c6d6f0e9e0612b200cfec182cbdbed26bd62cc5d4e9bdb38045bcb97ac682abda944a8d3c7d3ed6dd9c39cbcb60f121d7e92ad22138f3cf63f09c389b87b0bf088e81cfb3bb331a67f3761d0cfaa395938e019b0d7d6a8387cda496f53688dc7d4a9b5d5039bb7f256f4f06b218a874110ce47da0f6f9509d357dabb0baa34475db0036b5cf773ac3062717f37690a39abe1ebe6f79f54de5d5371cf58550289738037b02775c2bef35729e4591272b9d9c7629335ec9948f8720b82e98f13df25d4b9b84b0e0e836c0f4a4bf780aefc3edb14fa7406833d405934e3c73433c7d717cff1474bfee0212610081d8acabd3f73059fc6f93e5ca2eeee8ed049f97458f22ddbdf8418be12f8a745d864ffe13453ad6f52f91ee4ba4fb12e9dec9209ea4f83ceee5da623987c7b49966edd7f73f1f93fb9f2cb59ad2a5c76cf65461c7b729dde4b04b69f82384fd94c01dc5b54ebaf4708b50e0b74173ef64a3b948114754a546026853cca5c031160fb531d0cab39cf72ffddb3c26b28355b0082092b411183aaee21cd3701eea1da3868f37bcfa4e1b10c5dd1bb93688530451ccf61f7b3bd739e098cca6d23cd7b686e332100d0b18b5311c090c5c83637ddb99f579b9f97939e9ac5c6d34f29aca003a14979314a8ccf249f2f0737218dbac4ba9d9a6f66bc6a90a05e927aedffef649bd9cbba24c7d8166912d77e922dd66ff4e912de7084af49086b39183c2acbf6e6d46e4ac1d761d8770c6be018b744f5450b54022a0424cde24149f8d07f29aefd4b64d9950d4d8b73a19e891015e33608a436a441170964adbb48727f93a99bc6f4e6d04ad02b7a0271be2595be2cd18e00a8126d7c9e29b461e47b69c069e4e7dd1dae03cbde8430b06d0a6556439b7eded5b6d9ff74109332561630a77a53666600b4d7f986c3981e6124173d501b41ce8fa720cb2bedee80501340b3252d65133cf2a8ac3b149df1a0736bf995260c19d776012f350e8cd91176f1b198501a0e44607e463515fd8c587f9c6f5012846596b6aa3fbec0a0467735d68fa803b19bd377f4cee0f69153b7dce9a12b82b67424c7da1dabf6fdcee7f6a23b0ee74b1835e380f735086037911346b53349e9d17eb2843496e9b7a54bbd3c6cd1cbb2fd1ffc5bc1ce757bd988bec52feedd24f5eac3b6963337d802e02cf62e04aefa59197e64517ad65e019b9a6821e66b26ac36fa4fd41fef6616f1eb46d523478c87d28497a071872dd370025bed1171db5bff0e1ee837d03ad2eded971712d6fc244e6c31cec1b1a08bb3a5f6ad365c0343c25cc46fde67cbcab4d7c51e705ddad43aea54f5fa09cdb0162bca75d46778a4e3bfb40a79f34fa0c586baab42103390ed5ed811f6e7dcf5a363a6a98c867765d969e95c759efa06bf357ebe29086d7469eb909c7803ba6b7ceda74a62fafe3a67f2cad6f81f2747ed817194088d02f497b8ec368d8f72c8ac4b4d99b581a57bd7e583a2cf572c3a3d396cf0a66e97be63e806cef62ebc53da4661dcb35b2b9dd64e11797f30af64ed7ae0d1b9d51dfe0c17bc6b69d570b4a4c8fc5b54c4348394d65e99deb50949bbd2509e0ae20e374ee37f326001a323021b6b73cba756b03b08031778e32812c047034f7459d76e758f350f0dbb336cfdcfad0a447b0ab03b895aa347ca43b2fb4f69344ee782ad8b3bd4bdd6d086f4a616e2d9167153e675194297c38b6f4c33bfa25cd65a1a82f90cb74f7028b56a3bb0d7dcf2cc28ce8618a8a5005d3865ecfe8f08cd759056600687db1198f160887ed9b6ba2eea409346366eb19eb1465a046505a20cf9813f5bed3c1cd3884ee1c65b43cd19adc1fe4dc7f433f64be89afaa829df762a701f6ee7f09a1e5253df0758496fbde9f3c277227c791deef22b4b0feff3a44cb9dd4ebf7eeeec4ff295ae01744cb1744cb1744cb1744cb1744cb1744cbed1744cb1744cb1744cb1744cb1744cb1744cb1744cb1744cb1744cb1744cb1744cb1744cb1744cb1744cb1744cb1744cb1744cb1744cb1744cb1744cb1744cb1744cb1744cb1744cb1744cb1744cbffc38ecd8ca5ff976159d8b2f8232a6992572bfcba1fcda9d831db9174ffb74453746e349f1820cb7afe154cf1154cf1c5735ee3074f2228ea50e89f7b9b3f326f6755a9b1005a4ff8b4f5f8c59de7e6041e52eff5b7bea7ef91a7255dd444977a52da5f4463bcf8be561ebdab590a40ab68ead206f2210a8346638b869975595fd6bd3f2c6a04cd4d08f9a60c45e7f5a93b1e09743d7db9ef140bbb22cc6715ce008b2e40504a119c258708532d974b0249112e8a07e67dee990b9cd12d19f0877737afbc5b23cfe202086a2d79987b8771cd4189bccb489230bbaf4ea909b53b6d387a6e5c36e763344de4f084daa0779ec45aa98dcb667cd668d4cf1c9606914569c4c4b3365a22f7bba85072eaa7c287a2d57a8d2a65d279872793a66d81ae91b0a35ab29d47f543e2c35d198ac445cc235ce190bb2b880aea4b6f6fb9efb5082e8f3f66cbfff35ff20ebdfda35845559544ab3777b8b382873deebeff776e71bdcfdbe29a8e7fed705f3bdcd70ef73a4778b2c7ed11e48beb3d8e8cf53880bb22cc088b00f05b5eb90e05a9e1792dbfee78a0eb810d69a306399c037ad8ef7046d74421051a5bcba6fee9f0e1bfcaf7acd1c3d018fd9191d7b9dea9d8294cfaefe57ad26786497ff1bd2fbef7c5f7dee20827aea7d5f265ac559710ff14bbd87b1c504243b5919e5d16e713c13e8f13798d3c3c67586de020ed5ec49e6d71d66709f8355b7603d59dfb59bf08555063751713d59d9f614c1ce2d8163eeccdfdcc9da3accf87d96c1ec0de1c0a72d148edd140e2b02093c741ef886343c6463149e436c6f10a172454b773164baaf6d7682073617d915cbdc5841c11050cda582e77d477c059f27e5cf71e0789b1d046bb8d2f28a5a6821e8226cfbe6fbe7c04eafd1ce760ada9edf3709c3e0e3279eeb7b8299b50751fc35cae3495aeb168c5a1ba6dafc73a1f26728be9f850acb1ca5dd4c3ea7868ea8f292bdbe24ace8940cb7020d3682c6f708b855223e8ce1b8d02abfd22ccadfd64ce30537e6aeac3c61fb4e37e7a3e6b63cec674433ced7cfcd78db4ff98c8f38910531feeb860d0af1154d2004a148be6bc4b4edf684fdb5068b422390b456deedbf25939631ea8200e9b1dae8b597da6de32f0100d598cefc39c7da30ad6682c330c484d451b9cc8b1a6ee0ad268279eb9d7d4c3bb5dbcedf63036728c596c9d45714b6f42001bed8ecd35175cd1d8f938f85e435b92100a66dcd16bc1301bd513fe8c3f90377e56505f9c7509eb9522ccce6867ac53ec0186091540290b45bdeae2fed6837931f755f927de16e76ba2c39101f681c61ed523964cd161421ef067ca50c0f3ef36bb66fd9964bb0ddab3322c693e6bb38ecf9ec71c19cb1079fabe59031d4ecb0b65794ad4788306e99f6d627736bf4fbe2b84800bd47eaa0de20dc37c6ad74b33473387375d6d6cf278cce210291aa42fb79737dfab4b8f4ec9b09602e8cf591b797a153fdbcca93bc7637d4332da68ca8c07f8b63cb6c0199e6a2355a9bb0daaa522ccd0e66c1c3bccc5eebbdafb31b334b4df785cdf9aaa6fd038ede230474fd63fc33155fbf9a499f3ec7ed9d200e89de3331ebe87c5d077bcf3848129ef19c6d3394651874d34c8b9475f95e78379c1d6e8f5bac1f58917fad05c34ebe030161dff4d70d61799e54555384da996646c6da7c9fda68b815e86a2c94d17f3ed74f8b039d43f1175ea43ab60eb8fe7968f1d9615141ada79b89bd4fdb25913a11a6fb038bb9b0e1f7ac6a0df7c6f49d4f92654a9805a9e401e07e95a53e886747c9b7826d55479413cbdf4db35d88ea9fac0e2c30f384fc758d10b8cb1130f98ce976c6c8e968e59c1ead406bcaf29f277979fcd277036d7c53209545086ea7d324d1e1222f4eb509d253f6c3cf798d4cd6be7b8a2072c59df93596c7cb7563741c3ab93ee1df595717868d6f4c3e380767474c6f75a9c82739e75fa1e5ccb7cc3afa1d01790a797a1a0a4134fae43d1a21d3e007964edcafb66fe8848c449266d4358ec27cd7e65f7b73e34573e2474f2621dbd425395669f130386e7a0532cca9b666e19ced540ee707a1f786368cc5d86dd4917c896419829820f69c9300ee0c3a17ccb0b55cac6cecd0087733a6f7931e3b7054a6429141bfa3b9fc7661fb6d85a66fb2c6ce7bba1e350441467bb8dcf78f476ee674a1bb32ff43a7ae06908fb756437e3a5e4079cb503dd846a7f8307728ae02e8eec6e6f66b8be0d3d63362fc1013fb9e3f90d1f095a9c8d732cb758532a3ecc6887e9673199a2c543ebb3fb93dcda1fd686cf6410161b9e1f30289e79afb8c0024e9a794fd7da88df2095619870810af6c86e71457c68a59aaaa448a5ac3e1f6ee7ac9e435c78b747fb39d81f68ace14501340e7b0bdb27426147070dadd82d1e74273bfcd7b4ca22c069308ffed1e854ef00e27a5afca0658a1c2ff6c4bf53cfbcfb3c3df3d0f917344da92f7ce99a5fbae6ff9775cda70bff89a58de175b658231d5e233c62441f4e8984832ccbca2d1ed686dddb1e2c6e8d9c13080ccf029e97330e1639262bd2ba3b45b9b0c61df6d31603e380c7ad9d9fb6bcb38f1dc657066a8659946877da40db4e16a3b5713a656aea2a0368d23037dbfa52a5e9c312d95c3d593c5cd48554b06d4f89a405c301592c8fd8ee5d5ddd2993b109198e0ab3464686e3ae8dfa383ec7faae304199ace42d666b63d0abafcba24c8971cdffc4355f132871c1e1fb696f3b59e0b5616bc7f23fecb377338b92d4a2b8917b54b0f6057a35b66dfdb3035e9168c5985949bbbe38c6d578bd761a787622d79dde757de4260b8dbb1acfb3f17ae654eefcf4f2e5f70fe5bbfee2b5b1f09ff6f770da38e09bbd390b20ae2e4fe29a77e7cfce11f2ccb29115275e779298f05b9c018ea894e2a49bdfbaf75cdf18a64e785823b4d7d0d3dabceedbf929e3b1dc33639e9b3c5641ddca346dbbe6a0997bedba5d9663e2346ea3fd337de370cdb3fe75e524b62eeceb36ad778cdb686d38f367fadbd253878977a2a7a4c7313c3f56ee789ad93ff6ef099e5fffc1cf9404c1eda6b545f119b32dd857349c1fb1f6585b66dddb19496f77f94d7adde229218ada3164ba19de2f378dfe8504ba27635d3ac9f8fd1abdd8fe7d3511cc0d52dd0ae57a1c42b73ab52971485c5ef08e431e8dc0b32436e6b9b9f41d7767247c40868a140ad6201a2ac0176981806cba42e585d4e50245de0563b23385781c38fada4ab73b4705b2c101100eaa9d91eeac6838121c973a885b6e1fc5a58854a942229a4d81c2d97047890b5c8beb170e37dfb999a9933dd7bfa0f3864724277ca6b3f14a91c76c4b34cccce2ead4fbc00b121fea341cf4970124cb50a579303e5b8f0ea3f9136fea72549c7854bb4e3ca1c324f48ccd4cd5633f03e54488693896294ef816ff5955b850d4aa0032eca40265dd1a7c830e9a7572f1bd7987859581b4dd434e3a1ece401e782687f3741de67215e4c63a14f57cc29dbe13c1dd16795ad5626a5b3151fbf504d2665fe00288d849ffc47e57b9ead0bf496ee5517241ab07bda520e3947d0b16e2d87446f504f88d3e224629ef10079428a322e02c08c4c2b646447792aa0c535301d08aa14a3890c68f88db2586a78f7d772404295f9391265990574c6ebb9baa680347856e39310893be3c11e682931699c52bdb89e0eeec85257f77b8ebbd50389ec67d6c4e0b24c465432b8c8ffdcd737746a36c8eceae7f712ea833e3fa6234462e7481ee0073ecbbbae52fc0ca1a59fb99d0df5aaa550097ecb127c764fcb04769bfb49dd9ca4863cb152a37740104820489471d345286a60bbc99a83880272e59c885bff0f76e56d8a660b9b3ccca5f9d8babbdffcd7dffa36badd9779e9b1726cfc471a896dddad71a39e6499920372aa2f657a8f3306af7a88766fff8551e71464ffd27e57c28ed039bdf9331bdf6da79468e359afd69f7dbf426286b2ca415162d296c64aa9abbee4765d4cd3e3f5a1395dc5df2e2833d8372512b3fee0375c41b8e56013adbc2341502beb091622da70a95ec1cef5d8e4f20e436c4aea618a2fdcc8b15ac90ef86226753cfdc4d077d3a752c2f1ac7dfb1224fa22155dd85a286633a24a33eb446d277d72e7b616e95d845bd00e88b4751e3b13bea7fbfdc3f53e4f95732fbbb65e34528ec363861b24433ee5c37ffbbc922bd9cff0b1a06eb468e7c76efe9b0101b7afbbee07e59ae089af5afee1a3ae226c293728b4055cae07aed5cf1aa46aeb992c51a3d671f0a3b01c1763f0cc61687c7c6dda4eed70892028b561dd9d21aab8d5c2f6d708637dd1a6a7853d76ea3873472d387640a93a8e90a2d688947c5d417896a8e2d0f2ce61b47d45d30b654039220b0ab6c3a42bb704c65a4f6799c29a5cf21cfa28a672db4959391a1ad98cb20ab867e52e956aa1bd8a109018568394acf172a0b38d6160193779d4f9429b2cbf5d3d1c97ed2f0946b1935037b5f50b688ad2d96c7a96ad625f2e2ed89be1ed6e613d9f6783eb29f407313aafd83fccd77f2f7ffb3f4f8dc3a3a5b6bd73a6fbbbeeadf96839fb4cbf89ad02f9b7d829dc164a02603ae6bef43f46aa15401449dad488ad29967a92e3487d391398c00e50c8810106307bb4a61eff585cbcd8428b506d3516fef8bf2de72759950bd8787f4cee1486ea678e372b166532a83e1bc371194bb0947796b4464676c4e41a68fd167cac0594b3f1328357a40cb0fec86ee8ce42cefd663f7b73cc3694e11e81fb05ef72fc9294fca09d7edbdb6a7357a5d6ffffb7bda459b8c3f75f4c06c3113a76de7bdb29361f3dba9abc3c0a185cf2b0202fe1eb8540a16a665bbfc022b9630e3ddd7e6e813c7338e71cd67a1aae46faca57d27abfcee5a5afa9e51a16c17a3bad1234fed4f98bde5fd32a861f31c52746070e618e67a615352a1541aa36cb7b187733154104f160fefa5751a66849d413eb37f9fec058b5eff3774ba57e5352c822dc3561e1b55c75bdea06f776dda9fa023884ff78386bf3dd39fcab49b3de2e143b29b0b0b18e4248523ca99c3879ee3d262e6294338b436c0adf688776bcb53644b2cf60695b781c0713e50909f15d5235f2880030bb0b71c94a229186b1c71f929ccf8d8508164aa3e1faac4c059353054c53714c50c45fc99b2db19bd1e6d5edbc9e2e19cbffd4d74746d6bb46aff2dd96cc0ec60bf2d9b3ddf76b37ebbfb637d3161f68edeee433aa4030493b7469643b7a18296248f2d04880147964b5224d8a99eda43b4b53c330db36dc33fd2992773a107540bc8142923cef2f49de9e97b6b6cfa8f022fcc5c4e301c590f4652ecec75cf04fe0e8dfadfc3d49a446a657da60ee9c342e8642761b21835f2eab5bd314550e70fb4c3c6e7723e5a5bae28d708ba27dbd173f65861b7f133a5c4073a74b4f3b38733598334eb9a9eeb9866722d3b1ef2b3f159430fc1e048dbf533fdfb896b5ef2215f9ee4d1d1fe99725500a522840ae70bf3ee5b184fe7aefbc8f208780f55ebe7c01fa250387c5a636c9c7e6b8dd1dece1830bbe4561befeeb561afcfc6acd1cd3f289f1e6de1e7f4fe543e3dcdf56bb69d41ef7aec7e694d22152404e2461ee9dae53826bf7fcc069b861c10d11855a6220f915b72f6deb45db757c3d4a867948259a6f408b793ddd4dcc18c3783dc52a70d6f7797b59b69db682cc350edab6e260d1dce12312cb64490e4505036e658a6e1a8d70b87a66d67966008c4fe5c7d896f7524a61ff5eaf379bd58e350ca99cfc2336bf8745ea5fdefef8effb2fe93cb1479fae8b24fa6893c2b7e860ef7c493598e065cf39dbcf8a4eda6dc068f99bf4d1c0eaee4bb0bfa7cb71c7d3c473ad02cce8c67e43e5286821e87e3b7ec42a35607ff7db92f0fd57ec2f260d4dce6c4cbb85d6b3ff8984c31a3449f89e02e4a2dc152fb9ae958537b540db100463e94e460e4ee67021835f28d35daf20e9809ce88f7a1baac0167aed19082d95edf4799b532478ae7a8e82752c974969abea38038a431f24579304babef2e4fc644f85499a2cb678328160fe7050febe9a0b7fb7dfa9dbfc4333302a594e56b79da1f1e67db6bbe93079eb524505bb37c8ea2b965be3da2be9f8866116616a3019cc53cae3f438e792a0f876fda2cbb35ffdbfa1dcf6832f48cca489a7d47fb102d628eacdcf17c05b2c2242a2f9b29ef1b0bb29939963a4b91e28cd010d225e7ee2d1f433076f87848167e8f28b35590697b92951b37a7b1cd9399a1c8ae2d528fa8bce172dcd64faa1829c0b53c94e0bd32b3a0a219f9ebb4f889fb19b32be101dfe63c3f44abe6d6354d3fa32b5e9fa9fe12cf78b1fd563f794986e0baf63fb20f7202a2f2e291d7b800c622060f8293f463dbf36bb45072c79df7c2511f128558b6dadfcdf69664efd1c6e52c08b2fe82405ec6021a6258aca02aed0240cd40e54dc21b9bd0059a337e10410696e178b6c7702b8423507cc00ef36e9d62faa2ed0ef161c67c129feea139a8c3eb39114841d498f71369110acd58cb2c7e00e7c6864595b53975ea600cf61f96a532654f98ff613f0e72bf6af39fd2b28b0c7ecb9ef319676299ef995c00913411949fa4a59d365f5ed2e834d7f7b85deb3bf321b92a27a9f91db8d2168e4d0fa7d432b811e78378e88c68ea673bc3185b23ecccea598a37068d4553e8f7fc8c965338df191ed890fd681be59663a484b732e5ce49f52cc8f41af34b3eccb6ab90caa5098b912b143f4d6039cfd1d3c7f517ffa376bbb3b1441b9c9318b7d1ecafeba576ab43ffbe5e8a622c5a05cad30dcafa3511941aa9206532c6f9b533fa906da93ddf441ba72e05c0cdb63ed0efa6aa2e22ae08a663791588f14fec90cd648f7b46665a065c4ae6106840c0db50d0030712dd8716027b73863cbc7d1494f5a350ee5c772bda400eec11b747aac603ce171cfe4188869614bafcd3b3e6f7eefbf6c3eee3e788a7b1c3637d138dd3ca8756fa965fc1c1fef1997377d9fe7d3511e53a1463690295148db5aa6bf343fb3219a72211248006fd3102e6cee6ada191169b28374bd38bc77e26f50094142b35b68ed0ab27623123c97d2ff062890874eb421ec29cf04044534b9006a140397ba18b81178b2057362827be938378aa2e05e8f875a83c7766f8a60fc9cbeba7d1839fae1346b35865e3b20e72e3f2ccf983bc98d110dc157ed2cf702ded7d4159a32e87e42bfb3b3bbf357f5f2778b17db67e73638d05336ef62d9c705d9b1fdad3f78680f778c43f067b33417bb086aa6e4cea6a081da41b1978b4c645308352610ee90ca5c5da19820c09f10ca82477c7688006fdad954a0ee28a3d1a293910658eb88837456537e1804dd23eb2b2dd92e4a60146e664f699ba6d2ab77e742a4d2602da4f7293f3bdd9e1cc75fb8cada926b057b5b14bbb12c1edc94fcdee49bfad5bd80fbddfa52fa22a6f9dd93de32bf839b4d5b47da42bd18ac980ebdafad0beae43b8d3ec74b4f5851d672415447b92f882b97be4ad3b37b31e49eeefa6d0a86d57dacda8b90fb9be8187ca4fe4905e905bb5c92d6b33a93ca868a291f243344660ea8d7618587736202394c5264aaa919b23cb4e4bee03f69277cb89da70fed17dfe8a1649e7eff286bc96f4844f90d79e6b7b33b1d9bc8a3edcadd8fe9ef4848fd99ee301cefa31de23018c2dcf1c111d2a966c8fac8de51875a04a5323e5f80856f94c943d4bd079388a2dc30182e5f23bbcd0f678a48966e66e2cbe5840cf0c665c2c3b639f37d48a43438dc3305622b7aacd9c0c88da173fd77f89adb73280da15af7c8947333da0d9737727ff8057ec5def3fef9f4f3f2a7b8caf6d08fde2c9373e3dcbf82c9fb87d00a594c92ca2be249eb1093ca3a1a702d7dc76b2187dd81e357525050cd39d31b2a6be4b6761465098ee0c5705f923d7cfa35cd9070ee51dc7aa5c41df00074866fed073f76014a5bc0b52b0b76951fb1e291e397d638d2400523d36526b69e78a05015049ca8f50468031f46be75959e3057bd4fb6d9f1fe509fb28e3639c99773e2cff7fecfd5b77aacab63e0e7fa07df1522069c3cba152289132147580ba03ca5f100a422251e0d3bf4d3447cdc1c439d7deedbf2e565bd1e9b0b00ebdfae1799ebee97dbe31e8f1f95ffa903d46e0f798216f8aae620edbd0a8d2a81df6f7c23cc055cc59ef43bc7da6431c771e9e28f4e9ace5b673e543bc4085523eaf0a9f02bee0e99a15a8a090b6a8745b59c08233894350cd184867c448ab903911a7ccf23566087bdbb8998a963c01eeb82e62a0b85b541361e0366168844ab890d42417f52176be64c1da7980377dfea43055f89c73ec63a20be41ccfde377b0e453bdce77502944536db2bd87c8e89ddceb3e4027be6c0f7d0ab2ed60775a2a33bc141daef977d2ea90bf554c5dcaa0f639e650b42230db0823cd1d93826e26641e54a76d061fa6c9064e28676f826824873f5d4e379f38073b82576851610430e9d1baf64186bcdc89f38955bc828b15128ac66ec07ce964f19c5763a4340ac62022b6e8305d63eb705dff1d38eb83b9f9ddd539c9e9fd9e1a77dd0df0f7d0eb61f5f6b903fe8ceb6c1e3e12a2e2ac2736f8054552496d361bb99f8bc5e704be9b15fdfa152560b9e187e00dd6bbdae7151e36b207549d07552c04e680d8c6d51515b6ee22ee58ba9e0a2306144469829b7710bb98a27b9164d9448403fefe7ecf7677eca27feef29decaeff6f99ed7b4bbdffaf1e7e489db74562cb565599af9fad0f00adc45d432e3c219783c3110719b440bdb50c71ecfcd8af16119eac2619c31ac6b0f61c1ee1975e05c77f4883b57aee1ccdc4e5494fd354305ef493bec8851d9125013b543e075acf60cb5b9702cf566aff5bf6d75f733bbf54deed7e76b7cc4e9fad51a1fb846f5515e7f0c0eaa9683ddfa1f3d67bf17fafade59776213e6a88cc008210d076c8a04a5f27e39513e9b328c0d64447ebdc281b78d02d460cb51715b4f7c106e178476cb123a2ec45ba4a10869a25a70b5159a18a10264348036b2cc1b969b066d87855bcef425447717e6ed7cb88ecbe9482585eaeb0821dfd67dcff8033f118d07ed29ecff876b60a02c36466ace411a17b07ce28d7df43d877afe0b5fcc7f87c7df7de65947c04ce3316805f7eab068d2505fd772eaa867de659f373ac267ac631da7c93336636707924797d0a33c82e0723717db17bcc77bec5f8f235671205e7323ba539cbcc4605a7450d93c60478c7f0bdbf1c69f2977f1947a3cc267f46a7a6a7b98bb4dd2c75cc3756cb34cda4a1747f8e953f592e15670338bf5662d38d2a240a8834ec647eab167600ccedac3cfaab6af38b51f723b5f70dfbbf51dfdf97fe3d112f5b9a5bfb7ff6fbabdedb1489fcc69623395bce7d86a4049db3a51677acf8b7cf7df7736d7183d694fbcf35fdec696dfcd3f7dc4b13de6b61ed79f5fcee367390e6fe70b5d8037835558b2b2cf4fedc7ad0f38a1b37c20610fa1d4b11e13ec793a9b236bdd510517aeaa266eee08469d743995aec79c49c2aa9af04ac3599a2202af5de5acdc69ba6545b3c1ca79f4b4a1250d789f4ce5a3c78769dce1ade0cd62616f3b9a57b9cc5049d5457932f51effb5cf5db8ab5fe725f44f709a5bc1598bdf3d13e14c3b8a437abcda57d8dcff7dfbf7bff8897f0e3ff1f1baa45b113855ccd9a3b4e17a1ebcdc7dff617f7090d8ac8df6f8899def00a4add6c91ec3fbc17fd39e9eebacf5f40349d9c4e124c7737f02ef16d089129d217f82272150e36526d66c2afc581bba78ca4042cd8817431a4d45e15bec8ee82aa2104e6223794094ad5db0bbebd26b972b2bc904e3b0327880a16ba888f2ea2ebc2cdefb39167e970b78c1e68edf714a2ee8037efc3dfbf79fef9c234cdea73ec1d1fb2fbee2c9bdf75a5fa24e74b479d1c5a09ffa13aff7fb93eec36ff3cb41666df7d884bd4f7293f598c1cf30f89f61ddfab9d8dbb6639fedfdefea35deded9c1dd7af69a9d76d3eb9cc9821e3072a7d7ee2cdfe9846ffac657bb5cccfaca4ffcc2bfb90cfef34bbd931ed3f5f4f7cfe2d23cca60e4f3db0d82702e289b107bd68ad51047ca31080796173899d4dd96e9c39681911f5bb301a326e545235c5a6f19145da86e0d4150c40bbc8d6ce1cb6e66860cdb8ca185a472bc9826269fb08e76b9f12fc5a55db88b2f7c5087dc4cc59336cc4fed40fbe9b9ff709d8ede37f03367e1ac98f657f96667e992bf8ffb586f17affcfd9f1b627d61673ec3beedceecfe379c38d7efe7e6144ef644bcb8c7cc7d308f67f9a327ecd73bdd9f833ddec5c070a0bf89e33ee7299de5ffbefd2dff0a8efd2bbb7502d3be8fa1bef6b5dc4b60530f9c8b9dff7488ddc83e163cab06cdf10607329785a6510b29bfc373173898644ee475ce9833360e83d42016f43d03463105f7d20a073b7be7678e1f66a34102c53ad6841fe7e8064f6513952323cee126e47fb4c4666b92a56b1738d7621a76023817e53fed638c1e8fd2d7f37ecd895b5d2ad7709ae3fe76ecbfbd0fd06b631670fd5ed3e5cd5efd765dfb23ff6d94262552c97fe3b4ff1571dac1a7ad630e1f7bcdbdafb4944edd6fbfa9797de38eeffda1a3e7fc594cb6f0eb80d36a8a6d13789de2122a37a1ce5d08102044e6922440946a42dba19958ee20ec588900ca6527b758db6a24c7342cd8cced52e5ab51b1cc95292c34e339de105ddec7f67040353872dbb5168f8757c91735c99fc5641ff9243fcdcf8b2ad1d55eeb4767e67bbfe897f9e9c1bc8f5b9ef2a87d0cd3bd8961fc7d0efbff5cbefa5776f0258efd8fe6430ecfb13b63873d543fed9fb3eeef003f70c5c642c3d8d7b12e4a7740269e416cd82cede1bdaf6178ad03877170b32cf01532660fd2af192278ed6ad28a00de62ee6097565b57478b24802346944e189b78b9d588426989a6ee62224d928df4e5449d717f7f37bebeedb5ea9efcc6bd7fedbef6af9bfd5efeb066f3bf36defecd1df171bcf39f8d973f78aebebe7f3acff3b33b23d21c2b0ab03bd71d73aea573a427030f28974d64ea1ba391d41b7f61e34da2a70533ee0662923451961b71c61e18b740a8c319338470a1a363c660c84d77aeb1c6cbab8d474d25b3340cdb614d8970c954865fe158fe2fdc193fe0feef79b165fe94ebea359b8eb59e5437e7721deb6fea7a47f5e14467f5ce961eee20a38f75de73ff4bdcbdae6bf71c7df2998eee7ff374ff176b9c1fd989ffc6cdff8d9bffefc4cd47ef6b49c1d409ae72fd257e7c7519cc71bcc78ad749abb53fc0137758afbde5b8e6510eb4985a3a61b72dd28723648931ce998b7314f10c1304d3465079c32da4a32cd5d8b8be0f33a447edd05f723867e0ef96423c5f32a9c5b421848c56d73acc19c350164ee7b2110ce96dfb458efa37b9383d0a50b5d7f6add5f2cb3cc6bfe01b15aa8b02bc4956e041046aefdfbf7fef47b5054d8b8ddb26d1ab1a6ba9b3b42b882de79150a4314dd891c55a3ec5738f401876a3ce2b4760998d8a84871d1dd7a5ab553636145d4ed315cefeea61a90cd7127e02468f71e1346882335f57ba3f91f3a4b336eed4d52faad3f7bb9ac0732df0fd5c5eb6cef7ffe938240d8bdd5908bfc381bf844eef2a2c1d25f77cf7c3df077ec479fa418f7141cdb9a62aea0fef96b9bae3446c85851fc3dcd19699b42235a2bee1087732f2e646a553886a148c6e7051af5199026c38d358a58f73203466990b919b9ac745b4f0ff34b4c42ab2eb6ea9a8997044239e6fbfe0c37d6dcf74d8eb4f851c6973de6c842e4fd4864ee460dffbdb3f9cf71363efee93342c77771bcce418ac635d96bb7d3cdf631acfd45473c69172282f534aa7e24ed0a18e75679ce88d4d81ba61bc6eaf01baa7537c13978e4b276e275635f799749705bba2c1280a0dc84527ef43825c64e331b7c1d5b290061bd7a93b9999917206888d261141d792ab9eb7fead3dae0fdbf86bddfa8b68d6851c6d9262b09fdb7e5ccde8b58ccedcdf34505bd7fed3cc75b010b64349073dd28907dfae0d6a38b500775bc2bc4d94a349629995d41d16e57243f38126ec661c4de1b5b4875852f488e970be2c2465a52c5d580511451b1ae43a355224b88359713b3803f7be8af8e0948670161bce7edf164e15af9ee7fdb778baed410bea2cdfeeb00e7554a2c1173106b8508c71f8bde03e316e5fad7fffbade734bcec355faddc893b6b6411379e3eb02d372b4a0c4b99eeb4387acfe7494a9caef842d41f22068b5f2697397e878104d9c80594d1e8fd79d6bff198454e6cc766a44ab9528c416e76224da61796d54954be943548aebdd9871f17d4cd3777124877538dcb5e1ebbab1f1ba6ebc181fc5ecdfb1a9f7f2ab73bdeaf1dabfe703f7633de9b4684fba25e7e5b63254b0bc29a5c21b446646c84d9307ea9a6892725aad705beb7161621e08e8da1a883978083b48fdb67e5c5a709bd8f58458c0219351ca339c8745c33dcddc6080ee225b7b888c0a2258b125afc7b1064a649f5acfafb87b224d0caf16bbf5ddf9b8014be3f15b7dc4777e5aaf2531e7075e9b81d3b068d4bc8f99d4ee8c17cb270cc5eaa4aec43b3e1ed8dd47fd3df88cbd38d6133de022f2fa458ba2ef75f3b116dff7ea1a4ffa63dfc1607cac55a6b36dac3b2a29d855a4abc7737db2b844d59cc375c4e5579c9e4be923bf19f355ff8434b65519afb4c338e7f5d9492cb46679dd706bd0d15c8e635a5761810b66548d07722db6cd7b1cb00d292b8698b78d356627b6c8e7c61d48683563056c25afdb88630bd91520d69f16ab144581643448db05930d0d70cab935e0d01117c5459587fddb0223e2587ba555fa133bd5ebebf77d3ef4c1895cd8417fbfd7d1bffd3a9ebd841ed5db31fbfbaadf03c16e8fb0411faffa67d6a5084c139b7942a5c865ec861ad070ed3fa6cf95edf1a1ceca3b9310465c8acbeb0ed324c786c88192c0d293f1b08d290082cf0c09651429ab49ca5b8dd843d3a5b0f50a59c6069c26b668128e1d347536f159bd59be8fdfffcd79fd48cf2e2e925aea2a97f657ebeb5e667d8df7fbf74f7dfcde41b3eebc73ad875c643213f34889c807a85c667ff558d336fe444cb1e5b45e80af1653914710a69126ef71ae74523a338f08d3d5d209cee0c4e7a6bbf46b4ca6d640407c4da1d584ab7a8e216bb0253269d7395589866cda5cf45c17ac8ef5ea799fbfd42c3eaa7f0810dbcd61be40d6738683438ff6b77988f73cb5dd5c6fe7bc3f672fb839ff13aed83fc57dffcafe18ef9ff573fdf79eff7699fdf934e6cefe3ce92eeecf13d98f7396fda118d0d26d8456afbc127684d60e2f9a5614c288a7ac5c586016e9e831b1ab0e31e1c574db500bde5deb60e47623e65a98c6062e30bcdb8a89c35880c2048e6a6a0344e89dcebac47035907a045d5febcd2a62f2f33e5d67eb7af777ee9e07397e5dbfbb80eefbeadcf8a97f96bd8670f98d1ceb65f243fb7dda739d9cd77d9c9e9ea33ed433cf8ba38a61e8da708b7567163276ede5e61a95cabe36feea7e0e6dceee7494859bc84e2758ab1728f04c4ac57d9857d8078ccdf56440a8b9c2395ec942b442ab4399e70d0d465162371ed14dc3e77fcc056fc2b90647f1397d9cfee133ff3d9fc23de657fc233ec5b9bd36348352104a433918785d6cc99547eb202479ebe64e9a746ecb8be4ddddf08ff50b3afc16a42dfbd7dfd15bff3d96e85d1fb35773faf41c07fdf5f3eef0ab309f99498eae3de63549e1dc474c5861e6dc25b4b67dcb14649a96d25e0f8862fe12de753eab0c3c4136ca4d6d693b21577012172689087423e3f6c1a77813d9d88b2db175b3592b8118114bdd09565d5386e08f74428f7a1dbd8e237fc9e5fe07756b9f7a8abd5bbbffdfb39e6da635e7ef3d558701cea2af344e8f63f49fee3bf3d053e1b0e79ec6ff89ce31a809b9056ee66c13e04c92a0e2d79d70237b58f3093384f1b7454cf1883bf7d1240da26cd6f984f9d4aebd643a224ca1fb25ad2d37b7da983ad73193d3d0afe72493859b7b3ab1ccbb05af1ebc1ca9256d1ee4b4babf6cbfa9dd9cf4b1f095f0c1360cf0dde71a05a32ad4872febf5bc673fe461fc731a7a3a6c433d35bfc8233497ca232405ba5bf6bd7af7e39eab81ebfada43a8576392c182d03417245da0c09989400da26094f9bb78825ac3a7f3f3a90f1338dfc0975897e8d59626877a4a5224071fc53dcb474124250b06ad84265b3ebd6d11500685485b7071bdb4951e29b54613b7e5141922c748a8bb07d441df0b204b54a54426dd24af31cf90eb5bcd8dd41041967049ee6c63f817b81d8a96935b1331a488866632ffb57e539a1472cf8bf94abb69af0b7209ffa215074e43ef1b064eb9e7eed1fa698cf3f03c7f002d86262af102779890f1d0267a3df1e840a765751f71f8c095db22e6b89c8a36d48026adaa090b9c2f2c27480a7374ad8be932a346440780dab32d2a47ba974b3d9eb09292d1184dd2dc2f9a2e86a91e83cbf6924d8c51dbdbdcd5ce6ef7fbe97ff6f3303bdb46240534e7017b7cf209bfd2e1bd88ad289d74e9031017bbefdedb8cd7cf313ff41a3a2f064ca7cb20dd1080050bd48410d149c814cad9b5d0cd1c596c230239f289bc221c1709fdf31069f23e2e9a28a68eb55c0d339ab1adc8d276ae231f41d9a06cd491f170eb5a6a679b18a6cc93c0edb0265a3f5067e86b7edb373d57f336ddd777b7dff4f74ff40afed979dcadeb41136817b3f66bf8ee3dadfd49ee181918c90e9a12e2504ed87d424146c0df0702a026186d58c9167ea7843b7180a495e603aba146a82f7815525acf45c7b2883baed4e4756c2483655045745c2b8fbbcdc26235b1a417f2ed362cff76a874f47f42eff65c7dd23040665ca08728788fe17cbf7e7dcfb38bacdf929b59a4ab7d6fd197f1eb7dcde5dbd8ed661edc0204aac2ed6eb74be20d9262b85ab2f4814c2b8b17754ea0db45ddf7eaf5d21ed61177eb446f9408fe7e8d4db9cc5c68b10eaab0055ddcd7befabdfcee3dadf9c15e7e20f9f01e4fe1289ac8ed72320a99663ad71dc661596d2236dbc40a3ff8160c48c972b7647a9c578da45e33376e414824a4ac42bef2b61e4757095d6f291fe8481f8a39c09412e8868acd435e45c9f46fe7137542bbf9fb76e727bdc1c3806971af036c6ebec4598c7bbef0efe3933763f66b05a43dcc426e3ec6faa03e8c731ed710ca19a6ce753451ab084085612aa20c2ec8c4197b4a290e714aec7a450b65ba9a1921432c68065709913a33d2199da4feb5ae2631c5a697234df2db965ae03a62728df5a68a409abac1df2d818c7182a898fea43e8bee42de3c7c1a7f14681df9400bb9b316c47deef5844e68bb857ab3890bfaa2e7ff9ef3f92a0e7fd6237ae91370aa1e9c25c5b04b5ab0f30ff5d9ab9ed0c7cf293649a1d5c2867bfef73e4e0227beb3ef87b9b74f6e1dd9c34d64b8aff5648ffb11dab89df374b77736c270d2d87ff6910ecf7da4637f27a6b33ab25527ed619914b09e07239514a8efc7dffb497cb88a569fd6b20f5ac04fbcdb57638e77bfeba8ae7cd7e3200b95bfa925b4efe7e9a0e3f236f63c5d7728401517aaded9b897b99f9df8dcf071ce4d25c760bdfbace083d7bafdc71c8fa9a3e4149b73ee98f2a547f853efeef7f16f1beb72e713769ffeaed251bddd0c1c3d7cdb37e0683d9382bd683c7f3cfffbcf18b87dc263ee7bcc7c861375aa239bb5dbf3ef6ddad849658037a10e1fe3dddc15d5b93d88defefb9ff6bdbf501f94137def7f50e3d7343c4163a4648126704e80f27181bb6501ac848209362cc054b891148cbc6c66b85ae5101bdc5c77e8dee3cddd02de6a09c59a98e2d203b34e94a916e60d2441459693594b39be8b739cf9a5006e491ba184f1b37e436ff270af75418ef7d949cdb58306d3456a7767e76f7459a8cd173199d19ff1d5ef6332598a2aee7932fb71e724e97135e7f5304a033747c8d3411452547b1aea7c0eaf43dacc9716bca25369bb9d2cb89d37be2607241fea82e39bc46655a235791ca4515c386bacbb5d341dcd18508f31fcfbe06b43b684551706d51d9aa0805be64c80741b96f0540cf61557ef90abfab4e7cd7b2edda9cff4f8a7e4e57bf413f757233903c20775c4511b1b384df4f56b7bd79e6d4bfa75faaf7ee4e5f423ffdbf3f52776e9bf9ca8333951dfc95b17701d723313dcab5ffa5aff1b31b093c6367c0c7596cf3948a58deefabcc0f1f31cf2ad67e407b85a31e8ec7cf816e9f5a3a0e20115728e6cf3861679b39c7a6dd87d9247fb4e1c5ac04e90b0c7a27e5defa097c07cafc200299479bb39dcedc5d7af777304ceb5851eadb721536bdf1e0ce40413563837be85cc6b7d06aeb57a2e0ce1a3a96813cd1bc8c2d193c2a928adb649270b5fc334d2ab073c754c5454953b75985f5413d7aeafc2dc54d46a8c6599360b5b9989fd477303a8d831fffd0d9f89bfb635c736e515bfe9a906facec7ff80d72474a54553b63ae87f74893d7c4cf4619bb4c34204ce2631dcd51b7ef26bfb383ee637bfc2f0ee62a456eccec65bdfee231caf218de431b1a196146c131f6ab8a2606d6ca0573efefb9adddf637eea2b5db7501f3e26065bcb3de6f87b737218f3b90fedc1aebf7b86e7df147ceb4ca8c73070cc39670369b3c7fe0c7c89e739d1e3ff67f6a48a0bd82e7da09653ace2fe0e30f7b89ed3cf75d0883a2f6fe33275bfb06f4dead7185b21c065754776bfbdcb1f90628fd2762c44c1032d842f75982d2cbcc15c33792198a7ee0c09ef00622ac3408c963953c876c244c7d8b7d8c3b5e19ab46346a20de7acc05152265bf98ff4413a372e70364b9b7da7e7c3256a35abd848d53ecfb61fb7c7079f8bcfe36c8ca68c2e98335d16491beb788bd94c770b672c0172a5620a6bee03d31d3f2a2a7349c51d36d03c2edc8134fe6e62f2f72182b0238ce98cd3ce9f38dcb53c20cb641be74e4e3a78e769d586177f404c6b25e939ba35df8e230f98f8b778f0f739b0900315db284df4571ab6ef7dee3eb7961e7ada1d34314ee4b242bda9e6bc9ff757f99413399d0f30eb4f18c2f7b9121138f53c40d5f26dfeef68fcbd6d058578c9296de7d9ed315eb69495b059d7e794b8a95e7294d625fabd0d7ec4ed38efee79dfa3ed4767f2844ffc0607f7351fed829c8e27ecdd0b96f2a92e077e50cb5871228a28a33a010cbb76ca5c5adfe3dcb468c0ae71c1ae125ae7490e4d5c60470462846dd5244ace2440ebb00063928359326169d439059a8cbc98a4d7cc1226214e9d04e903eec4a3d0eb19e9ac46ac86eb7fbc5ff9b7eed0e140f053bc8d975cfcbfc0d139e4e97636783feeb978ca3d47035bae36d3991e6a2ead6f38736c31455731c50da1689a10c6d96a08088563374b3a3f576e4cff3cb87a358aeddb019fe0064f712e6d39a1192a9653bc2216434b85066ee66061a78fd846d7b2a4ad24b060a5bc28e6e1ff762eef43fba0623ebc7f83fdfe247e5e1ce7a17e143f0b0e3651f106affbee399eea8167d90844f54a2c0b14907c38726d667834dd2eb3115a4e470297c2109d30a3326f489e74bd5f68c02b94791acbd1660e1c4fe866ebfac32936bc8788bb5d442bba54d60007b46336462ec1240ce42353acc61ad5bfe02eff665daaa40585e4cdfac0ddd9eda35cf8601bebbd3ee1bf92ab8f02b716255bc753598929be9b73b4bb17ebc41ef6fa23fb1ea29f3de78ff87b574b0e6ae4d7e0da409304a060493d33a1662a78c55d0ddbb24827be8ed6be8eaba552a9af18f02d6be002c78d8a99112b04b06ee6c242336c84dbc85e3ff82037bc1c8ce2290a045d6b8cb312e58c2395e2ffd5b6fe883bf5b576eb25d6fea996350f0e6bdf6ac7effdc4170f2ab6ccd8351ed79a30a02629be273c357c9e0049056719cae514468b4061bf682256880659f9d6f58773c446699431e6db77062b554be9f05a96552a01e2b1556f89ee8c12db29f06404c544987ee13eb89c5df41e7867bb5eb45c4ed5823f3f3f9ffadefd5c077febfdbd73f0a73fd797fb4fedcd6ff2b7c2cbe40abfe46f85e7fb26140299d73451b8a0d414245799b41ddfa5eb0da792d2cc321011d325475ea2274698a99580a189a7ac91c14c1346a887b46e7c98a6d1243478963a31730da6b12bc4200fb5a116db22704b27c2012be5445cb437f649fe96ff1fda2ba593863aad45906efbe7fa1ad7b9d7e12117e00e9c18bb8f3f4ebd4ff6788333f904956730cfb7b02d0c67c62772e69602fafe1fb09c8eaedc89bca25a3a7627239a4c5999f0b4e601e631053728a3cdc20613c91c146b43818b26c7d459bb76d22c2612886278256c381340ce43a0ec300b9b84caeab2fd918ff3ec9fe364d0262e502ac7a00e7b3c5cdf97fc3d07e63b7e4e1b72f4257769efb7fcbe3eb35fefbddef1f3dffb98e5bc7a329f0d24d71ec804facb5ceb9886c9b214773111a51fdc354b2e68983b1a528ac63682be06f544078d07aa08978986ca3bddcdc49a157766944113b351e0766886e8ed436c39388115a213f8b0b0b70fa84b6721195d94d7290ab58ec7a00db9593e695aecfb645c98c3f42dbbc08abe3737176dac6bff92ee9703442154b20245520cebfd7e78f31cf5014b7656de973098718bb130477369b10dd29dbb84b20e655477add414131c867ca8f3a2b999eb6b9365e82e5282e1d5f04a82c4f035870b88e6c8968e1c0f57cb529205052b9ab126d6670f3863f7324051a2cfb69cc1b9fb7bce4416727427385cc53bffa3608de4acfb2a8e40aba3fcdd0f313f308b6c76d0677154123095187dfcf0c173f53a37e7c60d375186328f4acf33e00d57b7062def7404d9e39238534e61448aa6a20c35a270149d3aa5c7ac466af528e2a988296271e9a45e89afa5556718ccb4e5f4ce905af840ece1b5d7d65da289489621f00a692fa82a2fcbf542eb5837f7f3b3e7eba937b6f97d7dab904a8e41af791d72ed2dcfffbd1fba5ba331d8cfb50f3ac177be12ae42c3fdb46f6aa433537e9e6f5ec7865449d1e79b5f69447f8893db9dcb5e0f6059d0fa3947aa06da31b7e370e60f7311dbeae16dbfdfdfebc89e6dc33ed8c7c7f7ddfbb5f917740dde8eb93b5ba508bc7aaf830ceb1fe91a70738c57b5ed06ce882b3191fe708b0ce77e59c8d135502b64370567699bd85b232482c7b46a19490d9c29c7a5682ed5df0d0da44754358bf3e15aea0e8d40ae8ba9d070aeae700ec892c130cc9b0d83d0a3e565efbf64caeae463fd9cff55dcdd678e6ee96e125d3d8a69bf07da68cacec57b7e60534ff4e2b18786089c2c0c90fa9ea6eda5f83bcd46eaac0d75d809ff45bbf6c4f3d4073b72d6fd2ca770c1a70e415dba2174085187162448e7c8628840d8513e34981e0ea2bcdec4daad293a39a036d4a9f20c77227c54380f94dee918e62db3a94103f610b2aa93bc1984c4dd4a601961b1de26b6a6715bcdfe19dd857373bc288deda68b02fc1d3ffb52f7fa3a9ea24a1e7a8bbc794ddcf33974ecefc02baa5102529d2bf781e5ca62346f5c9ece3c00a1cc128d334f4740b188b06b3f170ba6a9864c661d0ad038e65588c675b39c282403b14e3a56c9522d30353339bdd550996202ad2e64186022bb448717ef2ff2031da77735db2fee8a8be027511a73b6de9fbfbeaef3eab576d0a53ccbf772dd2c25cc9a35a81b3d4a2009ca108b4abcc674085d1daf0584a3c486d71c560f44cb1b49812dcaaa700dc7976ca48496a6becdba2567ea1aa801f5eb0029a4d31c6396099614f84640a7a299055c435eff1339dbb3b56a9e6be8ff8646cda1f6d63eeb3cfc489346d86ab62cb0e51b69c6fc7ae5058885c57046e00862082bd98d1acce936e19e4181627186664247760c6519e6381379334d0c79e343a5b0e1cc7ca39a2e823b9d3155b813982f98b00917d1128e901ba411d57fc2353ae8b918d88c5fb0071ff888a735fcf7da5a17a9ff373febb579865ec7feff7fa3d39145f6f021e238fdaab79bdbeb0dbb97e0716c225de561303b70399ec6d7ba5e37b73dcb7e58d2d23ad1c97b49514883d4660a2da8658e97944ddc55bdf039d0bc920d28833ad39b99e4e6d6cf1541749825d9688d3b778b0a34419a98444466985a5b5156f5923b1ea36a8da678e0e56a1316eb4668f2e60cdeedb7f6ebf2753ead3c604f8e74dd5ee5c1c6ceff9cc877dd3ef5c8e9b95c057b3c70defe07f927b13455d282ddbca64999d7890d9fb037ffe31ec7ee4f9fefbffff09cda69fdb90f7447ca8f7447763107cea3c0d9be7c8e5ee2ecdd2ec67ddfb80f6be62ffd651aeb1b1ab39d08848a4bdc1d9ef380df3ed7eee775c4cd22fe1a6f7e21ced4d378fd5d5dcdb97a14c59f1ff9c628c073a4312d51775bb2aa6f882590b4532da1c37b640bc7cd2b1566b703afc3138f559e2433402ccc1997a19f8d46ae5675088e1036601b67a36b4660e05ae0cef587d1622aa3a552de720a59a252e515cec603bfcf5dc5765ef735a8efc427ab8bdcb5ebc8073df630d9cff9abd7da1e03779e7f64221b6d0847666c4be2e99847dcbc8f281e4b361b500b4ddcc271a3524dd954c2988d560b6acee86a88436a32943346409a31986f924ef02897084f04240ac19033cc693ae1643425b92488570509a4778676e5cffca3ffa5b1ef6eaf48bb8f7dbfc2e26f2f84c57f33e6de3f6baa79b0d7a3765bed30ce59fc4683f2a4f5777b7702c9bcadb1abb14c70154908330c47c1d24e4732778c6b8df922b31a94393a9aa22ad2aa5616c37b42533b61a9b680d061459a2e205bfb13d50a40b75ec1023a551acff20d9b5622e10d3bb55fbeeceba43bf7a2efed00bb447fc1a67e80fb3ca147fb8cfdfc659ff4239dc2d76bfac23fb2beabfde6742fb9d79fdc0f4fdcf67fa3cff1216fbcdf77bb71cfed77dccc69d22d68f3e8f2baf0ed3f0f185606a58ef0a869c71aaa7c68358bc9bb38f9dbebf2f7f1fc3cebfe77eceeca3d46f6abb9ec7948979bcb5739f8d7f3faea790e3ca433e6988cf2254b6fa80607cc16d1dc106d6c2107010c88820e2222483ee3219ddb738dabbd96c99b397ca55b70b65d1d82ddf3086e6adfd0a0bc4c1d576f36926325777ef0b4e739bd7b0e6defbf9ec7bfd37c2ef35055a3048e389bdc36d48237910d586858039f9a0fc97454339d8d120d8ca2f26f8ba9a8091f8ab0934c04778d97856d4cc448d878803bb561b9627caa4604cadc63585be64c850ca1c87207aeee6e7ec61daff4838f7ae8f9e01ef50690fca0df500e06073d8433cfd9099dcb2ffdd90be0348ec6ed7dac3e76ef63f87e5cefe0df9e97dfa0ca811e187551262be90f0761c6363e5059a2891935465b9c9b8f897eb741c4b9610afbbe3ed396ea2f8875339440d8ae51f198031a6b66467431f5da7a4273bc15f97ac3081d205b20d1b9039ea79390b2b57fd2bffdb2d677f8ad661af3fdb9fc7ffb9af7877d39bf6f6f939f9def9ebf0b1e430ed477f03ae802b8f2d763eeedec7e5fc405ac85af1dc639eb6ce7c4c81f5c0d02d6a1d42de52254d5cc0f18e2e58886babcc70673993f045ebedd48ee643c0f4d02d215b6ff0c44116aa44b4d56fe055e116e051764316530066a83024bc3e5ad21606e125d620cd2d20b10eef139dfe1d69ed2b2f95cbbb0b94c9ee6fdb8afce5af0943bf30e3888f3b42313aec651516fc31cb8a41dcec8241c2cfd7a1d4d70e38e87372e05112eee5aaa6e753e1ece630a52b7ad4b3ff7bae5aa0ea49637bcac2c7faa3a59c219066e17b3bf7a1c548fd4460f094c6bd9c1479fa8cc2f2a931ef709faa027d4d1efdb73230bf513fd946f6a915b17d246db3ffb21ee3cfcbd3b0be7f67004e935600db36fb5489791688724b6a42e0ae70a5be9560007200d8e281dd671007ddfaa1e9776eaf35c4d7c4d3036c99bb0747864990b39a1034f030123ca4b34672533e4610b458ca62b56a600db6ae616403bc6aa9de89bfae35e5cd6e3829cdbff046d62be8b3958beef0bc4d2f85b9aa1b7973877f56ebf09feaa06bfb771c7efefb56a07e7615605261946b410c02fd84c6432f30a674c6865733b9d530d37d79df3e0f53d4c9a9ae68e1e1ac2c6848dbd0cce785e871222db63c88a6cbc5e66ea8a00652ceddb416ce13c2e454de850cddb350875bcc1fca486e8575a27b9e04dbae4efe6ff592ff4f7f5f8d9e427f1c5b08e39dcf95feffbfdbebfebf47daee712771da8c3dd5c1df2e5af5ed768b5cf439e637b19915c4c9d6b5c98d742ffa32dedaaf5a723ba2ce9761938336a4927e6b88ba9672256ad0550047378eff141ebe7f515b6538bc1d174c1eb31b35911d3e18a4c1c63ae9ba560d563c49b876b6dc817144d5ddd33d8718dfb8c353ab78700dac4c16813f7f96fa062ae34f9f55a35c79a603f5eabed2e0e8c4baf161c54728a55b23ad8e313cfd59fdff6dc5ab793bb065248c1f1b5816e5c868d8455f7898e7052b236b198e77371e38e8726e72689f840a7feb0c51354138369fe54b02447a3c8aa4098a17641468014b307aa31e2950cba108a589b992e54b928a09600e7731ec4f7cecd63a8436dce419a7ce5bf8c2f162bbc1af3b0062f98e4fa30ce1971b8338fa7b3c66d874154881cd1e123a1388d4a56ba8c8d059c759fc6e1df9c2751a83231f026f9320f442fd46b75372fa21206d262c379f2a75f3f47bde7049c6767420ae6c9d429a38e89c872164b7adb229ede2fa6722a27b3073ca12d35920643c7f783aaf14ae92613478444d5b8006261d59e2c85260bf01892942ca1f017b4423cc30fcb1c58284b176ee6e8b10dfdc4ae15fe02eb7aeefd131b5e9d4c9d4df2c28b78cf8fea6b6e490133c10588c7a048dad779cca3fa5c1df25acd39ae92cfb191202e542339addfe9027ed0b7a9f7e1d49c8b2ab6691d06781373957daab759a6b96841affd226cd5bed4c97fdf9ffa075ad059ac0f1f22fed57eef35842fb3dff5ba3ae0570e7f1f7ab69e579b89a4e1d89126af9790f9aec69c18a41a696b93e5545f50b6425abd8e827415723662ba18533a33a5121d29069bb8ad85ec4253684e4001b2fcae3f1f981478716d487b31ad20b1c34e5862118f870f4bbb66c77ef2f7eba1ee787036be68bf2eec3e0c66ff564e7abf1ebc4a9fefcde7d73fd2cc42b2ad5361a362a94683108c94efafb74c6f745a3aedbc436b0cc48d6b3b16ea1859c25b7d31b19ad0484934814158a60364a49197cbb9cb1997162e5089aac5d429dda2b98b15bb4f8070091548143b3bc68cdf737b516f736580ab780caa2f3179fea572a6c356f800485bade75c1dea51efdedbc71bdfe6c2b83ed0440699cf651305c24e08544980079482b5c73163141b21777f3b5fbb5848133e684500411438dfca435dc237dfc525f2192babda834d397a9e27ced879186a9cf99a085dbd7a742db0f5390ca3427531d89dbdd4f19580be51a50991576ee944be9116d71a2049a668a4e3dab741c708aedda2c9883dbc4f8abb0dced3f5c2060f888901e140787e5d48e83cd0f19f2ed6eacf318ddff15f8c5e07ab0e03a7fcaacff109fdca9feddb3763eee7bfd7a4e2b0154678aeeedb1e074c2117fe7025347316c3514e2790638249d4fd1d48a2b61ebd33e20e0ee606e634c021ea244541b58ea0ba9381bc6106e611188d718067622a6cc4518326295f166c823b56b941b54036c661976ea5d688a4ecf353dfdaebfd6f0bd0360cbeecb56b1c6b18ff749ff7fad85d6243237e3dc787e798ef73c7dd79fb5bf9188eae7dc03c96b3059ec8dc87a39bc5d47908f3e1239d8e4c3c5565a8615b42799fd82c20392a97240de8c469b98d06dcda0ed8143dd082e178226e927cd6e22e7960b46a432e3b37b01a44459f9dc7dd65b9b37bcc14781041fec2c73ea5e9a1a72a2ce0a3e8b52ef7b1fb17fedc5dc4d15bcd6cff1278a833731d86632653bc99074e1a177813f71a26ce09acc63f85f547ed32186971dbf310f358d79efde1fe6efaf8f97e86fdcfe036b694e51ab999ac866b6aa77a44ef1a69386162356ac998833518b90acd88521473b88d49b259589619e78d171b4a67e5df8ee6eb0d66233be1031069ec2a2e5520808a48897c0995f0995c499a0cfc631dc3ff00f61fab278cde97f7e5eff323f9ee5eecfbfa1ec63ddc8b67f4da02a3308019a53343d8f523a3c2c61cb9420702513c0d73992dede45b7595efe90e5fa8b7f109dde10397e23cfe28b81df029f450fba70989ca125e0f7890b44b967649670191cd7492d781578e2c0e61ee8e87c06f87733a8539e5e92054a37441722db2cdaba840d055a2a1c1c84af4a640841a6e86321f8c18d124892910ee490cf68f63eabdce6edf8fe9fc9e1dc2667d7eadc725b43bdf6adfbffecb5e5eed65fa5a7e3cfe613febc33a993a6ae78bbcc17becc73f437756ce998d51546087684c4779e5781a1651e06848abca84b81b72c17bec1cbcc7cf6c9277b64d12c1df7ae73bef7b2cfc1b7cef37636ee6fece56b1ed9ceffc7ab8fe91ff1ea87cc15de0715c254c6474555f4705321883ab05c50f9155650bdb2c4939db120eef3075a632c7955f268364ca8290cfda25abd6d1b87e8c74d811dd8ce8b88618e0119d8896967f5bbfacae23ab8a96a558e02cbda85e4d141c7c6a0e5e70cf074e313ad27b50dd9ce33e167ac2f6bde1209fea53feb69ff907df3b5c4505cbe4531cfccce13dd2abdf8445a542c37bcb253eddef65af7732fdfb984c9d8db487bd26f0bc10eb9dcf387bdb83e41fc7adc676751706ceeaccdcccd3feecb568c5d739f58bf430127d4fa983366ee1bd3e2787e7d0b6f35eafe73c0e18d1d2814f8729852af7ede69a967842b9b07c2622690b636eb08290db8744897b947926cdd56c59a07a6e88a904d0e796d0503ef412aa6c66a0da55292481b3f029d31898e9688a844b1be86b5e2b7378738636caf731cee3a3bae4b76d5df4253e7d778606dda5ec5cb4d7a13fac9deae664fffd67f8619d5b98c17567b50b8b3e203062515bfb89965ad79dcc884aaf96cafa655e67f7aca35a044ef9d51dbfd72efb7d0eacdfdf36504921d5c1577b79bdd72c3b4f07868a6b17b0d227b8f4f9f6815a691413da45bad94986ecc4a20f71ce0809660621585f3098096d66d02eec7cfd6e83946c085736a5d5d6cb1db1cca027c76b1d154e94c0bf1d25d25d72ba25fa1f93b0d1fc64adfd0cbcad4b7ee497152298d5d2fed3e3f2e2de5eff3b18a5d363effdb15eab25c09b1e175898fdddf013ac926b29222c7323033493aaa26ece2a5c349160d5c8b71c26151ac4b4ee241013ccc3410413c307b2c41d4e1716e038a01b1788152a59c0f9f02ad22b339eaac9d2a65b3f779c88396397571c4d1841dd2860277b7d9cc57bc90517558f3b9e3a9bc466adb44fdcf1ffe09aecf6db3c18b5b1315249892bf16c6f4e3dd71eaf771eef4feb48000b4eeb7bb768dc658111d5c301cf5584fd21bf061558faf558689e2e324b47361df89d63201d9771399a7b8133c6366b31505b423cdd674a847af518e9d82339b8a7f6daf488e0389f0dae3b447cbd092fcbfb7bf66b7a0d8337be12f9bd3ec96cd2fb52679fe3ddba7de94b5c286ffb32ded379dd639bceeed31128e116ce952c70202ca7221ac3f17464d35c4668c23a518eb69fc64bdf9b9b75182825beadcd72a9fe2658c53634df63c14e3ccff9f346d05552a4751828edba731b4c519314b24b26b80a0de79a18e95df41ecf70c65d82cec712e71117c517b928ed58d3e867b9a8dd58fbb9548558fd840fa08185ddd44bab261ec163522a77b9aa67be05d8b2686e70302add89b2d9aa56321311e1b493795545b6cc97d3aa0c0d192da0d860cabc9842d703d574419b3ae182c79a8908adb7728a1dce30c79d0018e65fd5167f642bdc7dffab73fdd62a59bdf081bfd412ff7dad2d8f82592df46613f6f58797f10ffa7ce7c5e64c3e244a6e1754fac8aa4391d7531e5437c4065452c9230219d344210db7439d7c5c7094214237d29ee978ca9a250df5c4461851b88a680a77df8ba723b108423dd621493227f4345c094bd62490f9325797d527dad71e5e7ad9fce7b01b79ac1f7486bfcec35de8de1866fb3c3fed7d8a97f17fa4196dd2b6c688e75d643905d2e438d23dcdd7924148a4f27273c134734a204e71200dce248b78e570aa19cbd259738a916b3936b7d2fb488d8218cac8654e89004b858d23419515f3dc8cf2b0f36dd044cc6acfe0d77ec38f605d8f1398ba2f9cc8f1a57abd9d6fbfdf60a63e8bd7fc4be56487dadecffcbbdf0bcfe31fb468cedb0b9890b4718dca12840ea2296409afda90c19b38a82297368e3f51840178cdec06fa1a9a21bbbe768b21967913459df443054359628b1027c481d589523eb04c4d3c43e8fe04bb1e198dd8aade084d745eaeb597f529d5c97ebfffb6d6dd6e4d222e77fecb57388ced8123fbebbb21367025f4dd9e38d88497d7b53b3e8bd3bac7485339c540165487400628657935b9eed24280f08128a17b2a7df000ae59191a89bed6e362788f6115c992dd306a4e59906f79b1d658309a51eae998e27bda8dee13cb31420d4e647eab093e2c64a9aebc02f9f8645fed9fd759226e562f7df89eb5c23fe48885857a8f25e8efcffd1c3ef9ab4e15af862fef9d691b64305a8b205549f6ad5c977601df192476a396366bdd9e13f3faf59e17f27d8e9855235dce8495cea5f667bb988ad95c9fe95121324fff33083b3c22d6d0f965dc7e564f8dbd1eef05e2f5af7b6a1c702467d9d289d41c97e6cca144ba5229dbcb46c19239bad4d306d10148d8e82eec84477865a1c2114297766ce58007ca12faf6c19d8a414218f76d07114d34c44e8cc816c1b20060013dc03388635ddcc50c3b91a54e7088cecd37b24731061bb1fa7e8c87c697d8a747e3eed7a0f0ea580fdf707d76e39de5e7fa35901dace25ccd981ae158875cd2f48a962a149359137184ae75f4282778b2cc3d90a8e481e46e23f5ea86314489e13e309b1a381fea48837724933aedd460ae0f9d254f5d3a611ecde0ecda18dd510a6792b08bf62f8b75337ba5ddaa9d9f5f678f49c0aaa4f89203d2eefc05f4fbbb48c5e51ef3b7c7afbe8c3f27b347b71de867d610ef49617a49e636c81fda9172b565ae3a16a442184c3036f2dc8236245f6b62222102bb1846999ca22cccc53862182da9b2ae3bc79085d6ca2e7c48e0dd26d631f288cc6851df4753e48545a349cdb949f2e69fe87df48a07f9dcfbe802ba1db78fe7eaee89c0ad43deeb89a4a1e17d9dc321b78fee183c8a20d52ec14979377e7fce9316a461df070f6672dce74207f3ec6f1d176c20cf8d6b69ae312abbc4b2b6d218451c4a484a27f7c808f8b6f3184db142d96d2727a861e33f0dcbc56cc161e8167884d8c8a37aa8539600df4a4391b199cf419ab0511da9346505e351877d0ce46318a875cc4243527859ddf9c0ed73f9c92ebee34a8b02a1ded4638feac802c405ea75bce63d5fd37bdda3fca8776164c3b7b9d6f77d4e8b344d5ad02d3958c57ad37d59c3e6bd766aafd7f3e6398f34b7779f3595d061ff9be641a592e2cfeb98ed640f98b7bd624effa6172d1df5981823b5dfd7fbcf2f4e7cefcbe79f747bbff1ddc5299d9ea3bafa13feee6d5dbdc46dc4817ab336ef791c4f7d6bb859cecb5d3c8737fb1e8ee62eb6dfdd816952befbf7bfb51ffedfed3cf33e8a8fdef4147ee7179feac95b4601be937cf618eac37a6eecb141b1e17473bdb98f6cd886bfb35527b4c2df6228fe05bc7bd5e39e7a9f7077b7bd8cff237c0cb11e28af6168a415b19b3102022ea9d096d42917042b7792de7801d213226d469dd20b4634f187865baadad31ad3d7aa12c351b7e4ce1853934bcb32b88530e612f2693aa7f6f011b7752d95f297f6ed8658eab2f8181b76f300993177362ff997ffeecdfdde7cc1edc425da3ee1813edfa3b797c098bee080b8d925f6533df8f879767b76716ebf275eb9628a21d1668d4b9c8200072c83d168c9b71b44469c2ae178b9ca998237143086019c2df33b6d6939242c94b698c02b5ac07699c929b3d3074c45b424d00f7526122545084699970b8f0672b6a43073b93ce37efd8f639276be8c16b760bbb3d951802bf92587d5ba90ee22ebfa5a7f30dadd3595b495bec7659e7a5f6b7ea0c3883d6db88e6d19f9254e19ff63c65c09af40aea7a79471382345758d33e4f1c06d58a1723c9123a92b1865f08107e95c30484303bb1e67571e1dce10abe634bfdd8ace7104183da2bc36bc0c3b6c9256b41c7dd523f207b9c153beca7b3d9e9f62f90e76707cd93e1b4775ecff6dfb5d476962d35ae8c3f41b1a58ef7da61fc610280b777e15979b3038c4106f9ee3c0933c4f377230379813d9ced425ce24d12bd3cd2bc83a692d82d12c2c1d153291d276789358836ec9d1e33210308638979a06e24c4c3911012a68ebb3918ab9d031a814a3a0e1991acd3b344da88a0897f33877eebc20d99c91fbfee772d54f73193cf7ca7cc2867ea7be0f2e61b7421d6ec52beecadee74fb77d6dfae3e73bd4fbe9395a8dad6f411e5189133ad8b8a5732f03752535355af214113bd5e8e57b1a6c0ff7fab9ebb2deedd5aff96db3cbe05a0fe31de67cff37491eddb3b1ac9a46335809e61488cc365150653ca786c71b7749a82ea99af91676d924d178505db9b9d2dd62ab471a4e7920a0246a706d48e4652ce7396c59be1d50a0a61c22c13247783c315c4b64ac630271738a35d3b9682fa97cb40ab9a3e2f130dbadc99c8bf649d76d96258f2e99bdefb7b8fbdebfcf73a6b32eb6d5a39c3a4ffa03075efdfb3b03de3ff58742ab834ef7bb78f0a547c2c77da69eb89f89314ae5c1cef6bdb2df6b7aeef7f281eff3fc7d4731e8abdaf2a73d560537f77cdf60f612c3b7efec419fcf38cc4b80b2d878aed583d31aef87b91beff9d6affa619dd2c45589de5471e9d5b2505d14e04db27a83253bcd2d2c58974c1df5aaa75f77228e57890181081cf3e5def74e7ed7c9daf3fb3928d45af83d87a05dfa4fbdc45ef7a53d1a7f17df644ffa5f7d8c3906abd88659d4022d2998fadc1f91eb589fd5890d5b71b021fb393f351fbbcf3ae9abf8addbe3d78f7c9c32dec517fe73fe633bcfc2238dfc38d86be289fe2eb8fd740f451c80a4d8fd2f4d5f3e7ba2f6f5d40fb8c7bebc1eff684fdc272d30430ed62fda1fd6a9f5bd4ff4e1e3ee4e09b9b37eb97b6425cabc96bad2227b08e418f49f8bb8303f9fef46c962f0fcfc471a1dbbd8d61ee661f0cc69d5e699b5b3ddc79fe3ea317adb5fb43bcd0b315339656dc8b775cfbbdaadf5bb3ac17b7ec89396b37ce9f3b19d67f9f1ef29476daccb5decf9f9592af7b98f64faf70bfe2fabe5a1feb0ef2d72228f59beef87bcfbbe137d8f5ff5778e4ab489577b4ef1b3b6ee5e53e694bd38acf5eb73e71d7da6cf731ff4c75fe66876e2b787831e571d8cf69a337d7f3bfada0e7467d69a9fecd98bdee2d35d3236ef93f677b8a620b3b67b2ddcbfb7ff6fbabded7bb37c8e8f3837c7b249fa5cd12e4664d93ecedcc719cfbeccd9b1c5debe3f6931ed625811602de25fd6b20617d233fbf419def84afca021d5c7fe4ceb71ddbb98e27c0cce58800a10c888a0f5952c1a770e048bcadb0de7336331919c92994e15ed8426ef3d82aa880a5d4cd176de392bc205f799644cfd35a45d0da45d11d7a60f3efcabb9139551bbf1646e3e50de6c96593a5910a8cec0637da019fa7c6f67b16e16114f7a1ea89ce2eac93fd8ef67b48efc4ff67239522270bed18be469bc5fe9f63eaf6d6237607786ced85fddb13ff0bbfd75ea19deecaf60b4965c56f1eacdfeea7ea06dcab0b5d693bca228570baa8b8ce87f009ab0fb88c31ba9cd0c7702814795e6ae8639cd6410e702c79a9cb062dbcc3586128e4724776a09589a0410a3094bf974d426004f970aa56ea75c9f406f1930df2bd3c145f17ee5abf9e14d9fa74c56e04ef066bb8b4f676f7b72ff160baa7ffa3d3fdeaff4f4bdf6eeccec6cf4de7ff9d0466f05672d7e8787229c69e17b2cea6b5ffca4ad3afafcdbfe0fe377389237e7ecdb5884273bd185fa70fb25a7ed98bbfabbd8f61083bc3d5787f708fd41fdc6592ca7728557c33b9e8de689cdb69c0eb6a166aee2b6b64926c2585b1b5887b318c23b61dc6e224b45f144f0908c5638f30055f08618f28e58ca5cd80dc6b6033c5da50222d7d39c477fe24cb052bb584b43dcb9a87e8b08502b3802c94bbf64edf8de3cc4395327dddb407a710cc36f6cf74bfcf5a536db05b828efe3d37d7efded7b87dce37936d958109c53a63661c04c593456d8791db7cda997a56b4650242749e31a62e1e9692927183243de710b7aae4a1fbc523c0a5b0c70361a094d35be36bc0903744f2de52d8b3bd32f6129f5da087324f0e4ef866528ba6cffede739d0a30055b2d7e73faaad5f4047e1c33e3517ac070233317015ea5013fc5c4ec8fbbd70dc37f8c5ee882ad195161bb317befee79cb3cbe0c53f1cffcd5e7ebf8ef561fcf3faa5e577869b0f068c9a299a84add4ad8daf891b3cf536d4baeb7c467517222bb1dc8eb274e2d2f43eece098c3742bf26deb75ca477e3d6244de4736dde24c4c69ce1a96833b645540faf582133988576b5dd86acbd83fa12774ae76c76767e15fb551efc73fd4494ee7cc7a6cdeb93d87c9a8a53af0bdb20a8586affc0059a800536155a508c495d0d9954f68872ca4928cb973439884dd6e232dbd62e3e17d44679aab577e647b26676c4da8140442d32dab6d929b750cbc41c261e76952e37e8d435a9f71fffdb047e919b9f9b97e742fa57189aa6f62524ee4e37e1443bc19b3d705db630e9fb0cbe0079ca01527a28832aa13c0b06ba7cca5f53dce4d8b06ec1a17ec2aa1759ee4d0c40576442046d8564da2e44c02b40e0b30263998251396469d53a0c9c88b497acd2c6112e2d449903ee04e3c0afdffcfdebf7529aa836da3f00ffa4e08488df6b0500252128b4012c81910bf420848292af0ebd770537bbb4babedb99e67bdefc11cb3b41d06b3b9736faefbba9a49d09b2d5f0cd7ff4293f807b5b0dfad6bc19903f8f7da4d9f738d3fed0b5e08969efac5f7e32aca0f74a58b44a11ab77983a031e664adf83df2091974ac703b4f4aea95702094d620056a5909505c616bb6b7dd64d99172b29bdb064baca1454a7d1c28584b59bd13aa6e242adc22db908939182463e4fb25565d55f8b7ede501fd075edd9bf4735d13c721c4439c9dd963bd088d5da2394ada9d70bdff69ecf4d5a7482ebb5b6ec04d0c0e9cb8c9de1fb84e27efa879a38815b19f56b4ac91b080810a10b9b9d87a01b6bc82c3c0e46326970ae97194326a07201b8b3c1a08e8ade272d28b72bd2595cc7c203c171ac4d764282ce01245d9458b26e390121cf245da430f333871ab3ff7145d11677cc577699ff3d57f9aff3379ec9fccffc731f7f6e150b74847e078079c7a16afc34b43208a86a4129784e83c28642e2cc777c97acb882024373514707bce9097aaa916e572c161a4639bb6229c285c8bd48834ad0fb32c1e471acb3327a1ae46157a872864913254128b876ee5c438a49518df9683f4e35df7ca53ffff4edfdfefef8f97753ad69d18da26ef38c5fe9c67bc096ef5b7e3efcff3efeb294aff031c8dcaa5913f808912b34c4be9bd1a2c86991f461dcf611590a741620e998002fbd6b0f57aacfb3ddf1205335a0e73c18091aa7c9cb27ac52cbd8da944b1059000ee36217412d8f71a2de932b1bd3e653b353169fdcf7d87ff997abd32d58c8e7fab19906edcee36f8c263ddfc18271eff56b41ff825aaabd4e3a04010e51824acb1520bac7021dab9e4d3541912d7c63397d6dd8346654ada98570673c97031b3c8ca536845a0c81e94e1c05387b63f464a52667542c0d467709404b8996a3c2395f130559b8e54cbeeb6b90e98279ab379ab659ec3051c3f336575ffce269dc719fc19c3d07ed1a6fc77b5bf8b7c90e3baffdfbcc6ff89798d634f92f98dbd39832bfab9bdd98f77cc5b6807fc7276e0a0bbb6278c515b106e895ed0d4c2d9839a2ae9a8c1becd37b437fc39c5d11420c6493dc2a6b2e50a520202fda037f2c0a6c42db21c936643a1a1c656cd50096d1ec2ce5326db5475668976bff335749704c673aac29006f80accba53275fe387053ff0ca3bfd09afb088d960fbf6dea186fa35475fc2757cc42d7fc010bc7b7f1357ee5ffb4557f36a85a8158c76f3eff5033fe3567e6a0b4ee39deeaa90cab42a9ad3f75fa7e1a420330ed18e6a1e10453611b6402c70785a408c2cb9c0656304e3cc8f8a27c0881825b21e457db10bd8702d2a5ec66a8323a5ee926e98b1521a84d2350950cb3587939e9ba88a06587501eee99884289f8537e54190fbf989c2c33c7fc4defd7d6d747fa75c5fb739e1eacef8c85f9ef5cfb9b3cf989c1fd6dfdf8d79aa0b2a69090f368dfbca699cebf01b73cb996145cc92606f5b1c2e242d7cdb708416e93e15779c283a33d13a2a8603a10e0d6a538b9b4388400d512526c1a89990809299956d89a9ace645a626a4b99b5708a62cabe68161a7d2046c6cf611e3f5bfc091ff80bb4ca69a2323eda546f8cd1dd1dd26d79d96341787b53a9df5d7d7a79cd9756b374d189f0663b44045ba223253c9389bb921ef5c805b9735ee541d8e7129366ea173665225a5f783a9b2eb53b3c952480d64a68348e12c6243cb0588bafda4f7144f61b6dc91c5b0e4a5dcfa165809ab50a70067b7aec37dadd392cdded7bb0187f94f30ecaff5e5ff7bdeffbf78de2f5ebf33b8827fb27e3f38f34a3f63fac6577949b5e5606e0e5a4f92ad5bbada8c0df4a498e8be89ef92ded8c454d2347c52e7b66c29d3f544811b124a9d6ac623b5708c19ad3d152d67a63312016951e82942bbd759092a5a72165b031d136777051eea1faf1f5562d67e9783ea6ea4a1f43ade69dddee125aee6d659d10ae529cd56c81c8ed371342060b9e3565361d2b03888b6334b3ebbfdfdce579c909a75ebf68e375531e75410a289291ac3704ef12062edcc65d44f8809582e29f5872e1b4b13293c242a60338a0c163ea9ff22c7b48f637e827d3971cf7fafdbf2b917e16777ec89d7fe70bfbe70dcf7d773858232ae20f07aa2478aa7799a0c5145bb406653d7e423c1f88a95681b1361cfc686466dea095647282876913201d4c6eb249fec70e0502fc7c114088348dec6302bb9acd76ed1ce3870571cc08298d28999b2fd66cd2e8879791685ee7e2e9ab4a21b61c9e65b8ec7d140bb490db08459daed5f834e305d891938dabb73ef07f71bd45dcb93e2743ebd5768880b4f193e2604656c34dce2d0b00270df21e83851295711412312644ecc608964bd4181b77a50f51535a53a0ff8644eb33be1af7b14a201b211e6e644117d66239b7ab8807781662c2985cf51519f8b89bf8b5ff2d882ebf883a6ec175c7f9e5843b08fafdff7001cfb43bee8cfbed70e7feb3138d3b3c02d9a09ebe9237ee94b5f0fec8525cbb9ffda77f0399775a803eeed69620d333e02bbb41c2a9c1df95adef7207fed2f78e569510f3d1abf8dd77e933f38b34fde71d8e589557cce055c741e52cd6b8e3a40584e43da1db98d5e35bf2fe919bd416ee8dbe7d84efd6119854899b2832e51c17d00d2b238f5ca0c37fcd0df68fe843777ca9526e43d9534cc54226b5b8074802b5e46259c200546447dea2265b772d525e005b0e792224fcb42af58f61c467d1488709e67ba5b465b41cd1d0fd00849b19f67d35587010af03385a6ee434e7c72e4ecb8e05e78fdbd976b07b937d2d4785d8f83364a1ad22c39dc17e7de3fd594aebbef4b578378c686781ec867b7804baf245b7f2c99d717ad50dac6579cb107c8962bf831299a9947a58d58d60be597e615ed34ceef75df72810fe56c9ecb1c2bc5ea41cbd6a989c73e1366c4a4422b77e72a9090fc4939f8d89768a8ed6dc0085cc2dbddde28867959e79a97d1fb7dbe7fddb8478deeab725c73b30609f0c083b2d367345bb33c53844a8b883a252ae0c095b822940f4429e200c82d319b9655b44c485d47b9a1046367bf6e9e570ce328873b5ae895cfb2754af0da0b0c19f446ee6a622424cc93b01ea06fb83e2fdfeb873ec7eff7f8e2167deaa7bdfccabffdfef57e4f4f36e8ba3a69876d6c45aa2028cfb4986212872276cb6cc6cdba8c946c16ab4467e6b04c2ad178d2099995359c3468663b960bb12d54309e02a8243d0a1070b6ac687688a13a81f5626ed78f884912488c5365b9c28c9a37ee933e9c85c4928ba9cafb69859428f4fed807eb5987755cc76cb2e595bb11eadbdd7edcb7ee176df903bf79686469494ffd13875ada393fe0a893134cdeeeeccf39a6637f659e96c3260a711e8ffee82bece2439dfc3d87ece4c8d5f2f798f71fddbba7fa7c2f2cb848ac376dfc97fed43fc77037d1af3c9dbbba4fd4c181932c2adb376e0675ef0bbd9d8d3f3def8ff0a6ac5df2d150c38bc68dfb62e0c37a4b4da424907711c9145e3e0106651d17f239626d14a96b2d55211536cd1289cc3969d1dcd22731441126f82125d9008f459382c9008f0de0a9a04dac468b0bc46676a60a25d3aebb7b5fe7e58a754937e8eff11dbf1dff1433f42fbdcc1fd74a398d7fd55dcc3cb5e541d978492f9439ad3bd774502a9d302da11950fc20d47a824aec4424cba7ea64eb95d24070d905a13148cd26f62aa22006578cf2856be1475a091c1551e756350d1858722b6da95a7794d5771e199caddf7f8f0baad537ffd93c672f0eda5f09a31d7fdfd3b2f86ab7d29217d1073bf5e5bbdeb84b54d9c4accddeddb327fb62de800bc8dcfd4837f4b8fe6b1e72995468292cfa3566f8cad5f3b9bfffa771ec99b1df6c44728cdbfad8c6326683936e717439a70b35786aa13851531557100521b489df2c499ec522840562d48f3e6bb85cab7d73fc0d1d67f802ce54f7a6314e5ad222624879778e5f9ea339ea499857f97a3190bb24c77caaf12c315d3d60b8f329aad05828ac18ee18716609c091af0a3223823393ef7c73b08da5b4d2ae59e3fdb95765cffcc68d14e7115b784a0bc0670137a85dabf30a8562d140d2fd527c1500fe158379794ef35a4ebee3fcf411e39feea44bf67a7aabbd7e66fcb7fd9eaab0fccc37711aff3a7efe1037a840c55c7a2b54653db6d65d126401aaa83b837c323775cd0ff8836093150fe48c519c7b0cf46e9e91d918efa8657688880742233dce8d310b8c991b3a68666553643fa95c737638774684452bb7821a2dcc0bf5f9f7bf13ef7fd7f7e724886e816d3cdc7d1feeba434ee61067aad79e0faea0754433cf03e92a18f34650a463c58929756c4fc5d2378181340c70d12e8200dd79a0def0424a560c37b1cac731a9db440a6f1ed2d65bfcdafa0c8e712f2689d9a8427510b5e99457b88a02f42cd8ae43f01cb6e75bdffbed37abf0591c319bbb78ef8b2cdef3cf7db9a7eedfe667b84bcbe160ee838c5bb87bcf357206cf76e0dc38d821d66eb92a4ef8c7df73f746215763f6eb8d8fe833fefc257f76d62f79e5fd0167fcf2b7dfce689796efb94ccef5aebeeec746a8b04b0e1c62a7ef1f9dbdcbcb98e9c594017d1a8aece31dfef5b3890595fddc4c3ee9d77dfadc3a66622946a099fba0e321043c7ce51454cef38b1875f2ca8f1c7de5883cdaa88cbff3ad3983cddb3a9ec125564ec9ad0f3d995f787652f5503f97afbea405dfd592cfaff5577e17f72bff7385eba42a9ac476c0dbe76ed2a3dfeeef5bb4b8ba8e72761ffd59abc5bdadbd3a8dfbd16e019956ce365d28bb1f606bb79eca779186cca4c4555260c655e920d5d170d118820d3a6efe5a21eb69806c3e4aac264c81d8cc17c3474ad63a2969c9734a7139b492f14471c38cc4a4953e14d154e37416d62b0c79945249e756fd28942cbf2a4f76fc7d5a143a9b33bdba67e6fb76f9b2c37c87224b4b7d6fbb5ef3669fde6f4e36e1babe961e42c204f0aa743b0ba112f570370582b000cb349061401dc72368152f9a09b5d0a34fd66dcc064a402310119e11e2eaac408e181b859f8b5d9ad385cf222581c6ceb7b921e07d370fc58e9a7a95f662991e316297dec5edf779c92ff1d1cffd1fdb7c9ddbf4c0337bf8eeebf0b50acde7953be08af4b0edb0bd8f8359d333e2e42234da209403a26411b39d49a0b43ea932ea2e8666cc109b8dd3c18c00df938e3f1b3593a87700d56a2a42e331ed31273d7e98174ee355d9f33ecef7aacc9caae7f291dff190385284e8e4e7bcf25e5fcb7154eeefec29a39bc3be65288bd4ec3b2c857a233dc1b3631f6dd139beba1317ca75394e0d6b463f05593867601158eb8e9096fb3d9ecd2b03059ac3e3022cb92907cca68ea88a8e10a70f4ca226560d12154f4589575473b79166e87eb1ec3dc01d5a1913d71cd62ec954dec3ad281d342fda0217cee8b6782abe8e42ef13b7d79f75a42ecb013af383ce74b0b76fc6afffffe8fefff71898ddcf627bb94e46a08b98febd4678f7856bf087e7fcfd9887d8a64eac5d939670c355d2a01fc4a529196e67245a7113d084b85d60a105329d05adf8c657ea0185c6b3a72a2b229d1d0f70856d6aa755bd0ac6a2c194afa72a7e661401b718162470bc2870776e3150120dae889aea713851e312ba5459769422969ef5bb7f8cb35592575d80776bf1da8bf6f7b99fab7bd1f67eeed1dfd4a2f0bb58ccbb11f700af0f9a4de1c1d73ec5631f9ea339d5f0afd4a273cc598011377fa991e2d4a8203a0299e15a7ce405722334a83d68998dc2a79642e91033cb84edf6ae2a60ec0f57410575a438a16fc2703eceb06f224ca813d08092b9e5eefc529a334bbf8b4ab39f31a10667fb2dbeb51517d4c67faffdf15247e48ceea68cb682c1f71c965f755a2a94f192bce8a3747fe669443209b94c0fb9f8370ecfa3eeeddff749bac1b57d449fedeab7f9b41b688c7d18f3e0a3ec63b7d77befa8a17b9db618c3cd2c7401b153cd2fdd1dd63862cce96373a0ce4bb4f4145327a5c0895ddf615a47aec6f5044e743f841697ee8059a88eca96327338e53255892a819f1bd20d90c450c609a8190a4591965445e0be0f2a7153fd0e5eb699b0f18bcff03bdecc2e667b9b16bdbffffeb21fff96f7dffe3720e54b0ffe59cd76f30678b8fd3ec2bdb027af7b687f47be6049aed4cf56e6d218605b2e3d4dd641ee683e810a515a0795229f8d275bccea96956e9ba8ba834c70375577bb148ace636d4f54cefdd1af8e1532a77e235d7568b8953085eadcf954cc7c4d646e8eac99ed2cd1a2318914ab03f6f4a278eddddef8b3a6f16d38da5ec73bf813fb39560e5af8c7efbf0ecf50c0ad47612d18d61fb409201adf102ded7da5d6111bf65375e8fb524ee695731797e656988e99864e2c4c7d49c37410559e3a0fb247afaa1155d133d526ab99d5d634cf6094733d50336d06458c00b7584ee379f1675fe2923820d1260d67f05893fe33beb0bf89e66539eca68c6691fa74dcc7afe39ff20ed7e1739e532acbc0bed712f64b1785d4098b0673d6846e15699ebfee821ce3b8a4634e0af0a0e0bb19cdba88c94797c92ac99f5aa1d6b53f1656944b9528c350485806156e886a2afed8f11300495a39511cf282d2bab9ad86f4efb541dcee5a7b34ec121f14d157ee9033b55f7293382ed19ce6a857629ed6f2f57573cca15e777e9260d206390a0315404ca9cfd5b5eae5d20ecc2144d00154195a3c9f0c022b5bce426833466789295a04b9c9205dfb55d109eba94bd576144832c0dafd0087f53a01320e54b960c55213632a23457658a2677af6fc7cdb87ddcff7feb82a95c97b9efd2ff95fb44d0eba78b438e6986996f8ef73e45f38cc9b03a636c47a6ad177fcd7e621affbf735dcfbcfdf7389bfb44d4b509f72bd97e809dde29e7b3fe6ebbe8ad909f3111cc7b90e3b190db8d2360fbdd7fafeaf41ac0a40026f9bf4d07481e3f8d06962282ddce35d52e87aa2eaaa60e60a8d8d2e650826d4531e40a4b9a1cc588e46684cb4b9e52cb8827a4fe5cf041835ca2998825415c5baa55769b15ecbebd06ca78cd7d3fdfef2878a60fa26529bada7eefdebe101671c87e8b02ee9b536a47237877d6a1b270cf2b798da5bc46efdb47264c4da5d14e2e52176fbf81c27bd958b63b7764a38261a7e200a6071d1ecbc60b28f8596331b8d08751a1af0d56cfc97b5f90a4951d28db88c03f41658d7fe88653872a7bc1bffc489e45e656bbd906a33662a5e98b55433b219119497cb1ef5c628a0c6ddbc929b48e5238f38e1cc0459948b110662c4087e46a6ecb966ae22054f85fdb48b030e66acced958ee08c19b54137dc4e023b50449880952933e8bf3b16dc719ca84759a07b95b10ab955188e4c4a63b6e4185fb869274c6de2f93a9e63d8983de87b14d1786bab703e16872e139cbb254919b54c3fbfb368834a74e6def6cde25d18c034efe84633ef3ef87354f3eda7b9ca595a89377d881f0479c194fc7faf4213e310ef1caa1c664b7bf26e37dcc6bfe84b7f64dd76301f6fe5471416efe263ec2e7718f7b976e220def7dcb263ae46994f67abe1fa0fb6ca87a618dd8d8d353251a30b603338b071e100f28442a515a1031b920761611525b81054681ea104150e79aa0744953136bb8c38aa207a5b4e25272af40871e06b7e04b543a1da7a6ea119d51b3d8fdbdcef99b666ec476078ccd9439eb88a1d534c41770eadcac8fe1bbe738dcbbdf69c15cdbc7e0fac0161abc139253a43495cbea869b4d8eada5ca35b4f64956cd99fb97732ca4185daa237fabfce38731f77357f1d07ba71fef5d8f39250245a1a760b2046e10b5b12275b7c8a428da759ae3b520fab3570a35614bc50dd034a2d0406aad20180dbc1cfbd846656a662b04049e11c152c6f93c948399390ca6ca4e4545b39d8f9ace97ce2c565bd7efc54df9d1529b36e95b7ee726bc6857e3b25e747bfe5c9b686f82377cc5e71f35904edf7bd59d1cd8229bdb426779da05d65a13b276820acf82cad10578dab18aba73ba8f25b0292cb8e08cc7be0239a2b5ed9719139628e6a5be16d491a996cd126ad4c2243ba2c0c707e557872a145233933e408e5b09e47d933fb8b21651a69dbedfefebd4824a3cfa231ea84e4a7ec2a6bcffdc175d9c3a2933b99fab637fdde40b96e772dda2e1267ac5939cc7e81f9f1bd4275df86d625385fb1f7fc75fede1c5f23fe011977bdf2bbfdaf73fec5fb08b42e7827e3a72235ecf8f7a6107dfe0e37334c79e8bebf83e3d32743840d853e92e263517e0bef7a8b3c1dad30a51bea136e97cd3e1dcae1718dc2b885157f4504d7374e7e54865452be78c166e88c633966da2123d467db1259a83e64401441a382d1b7b9ee38cf4324eb49b72e7ecf7dfa1ffe40da775a8bbff2d5ee9e947f6737ff7335ca7d50571ce4d7c93932edc081471e8f4af7be2ed394eb8d5eb724b88642d0d61115b0d4c34feec16c372aa82de55a424dd1072d6e4414f94798827a4681982066481d3c5d0d1d2228b02089f39e51053771758d92a0a8c815074539882273919084d8e91ed8207054c5265f8886e6b5beba42cdedb2ef0dff702bdd7ebfba38fdadf484ffc7006a217de86d31e483ba575bbc1e06aac549129dc34d50760985e219f39a1aa17146d5a19edbca06adc0d576e37ac91426520619d56b2a61a7df0c7c644f4324f6df91010a8b865ad4405d428833eb732f3a1279a0b9e142185860a99c745e34521aa67d770e75d50e79f1f7487f93e067ed32b3c7021fcb55d18fc762f557b1fef845bfdb49744e8ac3f9f69ae4a25b6e9e2949bea536bb849d5619776c37e1ffb1dfc2acd598af0dafeefd7bd77860f19eb07fde592f6dfea408f06dd4db8293e8cf9abf9f85ad94df32386f02adfaf242b4e8892e6f7db988a4d6ac2011e3f01b75af69edfcc5cd351107566d36e388b8b5a23a5d7d1824f3003dd3c14039e533505f53a1e631f956d3db776aab768b4f9e2d7808f9a26a238f0583373097762a5e8836b702817db14f3f77c4fffb3f6d2e2dbde8c636c7b83bcddcb782fb1c1fe6fa53dfa93d7e5ec78c98b840dfbb83007ee58e8a86bd65e006741603c63d21a44f28685743dedd3168559ed9316c6e5af3e361d97409cc7a15311a26f9849c7494e2b57050ac9331228ed9896ce8a57347349b6e36cd0217f184567f1893fb661595a39d9dc0720295ff24cbfd5d82de270f24177d5fd8a217bc5e4bff563bf6a817ec1b9c44cecd7e30317e1d71801c8b414d27deb6538c7abd12716ece31bc7b69fb02cff2636d0509d94f87017a765067e1423946739146baeeee3e0eff25787b861f0f767ea4513787fa65efe560e6b3abb92432d088d128f85975a1252db1825a3a181a4abcc826c1411f98064b1f58843660182d47216f3c029c9f87e27720ca38a7b9ecc42cc8619c921f5a4314d7b54939cf4a95973a45085956be02b70ec07448b0348ff0507d7647c2da7aed87e7757cefcc16df4ddd5e129ae1b2ad3a038e4b2afabdd4d344ec54ec00c6020074295cf696f48ba685457fda53e806ce212d9d2623de066fd8819cd09e32461cd26d252dda391c22da44d15bc9c5bc52060789d524389ed6c90c25a8fc31acd2b59cda04312427bdc3557d4eebecf8379f6e73337acd3b73ea0169de96bf16c749730d8455a9dc5ddf0e02b4f435c278c761f30029f7b5dca23a6eca42dfdb9df473ddf6375e0a939e8a61ef4dc4b7aba6bdfe18ecfe44ab84d778945073c9cf46f75f07336f5733ef655c3ef2b478235d478e8e45188e4171db773dad64c36313bf7cce73f9f8e401e313de7ec33dee21c76116fa7e1fe99df730d7caee17fb91bf6f6f8a577a9492c38f8d4dff6d7befa348fae3deb5dc490e4155d4f19ff8e73efd013866e10bba525cc39e3201981f2c885fef1390e39f1c595b8472a9e7d60ccfc22d2660c2b7e0159524a9a98c2a64ac6b1b6ec62290674cc596c0eb6c852daa0c4ab482ebba418f69844ab48295acc7095b21d9817c88f6d774b2b841975d45466b9b0b395803c6292aee230fb734efc823b33b6e07773dede88e770191db5d6f6ff6f7ee45fe64e218a5f3b2a891aa8f41901674595da4e4bba8c4be72e20f01957f7600af894d8f74040bca38a64c8ac273eaca7ae3f1ccd2dc722152ef7be861738010558ba6399470437b4c29c857588895c78d255e6dfe8e45c9b7f3e57e37cb59537c89f1d70ba576b176459da812cd5e426eac0325187ab0bb4093edb961fddbdfbbd376547bcd29465db446d0eb994b3ef9feacad79d4769b9907b58ad57737ba279a1d40985b3396ba2995d4f11345461523305f4c1a3462b34b243925af31caea39c435114c0d590178fe9c4654d38b7d24120330791b6e7d219b33c036c2c673190262b9cc5540597f2a21cce002fdbec02edb41bce355f4747fdb477e32bca0f74f0e09c350f7434c42e699e2914b9b08d1d57a4c1551e04bda1f8800326e9736c0994e6a6166b9008065032e606afa21e13192416a54883310deb2d33b1454d38a1261e23537f4c9474cbaa8cba0a551313785fb97d7f963fba746d524d3651395c5f7616fe1ee77b589f10e90973b689fd6627df9e4369afef33035e60a13ed12078e89a2221d461c564852abc15a66ef99ab9450ade3e80e54e04784bc7c69daf0c1f8272d727504e51c56da109e096d9b36fbb2b94678f98d60b6ad53525448f4af1e811278ae4fd166bbc23bd31fd177cb093f1a15ef61bfb783bdda1c4aa9751e82c7eb25fe60c761770c7dca49ff4b85764969683d77d721cff471acb34258e9fb242892ba2d15143522266dc8646d01b5e4411c31a32b152534f4235eea5a454cc3070b84b9085157cc758e6527588905263cc689394ad4a4ba44e818409733ba1e8e1cc74c66e8e612269ff2f62cc6bfbc0620b775396ede777cb35274bfcfdfc7e7bd63ff322fc70fdce8dbdf741b3225d80651c222539f8a3ca8163f727dc85f1d8e0d41a3eb82ad5d210652c471b2c3189025e04e6d0441a6ae7a30672158fd1a8798c94a51e68449bcbda4ca0b74b411610339ba439cae78c6e4888bc34840b5a6476b2186eb12cd4795997983411d6f85df2a3de30274b55a2a2d169ee7fcf23b58b58b3fd100f5d991b3a33e7bb7d2cc70f1cb0fb730cb651b9fc8f6a885fd739b56817a9072ee5fdf33689ea3c1f7da18b9efb473547421c35927840acd6164af6ecf6dc2145d42299b909903092544554c239f9d5cfc674155377e753b79f8ddd969728a0a61e5138d16663ca84c92d963b590c0bcdedd19d6b35faccac556479aacf062ba2b92b017eb247ce9e89f771f4b558c363bee2a5bf2d443261703feff977e7ff0ccff2cfcefffe33a397fe71d07306b2a4c275a41deffddf3fdfde57bbdabee751e878b1dae6943d69a41886a4586b9e167508389eb0f092b18ca62a5d47fe10f0806ce3a2b98b4b5ad18a47d886c82da48b0389ddc2b1935c3eb0a25eba2c1d2015ed50c07be10f2d0e60302f5148fa13f7c55f61e4f667e8fe94a7a0dd94d5dfc5a8bb43cfc80d62d4632ecbc8d20ac974f16a97bf3ccf815bdc1ff457c523a1a7c556ad72166d11c9a0df0b9f025cd0b0669465eb995daf70485681d56638301c16d64510523592c88c4363e0496717a80385b24c9bc15ac704c12878dacd2cc9e8388b3cb5be4b7a3e48a8549089ea00d69772242fe7a121d3527e87bbbd155fe6eb78071b67cbbd4dabf9e847fe4b4e54b88aed6c414394f9216de392aba24454847c3d55f8daedbdcecf2330b7841b40d9b1300b8836d153061ea60a7df0bb269859a8233d6f7cd6623e1a66482d56c4220a1e1b8803d409587b815dcb07158ecff92fdfe5594548eb77fda49ff5bc0eb939c164f1b2f7261f39d0afbbeb5ee7f3ab1ee1eb73fcb977f1267a63c7b17e35538d82f8d8b378b5ce986fd501868e864a11e3803e044c549186275e899e690957eef869e52b94c5103931c177b8d4c98cba7ac4689584f70344dd6d241de9494ea21c636af28c14fa4e984b3dd6288f88be4c4a6786c9701515cd62aa5cd20760ac39833df70d905afb3b09cbc9e8d007f0e62f8cd3a7449b3cc596ac628b76d3c5fd53a0b6050f274faf67aa729f1206f5894df7df850efd2595932525de26fe533db1e46662219956388bd9e02952651769f4c02f9b9448a6ddee49a8591da94f4f71e83ec5aabe15eae04958bf9ea2923ca5b6b38dca767f7f2831733793911170469edead9d3a1be9050fa3fde7b6bc3bf0ff2ea7e1cb3318e5fe37708b2a1193ebb41b7cd813512937e76a7efb7d3c79e3d43fbebeee8ebeb05e77d03c54ff51bdeeb057d1755a1ef99c70d3d79c36ea869c5b28c4a55efb6576e7075ef7a0c03bd2355550898686f52351784e0a845928f47de4e5158e3e559a6711666100975b5c64d01f739468661b94f22e20c311d52489b46810f4f8911512fd9b78fbda7addcb9c81c5dc0705673c13ac552eca2bff7d0fc7cb5e69a2aa68b845cb28a4eb03eee537cff583be8020080d25d2f802abbfd49909db288053c486459a7b4acce854a8ebbff47964935ac34e8c40b9b7b5dff63b7fd5d4f8992fcac041b37fcaf87eee0ffd6d5fde0b8e35b6eb7c1d2e19954bc2cc151e43ec15cd5d52f12525d920cab3320ab3755a099a5459cf0936a202eed098683830b4c0d4eba477160140d3a4ac39b632142f1a1e13d8a21c0ed202d83184ab1993112dd70057754508b86d7fc00be6979deece3fd7d55ef7ed7ece12f55d1d71740b8db9e87f3cf6e26dcfb4d9fc5b8ed3c98dfa5a5ecfcc3a0a6bfde3de3d3cc7a9f7f09ade4c274cc8d0a33473e2f257fba0ea7160b62346f18657622da4b10a2ede6717e7a8afe547ab939076fbffe217accf9f7185eda7de859fda0a9096fbffb22c3df2237c7a0ee55463bff4ce349b58cd6a14a22e5687dbb8940362218254b37369b6981340a9df6c6f8f03bcdfcc468376e65fbbc7f532d9fb73f6457a3eb7f04b36bc6c6bae66ca716fbf8e7faa9f5ec3078e162eab11b7380e20d4fc8a3f60d2401fa62a0722749953c67fe203bfd27e26aa9ebfb399e7706a5a5ac25d7aba37dcebd762b98f712eea6fbe094f92dcecfdf8383cf637bf1bff947bf3aecbcf764315ab3042a3214f2cb3a75aad0704a914c24706a5f449a6a664381596de7a2506738927a95def08adefbc10ad7c052c59ee4c1f14baf14a190481bcc3006d7dc265101a91af6519b230e7b4764808e529f776891fb289bfd7a3eea7f9d30dec895e9fe6b23ef864dd60705d0f62cda69a041c449d08eb1031898844352ba08e6d8cf9a8d9cc6d4c93b29681eded228666dc4ef599d54c03db510575d89c4c06ae8d7b52d0471c085d14827115ae63b85449a1479e0aa06f35d4579ce9dca27f8fb7088d03aff4b4fc36a77586b3ec67fe716ac182db934d5c1df28bef5f9ff6ee753139e989e28f65e3b3e52e2d9d0129a49e1618e190024c270354b4456209ca7b691195c6330b03c226aa07a8ed96d24f0bb34705e054c211d18c8e9ad19695d4101ad749401b6c0a1054dc21a6b2f30ab976bff62f5da50d71eddd7ac043940224ec12fe04f356f6a59f32d8718d3647bdbe43fcf2e9bd630df8f2fbf510930e88f5b423255066a60e514efba0aad539a50d5585e386f8ce55c1340d52253185e15ac09d992d6725dafa613d0db4da8cc77c92840e4f0254b841b642b9b1f12dda797d66cc48d3ccac868be0499b973cc0a5ee7ed3877e9b1af04567cd3df4ef47a1a34fc34b38436ee697f6d303b70eece63e78e50d39f33cd7faa787f3c70a00899432edf90edbb29887d48e19ee79201e53251b08cb7110108c530a13adaec8625821cd295c3ba331033c285b9549074e957517301153ab0ee741da21224bce5a97539e63a2e848058d808ecdbed125bb1207b5dfab59ba8fd5c34c39689c1cb9605ef0f637c1ab5f5d0fdeaf8d0ad7c97fca25f4915feb758fbc3dc7a9f67b5daf0eb7749486682772baa1017213956a7eefcca65aa1f94aabcc6d9cc51a2782c1710a888e2501ee6888b1058aa8c86673ff9732556a402a8c7c1bfa349874498fda07900e6654e2a4c418333aa695983ef4a84dafe925bcd447f7ef0ffdd6ffbe1fb97d8e2dd84557f69e1ed7e98238f7261c44877d52bfed8fe247f73663fc818e45176b06f67203a416eeb999b918884e94d9c82f79ceab7a1694506304cffc506266d677ae29594c44897afa3833e988984dc06daeb995633d28aded692842268f6736ced31c2ddc40ba11a8dbeff40cafd6bcf5419d947cfb89d3f537b8a0f3faaf6feb76cc5f1ffcb0ebfd83220ab19cb2e1222e69fe6d5f9fff4547ef67fe72e83647ce21b08dca5a469a77f4e7be3ccf092b765dee9a12b535e99874c8165b12dc0f22368c71552fdd6e18a3122d67b4d8622a224c323c5560468ac18ea8cd340db0e216b5e6ca49e7f6ae2e208a9250005a0e39525a37319d71540c9dc47eea92507a536507e6e57af77f20566cbf56726ee3d7fef96f6bad37c88fbf1ff3c5861ceedea34667771db791d9a4446a1e202da79381d70bc28b2c8b6d2a539ae5334bdc3d28c0f917399b0337ee0fee755ed175628b9adb78396568cb2dd2a4d6b0fe9e47e296f69b83c46ab59861251e811317b6b18f7d95d735f9fd735e6befdb29fba505a4897090c5319088aab44d03faf8d0a72a1a173d0235fdc23177f15a5c5d1fea2fd3a4f56e84af7a1defc53e1ef77ee05daf6b1d50dbb5f154980ec1856c020d9a49d18edc32b351e1ecdc0ae6be422d6ed32db2712c0289e8683841858ec56258c556a6bbbdb1450105bc84e5dc5c6e030b4f502fddc0763b5fe55d923f016ab6d33931354fd29b72597f3cebef7b5aff9e7bffc0eb7c3dfe6abf1e7552212562ed9ab393567009d789fd9d3f75bf71bb5bf9ddaf5c7b928fc00b97c3fad807fda77f3ff1005f77b76a2ccf062eab7ba4c8ccb51a1981fbada76468da23c32b1b2309e9331b8b90d81cc73d072240566217db80ad15641b3ad1e89a84c6c63753051543141799cd4cb8f389bea139c6312c7a02c40613f4e8564b705bbd8f8f9c271ffc2fff733f9dec5f62dbf810db61f9a1c7eceffb5cfe17f041ecf78f2eb90a9538e4721ad6323d6896fd5777cd97b15fece0863391094baadc07773c74b607bde12bfa6a5c1fac69311cf8cc315125b6b17ddfa56341a94a9d80611ae4788915f23f26ffb39f9bef7b0a6f9467edc026b594d7b94e2da539f5ef5c15a7cd020e3d4596f1580e8489cd041a7a62ea1eb3b2bbb8427aac647d40ead80d3283684646b51acf89d321287d6a21164baace4b388942697a84066e39a4d31e4d53ab7d8ecd8cc6150e48a1d7d816b56b46bb985d11a7fd33fe9ec3be050973e4779a05a8bb514fd4617fd0262a69f7e283bdbe0ed2ebfbcd02aff55459c66aaaf2202373d606a985156a1b32801ca5210fbc82b2b9c48a30331553c744bdd73e68c686e5991154d1ce1ddf2b01755c3446d8078699986b3d52841a54f76a20eb90493a4a2cc766500ee6967e85af70b17d3de8415cdf47b85fbfe122be483ff9466bf782917ff9fb4a5b76d22ae952826d57458b48ab0773933e9072f8c82cf41857b848c7f061aab67a3a864d500e76730bde25d2e967a3a611c4597200f3b4d417fbd8703ea61162fc51f4c62429c0262ab939aff8061300850d4d4c6a98f4dff4ecdee04ebcd0073be6a5f77e8e2a8bef34b28e3c22b7c961bcf0182615aaf99143fdccf328fdf5390c65eb4a6a1388aa24c4ad507fb5b186073353377dab06c4163155c124367fadb8badcf1bce8316b96813901a414e18c3a310f79c8a85cfbac0950554b62b92a0d9c30358705a1d2114a2667548e9189434c1cf62f72183fc95d9ff48e2ea955819bf818e1fe1ea48397f3771aff844b2057dd77a26ca7b43735a2e82d1ae3add022e051e8bb0a6a5dcbc1c4a48bd9a859e11c511f2c3b5eca382886a1b06b851102e2c018cf0b14cf4d6e0ae51798d9d0088050e6161e11c91fa7200284c98d1b8a674f8316bb2df7d932fac803d1ff35deeb7f41eefba52ff53fe20ed8db877ecec02251772ff6e2e5f58fb804024dd471996544a22a0df932f17fed58898d08643356797a0265e12b7c1701c7a4634a034801a39997004f9b059806c5b0a07e53a5d05349556f913a5168ee4c28db6d13ed5ec51ae4b371a178b4d6442ecbe8f67bee638ff22b36f1efe3faff0539d403df20b760979650bf680fdec6bfff30ee8bed13b6dc71864ffc61a7dcfb15183844b28d4f901597dcf42ae4bb2adea5107a892520afea8c68c61f317017ce991e85cee69817dbc7f297e829ddc64f3bf626bfe4505ecfefa7e739e555aec336b05822192d866bdf02ab4493c5cc767402b9e36bfcd153070a1ec355a28096f98d9a86f23996b48c7a3498934621635c30321c0481a7a4a0ee920a62a2d501b7dd7e6ecbc7545212403c9e919679805781a557dff42e5fe42747a1d37daf3d792bfd92d7f18ef3ae9ef6ee957c1aae0f00227a41145ea51a5d46048c12457fa039673e30aa08203237ff18f75f34373cfc56e7f776b828950e4e3d1f8771afcf85282ab1f91d37f5012d27db9852199b384f159e0b28ef66b6bb8a4df32fe7a4eea721dec62add5cd09f7a9bd8aa721b610d579ce947ace3fbd7c71cfa953c2c4ee14b5a261682ae8ae8bc68ea2084986b682c827b154b03cc282d7c523fba96231973bcd8cc66c85aab5168547e856b5ea2ada76132634e3e37873b461c2535bd2e561042122de665aa782a042948b7c4fc8623ed121fa73ad8ade65b3bd91d38d26e50b3a80f9c0ec9d13e3e1fec2303eb43efc5419fe13abdfb580113a40c23662e35163ab31939f00707cc763622c0351b4b3d50d72b37a79b943e293103815bea3b1172c2086e926e8831adb76928e218c8cc2778e5aa351385f348cda1839980b105dd40931b4fbafa6df3cdb0e3dae73ec8fb0dfaacf55ad23eb59d3a61e645fd16bfe9577b9deb773d6b6ff37f3d3ee03955879b2973002ff9b7b92cf756b9ac0a1d78a504e3250f27c73df4e1394ef1f4157e09d59e068851753e36dba4243a2adabb998957bc7c5a45d4885352577fe9971c9f3144796cd126f2819296f0700f7e9b8f38705ddd8077e7386f7da466326166236c273bde37e46d0ecf3e9f72d4d5bbee5c0ea2d219fb635a78405244bd416021185b1988c762e2e74f031f6680f6a84d95a26781711780daf2551e6392e52914b50fc9d6afb2bbb88fba1971ba54858ba90a504c322cac42170af01efa270551c7e3013ae6272ed0357d990771c29dede72a3ec4ab5c9f86071f7e2b42af397cae94e5b7fcc4b7e245bafab9f6f779dd27eae0d027fbc68d28375cddff3bd0f6f170a25165caf69fd36b5e15a718f262fe8c76caf4050fe0da2fa142ecfaeea1cfb4740c2daf379458131d33eb35fedb3b48a5baf8de7edc8693e230d67eee1a390fa393beec95758b50aefcc52f0549349bf6724a4c659baa328fed1a2365a8325bda18ca290638c3563b0d88187bacad5c49a733b3f1e7017e8e72a398d9c88abaf58edade8e51b9a156d6cee05347645d796aaa21e878734be4e7f5317f1c537fb5dba3c9575ecc0bd62db1a0c243a44cc3f76bf52deff00d7cfd361316edc508bc7effde7f3bf33c27dd92ebd657a8943c68935d0cf08a4858782ae69ea22bb102340a324c4d00534d4cd3828f62555122b5c18102586c656d6c4ae40790d2b1b30cd872e5325973452e39407112d08a5aa023321b05e5d0a64c641416eddcbce9faee2286561113f278ee07279f213af2c7fee77a15ad14e577fbe27e731bdff230d6fe3e5bf3906f0edc25d7e260fc6641c70ef0c71822d2da3810cba93ae879c873d20d7bc2da0766a29d1fdeab73a60c02201e10a30c2dd62a52709fb2dd36b06046c7a2f50bc71063a79b977c1bf9bf00218eed95d9005b72e0328cc4d85911725b9ee3d4766462d382fb60fd916bea0b67fb49cb022d3943abe3fdfdaaa1fbb7d885277774d006b976af1c7b0019d0a7a123d3909e7436fe8ca5bad1de3937f6612f1df5b140337fc7e5bc8f0fafde5b849b81742cb7043caef0d2a74e8803f138b3bc2d1b0b635ee001b2860a21d91a8d8698590e7081b9c5d2d1bc82e75c9dac583934234a0b44322dc8492f288c0213d6a24fd54443b307c033d7d461448621aa9c737beb5b7d80b88ade6c463039c76fbd4dd4a67eed7b1c9de5793968029cfc972c2df5532ef5a499b238a3fb55d28cbff37f3883cd1ba6263ac30d8da438600c87ab989157dea237dc8eb7b9b6df32b18645141e35ccfe8ca530b5693eb9c5bedbf2434ff1de2779f95b79fdfeebb808a22e5630e401d1128be6d4a6eb886047109d10bbe84955285c696d3fe7b14b7ef5a2206dac391583f52cad107e505a8b9a6242ab8cc5258a88edb648699791ac195669e1915a9dc12c7643acc639b584447faecb5f31dfd312ad135597dca232fd2617814603700b5ff0fcd8efd741cf136bb8e10c4b1ede37a7712ff79d03fc3c1b0d37d86f3c517aaa6fd6415238a3b99545892217895d3ffeadfef1eb6fa87027989e4721fe2eafa81ccec5e2aff38aeb44c559aa3e6df6cf9a942813c71af7b9f7f773a75cd1dfd34ea978a644df0626f5831ecf1eb4e5760a7845b46245157d910638fe233fc16573b74d2d4726e5b7e7fda07d77835cec3a5187bba8dcdfdf4fa7b97a7d7d2dff653b65b8c23df25c861e789179ae59b75e495557159918353bbf88b667f6d777f67f20f63ec689c3eb986b35afbdc7b742a55da4c29efb60c5437919f7fadff700ac134dc8b44459aa92661feb1dfb4bbf3ecfb5dc38c7fb3bed026ba9ba218eb0a5335cf0c738c8182b71ff00d096b05a21c4edb925b6b1d214d84cbb84e2c60df7f7ba025c53a7bee93c3289460240ecdb527761d4ba85b9f325b69125732e6bec8f9a01b1e57206b9f18f704f9f7b0f2f59d34ef82f5c8edfd8e71b619f12db01affc90fbf8eefdeb8336f7b55abef51695f8c11de37142d1b308eb8d50ea80f46847190d13e66dfdb1517289d731c822ae8938f61b9906907a2a684928c6f1a891818d7800e45880429f05b0760b9ec563bc748903038206c8862436c52255e5b9f5fbeefce9116bd7f19b5e887223cd8af6eaf89ec115f7411187dff533b8378aeb4116aba4e1963ce014df8dffa33c0def91c5e97de79aed4ca8991158932d2ad01d2a7081cca84b4a71c703e3799e0b25aaea0e8f1dcda3d12ae9a5c5893ee101ee8251a3fbbdd3f0b1f13055794dd4a84d55b3f5085e321bd6c86fb6b4128f813f94f8b6faa33d6740e5e1e4cd17bf09c7d2d3ff788ea577eb7e466710c924fcbede8016b7a9eba72a6dc40937fbfa77105dcf13c626fd8ce2514471c065a4ce89d345a1416763b9438c4f396ba05b2adba0121b6c0df300f04e506891dedc8a9222aee23b418d3c2986c8ed314205d2e6301dc4c5d336b1331805b4f3caa1c929d54440273ec457e02fcff790befcde77f5a2973db989ab6b7b054e673b74ba44fbce9e1c38526ec02bf461ccbdbfd544ac915346bbb41c76272e16f5ba18cb1d5096ad839268421ad344053836dd36255c2626d8c6da644b54b7f798984515dabaea40431660c4344100712cd4663423fa9a5991c2a09125a41df80519c463a38ac7699f168a8eec4c15c0216e8198cff4bfe6624918dc1cf281977243dc048f01b2a484157fc70bf1e939aeeff50b247a5028436ad3208d28294b355c1df8faa928b2455ab671d45fc403bcdf13150fbedf87b7c92dbde819ee7dd197bf95f6faba9a324803c13013c897a9e2e79912a99c11bb18f0fe5e0f4a8405a88ba812160ee192fbc39095cdd60febe764f1aba7a63085861f3d2015668a8117a0c7998dbd7965e4f3028db125d40770df9131d5ddb111fbc5f0f1dff42e5f9b43065258d9965fc25173133df4d7f10e3683877899a8f81833ec63b4cbb1448ca860e5323da684ec908a0604d40d2d87b3a8f014cacc6dd07bffa687e84aac6bc2649e96075edcfc3b9ebd634cf8f73c7b1fc73c9c8d3ad29cbd9d50f6f1f0699cebf4a5a1d3ccab74cb20cd05c8ecd4f4f488147aeaffda3173a805a6ae73b586d45c0ee6819125bda1711beed2cab9c396a930a60f020bdd21956322eb6e66f36d3cce981b182bac6686573ab348c958dc53cdb744286eabcdba38e8b5bde2acddf3fa7996cc131564c23ae62d8eb9cec947ad88ff4cd7eec39a9df1d78c7aef1f5eb2afdcc5fe77b87fefb3bd9b9f83dff6fef5219f7d259f3d697698b4cfbc12b9a7601ae5d2e34c56d476bb84380f73995162d786a0f75d028cdc0b8ac18c6472061d8507f72b46a9115769eb4b2eb9899782e229b19a492c119f1760e6aafaceebe55a50bcc440425fc5ffa2dfe9f3dafe23ac7dbd4d2a94c7565b276523d3eada1e7a5027ec7b5e22f4b97ef0333bbf1feb60e36306e4debe5fad8b1a3eed683918a49ae13c6802f8397c44d2d5b8aa2f220aab193406f118cf82225b20a5097ca237988a694c0d88a0330d34632d4af99c2c9a59ac029e30e07370afce2c90a3de78760bbae0145ba4425daa898cb06bfae6cffbf50993cda976932756f1d997ffd19d736dcfeaf11940117d87fbf007ca176dd69faf75c3adc9db7a33bc38acf9d8bb128fad6c83624878d176293046b4a41304a482a551a58087a2a42018ad15a2d6cf2ccc3212c0813095d6578015e762c2ed6ced95ed80877216d8f5724e6a361f8b0ed94e8c95da608b5f6a6235534f950a51dd6d5082331c3257d562d52bb17dc7f909b19e5a5fd6fe3c7f4b9edec21fd8ef89435dfa98b73daed9a1ef20744f1c7213edca9c9f13db70e3a9b0f703a9e35113a42a58a5219d7855468842012b3166633a12146e48efb0a8173b412126fe7a3067d243047214d230b68d42e4980763cc8280e6a894eb98494e8151f98be1c697d04dc7e25cbcf6ddbdffba1f5feddbf86675f89fac7d1d75a0e3e1d1ae7f8b51bc1106ee8c8ef0cb59fdf43c3fd2087c4684e6c2d257fe586409e36caa99c0b74493a870edb2b42324b37ce97411192a49f8b4f32bc3495933884d67e9fbc3b52fd1da653a4aa1a92096b12874b4a0a02450872166b2494a1c2308a72e7426739b0ebed107faafecec26666fbee21fce717fe4dcfceb1a4c1333bd7ef1078febf7faba39e280aff3e9e7a49e5009616ccb96982da59650666432708111898087aee60c90095451642a0154a5d670cb35434b14610680e2074d9aa99cec7ce86cc5a8d10305159ef24b13015eb231da51952ba86c42af70f2943ded28b9291eebe8d3fb40ce6d234bde9d9bf018af6a7f99d37dbefe7cefd743f617f0b975d39cdce25ceff7607dc2d3bc1b5f39d455d175e7d80a02b90924e5a974461ea12e9390b85a269934355e0214284e854a3d0c4af0e0039c730d3d7006dd54c3de14d0470cf90e6ba84364b86456b66456aaf245d30a7339104cc60fc0a073ab31a98a2a9f66aeb8105b9c7cb1c7ff2cb776e85749c2ab798ddb29e5551cd28e57c21025d052131633c61bac444a5c529396bb01ff133ffa2536a7848a080f3c3afbb86b1785ce779884f6843bfb5bdbb389420cd212aea70c6d93d0c8d2f270879c7bbfd9fb96d7cd1dead0e297262c4c7d5b6a49e578a966a851c57d66166d54195ef4d773372c3803db0b34567737399bafe3edfdad83ad68127570da57d7f5b7a3c5f0390d712c8aba88fb7bddad0c96145ee711397103392581b409ad0d5f19c6b42ab673eab582511795704b178d331f8bcc652d631229ccae55cc9e765cde2bf382282ec12655db152d8793584e54aab6dbf915b8e8d882bdcff45e58709d4094a7a5dc1deddf4ffa76d0f2807fb360f7864f3b8793c332aa68f5fe33e8cb677eaf29f4aa01fa857b0ad44929df722a47adb5cf39b90316f888a3239bb4a4cdfc4da7a09d7ef4d7cfd41bc9067567724f1add1db4486cb789d4e1fa58cb397dfe730d787fcead2188d4a7b77cd6b9cf1cee4fde478ccb0f9c5b9ffba02afaffb0f776ed89f26cdbf00f7a5708c86ce3e2a004a4124bc807640d88771102a54a15f8f5efe6473b6dedb4b5e379ded7f33cd7d24cad35981c39be8f7ddf9d70411f530337a252a7fef5439f4af7019ef22ae16f7b909f6d63fb74a70e38a9bfefc055e2e2c53bd8715fc6f2dac73dc733db66879edff12675f63eacd2c55b997877267dbcf74d8a54ef3682a3234ed61103ecf08ce9de2e5de63b3cffdd699f5efeae14dc039ff1bcfbfdfe6ce3bfd65bc2612b79e4783fadab9deed745be442bf86e9d54f15e976b98ef0075461d8dee3454371655f91cbbd624aec50f113583207287b4ae0ba9d90a67ec25431e70f60b50439138ca61ca948e144e7cbb31316d2d9fe743a0a91295d84b1ce9311747efc50499eba95887dad3f7c7c7eff68a3fefb6387e3f7ff2ebe7710fb3bbff717777074e9de94e3bcc9487d67d1c093573ecbbd4191bf308a9fd671cbe37f41476c6c3ccf5f671b2ca8cc399dc493d57e9ca0299ceca230f9f7d470ebea5f990f5964a6bd164d5f8f1c0113019dd855170e0e0cb2ab6b7ededd1f70dee967c0c662edb09c3cb85430fdc7c4fcf991ab33b7498b3b71f6793fc8f9809b252075f29e5ac4cb8fd7cc6498406c9d9301f3213f5e5f5b85b9ef3ec073cfcee8a77e1805b21aa2effc27db8ce5ca4038739179bf878275eac7ff93ca47470c8089a62d0f4096da2948b05d6c526d5ee4648efb88ce2ddf571d42ecd133febe9f39a830ebe96b3fafb1ed8f694a71a0e75850b6a83c7dc317213608d6e807820116e0322109fce8c54b3355c7a0ea69d13802641d0d7b80b15d6c67160c4fac2c5f4466f56be21d673e099316d233ab50266b72633704b2042be335bc71c3366333daefd8eda2c0fa7dedff7123cfb8be79cab2ffb453ed87b302fb26bf47a3ef92b7b797ffa7f8bc29171293f78a64310535ccd81950828eaacec28516a466bbce38edd25cc6b421de5827b4d08ec2e289b328370c3b4bb3eb5912ea21c0b780750841ea92dcc709078595b40b8701568e52e63b923ca719e6979b9a4a68ddfe5077ffffefc6196fb95af76f05b7ef7455d961ffae83cdff5f53e9eef3bf301bf13df1a0864aeb5cd6a3c1ce235677cecbf3a7f9efd795fd2937fe4f5e10d4f6a59725b6968fa6b44a86a82084ef9146f196d0701688f236861a3197c65ed0e337e0c8ab86ada1bd040a6b1820d9888522c983bd324050b5e81dc7798899c18a48ef4b3aa9df80e8c7d08517addbec0d7b6e5d9f7ff7b2e918b738bd578f7354e00fb0a390f739bb987fcd1636a58cfdca697d8b5b80a76892b486ae498bb8cc4fa6860555e255c1bf9407968b5d1ae784e795cedf55a7ccefbf6951addd3de1e6397d35eef7db2bfab09dc5cae1ffa94c34d12355fec1ff3af94e3dafb35204f1df5e3550fd9f9f39c72ca97e90054b1241b989f0d2892366a322d8fb2a9227e29d992e465c6db1dd64b2d50822c0be4c6116c30116a59b3953fa59d5f32b2ac71cc22c982424c51a9e6b1826b4ebc20ad66db94061a036a9b9428943a32c82533beff3057c0eb3d3cc58d9fce5b5da1be73b6ee31e7f4e29c4156ed4e735697d9f0056349a0893084b024b55731d772c570b7f6a95a843c337d6da62f4bba8b598e5829d6728011aea54e064c52d89812503da65d8de8b8f26db89b03ab8e758fc801fba4ce75c2644c3803c290280077bbe0921ac13f365bfdc48302f27d3c273e9dbf0f8e71ce5fdfcdb375f77af989aba58d2334245c3e1e3094c28bf8a73dca81b69cb284f3bbd15c83317105a311eac32836b2c19b62eddb75f06fcebd3c7fd726add14e70f405beefec1ab9ece7fd4cb83964cefe19f6f7e5fc790e3d0c17f7a3db4666b39970eebaa5dd7a019774c910c3baf44974b75dbad2e6355a93023231154a00254881a0805e846083a86d420c19c5abf65e1a654f209bde68dee6062093c0dc2295692c57e38725bfdb6611d342f009a7e47f16f6e2efbdffb4a673a8e10d57bc53cd31a67cf9b3d61de2d5fea2dc962622d5115738cc68fcc4b04150a87542728729692dc8af9e5116fa355c2f1d5006043f12275e4bbdb925368c8491ff08804c488946998dbb05053a26394a791e917ab60e496ef89ab74053c597535fe744c4d7c5c6c24a54ea716ffbb36abc1391a73df959c7bcb87d9e1faed830e770b5b73d31472f72e8f6685efc6ad38a8de4e4759ee7ff46dcda54f71e0e7a81b76af935f9bda64d38ce57ee7db5d7cfd11eeb0e97d97552330b33c4086028ab3a8fdbe32ab4db1f782a5619b4806f6021a76824ab6621a0e7d1b075040b76a96dae90bd193130337c1be5d8cdef25356bc9fc9edbd91aebcd7a4981418c6620054b12037b2917f7ff889f762e2f17d81df37fc9b69befd9f6c7efdaf6233ea2a0731d8dd2e80e2c39dc8610dd3288ccac44a6d0948d2bb4bd01fbefe409bf3491efd81aad3014acdc22bbad33ce7e484d68e100cdac400c1572c479de850a6d02865abfb6e689ddf1a5b21efcaaeb91e35d303ffb79be5838acda9ff73cb2fad4b05456e346bcc4c47e6b07f67f13f96dccbdbd7dcf6323f8fd5e72f7e84fc0a388f2f7b0333ec43d7ef3dedfb6ea30effcb2c6f77f3d46f2365dedf7306853470dd2616f7365eff86657c9fb9ead7bd477a3bd8dd1e6bcdbc73f2a5d9decf6653529d3a779c8a37294f5e33075d044969849ad8da90ed644c348b8775a08100823b14935f44899baf1cbae0c4a6fea7338708267d211f7dc95ca072c4a74d38f796b31d8d869e5fd48dca00f7963f89ad6e1083a7fd15b6a1efb36ac9fff33b1968bc9c8fc869e7b8cf52ff47b5f25a77058eba0cfd20a1dfbbd2fc3068eb08bf26c8a22a6e52c03de6da6c5665a8a292a32e0833c5fd02f73027dee03d5b28f236b77b489b34beb53dbccc54daa9bb974c69fe5e477f3a2bc464efed59a873b6158dafe1ce3086fb395765ae7a25e6b03416fc3097302ddbccf087ea075ce19b3e6d881a1343c4e548eb208b999ae2254c21b39e0381cf2fb34c2ad4f2c23182c3383cd84b81908a9da2da66cc14bd02f88bdce78d0d15ae8989a8618e443a23ce713ecebcbfdd8e8d7298e38611fbd67272a38c809d88848a8b446f7d261c7bce0335774fc56ef1f30ce4e3eee09a3f36d4f80d50bde01e1d036755fd8a9d5795fc7b1d7001489c38aa4ff10d7c9480daf9c477bd9fcf5f233afc4077177793ecb102aabba6dcc833673bdad3cf6487cde43758e8bf6bdbcd61fd73fc4717b5db64975581efd06ac62031fb0094feb5fe40fc754dd0ac336b82337c2692764aa8a6cca1e12cddea65c2c828835c9602d782d784cbd4d6637f714046b51b15d4690c1296c5300c3cc6e1e4499e9012b8134244d35b965cc1a50c502eaca4a54775d46f0e38df69e3ffc29ae3190ceb888b9f9f8bbd7f51d9cb6fdf9bfc1e039c66bb38b65209b80fd7a85e0478ef12ff9017f9fa3d91d78cd2ba44e3ce67bdbf2f6b553dc73597e3a1bb281bbf92d2ff08fcc0d3ac171c259f3435679872b5b9791c0f100750958eedb9b5d50612d644d4d29b0c2eade0cb9a7e2f26e1d566d1d82a658f0bb7550fc02d46e67c41ed3748af3a4ccbaa0028b4c8924bd84c3facbf9cc0b67090d2b8ff536173a3de2dc7e8ef170151cb0cc8145a21f66d58fd8a88799c137af91f850dbbc2cc7b619e20ab77e35ea5184d7cb282f1285e6cb720696d37c2d9418a53628858156d49dedb0de26b1216799d6ede2cad663cd7bc828d27cda6e620ddd871ad39776eec5004f7c2a38899891eaea8117337de9b011a2e0aa5892421f3fe550ccf7f1f75edc0bbebff37727fcfcd16b9cf2739cbf27ffac7de6ab54c73aee7b187fcf781f136f890e33a27f5febbc947bea4c1ece7b7e5ed4e43ff2654f38ac7f5f233fedcbcff6f7ff35fd1bdc222b7f5034a820a5bae0a85693ac823b46eecc6ccaaa50676b4cbc76ae99465ae26dac8d7956338c95dfcd0da10897e5b26641ac9bb784f81a21622a8d3c5a38cd6cae7723cc6d9095de163b8c498382d0cee905fed5fb7d9baf65e2501f7dc666b91cc77e17f376fb257c32f2f7be42e6c075daefcfccca13fde7131ef7855ccdf89ed8b311754b6da99a4210362057950b96ff480dab9340e87343b9a4cab94fbdcdc236694a51e7934cf7b55c85c36c8d23c9991baf5387b982ee3a5fc38fc9d43344e575a9213985f934a43f77cb026b315387dcfd97f632f2545a07edd36bff12eedbd9ba271dde0b6e6a737ebac7df9b1b7329f12003de8eb27834d77fae83281bf1086a42350975c4822a9970deae128ee1826f40565b9bb99e4f7d4368a19d4f44295bbf54554244c740bc8ef5b18df5b667b44d822887bed66de594ad630385a973b7be6e1e1de5a9d30d49845576ed7e910bf3d24f7c88590ff2786fdf5da6fd5bb385efaf7dbc87070ee7539e2ed53b208f3edb6538f934de4986f2d0363951bfd60b870d289a99ccb5f2b4cab518dc751f627dfe9b587e4fdf59679f718a1d7a76af733ff1fda10ef072cf75661e785f2ecd23f3f143cad9c27761796394bba4463f7084b79c04a3acb00211d940b81261de7aa98d6e251118f158f37957250632b8cbe612aa3e71e496b9969fd6ca8bb5bcf50bcc12178e6e064633aef5213789d4ba7b4cc4057ed53fc6657adcc3e8375fcc677a15fd7d9ef3d59a279dbabf477b7dfb3c877b61cfbd4b7570cba61e8ccbbc0fa939118522b490536c335feaddcdc28690549b81f2914174b50e07fc8895b22441b7d2a1fd8dd608a2849e189685196cfd7e4c896dc2b014f6dcc893b06a7e2ca3bcf6b576c2b4f18fbfe6323bc9ebf33cc6bfc04d75dae72346fbef7d3ffefc1d6e2a2eed509f8d62d620ec307b6ee08419be49a7f13a23d6cd820223d1f106d53962454e93ca74e91475a11237fe54ac840dea44f726a9ddb185ad4a518e873042ceb2f0266c803d5182fa2007a4649b85db044124fe13f87f7709474fd8349fcf66aeae801df50aefe6a0eb5efcac1d717a2ebb2f9d6f6bdb056749e8366d565896e45dbc6496412a91243536f86a1c06aad9c4e568080734c591c7b36a037c18f40143222472b2e4748723a1124d085f53814f4dcd2ff14c12ab1761cb7dd5ccc2c84289c1a27f86ebf7350ec19767a09ee2c3177b2f74a5252e5b9d66994e5801e33eebc70fa96e0eb19e6f126eae45e46997cb8bf9592ca01ffcf5ebe0143d9e628126ad7eb66835eafcf0426c228e7beae22ed15b220a0b88faae173a54314134ab9593506f266cd313309f8b82f9a4b0ee99ad8d7c85e290e0112b952e886710572ec450f68240c4a6a2f5f5c6a25a079012b748672e27f13ae5c01591fa0ebec5810be0c0a5ecc0424e5efba1eff106cc23948bea350fd2cbd9c0738e34b189233c4877f692a3b83b9bc9ac8f7b9d19b89c474865953af61e46def07b4ef36d6e70ff7710241cade75c1cfa15e50480bddcc73adc3d9df929df7196dbcff4f163c2fd36aec6db347c59cb9d5d36af787cf6df3dffdf8875f7f23d8f902626601091d7c4bc6b967bf9fed2dcde35ecda5ee6c1209da0cd74d627a77ed0ac3e60ed7df07c4ff36f17e94e98b13b2d73a54d5d4ff3350088062d463dc488459381ade96a2c620d21c4c582daec87d0d0ad5f373788e6159f5a7a5ca9d982e6abb0929bb4568a4668b12062beaccc5c1081981668c8b092a060b954b8ff2a0fd9194fcbbf50a778bde641efbcac0f7dab1e21abb6c0d0eaa96ab63e830971bc47c43c1f036b27fa7194528551c1ba14c82871901beaf1362e98ca9c6e9de8b0e753ab5d44f7a3ccb5a671146829ef6e33c606665826a99910dacf8129cfcc949a51a38911ff07f2d4dfac3bedf7f390439d80832ffdf9ccd955f85c775975d4b773beb789bf0ef7e6cd6bdfc0561584124b472aef92d27bf4ed7c3107cc120e9ea4435ef3c2bbf910dbe07bfedcc5f639ab98261df539dfe4b5f09f5d4f491737a739b317ebef7db98b73ad6beee25be4fa3be2de6f31ccb621bd3729c75162c30af5e345caac88b27c8debd9365b8da304cc06592bef66b0f485035b66e351c221a65af7231bf2455075a67484cfc0dd16190c330a3c36c40632941fea3bedef73ad562f22ac25fc250e3478b10f7f3f9372c4a61f756ff9c92e9307b039ec7b346b13876d32e70b362dbc52acf65b46dad439dcaf7ece7395bad6b35dfbf8392fe5523fc6d171b9e963f0cb4c6b2fa700315ca885af728345b21375b309a8d8106a0ace776baae7700ee27538cdf345c416e964bc65119cf851d663ba03c86eee7d7bbc59328f88691e0a254558a0220582208843027ef5d7ed8b10796604ad705425562f7bd6fee8135d90973ccb6f7e25c63fc8f93204abe553aef4a3383f1ce957941d73ce3d53ee9f631febbf7d8dd0cb7129a970e4f06b5830dc66a5d7e172334ab9bd45dad8f70d642f5763be8c7029eda6f7a78136079085359ef9ae9c2f78b75af0c6cf88d2c25a794bc80c09e14de8ca3c2bbc4916e12620b809802452ff698665b75e96e21c97f27b75e2ff484e82ccf5b6b1ce86ac3ff66c1e6301d80be34b984f7fdf976b587daa239519feb18fdd5145d2833cabe493ccfce9f94ebec0657e9daf8f01a3e31de5b9260c6f4574bb43dabd7163b011017817322c980e5d3acdb601cfb7b4f0d741b8d9fa9c9a99def6cb8a6db05e6e05cc7f60a64c597923c93d880b11a58567662e2a98dd36a1d638b81a75f1277eddd76cc1b83e60077ea6f70ffb7185f8ddf5b6472c8d271dffb4be76c2afb9accf8d3a6a26ed6e934e992f1c731e5260f8e4d72e0c37a3a5ddc4b460351b3c2c81140908f484367a4cac157794c6cb369f831c650aad84036adf98f5dc31f384e31f0b0641ca831d53564e222f49edd864851a82332c924bea0ec137fc65a4651553f3da5369547e652e6174857bb3f7a19508cd5e70601eefcaabe738f5e7dc5d363f3a489bd77244391885ba097c1d8688043d0bdb78610b33b3cd1f71256e6e341f7008ed644080e94db47446ba4f68175385b081ef19502187b8635308111fdfc82a5ba74e93c7c4bb0dab72cd2aa107da182f3ee9cff9cafd901c7c16a30cd78a51f66b1df79ab5d9e4520c92837fe34bd09837c6af816a62f099654a27d8264a15728a8dcc8db505cd1b4e5127a62a4c1d1f7025ca64b0f8cd908b651deb899a81a0ead63ec061ca2cdfe7424385a24bf86b17529060ed7ecd80e530e24d70951bd7f56f0e71e156acc041fe62aebd9c1338eb894975b310bf7343c3c59c6b8605d25a154f7ed0a7d82757a8e9496e9ab1beb7e3875cc2f3fa272c940b6743f23003de8370e27552b0369db4e67c106ea8e501afbc1eaf7e8eb2a927846eef426569c285346465cf1d0a523dbfa17660663ab4c3b2f1a92b768bb05d50cddb654ae8221225878d1957e6835f217d618fa1985ae7b321ff5c5f1bc81cfbdff213f66b1dec918cacfc701697f2dcf11c86e5dd2e1bf280db9d98eba8e4ce9d8e6abcc00cba6985edac547352c34530b0511a7966061ad3d74b100c688bf9d84f2bdbe014dec63c582383767e41d7cbf2ae0b6d33661cb898b77de2cc8678f07856bdcb93f6fdbeb50815f181db586ee328f88df1747dfeac2f9c3dfc0c8b489f17e5357077bb634e0f0e73123f2ec2917659bc60778926bad061eb00608474f4c3775999ea40303e1644c987a062abd0d1b628923f58388eb3c89bd0d25b309d15128a990fa197d0d19a94ace085654b8782c4153f4257aeb2e26ecd216c85c182c4bed7998ecf6bea17e01ebcea3df9cf9a49ea24674084a04d38ea5303e799bef9dcd7595d6186d88040444ccdf99193433a70488e32f1ceeb47ecdd0b678a1792c305d56d5d54dd9c4dd94dcc90a0517393ea9b1db29b1fccde758166eb3195f7b260bd28bbc807569d517b4d88374d5c2ba1dcb48221bf5f38a5c64bb10e943fe2531666bcb58332b79031d312873df8dac63cf7515f9d6ffaf27c5fc787fb3dc46676f2599f6a866fecee37667285caaaf1f0327e7ca34beedec8eedd13d7fa712fad7cef0fec6391d775af3fc8a7210dd99bbb38c2bde0e3c753cdb31291b7cd8c17f8946fefc1e48decbfc6932cf6df47f24e3bc4d65fdb93a735df603405af9f2178be2bf26b77e510c756a9e1b57114b4727fff759467ce51ee3fe6317e8b11fa3dbdf9d1331c7cd88835b1be69c511bf449b47ecf1c9c6880357f7a5b11e4031dd6d5303defb53af4d6cb6455c0361e1f5d2409c4c674318653db5598e81980910f4b214dac2865666cc76a923744a6d205c2b4e0745a94b77597d6f48882602b240e8ed2ae6da2e598daba4600921b9f9e5ba54f58579f1d535e232af38ec6df55477ba2cfe5a12b4c2baec42fd7ea0d42b9776b7224ebb4d79b74d9c56cf347b24746c258ce114a249589993c4118f379a172c9d4c8b2b5ff7ab60c41c3461830da40e75ec885a44f954e8a888f5f63e068dbe8ca449990ac87531bc4ac1d96eced92bae657f7296533cdaecea68abffe7c88b781e3bfcc6577f398f75de776fe03e897e9d662bc0137ea776ea0bfdff4e79a20b6bd25e713c73b449c237b580afe404fec0f9ff718cfa7616e15bf77ebf5619736f23c2e7186def37bff77a7be089bc70862750a209ddd22076ab987bafa59af998e8c80f57ed8629e4a35aec122a149fc65b31455baadd8d96258a1060233af5b66985ee93bed5992d273e0986a5cb9ca4cc89af63c51cb90ef571cc5dd572179a29579e7817bbe0b338553d26ce012376f8187b196959a51e05189782a3bd1eef5f61719ce3116b09dfb5fbbb9055ec9997fe05a6f5dfd68cee2eee3f3ec81a6eb2fad7a71866d7c131dccb0e2e93c83be6427eafbf97a78b710b630ddc4b228bf990f7c2c9d721cca30c94ebd4407bdd4696c4ba49786b64763e9f0f749d70b0bdd1ba9de07060763c4a0d06b332ef53a8d61204bb9bbe7d4c2a654a8af57890b75895804d11480c912c5cd86275551e8c37bd78a7986c75053c1672f72d1cb4fdb98928dfcdebc35ce6f6e81f9955eac0fa0bb5c3ebd4973f7c86bdefbed75f6c944dcc5d568db5d438f8b48f07fc47e3603b874be5c85fb5d8b77d208612f874bce1bcbb5916c294846e09f18790a30133e4a776576586f262daddc434d37069f759814d3acd915402858a313a1957acf4d6d4b05671e52529f48130d4635cb288386a97701527ecaa72540a2e9ab4a28759dbcc61fda1aefa0af7c27f6b43d5a9ef5fcbaa17fd67e1a83be06671532ddde02a3ac99f8cb47fa1cf719354799e55b30b73111fcad23b38cae7784a9fccd41af32bf080bdc14cd9dbe437e7a73dad7591dcb3d2dbcc75f9282a7483b4b1ca2a340f8842ac824a00390465ee242ad616c41b961400e1a047ca1a5d4ec6b61c72b5acad8268b9e02acfe7dabd89ca9f2359dfadc58047a86022d4f31131a4cdf89deeeb905cd4abf4b9dceff7404b7bb0cb2ad526116e64453f9ce9dfcbdbd3ac79bcb7dd93d7d830ef60cebcec9d3ceb633c608c47c84cb9b77d8527f0ce5cf7619e46879bd30cf4cbe7ecdf7bef510fdebdcc919fcf8a3fe349a9c7ccb0d44b3c9dc53b73a6e738585ff8ec0a0e99aeeaf415afc4d95eed65b349abecf138ef3f3ef6e5d7b84f385069157cb8374f3dad6f74fedebfdafbc0f93ea67ef5f7ff97e3957d6c03cf71a95fcbcbbf816da68643efb2ce467b3feec5fadfc234f3c316271a2b968ef2537b66b09299b8c66650652672e86e618fadcc101dd2040b2a696510777323eb971c4c89abe661256dea22332e3d4894d00222e300402834162fed364875d3bdd181ce99374a26633fbcae1efa109bea6f7b77fec3f1a6f6364b2ddd5fafef7d25363197c33b33e1ef60787eea578eaee157bea32b5f61b4fe7e1ead3bf6be5ec6a5481cac613a9ef8c4ee45390e65a47641a436f381ee98f278483d4f408109408c518943b7b9416e3ea1bad7c8e95db7545e9ed5f70606f83ed198c3ebb2a315523cf222ce51106b9e432134425759f100ebf33cf01f6bb3ff31fa2cfbecacfb2367d1b562886cf2225e700f31e6c5b823bc1c7bcb2a182d9918288316d2ef475843248596cb5d5923665529b5bb34f23adf6e02e4986ee2dc01647779a88d86a583f3241ceb2164b6249996d9adc18afc76e9224598afa388f6a4546d6a201c0364fbf01fc751fe8764039899819b236fcfa5b5fa8f70333ec178bc06eff59fd73fe5bf9ee40ce4f230ff89b789ce8e988f97f621b25feb14ca1fd4f506a18bc50d6030b331f1011d050cce453f66896a6254014cb50608d63cf81a9bdf18628119da66d42399ed313c45751a51ed80b7668f8744e55152c69dcf310e01eb0407956f08951178c1dce1e7b5e4633efcd9771dfd7dae223eab437fd1ee3c9dc9494e3fe6e138eb31f95b3979c26b3f7b4d03c779a98b7add46314782c39c86c4b2120075a43c8be80df40d711b5315f3aaa58b486e91dddde2ca9b8440614cd9635a8245505bf38c639695a54e07bc60536b4e6db59d03c965790fa44db77cca7cbc1a53ca58e53b6c7dd5de9ea79cf709ab6af1f73ccd97ceb5f6821ffbcc650537ff12d6d5ab354ff9ccc3bdcf6a91a79313d6e5057c1c8478b3ac6f1f961c189cb636d1ec814614b0321b211a74481b17b74f39994ff46916b126ab682b6a6f9b1ef3f6eff889eff6dc5c61e6f78feb1ff569044112796ace459feadaf34ce3a937e732ce289657be6346828830d3d98f840a24c3d6caa66a9570c5e20aec52d7d6e9506eb3c9c69083141cfeda86a5374b5c8f611bb3c495f98d212c522b10d7ac13aa89982b140b7f6e31541c1bc8c6830c436db795e525b8edff346ec5d3d97c8e17ea93ab60f03fffcd49de8fbe59f8947fbaccb74ab8bf465a2312168f5855f6cba8c1581311d1db869701e085fa81b49f3daff276c17214333c12760397769b67ba52b844fd8da162be1a4729cb87586f67096d373ef1f2acb04ca4f286db78e4eb9a46cbfcd18fae1af79de14f3cd572fe837b717e9fdff1ee7dee5f5d0367f6b79c9ef4c1d16ebe7eedd4377059dcb58b5763c4398833035b89a1065a8ad1c2b51a52969db4a54314f470690fb26aa1afc90ed90c040496b81075e8fedade18a2e6351c024ddec491a52f49bef081bd46ce4f03d752cf221684157ae4850c79546aff0416c0a53c53879efa43ee9b6d12de7e0d53eaefb14ff67f73f0f705ef9ae4881bfcf6b5134ed0eceb7396bc15b19e19cb1a3f84b6480243d431b39c98a04d66672671c6eaeb73965fe0b874c68688bc228e903acb837ec70f8d1048f9a71c7fbb2bf5913faff7a47f2507ea88237c19a7e5c2610f3e548a5249503956c2b0478b299a6614346c6acd7801d757d4955ae27a5bc9e511d3b41e1d6645bf21f79fd55c76e7bcd3dfdde7e024df417bf049be2ed3479e0662ad7ca0221af9062d50b220b6c180879704ce42db3682ca36f034bf97aaa991621071e02f797bb3849063e23d486279dcf1dcd481330aad4d02ca35d34686d4447063484658de06a5b07c0772540bf10e87e23fa97fb4e420775f992bba4a3ee7b4ded16e4847b5229a5d3ad37d389750eb624eee00d35b98118ffb953717d1dd96d8e35b9f898643f1e897adcb39d5285466a6c19273fc90465ecea96219106beed21119709e869bd1cdc0585cc11cebbb2ee3f91639b00b280c42dbc4c89624ae0e3ec7977c3919a146d45f98039a8cb46bd8e4d37a27396743c28579e211bcac579a51332def460bc71e44e56f056fa7b8801b7f3266740abdd4408da4ea61c9f03dd2f3895439273417028842945297d33b1381bc96fcbe6774ec638779887aae5f69c6dc60c692439fa9401795a70586a4cba839f7c13fc837247cfc70cccbcffebf5b62bf8bc17a0d1eb9ac1265fcaff549ecd73adc874a38dfeb7b6085779f1aa25c966245f4d240fd388a7993530dc4c9e0dd12475b2f6dd3130c9684021014b289f57b23ae36fab22a7b5ce42ed6e028e1b2484bec6476338b4bd32415aa97b4b113f66bbd70ccdb4c9520068d9b95f657ef42b3bf6fe233fdd21f3163fe7e2f559b55b03adad4d3ff897f792c4a9b24d11ac4abd6c29a7028fcd5f308c65ce5415c820da15e9d19f90f4c728fb8be96dac0e3939f7d3a58fe82b1891cd4ed1c94433a0803d7d936214a1007ee62c06e9821bbb82a8744c7a390596530c43db3af3c27a277dbf8a9cedb1ffb462eec7dfc7d6ec7f73c26f51f3fe38ab96735c41c1617f75ad6ecf110bf5570933aec0b79a3d9557c38c9476de6c03ee6dd46f0dd41ffbe79edd4037c218727df69ac56092dee7402efb7a98d475ce110554d47a6b9854bdad3c1f270d9213a9de901f71e32ade301c5a3d0c1f7c16a5cf8b6649976b75e12df645c4c1382ca657d3f227a8725b3dab4823744035b6ce738282fa855bcecf5819baff6e53f9df9d766033e889745c5fad4402ff0a1decae3c7f3129903b5ac627b59d89c3def3bbd4ad290c6fcf76cc35166ff7656a242fbef0352f79843f8da9e3cad79d2754f9cd193d7cff0fc9da07661eef7bd599ae71a78ff06bfe20bbaff887316d7ac125fe24e9f5d853b3de642cdb90744f58c21feea39e6841e7a8a2ee3b3f7763e405b7f2ae7b18edb94b62bbc8f6fa939a20cdd64855c612008ab36800e0a66043a3786b58b95b745c3af35e72cc76ebe9603b3c5345f507bb4c65aa0c755f3c8b9d6b39a0592a2388d2cc023d106203f9f21fbefbdfb3fe5de7df96e9c7a6d3ebb1bd7c2d73ade8d53bf8fffe26e3c3dc7296f7f611dd4ca19434e06584e4a1384865c07957a48b57dec04e768355684089e449ebe645694c27b2328215e126cdfe8f95456775a50884d48b375aaac32713c47946a45276dcd6c39890dafccb471ce227f87576d1294e3f7308b3fcb5bece3ffd3acc9af63adf9b2fcd020380259f5c4dff18413fc69dcfc9667e87b7eadce0a79a8b33443aa1ffd8bec98b7fbc37369fd11c7e2a21c2c46ec7ebb20f2312ec70b14055b32190fe154b49c7830e6a84a9470a5e14d63801a448321ae714806cfe545be13059cfb8c2d10b837c329bb4144de274a305fc11f4b77d62ded9f6b5c8149628f75ccdb1f8106da2fcf6e9d38103eb927c6211775051b72e2bb38edefe1ff2deaf77119bdc88fa3ce5861ad11c9349f85039e30fbe736268a8a42247840bae03fb7019109ab91c814b250793f4aebd24cabd910149067b5b59674b45e16ea1613668892826c2a66c8ee8a04aa24d3599d3058c765632f084ede9f6bf86c4ea6eb65088a98a3fb279c867770a6aeca5df1bdfe02fb1b77f67876cf585c9ff62c5d018bf2e93b73dc882a7e2543c7e7d04ed8f39761a2f1a9e52d27e36958a1d992ce46f180cdc4b0665853962c3b9318f236d53d8d843f4762d252ca5b4b4cefbab9eec1a49241e87a555cd99acfc44e44a8477a13cf8d60c4f8dd9a1608f2a95201f3415cd175a2a0b82a57c339d7cdf0bfc275f3e66cdeb1cbbf9ff3637ea6ebe47e9e9ea7d77eff9f1c79742ec3b5980d0b862731c344a8585f52af8f238b2da66a87b8980bde42bfd2b6a4968fd8191704885e32e8d0c1deca8a21a1e31f9259455a8e913f60844a642c61364acabb6deae63026ac0faab12d18332461b310e20b6ae75e73c67775c00efeadd38fef79be276f730d5ff1a74ee70606e98cfb4fedf2e4cae717212d353cf5ea1c9f5e23bf2e3f4f860b5e0b9750602e22b1153673a881943f581ba6abc744bf5f8795bc0d6a11a4456ed05269198421d5a19938fe1ab968c0ae3ff8030389dead452d30a54d4d26e348566046a078405015b2f00604e09452507f9107671051d0c6fa789be84a3dd5ccbf503fd0e6c5dd35f65b9b73b44df5b611e1c9d779b2d3ef3ed7d10f5a5ce6072901bdd9c2019350631151c26325980bde2cd29add2c9d4e654cc139688870105d4cc60bc13573ae833635d0c827de2e3670b9985a835f8e4d7f6acd896a7e64d5b826ac2188835cd24d3f37544ba67025ab4effba1f94abb8828fa23fce38c7dcfc0c4be06ab143e2b055cccdfab0ff1ce46975a8abbdf7fab7ea3989968fb2c2fbc16b4b4807b75939ea328a1fb2da8be7e0becbd4ac4bb46c84ddbbb5d0db5d384017392c4e231167866c638d7609c451a0a46051b3c92a28e4606f97acd921a50086a58180d264e52d7c07b7f8123ef4cfe38bdffb708aaf7e63aebfa93ffc3b7d74ef3ecfbf808f76b6ee51273ecbed71cee05bb8699a71d3b725ae722d36ee067fa083a45e9e91dcc670a6919a8d828a6941dd4c116830d1f39641e8a5650ec554aca8e1c5c2517019355359663b04ee3504991076471228d992e51aa2da76c9f31f0b87ad637dd65dd09bff0ffa2caa4e2bb89973364a0e31ecc7f3dd67f36ddfe3e06b846ee6e904a8a5a3b4e319be7a8ef658b3f12fab53297683a6ca09869cf9743c92a0f197b65a31887bec0a3fade22d52d816469ec4da66248d3c5cb8cde01334cadc3b63e9782e2aac47617b9bc4367b5c953da60060e56d05c5dbb0fc694803df53adebd0d483c92779edafdca3d48143f2f9bcc375eae37a9767fadd41af1ed7fd16be60bd6076973850c57539a0724ca8818db8c08fd2462ed6641e1a28670a3d50128f44e98d52000b19e10de282f891009cd8a3708a0c6a0443520a13d7b84f8cbb7568dcef5801ddc59459c80666c0b14d78d9d3ff887bd235b14ef7367148fe2d2ea3576b1ef2699b842335e7f031d3cbf6b4ce65fcb8144c0917f79cfcd27c07f11006da012faa14a630a088150bb06ae6a13dae91b6317c1d680cca1b5acd4699ab025f173f4481bda513006a3425a60d46250819cfb64cf31e89d68d849e27d26ee732f220b92e16429ed6a8d9fbbecbc3fd799e357d8f0f253fce5fefdeccc8cedeadeb2791df8a9a6d525736c2c5f7f30356076d3367dca4cf73a5fe95b0f0ec3f7fc6dfcdba17890337c941afa84284e0b05fb7cf35d0d9f8d5acfec572fffe4ce9c7fbf6a93df9fbbe515d0d732e40ea7446c2b1964cc0114f33b2b67b3df6347bfac1739eeccd65776959ab3625742dc376080c4498a1ec45041731670fac4036aec57da0b5456ab765123522a60d9334b716531412a75921dd2492ca47e1e069684bdd77f2f58dd60aa47928e0ddc074364790293108c80a11d37f82c3e3625c46b44d2b55ccb9b7fdbc2fd83ee72eff9ebff072cda3fdd2cd26eec12ad5c7ed9c1cd7b9ac07a30b43e76e1b905ccb606664351d2d78d7a74ecb900d87a5ca359fe39504e88129594b2afb9477234ca4164792a7144f52bbeca8ad7cc2db3888f21be6ca2e71e48039a3a1db3cf883b011456de8489c52f31ce7fd0bfa4e3ae336e17e9be99d12d1afd73da86f710baa2e972ed2b2d5abd9e2fe52df3e3558bfbff329879fe11eef0e985257c889bf5cf3e80f8e4156ed6d1dc8b389765ae7223f852595cc3397b54cef5684e7eba0923fd8548a44f701673963d340c785d584061d514dc619b156b12103c4f18fb97eb7a34ef7802af618d6f06159c024aeed3e9db2288ea0486b8fc7b58c08906849e3011781f14ff47c1ff83d2eef377ebd9fd16fccc18fefebaf47148ebac5b5cff3f7fac7bbfbfeef5a7f3202f3c2362fcb65c96d5a69c6b21c4f43dafc084a89853d5b4b271fa8037bdf6985a4c85b2aa52f6163a4b6972fa6d24cc231124ea323809b6cea154b2656c4b907e9601558590b64339e188c4a7d36600ddb4bc6467e89ddb494579d937cee1b789eb3f8f3fd7e7d275e63df5da8c377d9c1aec57b1dfb953ed26bc47c2fd73cc841e61eceb59aefe5e6d86ff9650e3f3f0413a24312179e48f58e326505c2863ca4582c6be6c486552551f697fca5ef63b77ddcfbe55f25cf719c8393ff231c76f0654ebd2667cf73d8b78bf3f9f99aaabb1123304acac611d3dccf347ce3d70acf0d193123cf53c3829906278cc058542d5ad8f63a297ead1753761350b9cbdca04315ea7d26efc520e621f756c819af191128e33b3d28c70f370603d9646c843a7baffff0d39cd7eb5e9b23d6223af6bb5d2aefc77debc19070d0a40e7cb6179fe1a45e015ffa69a6b1cd74d526bccb8fbee48bf37cf35c279edacb7aabc371371f728c6c6f8360330f98f59014792422cf0bca260a68374f7418d04af4b2ca2b5ce4ebb936eb7dbdd4d2bae953e83df8ab719d0eb05d10cb4b0bf988fb9f03b73189cbf1d69fb43b4944284b44095121d600fe6a4effe9fb4b5d95d2f9029fec35b0677eefed292678b5dfa7d7b4fe1bb5d24762c01922aa1414750b86c2d0e9461981961cee4058991a72333d34841f1a3062955aa36a6c2d58b34e61ee9352dda62eac911df7cbc8a33e053c66f82188a0ce6a598a8a25c8c88c98223d2c034372f9ee0cf66776e56bf1ecfbb1f013dee973aee3458cfdb735d58b67483ec07cfa521feedfcff87c8059758c453ef8fda93ff7b299a0b8606656791b5ff3e29037b338a22675bd35027447952762c084b0479ad4246115ec52cdc374a0bb4043d0d7da89648af9100b5a9a012e518074c853cd447c7a6784764b130723aa8447a7a84e38da84fab5317aaf8733b898bcc019fcfb3ac77f38cee0937e7a8d3378902f7ec23bfe9497ef0a3d261fdcb90357e63e3efbec3d477feee2989cbab9c338a4d2b53a1e212aa8398fa9b895030a91e38dc2a889886eae28b91b10805550ab4d3ae40f61946bb1eecde79abdcd34c011b0d744837c6e8828ed374636cc40668fa14fac3967e82166e8d69fbec3bdf63773110eab126eaa79b4df134b65353ef5ab3ce3e79d6103bec16cfcfd5e923da23fe26afeafcf877f86e3f75f4cccff6262fe1713f3bf98982fbfe7bf8321f7995d3ac71a6cb2e7be814fedeb557a385fc8e85e1fbd58ff840574513ca2753700ae3147a384769ba0901c47ca91ae9a88a1d404f935221a1c646d1b58b189d0e08eb9f6560e9e9952e42f697b23341c64865a05255bb01a5b08e4534a598d593e0a81b54dcb6c9d4642d03abf9f6b9d77d5decdbd9fd48361c9c12ad5bbe1da58f7ff67fb7be7f5b6f7f5d6c7f9bb337df6ad1adb789554ac9013d0a435da1d9ea1d7de7b9ef684c579597f56d995d266b74161777e256e69cdcccc86663af9097c284256aa49c831a7744c18632ea5f98fb0c0a340a1551205233f6ac238f27e204dd2c46921568de933af104cf50ca8823a68829585a5969b01f73ba17d7326f13f4d4e22a4c591f7057fead755ea341fd8aa413ab097aff22c7f7ede6fc5072c1ff16ab4a691a567a5e7f954dcc67aa60b5bed96900502c82975d982bb02e169d6c71c863163581650e129567300cd85536e135b5041ac09e3c04685b59b0368a1cabbf739d4d38805cc118ba4869c01efaab9feffc6072fe5e45cb79d7fd7cfb1cad0dff358bd89077eb66f639583ac1ed6ba284fc8836ab715ba59c5dabd4174d6c75a6b2d28e031673533d024b4c5032b02d3af91492256c6ba89792db4b9868d85c37e640eba0da14ab8636fc3a2d4c990ebcb495b23f74e474ccd1337bf951a66c9341e62e683ebda6536cc23bcddcb6ac241231da5bfe059eddff163f7be5f219dbdce01fb7d293fe4b939d8fd9775eab39cd08778d96fb99eb21e1431ef3647fea1d773c5efbcf7b7bff7e718e67d0ceae3fbdf624dbf7ebfceccd7f9ae3f7ef6631ca121e1f2f1b457dafb9c405fc80bfd796fbe7017ff9fc222ff966efa2f76fe7fb1f3ff4f92d7ffc609ffcfc609bb537ff0bf84d9f96acde77a583639f69e9e6ad95fee4ff043d061ce7018b1218eb23ee1e382396ac509bc49a21c73972dd2e1eee27ae8b196f9c6eef7ff8b35cd3ff1497e8a9377a5facebbeb3fc76ebb272c80581fb77b1f43bafe69eeeacb76a79b33cb21acc192b79ed4c16661e38194ec9e47721b97b9290cab4ebf8cd9f94f6324239039ac8fb9545fe95b5e5ca727eae59ac7bb13592aab60bd3f8f3939ae73590d4dfa34c23ea1688ba99a2387d9b210b7d8c06ba28f098982014fda6d462cd3d7f1b0b401e011b36505172c12804d73854b0f100754b4b01aced48fd0f63b41f2fbcc6da64835c3d2f1009d0a3be47043a8b82ab6d85edef67af0f0fd396b93086b229a7dc8cffa34979954f0895bb33fc76e3fae1fd7acfe3d3bf7de7bde70cb9ecfde1c629dd4f0da39c7b974ecdfbd14fd3b759303f7b12acfe392b3cf6c4584ef531d0f1fc74da049f9ef1ac8597ff55e273ce714e2433fe7d9efffc01d7bdc37ff83bcc2051ca3dfe8597d25fbe779faf7f8653fef25ea47c695f848f3b8ead47cfffb8ae54fd8d4e7af6bc73dbc2c5700e32adf2eec8d96946a15da7094d66c9410b94553ef36534d8d57e384d9669181e6015566181a8aa5bcbd27b6e816369a8511decd7561a22ac7bc6649ca7e6dd30299bc503c506c954df18fe56adcf2697e9f32155c95d7a142dbaca2ad8c70934e40f3cc8b1cbe7b779ab4cad5de56bce64f3e8bff9b4c877d56c1d35e9d6a026fef6b6df5a98e5466f86d7ab8bb074ef23cabe4f01b43f8bdbf3bc70f9bd523f061fcfd96c3b7be90c3b77ea7aef1257f81ed44e4e542678feff9fa990e2b118295e4a23aeaca4f394eaec0ddf006f7ecd0b3ffea395a141e793e2ef1efb11ef48c3593b0c46bee7402697215d67995697434d74d3dd45b8619edf0e08fe2010e091de994fdd263a202365528a5f96461cbc7cc4505d5010a15dae222f789a67a39cd81988c0deae26d52ab01d9997ef349efd315f4d63bbdbcff4e9df1a9161ae958c5fab87cc232387f9eefd41dc1e31ca0fbb416764284133ade8a55424f226f7b03e436a994b3ace37536e488da601654e807ab582014db61bbf1a53ef6d9d4ba9753b841501941895609c9776109754119148eb90e5d152c190ee63af8412b71c97cc5573063fe7cff2ff6e70ff75313d1a77d2dda9530f68f32576395192ffcc6e3cfa7b9d0cbee9d4f3d2bae454f403360cd1e38c35366c055caef3a64ef769cb2ceb7991b5214cf75739256622d94b8490b49b23ac7ac809e6f5888f3862ccbcc5c863f0dae68cf0a5532039a19dff4d41e1b4ba75bf95355caeb721bbfef3bbdc502acdffaf8c799ce832fffbfc34fb53fb75d6a785a76c0dce8b69f6203f567bee33775c30967d0f5f731de2635664f72f4e67934e388677b916ee8321b5952799b45843449c73359b179a68f8cd0318b5079ba2ce8ce8fa01773345f2ab821fdcf3571e5281ecab5efdabdd43a5316d816b5d016d35f5b0cad47bfb63aa2794358613be1e39adb325c84edadac65f8ad1e69070e732e3631cf4eb2105c69bef7d299caa30ff989eed0e745768d1aae76f4a1f7feebc97725f1e301c7f9a25a6ce34aae6908a80695ed2dd1848d49defac56c904e007c1d6ac9d4536999179c7635d1d003366620ad2458385e19521852bed1533ada4ae02159609330af081d734a7573169708268ead65fa7845a33bb064f2aabd9a316ff493ae189dd7c60fb8755b71c048308bf4108fe217f397c13eae3aef1173c6651ca1fb79bdb747e66fbfef50d709ded3472fe7f95fcbe09ffabca2633fffefcf7d8b35fdecafee5e7feeb97efaeeecfa19e6cc176ca43cc69beff485c207f989ce5b4cae8373b93ff3bd9f7af897dc3da24bb14889c478ea6dd0aa9d070af9528fd7480380f371112ba9536595c4a0badf8fb54c798ad91df0cbd6917a5bc7067e947cd6c511dbe2552b7c2645ac6bbb05459410d9c9880db1e1fdc838b0a80efdd0f6b7e180dfc322fd7eff4105073901a5e06c37e7ac93fcc881f79c0b39bb03273c501ddd0b0ef27984fb383a9ccd2b1eab73f9fb8857ee79eee4ac7753465e33e7cdf04ab6bfc591f51b17f829c7fece5a97e4e355e68c5722f2d4b26a9bf4c29ec40f64ff80e3f1b5ba22bd1256c2ab35f736ff84a971aa35127a39462ff704aac40322e296317b9740da857ae3901263491b47444d17eab80f22e5085b2959423b8960cfb4dca07ab74aa9b72034df210ed77e156b3eb4da85dd505c2be457a05b3aad8b2ab34eb4fcd627b09aebdd05b6e01fc3c03ad9d177fa5838d826d557cff5ee4ae7cada546f9a9735e337cfd12ebe811743187ae0515330cdbc0d88a5a40667997bbf2351bee354e852cff4256f4c9f9aae6fe49ae0e36e59c41a82629af6e3903af2312bec2dd6a476a3abc2d7d50d731bbcb019f0012e09b135aa43235582a55442f4f7984a7f3c97ff6295fcbf865572f26fcf73320f993e7e9c47a8481cd6c621d0b20a1ecefb536ccff39ce6f77ac08fb5b721d6739572bb95ae971ffdfd03eef607cfa775dfc0ec5a1072b7a553f5e883fc813bb9c7ab5197dadd7da2893cd8fb20808594e50f4ccf39b23d6b0ebc4762c4a3a52bea2cc25d66c37841d52d724048a39c2ca7304c9d9f9a74e10f11c195efa2dbd4f5404cc7a6afe3cf7ad1fee6ec2e9c270ecee744feb979e293cf72d1d9c441d9acd8142d90dddcb39ab5dca63bc1c73e23ca0ef4a688696cfa65eb931ad2948a695a665de6c423e132b6b4852b0d1ca012daa832d7499d9931419e705428eddd808967f85a6327946e974e39c872ac2ec01dfc4a9fe02bbbf32aa63aabad7dacfbde605afe8b31cdd5f4caabde87cfe3f9eb6062beeab7789acd7c9edfd6f46fe80b4b4662ce5c8f0a05179c9a5e6ce0152de07c0e94cbe0ac4303d5b1a10aeaa21ae93333ae305f500cb288f5c8913aaae03ca3791cf33b1d81fb51c8014140c265c130abd0ad74ba8a0d5ecf4b068411e8d7ad47bdf5abf7b242ffd764e5188b7ca2a388ffe8ff7d2fb31647d601275a3a70270e5cb9f670298ea63f190bbfb002093c8ff116c7004fa95e6a018524ebdbdb809a09af6547ed364f22cb0d346664537b272044496471a950220163815eee7c566e89de6e422acdd06e9dc45645528d8ba46fed503727a2ec2c5c5f7bfefc4d7cfba73a5d8595d8eb6ffec4ddf1075c2d67ac255ceeedc0531d6ff76e7eb912db6c0554ccd1fdeff7bd3dd7a7d81569fbf39ff3bd2d7bb1fe3bf5fa177c6bffdf916f2dfee3bce5fffc69de929bf722dac76e4fef9b9df343be333f79fa3c7096ebe2ea31e1a0c98c17cfbe7ae77d7f98b3dcbf1ff5efe4b99eb9c29f6bc8dd9fde279fb845f7ef7b1f03f2236c8697cf7db6e7d2c9fbd460753279ae510ff3e2ee42ce8aa7bbff6b1557eaf149175ca83f5456696da6ab1f5fe083b94a6d403aac4f4330245173d2252f7e26b3430fce65f9015bcf0cd662a7fbb1a4390f955c2d26ad48752110c4914fec1e0f62e797624a6d66e16ab34644d521533359a03884de7d4ad446428117bcdd2404df132515a59e410d4b2d1c1492620696532b24067b2474fc4f70ef8ffe8539c221e166793833c3bb97d1a53c05582ddda095cf73d21f63bd9df5527dcb2f7eb5e63e76d144946bf3e8a9b6f0eb2279f14350f9446e4312eb0163b528e154965d45f531cdc0afd18dde1504da7f1b5bdc67d51808fd0b5844fd6874853d7a5aefb03f4f1cd787bbd48f4617ec8d2d20be990fa25bd8669c3a72882bb4c62cee6e34bc8d79a90945ff766f9a94b317f9da8ff627be520ff1ab358f7bb4d7ed4f358f536df5324e3d896203f74c0bfa1036097199973ae83e755ae857b8e276738fb4fb3ed4b0b7a0d848279b3ee65ec079b64b2364509a5744832665d990944ded4796404c54d2c524a46622695b70673cf135e12e238b277a77de07f9cff9944d5a97ed3edefe24c6300e18667fdf6fa025dc34e7bcebe5b16ef8bcfe9c648f070cc28bcea65970fa73171aa24e0bd673b789327bb75b1214d2e1979969608e0aa9b00e715294237fca1e527b63ee6d04d561296aaf610efab12cbb1956793e37f2820db80d9957a5bc9b2c686ed2f0e79aead2f761dc49fe8e3df87a5dffd2b3d9ee63e1f3bec07f27af249d9fed7bfd9d473bfe87df9db8ae2feb33569d5fb038a8037d590620adad20713a9fa9dcc5e56898ebd2a4c56c9bd1b11d6bed82d48a121e68b2f25a7f5033c6e16d422142d04219b11461623a0778bd74efd7bc6aca4cf701e299b98cd48f1ba03a7f6a5d500bfbb24dd72fcdf9a7cfb383a08fb9597fe693a12b61329dceee90c7cf2af8288e79c2779e4703c77af64518123a62bf8c24bad7f99499389a75b1210b6108bc74bc55186506e39b4168631371ec091727c8f56c59313fe3792fec26b8d1ba66aee5235463331cac05e6b3b55fcae9929b2ad0c04d42659795d00e005a24433e5c80e9ff85785f0d736e82947bbf39c0ae34dbb1b8bca7474b0d567c81d3a1bbce7d1f83f8e4571cd73df1bf5d96ef8982fa6ec4a21230bbd30840a1b45577a3693bbf1f0fa1867b6e233f7473033ba8930cfdffecbd4b77aaceba3dfc81fe8d170ac95836974a81286528ea02d503ca13848210258a7cfa7778c955136396679fd3388d3df6d21fa190ba3cb7f9cce97ba5a7795aabbc91b79e8548a5658dfd42dd49bb0ee6b9b063ad56f35c595390ad44a8061ce221d65a43ea35939d5add360769ae53e7430cdf7ecd15775e2f6c7f8e87782d5f62f78366d87e2d1cdff12f74c3f06e5d1ecf9beffca8e2469c97afe3edd743bad5f7cf3f2587fb5fc911eb278e6ff0028e30733106d1c6d3b42d22c894562b3c80c7512167d8700729516d40b390b1c2e456269211bc4386144929499aa37b4a582f09593db3ff6c7d0e7ba9d69fcd2d751797b02490d54c73d71ebd2d175b14bad5879eea935c34dad93e4d04fa5684508f43577dc00e9ef68ed4a28cde63744e799f385c8a405769e5aedf71b09fe57cfa9a9f7b77ff030f37fa9c37aad45b2d32f89acb292a0fd77d3ad75ed7c3613de13a35fcf53e2f51d627f922e978cdc10fd2bbc870eb97fd256cd5c9617f11f33d2e641b8703edc2df6b3b7b951a837ae77324c05c1df38dc56e0d4fc16e9f7db866bfcf3ebdafddb35f7e0e8e55eab82a025013dcffbc5f7fc7bfbe8b5fbfc91ba736536971793dee79a84294a7a5da1cfaed77bee5f8196dafc492386815f34b187febd923fe4db0827bfd8f3df734ee125b2d0e5c18feb558f128298b0e51733a2feb8a84ae214261a65a467d0d6ea5d55a291c8039a7bdb98ad69e45351c2a91e47e4747e91a1910d050faf1480d3168c622940b12b2152b4d2d2a5595704491e1167c8486a4fc634add9ddca0feb8fbbdcf725fa332cb98a7cd6e6d4907d7977b2c76efe8e116b59dfdfb4faabdf6e0b32855350d075b11622de6879e8bc37a300fba85a5a8c59ed38f697bced503aeffea1eeb391c183336a8881a78b84375a0bbbd84ae0c0ce576a2b16caaa3bbb41265e0e0275cf93ab1dc15ca6115772ef38b748dadb1196b28a2650d264666068cb6a9625a524293d80c3126267e89101f65b147e433b67f9efffff26cfbee3d71f428385abeb3eb796cb33cde9a4fefb5de7fd9eba6fd0a0fe9205dda6a75b1e777dbdb7a9fb1a6bff40df6fd598e77f00d0ca6c5bceda6c47bf6aef7179bc06aa61e508c5b9ba5a7331b559987f86a432df618e8bb75d0f87e81c074db04b1c6ee53bb0e9891f5e6a3b111684de0977ae39368e313b5115a9fc942af67969cc6d045d4624d5cb80175eace53a9413a787f537fb13a9c656ff6fee1265c73e82bac6235502274ad1f3c9799daec839dbbcfb5edfef986833fff35fcfbffee83bfdd01f3abeff6c8c37f399b873dcfdd5e3ffc6fb3f7999cf6cf78d4eb8f47de01e3ca77efeafddfd3737f0fcefefd62f7f7ae92b6f5fe5ae3ecb5dbd76baff593cdd4a64d04321581d5658d92dbe41cdf8fb9df13fbdad0f1ac9892bfd7e38359b6128cada34ee9529351caeb50ea59c6188e7daedf118e6c9ed31e2219f6890b64f5d0b270accf2d95c7611605ecef7266b5cfb8c015ad062b46bc8d0c3d206dd60abbed624d9432683241f01475ea3e01eca6fc643bfb96386ce7b3bde758d9de8a63e537b1f4614e844a2ff297ecef7f8b186abf2e44c9ba0397ddfbcfdae670565c955bd184edde0561ddcab2d604500885aee1f1959e166c2c2d77408aa6110e2b624b9a7ec1b2b8e86d3c2ee09c67994fd5630afa535215604ed265407ba6a7a932b58426f5c28c435823d0581323330290e1543327ff1b7445f7fe2ec7595ab9d93cd8730dffb03f751fdbe8b799475644a1bb8dc2a291f69f0fbdaadf3c5f73c8cdd0eb7ca612eb33982152b0dd393f0df4f1924375cf2dc8a98343c98b4de2141b52e1750c77677cba645ccf025b0d98eef762c7e55ee86ea7dbfe18a968e9591804fbd8d93269571833aa6d121b7a423df4d252eb79b7d555acd3adbedf6bc27ed773fd86efbf7eeedfc73adf6b656ea7b9ffef79b00f63beecdb575bda1cc7b98ee37bd12859b62280f533e54d36cf334a0b579f433c9811d7e485eb2706de22fab06420c308b89607b29871b3988f9886b57ee671a1fb402a0aea9e1fd6c8636e4d72e6ce2b91094b450c0a252aa64bbd1ed1f2167eb0f71e6fd045273904dca5806d3f69e36ba981545aed75766ee00f8faf5f33fbf529f69a3f176a5a877efe7fc74ae93b5f4c1cfa8077f6fffde723d7cd75b8a9a472235e49833bae35d5fd75a03235e77292723c229d9871f5d892510402c7ed91a01f23a0bb2971d7d486cf89d6dbe01c3e13e7a14b1c392121057e28279c44666ce37a6e439bd2be9ee8aa23bc8628e88fbc0b58f9eb7153ae2e5eecfee2373a4b7bffa23cf0009ce98bb0d942f24b35e5f1cee734ff1d677fe07ad9f7411cc6ddcd2998e6c5755a2c856760de6e8555674169fa5101fd4907616260212b18a760dc098e562894352adc3226621828cc22cd5c4be32f880cd1a576ba895576972897061a7e4a823e441a2c842686ac64030a0522259a62038d09bd6d5ff4c18f7bd5e9bf764fd669c88e35cc33f896b3fc5437a8699c8cbb3bcfd9731c425dbcf5921df7e875b90d49cd4c70b5c56c0052588714c83b69201f1b987955cda98eb7c9e24f8f8c583bd5949ac3ba094603158c04f149daf9401ff88431644983e82e9d4338e09567228607dc6a6729675eb2bba4f8a30bbd2ed96db575f2b4529b432d103e0bbbdf7c989bc3bebd51ddebcab5120e8a28c46acacdb5b45519f38b5a7987bcfc0dcef1d4c699b46993947d2de6a23ef25c9cfbbe3968305c77ae73de16483d6e68a5469cca212ad132e075290a794fb57e13c0ecc9e312094a8d88b9f7f31c23bc6d22c29b260eb3211fe127c6cd2a2d644494ba4386f403cd6da4ddb790a53ffba5b5f5b9a923dd2501c8b4e9359c8397d7cc223132f54e83e21cf7d45137fa5bceab631e5476d2ee6f5fb8acced4b75ff93ae71c6e5fc6f51627f5ce432c1d1eb43f131bdecd83efaf4db77a1e071fd7f9996beaa4425ac4db95e07eb3c7ce96709538c56b6de51c4f571c7acdce7ebcd58cbee85f08559696bdd7fb1eafdf9cea3eee7bc83369efe246fda38d533dfd0b2e233d7dcf27768edb0bb046eef542dfd7a3bcb3b8e1b98dab2977b314b0227ee550fb6fe138b8a106885209d0b3647176fffe7faf7caab9d65e994b387b4e9cf6e4a2c788b7cb0b67d7991e955f9d5dc77df7a77919779f8fbdba2f1d5b9e36060c449a479b7bce5c5b38e82ea1b825143929619c2dfa3aa170e8e5691714ca4be89fa507ea41623ff4f808b7d8c185b4e588e6a89c3b78412c86e60af5bcdcc5c2ce9eb18d26b2a25b4960c9aa5b7331ecb9393be9a8d51b1fbeff7c92f7def3209cf0961caf4f0fd7ffc7fb3bd8360e76becbc538f7261c062f3df2fb1cc6cbbf897f7dae928e3773e6d2b95205a36894e4ea79a245da44938fc8512e7630a21c6541851a4e5d2bd531c15d564db5be8a8b669800ec51e2ba812d661e701102354b75374a4abc4ea16f104d450c609172af1565ddb0fc6c7dff92edda486e9a7beeaa4fb6e1da394a86fa26daf74feaabe8624ff68d7a7d4fc73df825e5a6496db84d01ddd9bddeb57bde0b743b55d974aac132cafdad709033b7f518e7a88a73b8f28930a5f1adf6f195f592c1f6708ddfecd7e8f0b6bee6b5fcb9479ec1dd736f0547bb33fd271ad637e8013de5f53becc393e7690e78ce1f7370b553e6628f9aa6a80686074c942805a4f2da406b2642674e44319a8d7ea4b7ab4bae8a0bf6abb7f757fe1d1fb01febf00e582d86daf1be57d5126d02f4205d3476c2240c68da933c8b652e465ee952a131ce1d348ebbbfbd58a346c206abb4701798d365d4a1ed2c1c3c4580716a4b3db554490af51875d89c8fa81e8c2293e8d980542e8b18d225512ae0e6f4141b701e1376f84d9fb12ac7f77ba5efb17f4fe1207be14eb9a07d780bdfe2c3986f73f4721e1d39ffaeabfbde0b5b8fe696d54b0bdc5122456a993c2a1a1294cd6caeb0e115c592762c4c818bb06d8ea4a542aac32c31d0cce7289496d083a02f820ed2b8aa5940c4735436551c4238e70f3da1cb6701442ef36c9002dfdcd7321e7e7026e40fcd813b58ad44a0e711478f3fe897ea6e6293cf8efda7991a516f8fcb080fd8a708c03cb6f7b9c5eedabc4532ca56bec61a62238fb3fa11d9e6427273c62b817dadce51380068db04be21b39963ad898dd97c94e908b41d33848fada649ed7e111470422ab9f47936f1b77fd6c212028db2a9a40a26bcd6c40807ac5456faef3c1c466cabcb38d8bd0d19fffb1c80ac3ee2608fe36a879cd775bdf84362151db3372d8369471db142dd60e519aaf5f40220bb5846a1dc483d6b534d0e3993cbd88048dae682db724ba8bf9cf347232db3d0b31b1d53dc9b1775c659e6c4050b11ef575138989242878166a2b8548bdbe2605527c24cbd7139fffd4633f91b1c6ca0bfcddda1b771fde9fb7fc64a5c9d5f02aa10bb3398b775525eb2f7de69ecf02b7b2f6b7188df577bddaedd19faf1398eb5c22b39752ad4247a96250e0a59811136d8660e1f759affedc5c03245d9c67159d7c4116356c090d3fe54da6a4a48a6c7158e99313623dd2d4509971383114cfcde44eb2f66567f11f1364a1d690ac6ea39c51652d016b7cd419ee1dff89fe44efc3447a79c0c1ff8ad2ed8de3379995fd9de8f9c5a7bceb9f7fa13c71e8deb6cef821351c639054467d8b333e6d1e60917a6454336c125bb4b6953a4053471895d118a01b6559b2a39963a5a45a53e24853e4e472c8b3bb744a3819f906cc22c6112e23669982d71279e0568c6a4b35ab1e8afaee0dbfdefcb2b7fdc6fe774a54ff847bef77b6f32bf2ae1fda7b7f9dc6bc67de4df220fbfe8a9d249acd45da4cb19d1ac8d08e5207006779ea5f752a86c59c90a55ea694ee00c77a8276db64ec347804698fbe0cf9aaa419554e376aa49470e9b3aea501d287c474906254154585a8b20ca243039e3ba83c905ed869bcccf65ce97ff409ead4eb77a2979bb3a9e59cd21a7a06f12a09e0f9a7f1778b97e93970b6b33e19a3e31e832d550477569e2916a490955aca20e5b02c4169a46a09d0a5bdd710e272c64639f3c74b4689fa25c3e53833949890b5fcb1c990f1ee36d33e5440e0985ab54972ae830133c0598458043f8bf81176ff7fef63cd489ad9ecfd581cf71997e5f27facc71fa4fdaa52f76eb1d17faeb77479cc8957869c5ee10adad8981ab34c43ab66b143bd2151dd3b112dc03584bd9a339677092c09a8bcad202f2b79d6a2b9ddaf00931368e73c9e7a18b89568379090daa8b55600ceea3026ea252589ec50a54a949b45db5e2c65af01fcfb2436e67769e4fe3c23efab67e74c28d34563df0bd8ffa3fbc465f39942ee4766f54f7fe38e67b2da6039f11fa45bddb0f190874bc65b6c044a959c09116a9711b6cfb02eb38f048aaa3429a913ee844271733ee162c57960ca19ee6b892b9c802038eb90d1f512ee399a51adac910878f3a652227065e09956e535543c9a5866ecbe573e2bbbdab9dfdc7d74c62b8c53494db68cf037d21dfb8b8853e945ca7a5df48c3cdd23da6edfd676dafade15da733339e2ffa4d5a98461ce2192d1fd601640369696ba6fc3562623c31548547c262b96c386d623fc46362b88bb4cb18022da0d003733b3230ada784461bc9d236d0ea51321a8c51f7b7151d8ab1c1ba09d0754c18b8a2cff7e73d59fbfeceabb1c4465ac24dea5cd2c5bb55ae78b74e069bf97e1fbffcfbc8ddf8e39c84d54888f08cd7774873db58653d5236025762e0413893549f4ae76fef5ff334bb7343047a19f3564d39d412a0d7d1e5be94cf9a3dbfcbdbecfca63dbe7a9f3bcba4dd6f62beef51f9e2b9b4834f78ddba1fc822cbe7ec510f4a9388cadacd3799f37aeb97cd7816aa10d99ae1876a391bfe314958acb1e59b0930a722a4eb19c1a5345c9400a412fa674b299ce002ae92d2b4c8a28931f496bcac0734677a44ac3585d1fac6fded8d0cddddff1ea3103dbe610eac677416a3f001fbfca69d768e571ea82a29e16aca592f0edf3431cef2737f8be97ec521e857eecb9eb0d3262a612738ae2fea5f9cfa25bf5a779fb011bbf5f6e9395efabaae5a673ed5cc474c6b4bf03ae62c32e211ddf865ff918cfe9a381c9bac84aee062eb152df279d4118d35a9859671d1afbd0e2b1e2acc298c18c34f98418d17350d00b23d8b6e196d683c6cd6a986bd14c859cc35f3bfe37cbd36469f3bbbb57ba93fc3bfd1b99a693b9f61bad55ec6fd95de0db11ac108ac7d964d386495cfb2e71963415c2a7da2e961ec28c6adac93a5d820a0e792a966c63161b4997ac3fe28aef09685d2f6c3cc9a8dc6eb84a230aab0976af209172a13a3811184682d46f82e5578804ff56eaeb177da957bca8c78bb8a7faa47f4efb1d5eb78fb79e17095ecfbb37fb387b44e02ecc41cc7f3d0d2a935decc463822162388e10dd151e01364c42a1b24960a09cff484b84b5a2230edfc9682de56701d7b3636231d86c86131b75a1557722acb14e01081a8c42b566c9658291819bef1d31ad3fc84e3ef6cdef9063d48eaf9f01e7bc7fcf2755adf2c7cd0e65c3acc40ba577a461c229b01dae3216d396ff5a0d45b5666bd94aeb691d64644c101a230f73b8445e93aa41a200484eec1a2172dfa771e111b6eb5cfb8ca621e8a30b6fd4e94d9901365115b1fa16b7a51fe8d7769f2b6eebfb59b0bdf76b3a864ab293870a78bcacd0eba99dfcd5ffaec91f1b347fe9dafe78bf17776e69057e2621b715dedf9b30e635e8749adfc76cefb855f3db48c2333e6cc270c2d193019b2333fe5999112f98841b14d0ae179b4553e4190f1cd3225ae47c3871615ba4b819c78c3e60e01fc9c7009e8486169a99508196496bc8f697fec31370fc29fc77569c95ac9d5f6ac2f530c1611775532ec3fc65c3e26b6aa62c77fc370914f5aeca7f6e76f54c285e09b756cb3556ab3ed34145962ab220af13a5de8b5b0d9f30f31c8c634b76e82cb7a9bef4c25ce40a50b1d44bcad850db5c4183731c72aa9702d4aa5d2c59fe667d7692fcf77ddfecf919676f28e30a423de967128430c453857ae8535359b80f6d9d71813368c84817960d515b1c76d5ac8cc27e28984aee6e70a26941a6464f544d98f8242c11964cf53cd5ac723310b4ae1d0f0ef5a103841d695b5e22fd7c0a5bde9dfc256bd5b3faa8aedb616203be82ebcff4c5ec6bbcaff135443f7d2c800830a06542718c021e5633dd6b0956a689d5ab888197352036ea2106f3c20ee13abd0269d3ba6bbfd6beb9029f9cc2a665280077ec720d3504b75193227dac47c0c3cdd7da2b92c98e51657d4685e796ece9dbdd7addf578eadf6a4177bafc79c6589bd7a8f633eb926aebc46dafda5e066f70973fd455ee73738d24f67cfd9fac2f89417fad7fa521fc67fa7ad83b4f9de2fd38ee39daca9cb7b5af91b5e1420d6eb4040fc3883ca0caab4a39abee05c5bcba099a55c747e98c114ca7b0f0eca5988dad9b0af6604877327bb4fe1603a1f299be6d04e1c3592569f63cbbca7c1aa9754789552d18b999b4f8cb19e9ef421bde6ecced7132eafb1e36f44ebc4ee6ff7b8987d6ce7bfc6a7b30ff8dd8fe7ffd1fe7fe6703a87d53e9faf58ecf5a44edff9af7acb8e58edadb63eaef5e678ffd373faf05ebeabf96971d09433de6e82c2cca51669124a3e1bf6ef5385a9b4a256e8753d01510f577035a7b0d87347f136c74ada9449db5b3433a1a13105d953aca1c54453b65fb4ed8cbb3aaf24f4c22c8f75c8903350d4609f79142f9c1b3fb0e987dff869adbfd602b6a7fd21c7b514a27ccf57ffdac374ac41387fdfe72c3e738a1fe7ed85330b77fbb564f7b76ff961efc339f2c1871cfefd8c4d38f6b6b43bdf214f80b9b33b9fe3a6f36b2ae899a7bad5bf5e539ff7c5d157fcf85c53b2df27dd691df2a26dc2a2804cdafe5216a2f0436c538e46330b8de64c691e178219194929ac83cecda9e68379818733abd745c6a0c3d41d48e5f6d291ba239aac5091aea9968d03a5066cf4d09b027837d5948e2d39200e9ab1d2754e6cd3f77ee3dbbbdb6bc79d8b8b5feccb1ef7df24256c8ef1427bec25fbcd9c3feffcf01fce777bfbf936dfc5056fcfb3e7d9ba7a9ead261da9212b0b33e608cb92714f67ee9c3f76942a1419032a0bc42e9eebdf9eb959966ef532b1e199fe9eaff2c49f6b81bf7d676f631ffcb557fdd6af35b1be397fbd40d7047499a72187576e1d28d988c27444d9ae83d1839140a1cbfcefc535fcfefdfc57f0937e958b7e897ee0e8b98d5f7285d6ef71dcebfd13ca6b1e57b2e096d2d0e86f8f5055fb211cf1115e33da7442a75b1cc20136eace53834d0c342d62504465dd4cf41a328de5acc3441462c69cb126a93ee3a59e793633911de9892dbdb46c869e0d230f4294189fe3d15bf9271fd7f73b3da26fcf96ef306bbecd8e5c727d75e029c3db8bf5957dbfd02df210e7c6dee3950edf3b6e7ee43aba8e1f943080746c61a23609148fb2cab060d2e316a6b2102028dc2218890d0e5191949b5ddc55f8e1404b4266633650025a1a0edd16856e871d144d800e7caa018f0cdcd83233d2b92162512bacfe7d52e0e9dc6e7ecefffcad0d71b3b88adef4a3c8f84c0de5c01df0813ff4443b8675a9e3aad73ed8ed09967c375695d87b4ce6ab2ef957bdad02ece68bbec75282530d177dbf5fa75cece2dec7b7f579268629eb7daf6ac2376fb519f2b9e763779d5e27a56aa210bfe07d8ff80dff2bfcc6419b6ee7a7707d171376e38f1ab2bf8edfcef3439c3d1fb5d3fe95dfef91e3b8bb33f1c881a1695ff4b15c3c0785dd8712609010ecfb804d91b5eaa882334fd523af7005a36e3677a4e7337794b2ba21bcd670bedb5370e22977e139d98695ed1a2bf7d9d7fa9634e053eac8679ff7b3a4c31bc1dbd9ccde74b4a80b99a38a9ee45e6f750eeadd0b1f8717f4b6d7c565729500374b9c1fc5e0ed2176ba958ff03af66e3e5ff7df747766e567f33917e7d457d2f50d76372f30c0767f8c089e0556334a01b3226e0e628b763e60d66e7c6c6d74c27c402c3de2f6e39669e8598c14f33bb79b9778892c18125b3c095bcefc024504b22c5199888cc1d02f9a7baa4b479ee0b56f34a7d57b2eb3e35e1ff67a1ff8dd3edbb3333e4df2b3dccaf6ac46d62ff76872c8a734e9563bdef7fa794c35b9a4cec392953592b63e40851e79b95cfb04db7e2120b1c488ab478d76384a3973889e8d641ef524f4977139ee64b95ad34a65812e7d0f0e6860a850daba47356d132d9a4c404671281669077dcce1d83bc1425de96bbf6a1e1e74b823d06f12ce9ee5cff6d5794def7fc4a61d754bf304e88de0a6966edfe3d44e9ef3ebfad545ff4294d4f69634c775ecc8968ec46c0aa02b73b7f4b844c1285b115d684c87e3c48023e4a8292afb0443c11380f484c24e14a88dcb264a2a5873aa3f265437e8b6df609a79e94872c1b3951ca136198915e6ea3376f6d56e9df006ffc8e713596ae05a54c5416ffeb50fec624de256fd7f7ff77aefb62ae7417fe7f3bcf5a81df00e9fbf6b0ef1ed75b506618811d1d92c8559c70cd7a5040d900d235f6b5d61bb2b321a68d8b134af709d69e746b293ebb9edd6c9483d7a04ea8991b69e536bb4731d4945362fcca128eb455aa11871733501a69f8cd81386e829ce19a5a7bd2cdfe6b577effe0d6bbab301dfebb9bc9f3751f6b712c0adb0d9a57eda333af8ff3c676562b84614ba85e0fb5cd0fbcfc7fee22beb4265ff7ed289108f0619ad1e7b5125ab403df652bb59ceedba45e0cf1a750fdb48b7da382f3444b350748375a46a24349509a8424f1f28d9fd5d46bcb78c3b88c948ba14d663425011e52cc4b9b8a723d1438e6a8e5c56dfbee3d471d773a768228e8b4bd89f33b9845fc6445f8dbf3bcb06dbc4c8cc29878570c6bfd2da964e6148603231ec3b82a136d0f1c82beaf5bc422b14664e549a3dc64d880b6f43406f3b356a5f2efef4e2303325501bca75ce2ba93343cc30308709505a90bb461c6606abe05a54322215cb66f623e024da26f0a4fe76a1d6f3f51a7fc7f9f81957b639bc23f329fd9a6beacc5cefb129ab988fd7a2f29e5380b2a4bc8cf33ac449ffce0bf9f5f8bb185874d30ae511378b7877fe1dc6bc4e2bb54395670c5050aebaa84cf544650b32fcb3f4f50204c4554181ef78019f63e29bd41693a4d8e8a2948f14e24ae803e097fe3ab5c48c023949011e085d6ea4c36c49649b067d482b71cfa958c58ee808c4a3e00a6ea80b75f83dbe65cfe97f780f5a74c4ff1de6f524fedb4adedbf3561cb895366f39faa0677e8b4ffa72ac0bda7b9ff5497f130f6867c7de9fa7e9d6eca40db5bd0edfb0a75da97f25122b9bf86490278ebf9de8a242c0cd23c35a32a70e845503995b66d4b92ea9e0901a684db476e3f15a21237b92ced808f23198e832a279ba25141552513325b0654eed320d97b1a597130d0752c149d0e1eff31f6770127b3c0d6feb68b1ffadc60f788df698f21be8c59d1d7bcfc55879cf12c055bcd58e635d850debf995bb8e420f488535d661276019f56966251aedbc327b26b98b50a89642431ba6c98564d998124b9705436938de7ac660883aa1a69a8c235d75bc40639fb60091c152dafe1639f011876a9ae6c2f02bbcbe4297fac299fbcd39788c954ef350fb73ba7d3b97a34b1c8e7f53a09e85b3df27dbd839f4df5d98f3cdcd30300eaa9312efd74b5a667abaefbb3bf6d691bfbfc053682629189d116b832d330bd8e059e8ea9958ad2f78ba2440dea521aa672143c8d64954f6190a0b908e328228be230c731ca209afdc4c8262e9977d8b28c6fdd2da623b9ba40c0a460520149742a71b94bbde053ceda97d73d05dc2e13632ea2cdef6f77b631aeef52c7fe6e7df60afa546dd44a19bcf4bb89c82dd99f8b791b66a8e7efe87673ad695b657f2dabb7eee4651558f99d50331676e5c0a97b0c88ced964740f88c8c41dab920e242301de6bcc8426e65f7735b6554d502533cc5a12c9291b59db1da141ddd4c805873166de30255d2715baa5920a5a64e14fabe2ff5e7b9de4270a1d2c51eab9e27c07c16fc80897df57382eff7d38157da5b1fe3de2e02994ab87519ab34ec1937b05d7b4eee74db3fe45c4394c7366ba260b7a70eb1760ad0a3e07a76d4e134aed3f8423da609cc2aa4fc5203a4534e54a56dc0e462e68c01d13d8d808cc8117aa4b0f6624d0c52ab7d2224a3986501d15c9d52e9f9f4611b13b7e2d520e736f6fc426d5398e9ccc28fc148f2a8d4da98650d29e4b5fdc6afefff151bfa9dcf48e8b3f7592bfcdfdefb413f6dab1dc7d75a145ccfdd321bf6174959135ef83da4ea32b5dc0edbed28e0cd8c5b0a2441f3882a59cf786a0421f426a06970d9e0892e8124689296b0135a0b135bd4d496eba4cbf8cc115c94268cc90033e5b55e2917c9a8d0e29112a9fe45dce51c38d15f74c82fe2f5c9674ecbdf9d4f2f73286db839f0e2ecc7df73b1eee3ababea4e033eb3d13431e45038a8f6897a8eaa6c20ba54f73ad8e1dccd051cc4a4542c0132178562823127099a85e035f30bba8e2a5147d56397160f1d2a15a623b5a0bcbe9f1ae87e5e088391c2981a6c84b83e9af3feadcea2d3b53c1c3f5df09b0febf055dfec732dcf6f52bbd50538e1823fd7437d231bff91575f8447fda9977ae250df240eab62dedbd99e93e79cee7c80f379f8efb02b6d54a02ad607086938640e1294caa7f94805cc61181bc888836681437f1387a8c596ab926d330af4683323b49b57d0f520de200dc54813f58cab8dd0c400957a4e436823cbbc678569d06dbff4aa319843f47833bfefebf7d54b6db68d0f35b42c19ea6f7a50e7e7ebdd1a7ad139d05fdeef3a0568bddb530987cf1197478ce697f7f9c0f57ee0443ee1f02d25377369abf5be3f2c749518ea8bc48679bcd5b5b464ea931dfdcc7dbb1636ec5e6a8abb31f678d1cfd75587dedef415f375867bf11defed714c635f9ffb5c5ba85e35aeded53cd3ffab49fe5f4df2f56f7f80136d6f8713d5f73cad49e81d734bbfc08786c889f5416fa28b2712e2c62702f1d1d848344bc3856b63dadabe5ec7087a1a77a0c25a3ff28d08cc1c4c27a05e7886584e75d78c6813d2d1c06756633203370422e4d9e365c43163160351e5b5d4625930723f6b4a7d1d077db05b5fe4ff7e73fe5dd08bb989fe97f6b56d9d3b0395966a5fdf8af8a679a79bf7d57f6b5e9eebca1c92c1a0bf65856905da431b8fb280574811faa0f90009bf7a0409c48096fd7b62615d8670c655bd6676064491c1d8ead75c0db00ffac6a4633019215f3aaa17e4b0c6ce183096c552571a26c8e40a3ec536fab95ed80f7d99d3b8e8d8c733ec9d68c27eb9160c9427c6404db99e2525ac5efa89cfcef5b7f7397cffeabfe69ffb45bef5a94ebe97aff89e2fede89b7f73b0bfc7df4fcfdab0d7e70c0fda8b5ff2f47d19079db1fb7b1ee19f682dfc37fb7fc68167f4584339fe5b7b19f7ba9aa2fdd8f2423d4e3b8c03c0a0afb50baf8cd694d781d4f4065b701b1932f7945ca74afab46c8733c8660cd62b4ee0348598a7c08d10a01d577591da5949ab743be39062c508a998e3e79931630f7aaa7b263ac112fe3aa7fed5daea22d0df88406f226e66e2385fbf5ea3bff4114fbe37f05670faed5e7bf37f5e39d9bfd49dbe4a63e8c4be9f893f4f751a7e1b831ec7fdd3bcea0291c3fd7f81a32f128d19c2110d828391a02b2de85040696fcb0b6feb2bc5fc12f6a4d60e68815a5eea28aeb03ddbad6dfab8a5e5783377063cb1fb362dcd11d1b091f27a23813948005c2367a012abd74b4628084a0c3c2083939ce4f76bf407e7f7e1372647aefd179fe7ff3040ff2b3040bfb303e7e2bfff593feae4ccdbf9c2a7cff93b1b310b9a90d3dac1b6a9fb9de2122a2fa5ee63a4239d10594892eaa25223baed9ba9e5f5a28e55484785ece4066b1b8d149846251b7b5da6023528e785328585c6bcc06b02e45362f77b5483036fbbd29261ff2ebd5dddf5bfe76c2f55171ffa9f9722549f7da05fada9a38f77394f7862c3fe254ff8e573bc6af4a6dbdfad19693731a36e85219c0a47946997796824bd2884bd04d4536cd16542154b68ff4e388f46ba68f4894e75646f3aace12573063052561b547fbb4833db9442360b0562140d7d02cb38c45dc0b306196ae639a2373be5fcb8d4177dbd6ffa3fbbc7bf78ae53fd4db1eff163ea97f9bfa55fe05a5a9b755415ebc05a19a2cb469cb61401384d2d682470dc1376bf8b6d11cef3ac401d7c9a11f98c78c322c2f28866a154c58656bb139a6549b159e3100e83b23f2025033398e553a06354b49ed433e70a5eeedfe5fffe2d560171886ab9ef1f6bd4fc68c7aff2e13e5fb3d7b3725f755fbdf3ba5e75bad5f798ea0f3ddb27393da49250bcef13ef4e732aeeab06fdbbfe01e31bade91ff064bdf56d5ccaf3a0e17ebc1be5794eb5268ff7bf3edfc3f11a87b290a5a6510ba9a0c3534f7731c9ddd8efdc21676c188599412c18f8068c13aa3f492beaedf64990bb41940f7a2914ab44134152a07becc836ae064652c075c4ff68a9cd5624cf569eee4e8413754277ffbbfa81df694fee7dc06b7a339bf339c03318a1e084a7ecb7f6a7396015f46e8f073a5b23bf784e751834fe7cd8f0b8d0b5845a80b0872d02fd01b2c41017ccc3058a798e0982592ba8bce7160228cf34366c9ea21c8178db0fe61c4e99fe7743219ece99d412da1242068b0980056318cad2ed3c3680117dd89ed429beb4331fedff95f5a633e7cdffb04ff0c9dfd973f37ffeee57b646d312e3a14d41dd602d73e7760db1e53e138a34a6093bb6d8963b78ea1308a36ed0f9d5409fe78332e55147874de569b58d0d45e74eb6c0f95f1055caf02c11a4fae03929dd168d701e000582919ca69db5f61c0fdc8cc3e35f6c4df95abf3b6b5b5e793cbee521838ba8728fcffe4d9d3e38a937fd926fc3ddfd1d38f0eb1fff7dc0b75cd7cbc8cd67418a75c0159e82ec2ee09940d5a0c0b6b9f02b7c8734fcb4db8ba92a361efcbb9e57c2a740d353ab6fc76003e60e73d2423e73bbb76615a6a4304b52e181508fe6b48381b4d9636ca03b46541be9b88ec9e05a2c5f16ed7b41602e87fa2a01b23aa3af785e27fbdf359ece8e7d7ce7bbebb368cfa3dcaff6bcbbdba3eeca551a50dad62feb80c1bac7e000c436bb97855cf8155a618504d1d9325d342456038d00734be0dfce03d192152a244eade60a6e78895a56a6465c5a1d19e1c2575933afea4aeafe32227fb7335e07f311f37d507441c5ea2f38dfb208f4b727ba289f7d87ed6d7a73238ed669b9af931fc7d58c7d8fda75fa59cf34541bcffed34e813e13b64b49077dd2896560370635dc46e88f1bc2fc755ca0516a99b5042e8b0bb9a6454f13763b8c1d3891761f4b8a9e31ed4fe7a5a4ac929507eb30a6684dc30250234382bb98950fbd0bbef1490de8f83b9bb8423fd0dfb8892ed9f17dea4fa9f1f0eefdee3f37070ccf757c6b4137f0a5adadd148de0740605a0d6694b89329e8bb64f1a7a34cd541276ca9a74b41eb4540dbc714e05e3c724366b545325c759efda717515930db6d10ad17a2141b5c8881d8f6ab8951d71ea5cbb81293dd9849f9fb9cf49918ffd8f3fc9dcd3ef642ff3b1e7137d66b7f115aec7b9ec175e7f1632794f0842168d2d12d02f079ce9419147d874135898a74294bf399320530193488eb4d0cbc9659ab65526583d4192c7dad4501dd6c22f6a809db5db102cd124d92d8ce9a0968ee30c1310bd5d22ffb4874f84437e15bff768fcbf51b613395ee7c929065c95beff4592c45b4d7c83862f60c9c4565fbc67b035439ff5ed7f813fe4fdf9dc7fbf97bd5c53ce50b7838e8ed16bb38e52df65bbcaf9b9fb5e17baef93df717f801dfe52df20be0c3986fbc591cae622e9f7fa5bdc1ea8d0f5a1e183022390ab0e63601500b618b705ec111277895943594bc3f9b2baab3d1608da9d888d25fcf73d60645c6a3d0d563c3ad85e56b71c53cd2b936b7f45aea0ccf9db1c90c88a50d4544b2882a75abdaea17fa4adef7fa4abfe0d2ff418c7c86abe0dfe678f7dfc54107f5a3461239e8fd5e1f73696d140e14b5454408644447adec06eb1955352ee05a2a7137a39a4e3b6889ed4a638e6b492090082546d5df755aea4872b640060e7959632f747bc86ad773020769e15602f45b6c0cca34844540f03601e629e7dea598eb8413e65bfd93f33ef3f6867361bcf26d1db56e5e7b78df7da7755fe8435eb495b284656444200035e7454384f1b841651f4db50780353c4c0ba8cdf30c083bc3116f9cb810ae2ccc6d6059604ed0d8d7a2d6d7d433718a25a56d3bb3310dd4007b7cbc0c34cc528aedc8c04b01dd108db0f24eb8492fecbfcbb1d44b4c74a22d75c09e9dc9791dcfa31fe9a39c3de3dfad8df7ba23078dfd8f9ac71fceee6fd6d857fa2567cf72bab30d9f7387bff5013e68bdeceb3e1f9e47d30f9a3ed7af2decb020ed60150077988608059a8a13c72d45255792a73d42b36504cc4d5c793a5383868ca0eff3876542adce837483215e4b5b583c1f149e622cd5b30db5753fa13a0a7211a22eed0887034f7b5c26b65bb393bacfadd6d687f3f0a3e6f9f7b8b6ef6a3947bb79e016fb0196ea4671f89ef7f2c02155bde3bd7c7d0eedc8a173555c3349f4874d140e9ca8c83246eb212937604ea3653a12139f0ac1f308a045ff31b69013683d5d8e14c665bd08149c3246d7a2cb10295d1bdb2e10955b057a060202710aeb4d0207f74925dda42bcc043eac7d0a9bebe39af79a7eff99dee58f63fe693ed9d56bfb95db299198b0cc9853e5b0115a61e00e025d663332defa25ecbcce8d45774e77fa38ae81cdc43ef137ce63636fa6abf8c231f9eef71f9fe388ebb856a76de1e76aeb6bf5808de0362aeb9a1578e195591b68624c94f2e6b6d4e22e9b31e6f6788e5c5e49cbd322402adc8b5416538a9e13856a8fb6cbf9b071b1dd7f1470b0c2d5dfad97bb062ba017f04cf1a2c6546357c61b5f71a6ee7372ed257f7ecef54cdae892ceda19be90dfced10b9fd4617e5ec6dffbf157e7e674341bd1ad570d3a5aa076aea2252adac704e8110a65958ec63a67a28ecafa7106e59397231731d78ff5c126858853509b81e66f7de2367e51374c93d9446b6608445b3c121e291fccb86c863e6026b11b6d5ed63fd7d0fbde8fdff95afb98665ed226b5a1167faf8fb689f79c5a508bc0c3fbf9bda0fd00b711c8ccff103f459696e871af69040ee3eef3ad57c4665ea02d23500f490e4b42b342906c8642772c42d58bc3411e68f20953eb6c6e2e2d3fe3f0cfd41d821be86e01b83d60c576ff7fb45d57e90d69fa0c7a26a5b8c5dd209a8fc6060fa54f0ddf1445dd8b43f1c4f946f33a57f8862cb1a5977cb1323ce60e52c6b6bc6425d2da6da0c3d8d3da31b1fa86af7b1a2eda995f0d5674443b4faf7bb351a153c0ee7d2d0357dbaed0ad0ed8d14b7d60fbf96d6fb376e4517bfef86e8f38d1e31a6aafc404ac1173d773223452a41ad5366b5cf497be066748b97771a9b258af8997b3804065a72542d2c19394bb8518654366b8cf7ed094d878d4115033c4060b6f2436b2701d596e74a15b1b3ff77bc2aa5729682359f6e9adea34a931d8ee7fd7427fe1d2f87f877afbf85b2e8da39e5323b979f42b2ef027dc42031bc06d5a42731ab2e7ddbdf779ff8fcf71ec6db80e8b1358d29cdbfd7b06159b5384508534c629c0b4ae92d2d730ef2ba94117193512b668c9b65962503f27b06efc02df4d010a50382867ce781de9638d1916f01ce44d8dbf9b803779ac18c46c60d00e39b872ddf905fd8a33e7eabeb6910c7fe8dfdd480332dae7048ffd562fdad19fbf3bf0555c990f7b34a4a51b5ea83406330df1ba251cddd361734f43ac18815c52733a63c5c6ab981e54784a0924328fcc586538d09a0a715447456b60ad5ecb2e33e7aaf627800da2ceea61ae7b581f64c968b048471e482b71758d2b35d473049a5a5e7ad7c313bec0dfbe6b3329d1323ef081bc1b5fdb7cc115f825eff27c440d5e46dd6c3430d128db26c035b9dd78f302c731c01eedd0f25c4f6e14e275c2553e0dd14a70b6f94fd9f1a3ce5e93825689f0effef77ffaee571c53b166dec7056e7dfe60a4cec38643390b829546b97b9700154c8149632d1b30cdd4c5c8d565694ed290595ed0ef216e1998c198d09a7a16cce7159c7a103ea35cae79d0a70c5a2db15d1600f8c4abc1c6d30a53c2f3bdce51c8b464cfb161ae2fd6f3867b1dda1baca7f763ee6d9c2eed7e1e71f379774e1ec7b9ea7da6508e317527f1482d621d2a0c3311e7704646eed0574a71883362370b5a2ad3d3cc1819624673b8488904ccc8c674940513a04609c5a65f204df2872db5f449cce40a83b68ef52cf3c2bf1b0219e30451e15cc9aff641ebe37cef6604da7a1a1e6a1edef6b55ea19fa957e489dd7f166fb59033bd78afbcedaffcd56f7da8e7787ad136315037e53b7f23fa560b5194fd6d12e84514e2ecad37879eb9e79e23fa705e6cf5c704f497af9c58c159dffe5138e326b65527ed7e9596b099f2ba7bffdca7dc2f59912ef4c79d4d4e80dc465c6b529b6d23b0d7365a89d06b12e03e7dea21fa7c8f3d17c84b8fd0bb3137fbdff539cf5e66e6a127ef437c79d2c7f582dd9e8683ecad3e715ee725e1ea39e67a9d1a6f3a1f67f28c8bddfe484ab6d7914f0dac92c5ebfb3c574fdba425d3a4533451a534f18a5139c3ffb0dbcb8ebb1686ab52c3fbf677a525dbdbcfb4126ff5bce02c5ff356bce378f9f2fd57fb6b5eea396f9cd3ff56c7c9631baee21fe1e3ceeec7dfda8ce3b8bb73eda87ff2655dee627ca4e1111a22254b348253a2ab0097b89b97ba95527d840d4b672a5a4baa0ffc7c6c785aed125bbf9f74e8c9e7ede30c3e6829c59a7070e5ebe34e549916152d24614de6a3f19672fc9814380f2aa17b156d8512c617359b9fe769dfe5b95e39c14ff9f90ff5bb135efd37bda48b79fceff0792504b254eb0b3e82b1cfaddfa08e2f2b51278738783fee9e636671357750e81508f9408f238a1a5f435dc0e124a2ed746ec13bea48dbeb64c9eda20d34d923451f088eef539bd5a9d6164998c549e9ae30f0bad8198c99ae9e13f87719687d3687751785f5231aa1905be658e8d926aae0491df6fbdcda5bfee46beec3cf7cf0e7ae39c3d575828b86ba08999a72bd8e0c772d6dd8c5dbf7e7ccf8ffb0cfff1bb0cfffd73bf7bfa977eec75c03510957113773c1fde62d8f7a31b775831c899b25367c8e002ba62fb9ee5ddc7efa3cd7c654ed94ab05836e1385688b40f32ca858a2524e916dded3b268e78ebf8dbaabe2ec4514228572ff880bfafefda05be8d902374b010568b85b8f3b7bf2feb3d61e7cecebf4dc03639071de8e933cd310443c2afa63df2896514e9781d654528d3559b91d1e6520aac4362a150eaa4187809862889771d958695580b82c36a96293b8f036b1512f48c97ce2c8bbb963f5e2506d92ce6f53cec22ff0a2bb67ccd2aa6844b8d7a5debfbb4b75d7331a20bf8b374bf51c85ae39e5ac276df6bc3f3b0ef5d72f9eebb8f7afc3c3b79c3ff6e291c2131d5a3867f6bccc50baede7b360051837b5a8f075c29b4028d788b8d7c3761f2644c542b121cfa5c673aa738e1c56c03bcca916a9ac13108e315f2dd34e1114ca8e680d17b0deca6ea05dcbc11895fd9eb8a8cdec9fc61dbf5bcbebb9cd0e79d0c3b87bee8fab390ee85893cc376921ef44e7ae853380348fb651e11a546b01e3ccf1b74d1829f729ae9489cbcc49b5e639ea32231df61b6fd83cd21021160a26081a7b2adae01103b21b3cfb25bef778360aca7e9c74ac0900d3830bbd8857f84b9ff081dfc5fdb011bccd77e7cdf8bd36df698cfeaae3f84e6fe9f335ab38d0178991a977fcd3db33b1d917f839ff341fbeb3b936dbc5fc5d1cd6ea2d963be3db7fa39df1697c23e658a57b4cbc7acb657cf6fdaff6ef3ee3457ea22176e63dfe37e10ed05776eda2cfe70a548a2744c43d63d62686b40d406d930263496b5b84751b00bcf543650b4b2959402b0ee19669994141bb48a83b2334db200e975e19691e1c3433aba6b852c82bf5766e370e2acd2ad6b27b8fc0720adaab751e3ee79ffe2ffebe59fcfdef5a90279abf5feef5e33dbfd40d358efbfe9a3e4595f0fed39718a0b36be2e1966be2d3f87b5db70f98c52979f8e51ad11105b598972824457fe0d9ccf069b699e7033477060257bb3915665c152d29d26eee609518f00ee5bec60ab49eeaae2f80b9f582be830d7f1973af8b694de7caeae19076ccc6c8239844a17c668a3558a3a735ec336be4bbb82a0ebd46546c9538075ced6e7e854d9bd4eed749f5996ffeec9979def6fcf2ccbcf03c3b3fed025e543b3ecff5b1dabc524d42e852064de71b88304359b310ce22ce9e588e2c5c89475f6bf2c46a8a38ac45446b266936988d5040ec7a8180492495cfc2c6a3c092c0b3b3e5446b04d25ce4f3b663804d11644a7402b25c4494df44ebe81dfef8871c4137c6acbef31b0e1a991fbffbdad7bb64e7c29acd7336c1c3461306d424c54f846746c0535d52c1598e0ae9c078162a1c946dcc4ad122abd878417f8ad8208b73c602fbd16095da52da9fc8aacea48e7862351b02dc416abb251e0da018093328bda5c74f3066e7ecdc6ffaba4fcfbca13b9f0dbfc6345fde975ffa90efd7c666caf73ec71779f4e399f0233dad97fb5c3c0fc02dcf838f18e8f7ba59075f0a2d7ee94351a8cba2a1a9c225a5a62085caa5ed061e5dad399594e696818870e61cf929488d28570b0123133bac95e15813460422dab401ccb27814193ccfdc847906d3d81d6290475a5f4b6c117a951be3905572247ec211f99bb575d2a3728819fe4d7f35aadc2c0274170b6fa2632cfc236e7e72036cf499b1f7b1e3b9ef8fbdcb57e6426adf607e60615b18ee988fe4d8ab040c823ffadc19dc79237947b56ce88d0634755895f2ace121e609d5ef514edb99ad8f247351a2f5052edb025377e5d9693b1b495d94fd3b61c3b1d0e534d2951de5519b5259df8a1be57cbeeeebfa6c04facf1180da94eb593a7cd1aeb8c8e1bf484b985fe631da9f3fdb1be407b61147476cf2cbbf8f76fc2aad137d31735833d1362dad6ae4e9d2a2460d625b034253775ea84a66bb43391282d96d8e693390156a528a625e08038dc41dcac72081e269c61fdb39653eebbc2e18b1f104b4431a0e62c2feb67197ad265dda0b6c6b73ab7915a55a25437d1b71b37aa78fbbf9c4ed72669fb252946c3be5629b00ed72eef636b9495d947b8d88322dfbcd616f7e788ea32ede75fdc284c19c5b8c45059a4a8bad11701f53ca3a9453e059992946388a781ff0b2bd9f8295c972f4182bc1f0a27f27f5d40834970b88a6c896ae1cf617f34a9219d51734676d02c64b9cb32719a23805e30d6770ea1557724d95288b40a622eeaec4ce96875017e1411be39b7311dc489b308f387a141c2e929d1fb0b70bac93fbf8e5fc734d49f4457fe07776b1ffe40134c0fa6094d27ecc473298e791c6b8697a85143eab6789ad3035601995cc4f4b39a0041a8106eb18aac6d7d9735ac2a1b46a2d00c8a139eecd7369e045e3255a3d9a18a8c3aa06326743a14566c0e5adb0e3471ccceef7a34d02ccb73edf234ef4b3ceb408fde6c0e7099b37bb79268f75c4844400e6f1eedd03b6f347b498a3eefbfa66a3e661f46dbe2fb1fb8608dd7dbeef2c77c8e7ebcbfe36e1701587b59a866c9b0cdff3d19fc35c1cdf056feb18d0f7b662fb0f788a937777b17e1a9ccb3bfe5aaf58c9a1bee74d8bb8b6d72c7eff3c5372e8cbfb45fcfeec17d112e770ebb39afb065da723b98dabbaf2834644395e09a5a2b41aac10b0002bf549aa684feed63181a3c010fe548706b5cc38b0cdfbc4910b6637029518484bb8f342206a28cc6dd74b748c29744fedc79973e837399ed4614dfaa977e2aa7aebd975f993faebed7cff33cfb09beb5562489596284b016d62c0ccf4853fe5377db70e9c71c725a8cbd684f621ead08c84d914590c11083bcafb0603512f2e9a75a23d98a2933d6a4340956f782311a0d25d52fa08302cb6cca6060dd93262752779db8b88b791ba6544e56a93da9ac66d354ee80f7a237fdebb9847bc5da5e005cf75c157bb09b61d6589dd7671888ffedafbcf5ff63f7fb7e7fc99e53ef9218aa4aac944172e86ccf5087c0c2c84711819082a8a7229182ff4a0a86da2a49bd2cdd6eb58e797fa131ff9cb347c3049c840e2787a1c0a93146c1619b88746a247698b3d0077519d911a28bbba56f6a926f31fe062c923aeabc4deaff1dd9a7ffff9575c2c6434ee511d0f3d926e924a86b48b3ac66b2db1d83d26a8486c8cfd7090052a8b63adef7a2143b8147722475b5a315f70398e68a65243291134620ead25eb0491cab5288b000bdd82001cc46cdc22828ce00217cb19dfeaf1075a8bda8dfaedced405fc5ff4d9e13a70ea025b4d2fd2e9322a60c7b8bb0eacd6c714e3384c372965ca736081742418ef75812d735cb6a100ae1501e161031944cb84a0721b58cd1deed41d524c88fc6f2b468ae3422f7995f984c01e57e8ca1ec82b707857e4f8cf9d43b1dd5fc61c673fd023d6a6b9f7ef390290ad63a08ae8a0d7f76efcdd19e45fd97ba65bd2d23ad1c927495144c3cc660acda8650ee7948dbc45330bb8aef915eb51060103ed58727313148a20dacfd37cb0c29db741251a214d8c6222734cad8da8ea66ce5d9f51b5420eeef9855a47e5aa159abcbf70065da1d56d9aeff300ff7538e74fb84a0fb993e31aa88ef5e2132cb3e844285452e197ebcee3a94ab94ac0788f9116dcd48ed77ee13bab6ecadd3a29e1761ee89b283c7077bcdefbecf5fbfb1f7f8f7fe8d7fdd60f7ec354ffd7575a4825cb848debb4fafb7a1d0a2e71f3a17acad5b328fffc4477f716b6f565bcc39a0ef43a29c5fa57bd4b84694127a174dcd8b37a4ba2b53609f1a374e07d9ce33220ee44f0716f66799aafc1983a748b686b31c52a6e3d6e7c822669877d42659b96bd4da068cbba018a47d69ae799c1ab5a50276b59e84682ba8b4443d7f62ee5895d347b3cc845df65bcf3e76f90b7788f87d89ffdef3eef7cc8f1b5982a13d9684d3832135b121f601e73f329a67828d9b8472d34f24ad78b2be53047c2840d16336a8ee9a28f236a32543046f42c67b058a79de07121111e09481482116798d36cc4c9c021852488ffffec7d5b77aabef6f65722201dcbcba5121025969003e40e886321044a1515f9f4eff0d0a3b6d6fe1cfbe6fd5facb1db6e7f0672989987673e4f5d9250fa5734d62ef82e9ffa48beef11fbdc5ff24bdbfc7eccd779d60ef909e235a7716ef25f10809557d43b11fe6de9eecf921204239dd5bcc238d2b0cf8cecc90fc550ee1a48cba8f548b49339ee62de4cd24a6ce2028c71052339ca70c0c45344329658ffccb494ccb35cc5c0c094f0c99c02fcc043b862e7bd8f577a7af67189fba13fe5dc6ef61771c9723904596aa07758a0cb389b4b9c47af589beff3b76f3d41573175e37bacf726298f7eea71dc2ff1b25ff602e2ce3389dd6b635d8c935d63f14a625fa90129c4c6d7d59812ab77b167ed3876b37feed4eeaf7fd89b7d879c355a25baa9a6fbfd600c3649850e9aa7179ee7845fbda063f625bfc8a098b3ec916ab0c76c114f0db14b2ce422800151d0454484e977f8d59fe7cc9a98833ada7d9533fbfb7dee596f379263254bb696ce0ff88def35ef062b5efc9497397ff71ccd4153ece7f37dcc0358aa12b61bfbe1c067caef796c30207ad6308eda99a566b131d8264c2a3f44c8e7f5d62b989d50b0e1dc3318670f1e1deb5ea9e93ec7c5dc4acd040897b1ccf4691b0a0b52e9d450704808cf46b311caa7fa8df685d7fac96fd2a7b9b5fbe4431f780b2557c5e933bd1377ccf736e2d8139827bab95fab6b79ec7b71e39e8d7b5cc3bdfd1c3791de5fefc795c3df70e28280166c441df48c7405a646b640bc3fe51c75b8c848ea0c6c529a5dbcf803bca2cf1974a7518e1fe8886d129519ac88bab9124dc2f08694e851147234d150809d4119ecfa0c917f9a2840e575591c5828c3bc9d9ef9f1d772d4c7775fefe3f9d35abdf432fe64ad5effbb6b755874877ac3fb31dfaf5152c24604da699c9bd6a72046b1f43408588732af92b348d5e320648857031ae9f2191bcc63411ff8c57623b99bf3223209c816d8fed31365a4912e3359f517f865b4155c9099c36002d406859686ab7f86808549748931c82a3f44f80b0cfac57ed8abb5eddddde6f475dcf7f39a1a6c9bdafdfdde6f6fe74f016d4cdde7d8182c086d1fa75ae6a13c33277afb841c6b3bd5feb484d5769cbb011f8968aa350de15637d1e5048fd0c304482320309e17783c0f919ed2cca11d6ae84834f3d2f423bdd9721b181e37dd194793b852c1019ff8d5dcfea44fe23e31d3892fede067be70a7b5b771111ce62f9b00d632fb9f16eb3216bb3e492ca98bd27dc056b615c0054883034afb4d12c220b0eaf5dcce025ea851a009c646451b552e8f2d732647b4e76b206444f9a9e62e648e7c6ca198d16cc1aa0c605b8dbd1268e7b5e3fef6453bf8dbb84907fbf750e2ad06f2139fa77797b93ec4f2ac38f2f0b22c094ef37ef677edd01738bb6d0d6c4a7b1a616e2969ad023b3222cd5df8059860953d05005969b0dac5da816774953077284ba4e38202bf18b701aca7dcc1041790603b2b12e7c99c177d218dec6966b796b04d3da1e051047f9688a322d1d8392fe9f7f6bb10bccde6fcfd7bbee7a2b9e62ff50f1a5ec2beaa3da91f63d17bd89b839658214e79b277bf3768718c256ef19318915c38ee0497e644e87fb4b95def026740e715ddce43774c2de9261c7709f54dc4ea95008a600e9f7ddedb0545f380edcc6270e0cc783364362b13da5f90916b4c75b312ac5ec7bc5d4eb43e9f51e478ba6f30fa055785de6ff6feb5e0a636e5ac8943ac1d3550af9c83cfbdeebf3d07e16093ecfdcd215009579ab48f5a6d5f3cd73e06e86eed77a1a5dfa53ad5291d2f53ed4fcb1cd9f2b2ee2200773274b7980d5c51fcd94e0d251285ea2417786ab896a7834719e2b1546ce76bf029a8d8c233c6a6e7b059b4680866682829dd52a6367e5e6c39c76514e28ede9eb3df2425cae4103451f8f7cadcff3dcfe3fd76eedfc63ced69338fc2031e6a3b25c7716ee056db057abbf388b7617a5d8a117b4c0a6045bc06a283cc2f71e019de8d3997fe5a94aa4a0dbc49cb6bf128bde3bc885a18484b0cf7c55f7bff1ca77e93dbce7b44c13475dc2aee98882d7736a7ff768867cf33473a72345ee211dd51236d31748320ac5bbf925e3a72454454834b206656e3cb4a68b204eb8864640e4530a335e2395ece0b60a13c9b79b9ab27360c52bb51f80a26e7e7b50fbc9143b04dcbfef60ddb31be906f9607bc99a8d86acac5c71ac959fe0664b14e1b61abddb77d57155bc72104e2d063f19ec7e232a643eef7e4a14f4aad44005e3885bec58dcc6d5c4db99ba53a2be293f673788cb1afe5b43789ded4577343e7dcf8bfcc0df537b1ae5ef6e3f167f2778d6e38a3276e7a232dc4126b758fb17187a9da70073f4e0cc531894cccc746a0b7f5dc76334161280a17fbb9d2598566c9a2bf990065a05c55be92846a783a1b8d410ce14c58bda5d4a2debc609ec851810b7335d59b5e0cd8e0915ce2703dcd1fafafd7baee965f3bce5b5cc2ddfb793cfcfea5eed677182f604c745844ba78a04e96539bb9936e10268e08d26abcf1f4d661c59f6d54f80662a8c74751cf23309f43f4e431b9983bff8c39ac87585bb582090ddb919eea452f2dd35d62676bc6eb8e152dc2052823e5ba3294839b6b037b1b76d0fcde36f1d5fac0dd727a073b79d0a71f82fa25a6f8f8b7a35f7b4b6e53da51cba8aa52ae745c59ad08a136871025162c186396d4617ee3bdbb131c6a2f58bf38747f9413b8873fb9f779e52bfe50ed8ebc94e7cff33b4d299c079a883cbd5e7b16d8061c4671a9ba04ecd73b7303256060d4594ae48357b9716064e5440324cd158d75dc0436e818c18d57b639b1fbcf69f9b4c145b69ad9608998e8110e841f34a584ee920eff7489d6dc5cb34acb7e77e0b12aa5fe3fe29dfb30e6e1fc1bee2635bc260add4a2e4efbf1b6380bf84ca8a9ee56a4c856d4c6bec70444102dbd510666e16010e472e385ff36120a2ce13f03011fcccbf689f30c48ad1f4a2896d472a1b4b2421611880c4b9b41f1202872102fda79d1d30484f9cc191804aaa3e6de855cc1e9ddbad486c60f34a4b677c10e9ce62f3506993c6aa77c7a0eeda857705bfea5a605f683a261140a480adf1056e6932edbc5bafb98a8c1764eb1297464e10a877135504c3347c2287a0cfcdda52acbe730f3661077317015e55b9d18eed02b526302d8242d619576b0f508b325c739d252fd4a2df0e7dcaa079e65b01461f1e6735caa47e9998a4ab816078ea6631cf93d97977c8a397afaf0992b75abb4525b69ff69d2fd3876bf79d5fbb9ce0f711f2e51c33553076fa6a19b2525de246f3edc719f7cf97c5f6210bfdb33ba170e5601f5bb3951bba9defab123ea208746aab22db199c9a8727cf6b4a35a36e30cc3281c3468f7a7e713b52670b0998782a7231404bb3ea49668939c2d7158afe74c569cd5b314b81a67ca65ba0b70974d6fe53c16363b612baef615dc21aec62a0af1d38917693feea98fe006ee170ab39423ece7b2887593e142c0486bab8415005b728175d4bbcccd7f910bea32dffb7fb7e985e02e38f2659fb8a08e3cefb762f5a319cc5a3a4a371eb7ccc880cb39548657a92835bc16f168870a73ca34778b6186c5e8ef46d2d52600835640f834b75d3f228589ec6c3d2feb1c1397a70c6eb1835622a70075e32ed21a9fd1be4375803839c79ffdb6eef8a673fbf75a9daa10fc906fd9cf73f7bede7a7dadeea29ff0e5f8a77dbab785db43bdf7431d553b8dff733f51680d15167816967ac461a407851a61a8eab4f28da094adb7eba3fbc4c6a03ef2e77e9ccb775c6e57d6836da77cfffdc73cf5ffc0effc30e669dedfe9c89dea25376277c448e588c2220e218fc0781994752e01c351aeac58cf265197ad8566ee3c0b64b1c586d810564c6b63e60c00d3e1c2ab549cd8ff9649d964a9d65f73f57789a9a43efbaba7cadd7a45fd1094d98457b54e8aa8772f2ef4383cf97e1cbc61f54e6b77ce89aaba29c7079f3dd1dd67c191f661adcf786554f7a997f48bef7dc5b2d41f795ccfb85d365159abc8f04f58fd6f394a8ffdd1cedf75eab81b691fb5f2a7a558455cbe7bcff14ff7e881e3495ce7c6be0b97f1cb9e3cf03a9407ae824fcfa16d0f1c87b7f9081ed1b25e40fb1985aa08ec76422b3ca25c580113b1b48531355849c8bf65aac433ca7d93166a3c2f5133358423010cb8253454f4fd942a9b19a8f1540649e8ce02ca3406c63a7290f0680b03cddfc9023efec247d8bf777d95c3ebd0a3f4dffdf7b7f18ef7a708ff36fb3371fafe9ffb0aa1b74b54baf4c8b887839541215b4e80db0596bf443a9a71a77ea0b7c58787f54e38db89ab38a493aee41d7c26110e1a11bad531167fffbba61d794d6fabc1053962422b34a1a9d5040cc6bcd480a737ebd46004570338d14d4835b0439aa6c95ce1489743043cddd39ae76927c294821a2b38492d77c8c3a7963afe12e562c1ab81ef01cb208e529ed5dfcc28f083971adc796c58087ee831d59243bc61ae5f6cd7ffa04e7f71ecd3bd538a70dcec638048efaf93830dfc4dbd5edb060c15a4ec8354cb74aefc1de6ca4e60ad7801c7be623a35b2263090c10a04459e3db14e4e992e1d645b3dc20494c19f8e95635d322912a35ec6955acd29ea093298f885aa69316e6315698879860725bfb5ef65ffae3137d5341cec1263a0d20a5fe0d9ba180bdc414f062bb18fab82630e5f84ae1673d6bdacc185e73ac50a3f3eff87fa86a7815628358d7377459cba200c953358bbbca01bb6686219164bbf94162aa316e558cdacd54e76b210bab90d34b8f30bacd2428ad4d2345428c1397a4ecaa6a09689623558cea8a5b3420c67c35547b566c5e1bdea1baff7ef41b7ffc39d4ebed7447999bfabf7e2392ffb6fedf569bc937ddaaf2bf76fe7f50c95f04af741963814965b138de1c419d8b490311ab14e54832db9d95e5fa8e7ff6fe6641585ea3d86e3e42f7c7e9e5bf37b56e319f52eb641360ffda5d741e81b70270cb445b6cad3a27e9cdbd9455d0d61ab525cd77df8dc4bfdcbf7df8f75d80fb528a35f613611c95649984da966697e619ac4795a0656865858af88c6b6a2fb6b62152d4518e9bc00ca33c424e659259cec41e8c8e079c6138d416a8301b1508c3be525212c59d99f9143dd136b01539415a92e2916e84cd7f25a9e1ed7e9025489dd5f5c8f55ef82ad2ce270dc08bddd44a7b97d19ffc47b7763cd4d2e5325b7332a03643591281a8787f523b1019554f29840c634514ac3eb5027d7338e7244e846da631d3bac9dd3484f6d8411858b986670ffbdd819885918e9890e499abb91afe15a58b221a12ce685fabe4ef4f3fcc2a1cf681a1ef8276fa88de24d74c4dcff20b77097dc7e91e8a7fce1d1777b1dff57fadda12213608198a027bf8c0cacb94b31c253dc6519d2d9901466480ae9311b426948c100abe3420942e4435ab6025bdad62f4414d8f5338572c5c0534bcbd4601c1602d62aa0b889897ac6391a2721ac2971efa5dfad528369316fbb0fb9e2c5f7315e62f8cd3e4e4cafdc63c77ed97bd8ecbe76f4390eb89377e36be0b65ccfc1cfc68464ad67d49620b4173b90a5bcde450c3e26611d7bb4758391220cc009b3f7b1191a23bb9978651fcba28de34e06918291acb045881be1d0ea4425972c5723df107a30c29e4f0603b6683642139d5f68bb7bf51cc6977554aeac15ae856efe000ff3f750cfbe83ffb891b6aa92fd393b9dadb7dfb5ed6dfd2987f56258930ed305894206521df2a0f096335b546cd1cc582586dc6e46cc065ce6b28b3bb14ef4dae2aad625ed33524836278338ee304bad0ce39180d8ae8967d75bbf92b94fd17ecd54a20b7d1ed6c308b8d6bdea3b273d99573dd317dcca15cc7921c3c14a84994af36b3eff61cdb43bac1948ed56cd6db63bf68dbdfffdb8663fc79b5b0dd2e55858d9546a7fb633478ca7fa588f4b91fbfa9f5ed4e101b1faee6df7f9b9b6f9f79a227fef118bfe80af343d68f3dc563b40865fb401a60a23add53915430f4a9356c2881d0b909cb5d4ce72a406282e7c3d52aa129a5805848939c555325c6d6595b58889715480475c414f74f24928f99084b4c7462cf618dc88326b98a59e8210df8a015149e937891e7dc5337321f6f7efd1f77036ee21e6e46631e5fdf2a35feedfd8ffa02d6598b63137dd000a9ff27ec62a369e2bd7e4b6bff3b8ca49d0e449e56bbe515b2874c389668ebc503e13c008b3fadd04608534f128733988ad9e219567ce87fd4d10aa2702ff020ac76d306cb6318483c0a1e05e363fd1cdfc5d6f98760deb2cb8798a5daf6172c76b6fd7d3ffbbed60eb937fb13badd7cbf88db7d8dbbbe8a6d862ceeb59a2063bafb3c05413cfb4c30f4188d81caa4a32c528fcbb1304ce820e1748a3062ffa5e1c2ae1eb68810bb766163003ea2fbd4aea09710db468b67cd1df080b0c908e8258af9f523058240e36fca2bf23f6f7d8db9bb9e63ff6a36a3fe81955e90e64d181ef13e657f524835e7be02fe5a69a3bfe3d62974fe31fec5c37e5f0d0071b71a41d3045076e66b01661a6dd8a650d0866d8405b9f0c8c14d611d3d82c2df1c073d8382acd2769537d36429a67403aed20c7c53f3362ff76c2b200850322728159c7c601cc4a443337e1b0a53678e636e482892582aec374339bf3b661b904fe19d7cf6fd79475d3106ff6be67cc412d6da5bf3b8bbb0b75945272333ff4922c0ebd22c5f85bbdbf2cfb58c339eb2d7c8a42af490dd544657f75a5de53a73b70e0253af2d1bd7fce330eb6fd67d782cbecf84ee04184eee65b4cc9c5fad4a5777aab4f2515da7eac7bfdbbf0bd5fe5d3befb6ef3521ff71957c56b1f77b58f1df0463a6a2b02731ff735e2c3da5ca8c7bd723c9bdbb4ec6b89718869d7074c4a88b428743fd7f3dece78f0d1eea7365b0b9bad235d7de9d7dfa09570796efe03eff769ec178eef93bff3656df7ea79f78206c71acbe7b6f2126b6cb08299b8c2a65fa626b2e97666f507a9215aa409e697729042dc4e8d7437e760441c350d4a6951079951e142a284e61319f90042a1b1686e357ea29bce44073a676e2f1ef6bde0277cdec16ff4f40eda99dd9c8345a2b7dd57ebfde12e1efebdc4bdff568be56697daecdcce5fbca3adf5ec7efcfb179e616febcfcfebdedecf7ec7c3ff4c6cac61da1f7ac4da89a21fc8506dfd50ada61ddd32e5f280baae8002138018a312074e3d414e36a4ba5bcbd1bf76aedc2cad9e0c0cf053ac319b57454b4ba478e8869c233fd25c9b4268048e1a441dac6ee6e1ff56b3f00b7bfffd7dfcf91ef85d8e23f40eb5ad746f5fb8d2e2501c712e97fe4e0ebaa437e614e188e8ed4a807a226dc8924e353153c3486b4731c42ca2d92c2e6adb0303917690c71c5b4883464cd9b3c71b31b71a4519cea5d50e44580f88f60ff0a20982d1a0f20a5551bba707861c224bd199ad82d411f7ca297e75afede3804bf75a1185584df9cbbebe7a679ecef7f64b8ece4bfb24d2e15604a04a74f883fefdbb607154aaa3eca0eba3f7b3173fedfd739c7a126edb17e4df4652f5141569eb15a88bab6217142c449a6fa65676e06f62252453adbf25393223dd3465c156ccc606216c8d0a29904a75415c97daac11957078c91809613ca3d6c6d3641bb01a09ad59fb653690bbfeadd8efd7f77ee36539fa21d7f28fc735a777389b288fc2817ac39c8217bcccfecefce6f98e3524f4637c94d5e0ce1dfb4cd418c0962cfeecd2b206f3b036020acdd8025eec607c63eea44b6cb5be1657a05d6f87eea239f632de717f1e7fd68c693ebe594f1cc1711b7316889ceea6ba7a88400d910657c42900aa981b589945a06f20a81ee6b9ebcadc5da1b2b122a6741c52733e6c0c42c740c07a902ae1cd2012186484b368c729ac5037b02390024ed81a6b7276ee47fc326e28068b88bb2a19f6f344dfdb22b17be59dc8d3b5b73fa7e4cc16fd15215aedf7c5ebbc396e7ef2398e1aff67fe307c962f7abd8b5e7b9987febde6b97f99abfe232efff4d9f4bcb7e778561792a7efbfefccef16763f3f62b7e9b7bd741f7315a73ebd5d0f9c7dee655e429427c6e09d3edba518e165cf01206db57aa7bf7689a759a57a5b2795dfc85275718837e9e2431cf2452cc4bad471d53bbef80b1ab5ae4a0d0844e8bed3ebf52f7ed7a1c7c9f9c03f7d3eefc71e4595547bfb048e9ce4c1ebda5fbadbde62d112ae0e36690816890df37807b4b464ea7b3ce205aec1377d8b0b9f75b3b777b0ba23deee2c863cd5015eb9b3b7d33c3abb939370b0492bbf1107fbf3efdb3d147300d272ff2fcbde3e7b212ffea2ed72a8d1be1fff6c4f3ca73b60461cacde72f6d6a5f57d4ef5fe7a7f279cf8df4ffd0ab21655d1485d69b1dd0772080e9f8bb930bf9fef56c9b2f7fafce812f7a2dd2fa2f0b596a04d736b6f57cf3ff775dde1d39866261db68bf8b639f6cfc3dde75ce3e7382675709de86626df784ab7d3bcb8103f0f76892e0fd8edef7b554e77a5f3f74a0f0c6bf67ed5f8951bf5334fc315ed9d4bb981f06f135768932c8e7d35fb7dfe6a2f7617ed85f6de073d9ebb331f543be4c84e3c7c6f7374a107ba8a7ad323c6bd4e6cfac273ff51f7fff75cf167fa343fe08abfac8bf42b3fe083e6e2de4ffaf03c07aef8dfc5980b4e4419e754278061cfce98479b675c98160dd90497ec21a54d9116d0c42576452806d8566daae45802b48a4a30240518a72396c59d5ba2d1c04f483661963009719b34cc96b8136ba13763d259ad58f4573fd103fc1063065fdd9957733bda45cdd1df639df6e39ef04d2e103bedf4fdb7e77484dd8752c77a42b0efeb6c8aac5547159c79aa1e79852b1875b3b9233d9fb9a394d50de1b586f37d8c01279e72179e936d59d96eb072d7bed6b7a4019f5347ae7ddecf920e6f056f67337bdbd1a22e648e2aaa7ec0d7feab9c0ee85eeb1fc1fb38efb476df69729dfedb6be7e842fff97f3847e080bd4c42af397def2ff4dc901383416f02c4330971e31381f8686c249aa5e1c2b5316d6d1fd431829ec61da8b0d68f7c23d2670ea613bd5e7886584e816b46b409e968e033ab3199811b0211f2ecf132e298318be951e5b5d46259303ac3a79ce6efc7baa587bb341d8283cdf891ed3aef43fcfd9c7fd43a7bd5d67b799e83becbef6cd7408662ca1c970a05679c9a6e64e005cde1740a94c3e0b8451dd5b1a172eaa00ae963332a319f510cd290ed902d7554c2694ab328e2ff74049e7a0107040109e739c3ac448fd26e4bd6b93b5e30200cffbc57f582edfa0f5aa61f74f5d0672ea6d3da7e671bbfbd877fa2597b9ef7ff6d7ee5658d8f7eddfe5e3ef5f9eccfdfd7cf79d25ef8854d45a5f0a35d13205b3d4903faa8e86d22aa74af8c5aa181f1cc6e1f5985434ab34d4a3d6d4e577a0290c594d844066bfc1095be019f6390ad53ae04e159434249a63a8081d56e11102ab65bcd33e00a952d8c6fd7bdfcbe6e798a9d5ef86ea6875e3dacc5fc2acf56ef4e3d82df3ec3317f7a8a1df989a76777e819d4a4ad54bad07abfc08f0d05a801818c08da3cc8b2f5a640b0b8fab7e17c6ccc46925332d6a9a29dd0e4b34f501d53a10b076da79dbb205cf08049c6d45f43da754f1eb0487419c0bf9a375239b55b5f16e692f27633cfb3d18c40f57b3c52733177798a8fb789c3aa98f79a7d2c2b1d5c5fc70c7877e20efcf6194e39b5e3baa6760b84aed61fd6951c9fe3b6fc37b3824eec02e5eb01358928d163d2510df1ba8e68dff0f374eb856c1084fe6eaae30001b9c60a6eb0867832b2369882565870e697c0601cb629b334c461943a6ec72cf94075ab9bd1d6f5d8c094cc1dce9dec5e18cd77fb151cf6b208c74d6cb3556ab3ddc79af0156cc8853ccaf79a2af7ca5b9fd652479bd4a61fd7f7f8b706fd42b7ce2bcc9ed45d7baa67b167355b110e04c9073929ddcd441333a4b24dd04927a2d98af2ac9a0ffb4f01ab574889ccb35d1b8d584069ff51ea991784452f81d08a2a368a392ca8d68efcd21c7b05b2f9e14cf920aaee8515615d5ab25c866ef72e17f2192b7bca21e15d141e7c1d7513a6e425aff59a5bba8205ba0b8fc0e7dcdbfb1cf0cbdf4e1ce5b7d95c6346704199da44213365d95a51e777dc361d3fcf568ca0588ed2d633c4ccd7b34a8e3064867ce216f43d952dfd4aac852d7a381f0c84a6da40eb3f46217aa696f2e7e5931954b0927a6344051278f477c37214dfab67f8edcc893ad5959618e30bfdb81fceeda7fd355049895552a20b3d601fecb91e87a896767f77836e587b7e0fff8778f3cb77fdb00f3e3fe7d71c8dd76c3a1113d4b9b31964b388f8ba57c96caa3536d1b036058389a72986f201c1ce60e40118f91d1cc7a5d7fa2a8b525b785ee19934a74b9f51232e33e559918e810b5326503cc21319d225518531b77b4b54e23a85ec73edea6a5cf3337b7c616f5ce537bb03aefeb7ebb5b8891be468ab1d9724fb7b516515766a37d57c3da1b2084aa964555722ac5d443ccdd7d90ed1ed46560af1d1601938359dea75ede77e172bf7498c9460bc4518288f86c56e5e0d76a4041b36cada2844236c603101300b8c5b3935dfe5f4bfaf937dce05ff76eef7f7faa9c67ffa99a4eb43def1a6de93a80b0a34f335aa238735b126b6096f6c6cc00756341d01fe565abd9657e3a5e4ac25b02e5318b5441ff744d08c30973ed3ad2531b251a2c9b167e0756cab86d0c68da8db205bdbc81206a9f5b4890d3798e7eebdb848b248efef92c56b0de552bef9f419f09c1a2fb97d7a98a3af6b445fdad9eeffececffb776769b96aa89ae9dede1591ded3f9cedfd78c7f5386277ac53afe56d3eaea012e0421808b0adb0ada5e8f07602e0589666e841d764f0df8602a182c2b548d0af7c03239fb98f9e8d3cc9fc5d602318e826a58e788a55a44754aa347447fea2df4585b9494783696ad48d67d75dc42443d6adbd96ac4b43a6d2aaf81ff1cebf8e778c234e35d629b16e8f09391a615b7529941a0ac53870b04158b1e3a13ba004d75121963eddf668e98e11538e5f9ab15f7aa667817d0ca48bb259528e2669f96713b1baf6196409b4ba94cb1d679e8e47429f59324734053e805dd4a93bf6ed9dc505e04c2ff0461caa38e05be061ddceeec18b6b7ad4fbbd53feedc33b9deec577cfa39d78846fcfb3f955b620857448a96d69a5021e0a26ac6c1b84529f5115ce4b86662c1b25b6fb3877e4c66718e0123f6222634c841158db65002dc046d95302066862d4635982e9bcaa3b1cc22761145b6cb818b17fada7c3326677d59a55a9e1aac8d8df273fe036b90bcffafbf8f464c35e7f3fd5906e8bdfa609175332420b54a44baa329d8eb299178a9d0770ebf1c69beafd112ee5da2b4cc12da6a5ec6f6faa6dbbd46ab214b201b2d25ea4091ef1beed01c4bc6edcf99aaf71476de9a25f8a526d021b2ca55de85380b33bc66f1fcfc431cfbdfbafbe8474dcece8237c5ed38bfec3650eeddfdf4fefdee9b8beef9ea739bddfed7e02757b51613a58339bfddd4495d219c7e3d45286cc95cb8c5a11a2225f6f17c4c88c448354525190431f0fd5a59679132dc388f9bdd8eefb24681e02473481513fa41a6b635b9a9e257794b0c8232813a5bab79ff0b5fd3bf715eed3db7c6d2d86b7eb17789d5a2745530a251f664e36f3a8cba69d9ba34ead67dc1cce6866cdcb3fdba4548285b087aacc4c195bcf797f902868ce99dc12800b5e30155394c7a36ce85714788469c891db19ab1b0144c9ca6c3da36c983ab7c75a3fce4b0defc169f33adec96738f6bc9ff43d6febdfe40d4f75d4727ba5110d6d519e119e0f8a58973000a2468b3fbd983f75de6830f595a44165759efabb115029063091da4af3983499936589d56b05731b9fb078c6189b6a6d34a3be819524098b4caa41311f89efe3ad0bf7c58907edba2ef95db8bb5f38d60e7bf7856fadbb8dabfb704794710581df5133d27cc33754882ab6232a9b7a96184a2e96bc449b984a67361a18cc61bee4758448b18db431600e5e25f9788b89cbfc1c93299003aa441bc3ac14aa5e79453b13c05b0a000b6a2937e6dae6ca1d716e1f4a98a5bbfdd9053bc94d2dbeae09b69de6e93d72e865c46137ddff1eba20a9709df0431efdd2df1b6f78d48ebec566f895ebd21166d2c623a2f51b5f87d154efc3d4128f7434d668a116316f325f73f1cc5275c4239d973d8086ab655236340885898acce44e0d269d0752e39f960258f839366656aa4936b0fdb07e4ced8c515e2f8273bd892b3a9f9f70ac173062e7ba88af18d5333ce5674da0b13ae8fb5dc02c1eb9713ff4a59d7d4664a9816b51bde371feec870dff2e1243a8b46c37113ff257489b9d7a053fe6823fe540da971c065af4ccab359e127672080edca9c2a68d0cddfa84313be9e6fc04337f8718f8ea73ecedc57edefce6c8e58ad53464bb3838d4d6b7896eaaa47ae1aaba512b496baa00c80a71c6e68e0878210dd665b62cc522a2ff0c9f65241eb93919aeba386725a1f28151309a43390c7254b01c6508ecefce6227167d40c94079da58673ad808cbef12e00164d7941235660abb27dcf8376bf163ded6ee4e3c7a6514226dca8f1c8dfb7315f1edd15e9cffbd39621d6fe36f13396a29511b1a16669cbb83d872d554fb67b2c233bd507a096d86be86d8549716d1cd2929a0c01d7b4a0df98834d70bf4a7ed8c6639a29920d5931969d29dec9a5ee20c2c5f5315b6612da1e8bc111a3038ee2178598fea658e632ecaeb3c059f7de8ff34b7b528a3f7737ae0d3f2bef29dbfeb79b76a90001f4cb4ad3963d98ae79926755644cc2d51017b9ec21565a2274b1913a036d46a5a5eb132a1751de5038d8cdcfd9deafb453f8e72b8658559053c5ba514af7c3250a41be49e218752c13c09eb1ebad95f3b9dd317ecf477f663b77fff3bf4dc1cd7f5c8a1b5d33efe4ebcb5b7e881dbfa9c5c4b5a2217c0d7678eac19c4b5044fbbd8328ba0147960994b41544474b1963a185225a3d8062ad0b45e5a445b664923a1de868678e301cfa0653f0e8cbf20d2d58a976e6f5efc0131c3330661172c1a2828be579efc6f521ef8e9ea68d12fd39dd9491b6a9ff89a569ffa4fd67b7b9ad86a31d54537ade4bbbbf3d03bd89de5cf0f6b0bb651e8eeedee5baefdc23d7be259ddbddd891772db25a823c3dd241c6ad12b2efff25d9cda6a6ff3dfe3d54f9af0dfd6b84fe7aeee12bdd7a4c6116ffddaa3a5ab72fe231dee3bc470c7bdf95d3fc03b3bf1ddf3feaa36be8a6d7f23b56849ec9539b3b238017824ed96a7251c4b5b3c21968998d76e5cc215b7d1121928632106113709769447c26c1dd819e116b3820a8ee7966f24210a6696bf951435296f9752af472ccf7ab292e32f34453ebfdfa117eea5efe1fbfec8748deee1237f31fe3bfbf1ba461fe73cbda147ef30e7dcd75b41cac64f3aa9cd59bdf32c17a5ca0dd3125a84e189d4eb312ab11bd12c9feae38d5faa01824f3b120e7aa9d5c47e4535c4e19233b1f06cfcc82a89a322da7955cd08074fc24e5ba6d73bc6eb079ff67637ea65667115bdf53f90cb7eed1b5ff12b06e51257c44e9438ffc401fe055702e8620eeac4866f7376c0ab5cd51f39ad5d7bf0dd533dd30457ebebfbe6ef1a2deeb56f3e8efd6ecfac8e9ae7e849daac4e16da69dc9ff77452a8b611a837a213764a014aa9c4133d0b66b00629f78160ee8d3a54c7fb382d59115de766be17c7e5719e425709fb8527e6e373fc8aeb923722b57b1a0ffa7ac4dbd18c82222d14119d6f48583fa6500d49d9a7dc6a2a36520e67999d5ad96caad70257de32b1c492dafd3a05c592d86848345c0440204e0add67f8415675c78c688999b74156d3482e8ccbfa72a777d161f9c976ff244765fcf73cca97e3bfdd1d21ca44493fdab6630ecbb8110ba925448c8453d349277aa986975ea9f568270019653c70b299d40a3da8d862a253932845230d366937eeb1d13f2d8538f372e6040af2197fdafaa0d8921cee08c99e820ef7502977a915ed7c05cb49e7b612882f34fddec7cd57725524badb1efe7027d8873b601f77e937d76635b48a58e6fb205d929168244326d6dc9831d7f175ac020b0c9081012eda0521e8c107f55a144af1a2bf8e75318a69dd264afaf390b5fee2cf26e070843b394eac4697ba8b98c3a6a2c25544d0b3e4db1d3ae7b0fe3667e2dbaff3bb8978adbff59ab1ddf8a3eec867fff16d9e8cc12e313273ca61219cf1b7bd98113ff46d6491e13789ddaf847ed28f3af6df5eeab5cc6425ea64f78a01b9d037f3bd5f71f415e905cdd0d777dfdf71bbc418bff5865ec8cdbced056044a1bbde8ff16def5e29ea035f5d583452871fefbaf3cfaea21077f275fe0e1c13edf933b7b5d0336dca8179d08809994a0dffcd773eafb5ee7de775f2961fbac449b5131c16ef7cd2936ef9711dcf6af2071f5814d1ee5b9e8d4e7004d292bef443ece386d7fad8176bdd090ef4b75eef03d6e92c1690b65acf03b04a2bfabe0ffd0a7ff0a5b5bec29bf91943f46b9bfd61dc575b7d383b9cedd2b2bf3b6823df8aebe2fd91a80679aae1b5b0e51a4351c5b430a24ada81064192bb05d9adb478f44f9385bb8a81ec986e3e4cb53e0b3a15082e4ac4989d6862e5e57e3b87b826361b33f06f231535e765633195b59cb15e5cf48dc046f88a8ddeeff35df2134db8e1b13e7a97b8ead399fc68b7dffd7d3fc78b5b799bbd16335849ea1ad34eb5d2f6da74d80f192c34115a26d3401050388af5a76500714e3435f5b85a230b70c4a11d31389ab17a1484fe56584f46ea8c4154a812d9ad9f5a99ee87d8f72a65a410cf84e119b103bff13d707b3d7f65dd2f5e75acd7bd9a1e3835ad9b319d4863f9bcf27a42533e765c3e57fe12f3a6e3d4cd65386849a87a54cb22eeb863a2b501ad32e62dfa56cc119f8dd2de8c82c0576e301b36e3a87301336a26c3c163da61413b3c99176ee357d9735c20ee579935d5cff256dfeb2b960ca42f7980d71e09ff4afefc0b9e85ef6ac1e7fc0bbf5c974b631ffcec437ff8a1dfac2a5efac49bd3b837ae99dca6bb7ec40cd54445bbf414f4385d69a4aab784f6779cd728b6b13b87190842617a0a0e53ad85a86c9f25ef1781218abdad99ea683ba7f5c4d3100f98d806a3c1634ce05896699b186241c2da139618fa57b4ed7fde33b1bf43fd4f3df2073f44bb7237d489bd3dea465ec5cfa477d284ff30e6e19cc5bc5d1db52da53af106df88f3858f49a7ec898e11e360e4156d1ee5781829a12745339943ecc7056a26c00d529b6a42c3001bee43ac6d8d84329e0cfb45ac1491c47d14d0da51dbeabc913b4376bf8d01aa665ced50596704ca89a71861d5e07b9ea69fe72fb5e4955310ec226e56ef7034877373e53caec51034475b7f2d4eb85017fcedfabdf3ed8e77ce87e7680e3aea37da4b465d6b463012d61f3dd2dc1a15d444201b78b618fa44ada5018d89913928fcd732a85c6a659974bcced3258c83fe9254d0449a1b06160ce7a30c0716c294b9841146e7b6b70d4a65cd6cf3212aad6ec6a54ece706857b04e3fa91d7ecda576a9b6f49ed3e32ce77c8a758f7b6334fe56abff85ff631a222d31dc77bc1ade350efc32b1a136e5288bf4ec47fa1277e0b2fe30e671ffb4991cbed874ed34ce4d39c72221aa436c6020adce3d6bbfbe6a6f1f66a8aaf3d8428319732bcadb8779c1623e42fa9cb7c18caa169782cc6096c7dc5d31963d06ba089142b5a44f5b41ac4e502c78d98f59ce0ce1b84ae6d2f734d3b81b866effee0e7e99bfafb8557631dfdb87e8bd6dbfc2c3f73eaebaaa53ff29defafdbaeeefeed735759096be6881931b75749cda9f5bd88c2d64c6b4b7939a1a4888bc80882aeafeeda61a7b4e599d7bbcbf0e0846f3457fe53983302de02a05a8e4f4dfc653b51b01ba14046d7ce21ad8918b79a14252344644c61dceb35d3c8a9618ba616c7c55a77eb73edfd7f63e6b47fed2cf7919efe0dbecd7503be852ed6eef019d1770e333584b8ecd893106d4106b6aa45da0d526e2fd6eaaf78340a9f1bc721fe2d2da48cbb5d2d08da5653eb130ed4595afcf49f6e85735623a7a66c67839b3db9ae5198c7261123d336650c608089be72c9e9fe356aee56a37e902a8e8a4c7fd3d56c8bb4bed3f31c68de0308f8ff3fb3afe290ebd11ef56b79c0b2f1dc926e9941e840a8b3c336390ee642e0793ce9d21089f05452a2074899d27933b6e16d33f6dcce57a3682465caa31d2c462160a4280d4291733690312113cf694bba10cef5295d5b2c48c97e05e18f96f7843bd2b3e477f9704071ed1ec7a0d82de252f99186e73d48b3dc665ef7e6f0eb5ee1bcf4542c62dc951487400316381d057ba9f2b87587d88a00b98d6b7453eee113b7b9a85d0e19ccd124bb6080a8b43b60aaa6227ed7fbb546f8744d11e36fef67058af12a062a2ab052f9e0c39622ad2d40e2bf4cc6ec57385c84c4ab48c43ff3de7d9054c57bf894eba75eff5285ef571cf7268e080813b707d87ef38f58283fdffde4f30dc26e66fbc5d57b124f7b84fde8d79bc53fabb84ab53be4e6b7fa123ca67b6f49260a579b4d8cceca692ccd2a6fa9f168f5010d02c48782670916aa96dcee6bcbf9615cb269dbf4d2b98630e281a361c75d08cd853e7e73e4046b6884a394a3554c60af93189800cfa21aac4d46357b52ececf57e5ad0f5a1ecee0671af777e91b12ddb47255c4dbedabd6fdc7e7b85d17910a4c0d3ca11ae071d16c7d32de26baf93473d09032b761442c67a39bb0bb65aa33fd22ffcd45ecc21d347d2bf482973cd89db7f14f58849bb455c14086a919113c983b304c6dcbc4809571ee199ee522ead40f736ee6a27007be4a7b84c305d25c8769aec0f6931684a84a8326c756a3cd47831a55d48c4b14cdc201c6b6d949036511ed530170e313b6c5bcbe4567e595bb30197eb737d93a32f69feb1dedce0ff438eee2139d8d7bb8bb4152226d7f16a6dc3dc4a4de2f7832e6546d64011f08fba7cd4264cfa05a21929554436190b34e2ae4490eeb480d7a1cc2092edac62ffa0be6b0519a0f90c8e13466834d6a4934a3668dcbbae6d41d45a5c822e2daf148ecdf19a302ce98c2ae77730fe1db7b467c7ba8274fb9bb8a385a4ec3bdcdbf96b7b1ee95b7b9f61c8733728d57f5c0cf7e437ec70b80230df8209560486b2a8fd78db09a1cdb4fba30d02aa05935e7de6d365667da4fb5554fb98cffbe873f8cb9dfbf52c9379dd55fe54cb0063239c230c8698b72b80cc26217d84c2776bb43760b48590f85219a38f75b4f6b324a2d23ae7c8de5d91041d74a75b10dec95c1c0de1689562865cec37f3d02bc0d19457aa0f77b13c39dd0c25c26563b455778037e9cafac062009ff7eac977e1bcb1ef876afe727837b68361dc6daefe5139ef2f8bdb7e998b5461466c69c3d195ed12e9121e2809a1a29ccdd3c9491076b401c45a4e316d8d9fb37ace44533e084c558ab9f58852be1d4ebc4618108518f94c08f430c3d880664d73c7ab9e818c063411b1210d720d4bd979e4099eeccbd1fb94a6da8c5c38ffc49675cc4a558c55c3e7dcc7d9deb0e2465a6f6fbf788d51f9fd5357fcec9db5f473a7dab135fa8551f9f1bd427dda64de2304d0437f0409d613dbfdb73f44eba901ff9a40ffed7c7e7387140dd9643f169df1500615f67db98d64282bf9dcfdc3536fe2d11136be6d05d60b94238f50283bf1ae2cc931dd4d31c3df839d279d1aa39678517a2d18c67eba8448f51576ca8e1a239d50055039c968d33cf71463b1527f7b20fa5eaa6fce5ccbfe352bf6a23dc2c1982220eddcf7bfb223eee0eb1e9c146ecef4361abdd9163e2e3739c304837ea4eb071ca582bec6c89795f8f73f7512cfa4dda2157306f83395b46da1f801ca505d0f5588e7dcc8a5d5a668134dc31b75a1c978c63ca8867b54fb16e6de78e9c61073b9cf7c0cc91a6dfe10e050d0a1cf448bafbe9912465f1fe7c821fadd9d55e47ab3bd7c7fa2febd576af67ac84ab74a7b5deaed7bbf5fe4d8b4c1396a54fc0c0f20bf52c28d37d52b4693568e705d3e35d7fe9edfa35d298220ad669a56a66b049301a8c65a7f2d4511342a1e695b51615d0601c06c2ceac49470d0ffcd3a492062a541e178d1f85a89e9dd72c7e79ff1ef4ba1a51b2eed5760f7bbbcf39e51b39b5b5793850532e4eb89cab7ddbdb693efeacdbfe7b1b6abc7fa73fcdc7dfb597b17ed1b76daa89ce2072c6dba9aec2a41a0ce696df43c47df0346b49f2c1508e5840167f36a4ac2712b885a7841d58ac492b65cced08c80ac589fd4fa3b958c561b642c578298da7cdccf6970987946a7049726807bc713dadbd6fdff6618fbbd770e6ed058dbd5ffab9c7f1deced7817fe45803b82d5e2e45899bc440cf3ef9b74546614cf476e0511379760d890503560221f976833a0bcc6de5128b3d271d7af28bd66736aad35262529a11a6688d78da25210e66103f120bf1a86c4ac9ad3670062ac9c7600ab2fc5e359d287477515834929baf7144788947f070aed4eee35de75dd60d79d7e3f34e7be18256c2271d89cb18b523b69d8cbff7a5f4363bd398f8bd7df8426bfbe27e3ce4746777e27488b9dcdb88430ef1f56772f0dd7abfe0a91e927050e291f4535b41e60c86c9b03f40cad366241b46544d902a363e75e98c20c86c7731276e49477fb732c730aa84efab2cc4bc9fd11c325f0da669876a9ad32eb56a8134a6f17205020d8e02428d9840f6139eeaf7cfffbd8e9bdc5ceb739dede39dbbc4bcfd932fdbd7a6a458a35b31686c6c0826b712660003d593ba7a4ebb81628b46f7f43ffa0464638faa9615ab9eb0ea47cc594eb9a0096fd691919a3e8b34612363aae1a7b95df408c7ab940db4d8c97a29accd38acd1bc52d50cba34a1acc3bbe65eb88ebfa9aed6c239dc63bbd861dd547fd5cdd94e73eb129fdbdfd4a89b2874f3790997537d7fe7fd6da4ad9a375ca8751e6f1cea00308f6d76ea99fa8c8dbdacf171ec2b3ef03d77075dcb106d13dd7cc3a9ee2e72ae7ed25fff5a4fe62cc772eca1b954db5e2586546989b254a79f79e92e61299a98833abaf4cc973fbf9d7294252552890d17894ddfe38ccfe6e5a02758b24c1c3f7bb1ae72dee3c376c9f005e70b5651f8b5cdbc701e7711474a546c35e5e25adca2ed7d983b6030aab484b9e0022443509ee2960fcf3125074cb576db7995cf0118cc822232661c6b410179522a9658d2615a26b0f1b48b95ecb191e0b1d5db205b6b498997917ada2545bfc3345a465ad1628eab946fc1bc4041ec781b5621cc99aba72acba5932d251411576c19875778a4cf6b084fd1993f7c315f7a075e952c3bceebfe7fb55ff93f5e8975d20d3823e251f02783964d1814722778f61c5535f2796da723ba6145e3a723a6316710062cd282221bf362d54e35b71715229076b4497535f0140a994db7338e326c032ea112732561c0dd21edf0c3efb9d43f615a2ed5095eebcbdf63da621b76530ebb3937f329cf3689de5c3b1317cee4afcec4414ffa587bf59ad8ee6f62e350f7b9f4f75beb61877891d368cbd4c089cba697e672300f15a6d43463f0af372f561a75848629ee18ad07d48186247f7546c583c7db052a981e10daa560f084e8bf3606b227ba6cc6ad02100795b440f1cc61d18c9a4b4e71ec97e34d125ec6b41ce758aca233dd9d0b98c1bbd4170f5ac16562c30346fdddf827dec71bf3dea15a06cadf5002a7b1c26164e06d6a4bd7e7b2a4da9fadb41a2e59cde232ab48386e91deb4cc610de15bdde742f734e652bd558cc8962bf69080ccc20a0f02882dbfc333a2f79d29a87b8c2028cb16d12ff8150eefb1df17dcddfc208771a73acc47dde5d7f97c7b8e5ff18250abcd53bddfca60b514368001ab87934e68898167b868da6927ad64d7c49e43b504f8db79d13c0685b9f2f456049dd0b1210d49dca7b8c8ba4917f588c6e248e1e7983138e36e453438e4b6eb4f35a9a7cadb06e778f52b75b0c37b9b51e8fea0f7f5734fefefedc19cc35db278b1e3c7f14f5ab2b76a2cb4be72db98e06749249d00dc62cd2c520a1f3d38c828104eaa6127506c4843b19c71c698663a5415adaf09073bb588ad364c34cd081484828375e2081e19d18653d6449d6b1095f6fcc2db218bad59886ebe1b85336e625b75d23ef807cd94d73fb0bd77e10db938f6716fe3dd9467fbf862230c374b827d7c71c27edc86117df2a0a289f6d48950b6a90e634f376d0671864aec11cd375203f6261aab84e56913ad9f07b97a94443ef002afd868d07188fcc0ca769e8e4cc14d9c82419b729707965c4ff5becd8978884b01039039b2aa9bb3fafbf731c3220a9142b9bf3febeff9282ed53896c9071ff97bccd68539dc8ad0cdc581a7ab55e90e6ca2f2e927bdbcf7b05f45ba004ffbff2f39f89c5a93da6c17e96c2d6db512a1d724bafbfcc5da5f7aeec6fb45af07a5ae1e29dca376eb482d7bf63ae1d2226a91cabc04281829a623a6e09cfee96623b68c99b70d98d7cd465e2b4a449865460c8e8dd9887169099be76e16c3c2f03af4e0d98d39b36a1dd9be1ef0de921ade5282db306097f7fdcfeb5887f8fc15530d3ac1419654b88e8c6bf7d4bdfa048ef1eb4b3f4eaab3263aac1b3a9eebaf9fef57b5f048873b6a37ab08b02704dc4706dc29d290eee532a00e2e62a89e58b88f01ad8de4144cf57a3a2f6b2580d0b9855b425c9758d4a4c41d62bd6706aa9ec42358cd46324f47544f0dbac1a5c4d4a87306bc5e74be9ed7eeafc37ca436dca53adbfdc0b66e0ff8c9ff8e793d7c661a0eb2b4422a5decf7d1e13e3b7b9e29f9bb46c18d18d8d03762bbd6058f36886630e864c0002e585873c6b3d5cca99738a44b62b71926039787754142a6470a597138e8f9cadd12bda7319e1933589b982218917fdb99ad381b6591afd70f49277a09531ab2504d605d5dee13ccccbd1d89f9b59aedbdf45c5ec73bc408f370a0d25215bff20d3822116f9ee6b6cb521dba3284cfa2127a041890e57683cb6d8746ee04e5ac27b4d6e3a12be6109134576d429f3698d6d3c97e4f1a2e41257013088ba96e1971d0f88260cbb340450d57e36ae0cd4bba8ce8b96ff07dbd888198fbdff645cb90d562f8a9d7f9bfeab7bc8e7b355fdc5dd48ffe65def2f82e7f9aa97118bff18efa0bbfa81d65cf54c381ec44c50b0a82025442475a60b979ac4416777f7b13ad81accc48c095352fc49a8d149971a8840eb6b3112353dd0d047539b3c71a65d88e983b4b1d3c99f106700e67b16d2e48c11e63dd9d468bfe3b2e89bf3fc805bfab155ce5fe8ffe733ef8721efe1063de86afe1c8c4059ea615cca7401511907652aa49ecd42e1a8d977e5893892e6752076c5ef4092e51e00328a4a188a4eed0af8a4da0d7600ea5c7177d3bb0d81815609312388bc31a11cd0de70ce732cf1e91d58f030a6ee5997da97534515534c2666514b2d5ff8a5ff2756eb96b1e7ace4a0812e760a7be78ae537eeac73c4f564335b09536d2a3426e509e0d526eb541c736c2196bc8562a30e4f2b6fb5135a9dddfc92128f7ef1c5fefb7b90bc774ccc136315c6dcac5fe6e7d3aeecd4f7f2347ced2dbee45a138534f945b4b3c82d82f9a87a4124f8c66bd28cfca28cc5669255952659da0781015708b46d4c0646010cbac93ce5d1080a649590b6c67285e3422a6b04539eca5057062089733ae2256ae00aeea8ad2bbf586bc628e12de2f246fd5f7b9ef97bb9336a2723749f0513ffe5b1ff5759edb6cfe132ea1bbdcdbaffb6c1585b5f971bd0fcf71ab86533ba56e98d0becf58e6c6e59f76a29b31b1da2167782d2ab9926ab02437da8f2464bbfdbfd886d7cfc2f0acc6fbdbb300d272ff2fcb52fda04bfee939b4439cf5f3de4cab89f5ac4621dac57a7f1397aa476d44916eed3c962de6143016349b1bedc45a9cb8607e9217be0307da3b9ce3de6f7e1bff8465fef1dde5058044397c261c9794b6586ab51e146c8a6916a25286ac830b51aeee9283ff7fbcbd5d7ba2bef73dfc827e2709c85ce3e1a004448943c803e40c88771102324a1579f5f7e543673a6d67acf3f1ff3dabb6256127d9d9d9d96badccb0ca5771d8477779665ea3437eeddf0d0ebadf6b38ff8ebd785b03fa8f73d1dac8f864bfe0320f7fb67fe598bb2ff7b35d98d24bf8135840bd4b288e578dc6a1291963e34408ee479eec29e840d6a089f4f817ee1487556313d1b4766e740b2a8a34a8765b22ac49ca315ec6adc78cb14f6a8e73542c56ae0324d25a549ae4829be7dccf7b1ec86b7ddc8d3cf171347a809f7b4ea3cb7c4dcf58a9e079799fcde67c3db694502268f8173ef096729fa6bcb5578c0026c26dd614800beb87643d085c54d29a984b5a6c23d01f55c323dee8c9726a831cfa880266ae62e9f15a15995ba458fb4be1e08eb062cb593789cce29696effbfd23b60be992e3a2be79963e3ee88ea8cddd33d7d773da5ce6e5abcfd73cd47d790b3630104d751789cd21affd11abb4955704939843c267235cf555e62a2e07ed3283a74b974026664608b917d43aca2b67c015945ca30933ed237792bda8b9ad4c6931ca3be228481be933071cc24aef823fe09cd3f31d97dfa8abaef7a77ceb23ec7984455e2b98899f38abb7df5def33c2fb703dc8de04c8efd4b458129ac01c585f54a379c6551351045625ee22d331b1db7b21b53b3a2d02c1db3203fa4b04c65f88fb64442e3c0a0106397546e9901cb2aad079158c42aa17192db62266236cb63503f299de8debd1c305b7848eab081e5e78f4ff07f71a27fb9ed67d91375577a9973ffb8977fdf9b77b8e1613ee4b190746ee104b7a1a124357b9c14c6ae2d9ca23eb88aa98d79c1331fe22e16c2f077594537bc485ee04b3764ab71189c68ba0828dd0e407372b3328b92f6bbea32e1709e078495597c52422f0615ad23f6d22e30248619d7d72fe86a3efaff1ec690d1968f7abcee4869f5f3f023b701a375c646eff1327fba61f57def5fbb003d2b5701ee3832af933a738c80c6e4683bf5c989519811eac3c52a4a6644aa0690e99453483c1644c880baba42a96abe82b588016b286e0c84311a7b36336e07e0ef3d1926b92d58410c1a7bc518bf980fbfc6eee80f37bb7ff33bf7f84e5753f3db77badebbf736de83ad2a199d7dd81b1d941c576951b64461d15e78ddc84555b2786fc422bab50503bb4d216e3c57c55da3eafb527cb1cd2a140a1b617cc20861afc2359770101781053e28ab20089391b92d2b1a88bd39c9247ad8d328de0290edeffc6adfe776e9993cdaa24267a21c6ebb4e6e5e7f21fb3ff1e3bc641275d046404f749ddeac40c5ff69537fdb9e63deec3907366f40e9fb223f6d49ed16fa3448c53d2b49be0384e718d374b5eed0957096105590054b06a746046b7c8290141d59a819e1d8321b014c249162bc8ebb1c4a00f32c79f26d5d8cfbca76316eb70010e7055ef0ef76af19cdfffe4c33ea349b07e0c46f7f7365fd6091f29f7826dbab6f3f933758c7c05300f048f964e607257ce12514019a324198a66b5ee7074e7993a3fc25a897ea70c5d29f7a94b8c71252378c80c7d5bfbe53d6fe7bfdba9e1bbcc53adf4c86671e593cadd719b353fe7e95ffa09ae6beff367f06c503882055aa2762b188c658c7accbe6ef19080250d4ca1d9e84f31e167e6d0a3b4617fb5f7327f2e73e75fb46131cb0fcae940a8891b09f83d67e4993ab363eae446d87c3be6022f089395125f81422d5c32c816e0c9a01a190b436d52af1a02f72bc431af132147d17a1c48e7c95cb23ec8077f211bff7939e58c3a9d155235e1e291d8b79febe6378e8ebfd7919efe4f3fe72639c5025a5eb10289e87737b51ece3a7a8ff1bba9386b70ec32975797f1f34ffdb15ee2923ffefec2bf73bc2fc7aad2a5f7d4a74d6046c239a4062fd9643c8d1cb00f009aa40075671d34a842a5d116371c0640ee56d118a74308724f53257a92bbd68c0ca14101fc11392a0963dba7b52530421b4131e5868542f0f5b82af9a3744bdee0065fc798efea974ffee0128f9fc6d7d0d5ab1aed9b1c81279b67356f9298b4aa66ddaae6c7ec53399cc7f8baf76dbfac6d4b4b038134967a11b73aafbfde7b7eee17a217d42cfca40a0d658c37f9d43f60c863c93496882fb15b78e4fe3de23977c1ffa82ef26c8743f633ae3cfd0cc07dfefd1493000b577c1a09b959c605200ed9314fefa8b693d46b7fe4a6de461ec691def44b07d1dc45f14a232b6c6640709f2550fee0b1fc92b0a2583162131e1c33c8f601e80e99db6e22c47f2884235a6b4719d5819476fb2f3149d6f02ea92ffcea7f89d9cd07c6eccf4ac0b58c672ffbeacbe70e1fefcfd5e0299aa6426ee520f512112b43f8203dc2729707bc82bdd27842b8fcc23d02224f225685269e3adbdcb5d2a58396aafc7608a604b3ea00028816cc21bb68d02531e5329fcaa5d02ae5ccdf25954a445c8cb21bfcb01fef01e3757a3be67bdcfa7ea9d57af9f95fce45821c7346bcc0c0ebc46c472b87cf593dfe2e5cfc3d6d48954fd17c61f4563e451dad4787958bbe64da1f9693ae53ccdf4888cabcb6d6b969ef57539e6021bfabc19e65157c4e6ae9ac1af94c1844ca430e612dca86bb71031ffbe0bfdf4f3eec2cf3c2699035b8952e7b99cb6ffaf32fbaa2601f68ee31849b2c26bd32bef6a949464bc77222b785cc532937e02c75be6ea5b139c8b21a88e836d4994156ab78c9fd54c632165cef22d151dcb49ab981c1a91fe7ceb8625cfb0a147ac9f5143b2426cc17ffe2374efe53c69fe2c2820ff1c9f1c9a7f0d1cbbcbeb67fcd43b2bb7c86aafb051f1c9301abc753b2576602438ea200e03e707dc21cbe5e4eba2d29318fe0e6286b9dd26a1c2baf05823198527bbaaa70ba72a4a3c057b8f4904da1022b974c9896df1730814ce8e720563f4213b9e25118f173bdf51d35a6273b99ba4beaf12d1dc72b16e621fefd5a077f7859132f9faf63759f6e2335559bd645c1346ef2586eb2e8eb41d4c44e60b1144d6865485711908704fa0e9f724e11878217610643734909a7d5b8e251d7e4283458d3eeb13103bcf4675c1cf699f9cd202692cb690542de9aaad475f2d0b1fa8509f8edbefec6bd5e7e8467dcbe74d131afd14d9cf803f7e6dfda7d596b676e42418abcf18b5574cdcfdc71d6c5ac788e1876d35a3a6183a3c020871ca1307315924d5b30d3bef7be7958c4bac8eb51f7c217f129aed2c7d8e88237783927bde4e9dff4e77a76ba3317297f3083af17463fcb44b75f897094373ae4955ea86a3ccd4ae204a2dbd318c9b929fb95687f7021cbc02cacc824217689a46681f1940ca2f19f738ee84ae32a1ff068c5c647ce49c09dc0a2484e79ad82ac56f7efb9c6ff784e1aafe722fee739a8285f4a845d696298ba0887f57819e9c4e055174a0353ee15e8de3928e39bfcdc8fcb751b7c24af679253bbf7c67441040ce6c92fd2b146bc9eed53ce75ea903207b254487f597ac136759cfbe28026e8943bde4a617d0223fb103bfc38f9a8cce87476b9eb7dfdf99f706bac26732ee42e016c4820ff12191ae71c3539c030984a9779cce282f851f5f590d45c26dade44ce08a4832c7257cd95abebc4184f150aada4c6236ada326cc8814cfd6d0880c10cff8b1cc83489f9c08fe330babb46bd3dfb96eccc4d7f4b732c7c047fd28fb38f1370775e73cd196fd565678d7c07dccdeb6b74389aaaef0215730cf59196fa7b3a047b068b63d63090f2276bc5c6dbf93083598312ecea8e0dfe73ee718323ed64e2eb9e319e66263245ddc98469271df00fdec80985e47bc47843445150676c65954f970fcbf9a1a3342ff5f9bff1f71edf727bf021f7fc3613ce6b5eac1bf8f28b3658d2f05ade3e7b0f0f5b3bc6999713ca5aeafc9ccffdbd1f573dc43b7c0a8c57d3272863390a287a96b432a8b71911b7abd3495730d4f6519ddfe953cefa5c4362143a134ea73cbfb8d8e3d6dded998ff90158a8ab6e9b813752c062119363129fcf91977bdc3ff7af0b26a3bbd7c7caf5d7217882d2c19253ce964e5f12516c9478322367335a3a45a2783ee431f603581d56d5382555578b8acf12d38e5356f0056847ab7a6704a59ee40d2e92f5b8a342cf584cda65ac309bec4678ca23e6b281d77fa835b9be977ac5b1f053b33156ad728bbd8ac38b7e5afd09ade247d54ddfddaf5ff3fa63cd6268a631d96426bf6af45967adb03bf1b9fd42586b49d12eaa11605efb653e14663e456e38d82035d55138edeece3ce756c6dab8ed0b1e526f726eeb3c9f0d6ea93518eed77106d64a74f3c5101a0c8cf64bd685341a0fa9c09b95764c6aca64c5942358e771173999d36102b09db9f991b3dd2882be85dd761db8e1e81483cc079ba9a92d85b058ea392331f52351aba91c72c0b43d920616e1e7b993ff8ee3bbcca9b512b27ee171b9e486fe5e4b92b908c8b3aee9ebb97e938bf20139e9be502e1fd404fe7cfe69ec3ee8cf9593f2be1848199ccdcdd9218564cb34aa4283c810582005d0e4b020dc812837d522afe4243500488c8e500045ea167dea681c51c4f9d4df50b1d90642b712e88d8438cd286fb80b8f4c17135a8f3d2e54c151d5af6ed465ddc1595b24465748e345d7f1a7aee4707b2cb991ddcac95efcf97ff66197b64e7ea9d7aa1efdd33e31377c16347c861d06a9a310369ef65989b5aa315d9898644e9b84a6ede7536965b4f8cec1064a9e18f321318987fb6c320e12811836d13cac10081aff8bacc7c562e024acd424f50a278d9f7ae94010d41db915a7de314647297a285dd65df8187e62a8dff1a99df30c112c539797e925cff57f175bdd1a4bdda4de45ffead2972b87e2dfefc71f34b61fb57d1eeb8fb4513bfc0f634f2ab2645572ccb8fea1dcc2675a210cbe8ee4649c6080be10ef09642621917b000b8892a461038bc62e6bd484d4b849d65d9a01527011c2c8534b4c3164bc0842a14d3cc87d0e465b5e3b075af182c2dcc8f59dda18a235ae31b2b1289d8f34d9cbcc186f53c1feaa9d71b7a6ed591fe1f51eff8bd72a38bee34b7b3a6bba9e35f9c6fbd4d0fa17fef6e75d2fb875779bb9e32a896f6ae39c9e632ecad903e2d17e2fcf388ff39cbafe0c7e3effbebbf9e4980282246566e6f2927b7c9730e22b6631e655036b2a2041ef45a54c03f6755015eb53d36f046a977983c91cf42e77d48c3785486b9c302fe831e837896e05317815b2d658a2220d6262a4257795c6f762f47699418adc787a4e8c7e9fd5bc92821f6edb9a3d2226fab0edcb3e7b19f3458d77996169e9729d9fc780dd97077537a38561a139b40d3995b348e3e7b0f247292af691f077abeaebe8bedcc0cb7cb04ebf7f4e0c043e811b058fb803fb6993e6147b59e5b986efb5ad5e7f4fc3d37aff741dc9e95c996abecc408f58f515d07577ea8b90105b73a89649e30051dd776795b9e37deefa3aab6faedd47f1a7ec32637c48ead3b89c715baf3f5feb7fefa9ab200d197018083c975511064edb8735370243156ad21da22ad9bfd56ef9fbbe7caea7ae66af75c0ff7e2ff13127e0ffe00c98b96353c67e99c4582f44a7577170b1e7bbfedc8b993dd78e7a41d5ffc02502c221cfbc922e35aa11d76d951f3b9a41f44321340d0cd26446b7900ef1821ab28c22b09a920e537bc95931a1b0a561a3086385b5a2b608a86f074ecbc840dac49029634fdb15b2ad745adc3ac7bc9fbb9e0f3fa907693c2857b4cb1bf6c21372b6f5abcf571ddffbce1851fdd590cee6801ddc31a385abda32238d6960da5c72d5c9c97816b8b2e66ebf15a868146cdbb9c1fb80f3691623a200decc0d1ee4507f170c9b82565620aa23a9d106bb4f7d58711c9a4f20e764430c7f48d97d31cc4aa05de6ea9fdcdb9fc1ca66026d6504ab34bea583113ce81c088bd460e7fab4b3affdd5fe558bf0be3191037625ff760c9c7ea98cc2a6ee6c8f2bfc0557a4c24e72cc6af54552fbc7aa542069da2399fa66c8936d366857326b262939d249674583dfc9a93d5f18b26546d2e786d3878c6c84875a1c757bdea8ef341a6bf230ad12acb3d399f7d779efed58ddc969f1ea79bfcf8b0fc632f98897f95fd7d920c5e94c7fae857af9b9bb9e5fefe7b610b361c9c924e1844a9d182be61f93d8e6cba93e602117527428a8c19e36ea99b8e3924279541cb96c70f6aae6581ae48be2769955631c0c04e30a9b2b948fd2ea699f79054a283f86f5d8919c9b8af25984de6119feeccf26df6ef2a25fe7b3ce1b7fff6e2cdeef2dc323f82f7e6ff314635fd758ec1f3373d65ddbb94f83602878eaf64b4995c19c6e9f71b40907d4939aefa8186ff3f5982603b625b0d6b9f175c8ca1c645c8621e50147ad99829945eb3e912549988b3aea1573428b4de0aa0d1ef091d20aac3c69321d1e4328fdacb9b7260d16598d1af9698cdb43f6942e11d63957f30bdff67b3ffee14ed3a2518778a9b61955107ba8c1407ee1cc273c96b3a4f177a20e3ec2fcbee25aff7bfdd263ee14a0ce6ba583cbfcbafe7c8a55c23b631530caa91244281ce91c44650112430ae65523397cb3688d89826d9534ca2531dac8681c8bbadb4771fb235b7f1db8a31c6592ef21d440386a1452fc7de99170d5d8e5aac253e22a630ebf1dd9945bc1d44ea36afcfddedab04c7090bae3ea13b161ff9073c8cff62eb6556eb197177cea3dda3cfd824b9a895d9fe99613facd4ccc828a1a8a0c586b32253c89c6dff17dda885d2af031337e6928ddba1f7f0076f7b7362f31822ef37adc2531292f7983bb71fa0756c32fea384eb8c0a670d4814c751151dd2f063ba1a60a68a39bb4e22c2a0b2b70d13ef05495c7f6316f5a27a144664d1124e6c6941a45a2998d543dde2c51d2076ee7a50e9a24955546486e71ac6612aa87e978278d5f24061f5eeb57bdd36668ecf6acd97ab6cfcf3cd0f14d6ddd9df1c49b67de8c2966cfc1fa9ddefcbfce81432af0695f03d773e7ebcfddf5ddfe8137ab3b10d6ff908d2a43407852ea500add702f3866cc9faf74c199d7da8a7f3b66d02e435a8d96acd04be40349bf6d05e776dae47da4a5960ed9284e16cced66a9c67255c16560588770d03b758adfa1469141dee68efe636ca1bb9bf5c10fd258b8b475f647676ddfeb73efbb179eda222b8b2177aaad32f93c605f0d36a826abfd82897cc4bc62831d6b19b9333382d8a735441c742d73186055f73d777b2315edf31c58db8ceb2ee37ec3a6c928138119b89b2311bee68e8c72d31f948188bc5137f1410c717e37e97e620f9dbee581fb57df06f54290f5d5af75a7b34f72d9473fe682fb8b7d17c0face5d19e40d0e432d753455523932942616dc945ab1c31623fc23d57a9470a75f790407acc3a4de98914b4699e3ef562eb768d57f493d3de7cd939997e4282a350ff9668feb7e1b01dc2a84cb05b0badcfdf8defdfa1ee7bacbcf69e8cecc07c423af35a74f3ee262db9858b9cb872bc7c011dfc78d3f8f44d167152e7250592b166e9989bbd4443072fc11471829de568c3fc1b0e124d3c191d781997b9c30ee6c979e6ed994db8272c88de220bd04087600bc023019649bb9ba155c85126cf659d512ea7d33df7193fc1ddff573febc99977fcb797dac6bf1bfc87909dda5e25ce73ee4eef83937d8cb38bde9cf3fe5bc7e60c64be55adb68aa8a4c48b1301d18b9aacb0cb40b447e64ac7023ed1f13360659fc74881adbcf45374a1d7f1345e35da4f12e1016ce9103b0284412fb26ad38a3c638264277594d528cd02240fe6ce5f1d1bd9adb6ff5276fd5473d2676b2da57fbe6ebcfdda53ee04ebe13d6ceb84628f574cf9c9e735781259b8d0268278aca3830fd1176a0a1aac260901bdc1defa5699b19500e859ccc4dede47a768890bf5793cea2005721f86a2a4a36628a0fdc9000d75d1c567e998ba7037f9ff3fac7da37ffac3bb2107c94bbe8f997ad5ff843f31b79b1f3d8b5ef35e73ee4db78003e04b659adbbd3efae7bc34bfbd73cfb7df81052012bab2c2e623f0a2b84286a099fe291e42dc186ec281b4fe4209f39b0baa8ea5862a821aa79413d0cd864cc29202277d49097fc7b8a8a4d8a8a06d7c9368fc97ce9f156acbb90c7c59620554aa013eafd616fb8a98b327b10e6119ef99fb3f86ebea4d3b9a949637e948db2550dcddc41d552c88e8004a43577787d18c9e1ae73d373121398d768b738c5adb15dbcd727fbf09cfe003b5885f2f8311187ee14bf9fb55fcf71dc47df5fcfef77dcff3173662c060524e2b355ac9e736d0fb927d74afb4944d13a4776795f0c66eda5cbbbdb7548b307e1b07eb677f28fcf99417426c6cfd7bc0dbc4f4f35d9a70d02a29173e9ee0e4bea1f786d394185fc68ea58d159ff1aa521ebbe0b2dad85a95910734da7b2c860b28de22733a168c7754b152abea88a6f025786d86b119e228720b54ba1dc476e1b61ad7699d93e4a4fb54cddf13615a4f85937701c7d54f35049e143797cfd37c93b1cf91f3969ffaab5f5735f7aad69f54eef2bf7f045dfbdf1751657aff5caccf7ba82bc53d75ae4991ec1c559bbfbed5919c3dcb3f7794386f3da74c7affefeed1dfc59d374afc46bfde8b7b58b673ee9e7d37be706aa7f62e8d7ef742f4fef0d739714ca655d568f412a64fb4b83edca8fffef3a88bfc6eae6593d38ed59c683ceead7764f3e86e8a4e1cdb9067bfd117fe5cd98ae93e2b04debc4cc1a1f107180cc1df52c7e02b8696da68b05f1ec49d2c82f326e0749d50183be8f98d54977eca743110afe0d3253d3242e50c6b581354903a7b508ebec4014430874852be2a7aef2b947e27731dddf638e4facadd7fbde471c1bbfc7e96ff6cbab4ffca56bf4e1f33fc404bfad137abca652f0276cfb5ffc6410412091cf03803dd1f86da455272bcb9375bf8fa64f66862454e5b7fb7428a3373aef1fc57f7fe2b9fb603efed3d9e67ae6bcf0863a1fe1a36fc66839505be63d6d79dd62e5421b5730094ab50f2971c34a22eac8a9d01bc00692e4827b14165355262385c26d5acf0655eff6acd145045518209b45a68e950b0306c021597785449c9158aef3018544a059f0ee8ee5cfb1cc87f3f2ae3b46f68c8fefea231f7bc7188dcc0feb106feddb312e94408e5c8f435113214d3fe08e2523e4831c1545207494b2ae4c045fa7ac2301f3e7d2b34986d42ca8fba9aaf988099260ca874cdbee8aed4c16b70725489f54d80f3c94905a7e4f623c939e5e1247ddadbdfcb6e64fc5f6994b3a3fc23233faf7778b7f1a83f7dac0ff3c06effbf0b55b98eff7d305bdb4fb0ffe9fa45afe500649a23804c1b4c091d076ce7082dd318f4cdc70eaa39c216fd50447e6d9db8c928271bd4e6bb015158f89c03146b82695c5f29240caac3413ce41c6159025df49d01f53303b24fce9c018dc7f4603f75ffcffef5a781f69767eb80ffc2d8ff39c99f6a7b8a903fa80fc6f3d3e5c6a80ad7dee852fd8927b70556b39b5374ae3fd0aa144715c662516a92bdb8c3e0d8255c67c081f734722fcd33b1ad773d4dfcff5f5f89809b44be3f65c3babdc5bfc0fc183cea727bbc22273f5979f77c5a7f3eafbfefc799ffd1b874ccdd37ce0413ee05839b8cd4111e7534d834af1152daa5c7407625420d492ae4aec25316a09957ad5f07530657d5071ba6a48c263c5c3524e71a51789465b41fd30ab67fb8c858043bd4f2b1c29039bf7f3d2fef6fe30af6f6141c3930f79c0bdf5bb762fe73ed3ef12d1b7ab9a752af677e7face68745f2d32d55c54d8655541a4631da5260762e4a3f9807c5ae96649f104372d0a5c94502eddd4cc7b0ea4a9aaaf80197dba8a15c7350ae4c0bfcbd2b6f3c93894065e333307d4b146aa82b170a056429994e12470d0dfcf7fef7dc60b4f6597c4784885baa57108de6bbfffd35ef1aeddf35c37fc1f5260b01068c80ddd646b706deff3f98788a34e794f5068bd594ec6b6707a837334e49536b0191c43a0f08779a89f6debe7dcb44f7dbb9d8f795b23f54ff3ef8513f4ccb37338f7e1375bfceccfc9c79a77eb93517520aca8d2291a4540db12128b41ee49d0e3d5643c5280a4b9d12d03ce2b5cf34670bd0c00af98ce81a860482bee704edcb951982bea079c05dbb03e6c99a903e1a065d6a82f0ba3b5d2c9b8573159f0f8de3bb65fefffb97a8ae0bfef5dbf6c3bbcb1f570d656b85b8b8ce8558c0255c97855f5db9cf2c95274edd2918203c70aa63e277c76cc4537ca04b1b16b0572dd9969350e42ae9a95d74e396c97a1591c88e758349668e9c02e456a99af3b7fe9e543588dc092cb5130488975f1283ec04a0ad96635eb72cfdfe72e3f2a57eb57fc3b6fed7dfa1f9d1f61913418e4352a5fe571fae5647458084bafbcf0569df5cff5ffc91aeb8770c5fe1ae79ff5d56ffa01fafbfccd39265d2a861083fc3b67f098393aa1869c4566ebe0da3f308f0d0a69109885915656c52a4de6406a3eb577b49e8168286256e687d040ceca2d20ad1564839f9063e7a57567d1587d5f35788979bb558eee645d0477d756bfbc77fde2576fe2271e6bef9fed9ee2c597f56e15b9895b698caeba8bf7e1c5b80ef7895974ab29b712319e313066ccd4c7d0d44dc4889b185fb7acc16da2ab23adc021a124920ed722fa0a2243f5326e4dd2904510eb63009981cd42a61e9a33a3b799018eb9d36d28925f98bb3966de0c243778c23f7fef44b4acf5f329c6cbebf141c63e78c9d75df8179c371c5517fe858540eb938d1381c1abbf1d2dca6f5d56f391fa006bf65e27fa9a1b7d5beff7dbfe775e1baff3a837f85fc7cfa735af267077dadfa4b895a73f3ff301fcf3efda3dafe76c0d9f651c76e73a77973f5ffdf99dfcae551f215fae68312ca0bf4b806f10c4cd08163413dd77e2c06a35250b66725fd5fd3e342c22d8e6485d3209aba04f622cb1530059178932d8c0b9da66555fa400315191e7a469376aeafb69930f94229433f9076dc9f173729313e251f742e7b62e36acb13ed90ddfc993413c5ce4531c7350f01cfadf7390585925a7b8cc61008b62c9d843ce73caf48bdcb3ad4f9de74c1b9c6c95c4e476bdf564643dc4effdd6e6d9e71d94abf7598dc0b9defad2ce7de7b7814419aa20a9f073ea3920d5fe886b1e468014ac51475e59098dd1404cdcf241da519303e1ec46a90b41469d8302c16115db6958f52666dacfa74f90ea16e765d5cf4d5405dc3754c597cac8cdb46e2372a3defa2e7f177febd29f3ee5db39befa10173b813b194b9d3578a35cde66ebd77725efee954e7ffbfc0b3bfb9617e83fe3b2572fb8ecb7fa5599e9578b581d93f8dbeb670e37fce469ddee3203558bd83e6626d189493ec1aff0417fff6d7dffa9fdf39a3f9df332775cc8c9795f02a7bde0ccc1402feddfc7ab8a7c6aa81ec3a2c95cb20dab839598df605a77f6c28035ad104cc5ee40756bf01a4d32cf9ea708b3b92175ee398382dacec498b0c69ea7b5f47085248e95c9ddb197411ee683d40cd9a6ace526881d90adbb77e7de1bbc4750b9e33211d6f3cbda8fcbf07d1dfc0798cacbbe3bbb555375386ba3d4587f5a93e511d829f3ac7bfd9c187c97087f77bed77ff7dd35c6bdaf3e7ac0034e56ce38c55e7b5053a4256aa5685a23f5909b5009954665104b930be7100df6447ac417b52294a1795a6a3fa9f93a9a74f3d4500b5107563ae926c1f4e4bf8a8042b2c32efa410634c99875e4baddddabc995bba84c8d33cee2cc01751b43f8103cf52111789b08a52f3c3be7b5f4f6bb0eaf47f0de737b3ae0b574c1312b6750b99db572f10f06ba2f61c9474bb7ab7953eca8204d6ef8615eda5e0adb528162a09ebd4ea82cc3baed4333ec23a32f43a35890588e224797dc99f5444bac62b54f459b06a51cc9f809d2877182aafdcb9970f9bed6f862e79ffb262c544c368b98ec53833fff86d3fd8007e1e718c4fc98bd6018a38fee36fd973ba0ebda4e4e3eecbfdc9dbf7adecd7b44e33d0fe7bfc7122f350b8b23f8f5334dfec0bb79731daf8341b3b0468c1952e0464ff21a1d387db2f229af23836f09f5bb05b0ccac22fb048c45de704274d02f4ca9a950d5aae1616258df290d00a572aacc225ebaed6c61f423221c9857fe9eb89c2b93c1c829d867ee4f7ebbbbfd9b6e746317a9f1f5337cccfd037294874474fbb3dd5db4cd5e70d7f4ceb8cd2d82b02cc215255f448d358e03b012a125bc769f7bc8e44db25f31b54c51d287f5614435e942d3e9f1900c91cb17c1ba430a4aa6d6dd4e32a5e9d419886b6d8246d54983f60aca5038d8a783fd057ba410f1c77576e77a2e618185807be9f1ddffaac6f77dbba73dc92ef29a3fab09ec3283c0ab56d8dd5a2b043a47c2559423249693f17e0e90b944ba57ae4c85b66baafd5868bd4d6a5d11aab738f60fd964bc09076c28a79885b5f432eafbb2ae8c9c2b3137f09e386a9b6bbe10151a118a83cc0c616ae081d5fd666e3c2a263eeba60d694c7ee5da3ec1cdf5c2c77ecdbfed338fdfe4c278e0387ed0f6652c95fbd49db5df847f7a2e54f78f67bf60c941715c448e25a8feb65dba7cc0f1cce29e5d64750112f8d4bfe57eb871b771e5a9eff44d1ebfe363f25d571b6d655c5de2809fed5fb9e7eecb2beed31a6a5adabd9c7456e0b6c3aae2208315587ab30373798f053129e3db48f4536a3283515ee329dac9ba1b142c60641299d745934172a0ae654502cf323a035c14fd6ab283dc435d50e96766aa20754eff7f77cc757adf4312fb9fc40cfc772cf3ef6dfe9a7f273f73e6a7bcb473a71fc11d85e191087f96577a19d689c5e0cc0c0141d453bba82c6cc2ac6d00d13306e336053b90555286311ba84974b0eee6825942d5dd21649c6434d873a75f12d6ba64321e89aafdb16af4480e78116af57d752f96b9b9bce3e58cfa194dacff7ebf7fb5f319b373dd037f7da6e13f686d28273266a384b798b8dc599824e56660b169b2cda93d5f3268a606d9e1a6c0bc2c585a5b1e9be23ed2721e4ce55a3ab0490d7f92393d5f3aba92d5788862ecae4a7fc20774a45ab2001690567cb7f4da308ce5bdbcdfaf3184b76b8d1fa1a169bec6509ee7f2abcfe0ac9d79a746601f3860bf143c8dbcb6cb4bdb56a24f56dc36692dd3b421a6588fa350b7bba41a0dd180a724f6455eef6080c263c8b18ca89aac043b9058ea144819001d06cc024145668ada47197522d0ed2c8a6d9c9a3cbe173b9dbbfaf9960e145e9fe2b73739a27fb46f567fbde243adfd396ea6ce73701fe6abcab50d72d16d99911c9490a3a0568514cec03ddf22b59e442e59468224919140ea8c0e29227839f5a9702ab042d257353b2ad09bb4ceada0663de5a19151fc23e43850540a3a284d6065cc0dd811835b7762beeae4cc8fe96be9beba8ffbb0e6f3e56f7121ebdf796667aff435dff33fcb5d12934179b3dfee10ded54a36677b9f9e5b2d62acf35a5fea2a627ff87b7d3482a9c0db8590e75a0c358130abf99018e8f0e2b3ae9cd3eff286a7b37e2a822ea9c7fb2c7a5d533ebb114b9de6211c941b76b9c18fe9b5c6266f6ee15182cb59f23173f3435b5dfced1ffbd75deaecefcb27901825d8b34d82eca39a62acd8d80e399f50ce0edcddc114cef642e029a5bca6da46ab5a4de9e07f894a3e93fae9a06abf8da67a96546d93b99625391a68591991d93e278219942b074fd541543398c492e57fe060ce3d5f671eaf6404779fb8f73d3e242efbadcdb39f7d9d17bee2a7ee3b7ba8ba2b4fb664badd071ca5d4f59f31f70302ed833c8ee38c69824bde6750c5a98bbdc848f649c975eef6dbd4404731b5bb65bc19e59e3d4de21064a2ff9e733e70d3b668c3a5045f07ae7d2bd77ac6cc36c1f762971bfb78c1f087ddd946ff239dd193ad73973fcb093c9fb1cf73f9ed77ffa2eb009d832a65928b769295f68caec73c14a40aebaf230937c7a80eeedb873c5f2b8fb4ef733a1fecf58fa8f339cdb99880545c7339bfdaef823f7121fd2d3f080b400732044eff650148bc007abee4a8e24661cb32dfd31a861ca22405f2b830677b6e7451604a2b8a7607551645c689b37275c1380e564d30a295bf5bc5a4a648258b4141c6398e786ee04159d4e976d8fb97f9777d5fd19fc7355fc38d14fde1653ff81f68ab1cf29a83734dcb1aeece7b7c3ceb5297ef72971f7ffa82bff4f37cff716faccbd43a1afc924df5735e23ca2077976c74149ee2ca44f5aaee6d52f7986a2db349475387edf9ba9b2d5dc752ccda2d8c31cfd9ac57838fe89481a87e3a50a3b798c6d512f935877a1e1878cf750038f2bfb3a9ff28bded4b7c20482bebe4750dc0f1af775bd7b15e4570bd7ac969fc2dbe7b1007c5750d590be15bcae5c3ab75f5eb3bca9ecfdc69778d9f74d5f06d5872d2e595df936a37ca84b3c7601c04267656ebb158c5a4524e7b0ca6215840c4a386cc024f2d96a25f2f451be45483a8d1fe0a715321348f3c55e4a53fc963d28694b4215454195fada8eab7abea0ff7ff8d7dcc0cac7333b8d478b8ba4c8fb0c86b756bfd1cdff3c0fcebfa199732c6c3a5ae8bb489b1eb92d86f5ed6ce9ffa77f5f177d6cbe2bde2fc7b8ed046b9ea9854e322a06a8e8f1d5c3963963b9a09ae0a02bf990b8036199c0d73e06c1703d2cb186ff3a6d599a3da85419255c5e52a96eb95c7d78425063746c7556c0f09248b94757352c9e740a07bb97b4ff668ce7c059fd2b2fdefb58ab9e7efa5e99f6c7c3ec7fc6affaac77dd7590698ccd533e5f4bb6cca03e95a8b884133a0df0e51b41bad9c3661256ff8e01305954c6168a4ac35126aaf85ab81a8ba62010b9c6bbc962e6c02737614ae55a4827c59720433111eb8b60b1afb69e624162ff570ae557bcf4d7638bdab14ec39af79f7099d8d7e513e3dc096bf61452ff6fcad1f97bbd1e57d1a11260624556641b2b858640d1b123e8378eaf3397c1a91461f68d3ae65b5d986034f1823dbc0e471aad5282b931e5354440c7aca2d62c1fd847b88058cc10cb4863c76bbb44645508de769d409d9c82985cee8eebb518f7737e3bff7e7c57fb4f1a9adb36f8059fced9fb00ad453e92aea0e01c46e3ea0f0e46b17462b133304cab40d3cd5b394eb692e428bd57d89792ba4bb3bf0f56e24e2d6c0751b61e6efd2013356c3904e51ada689c5bd220c1c8d45a5e673a842a2d931ace4463d8ab3b33ec7b87bb986275faa13015eefa1efeaf332c32ae5af33eb708b973df7f8f3eaa2db7f3b667d0436e234868d2e33e3c27bfdaafdeec2d373df9949207f60755bc975f7030bb89b9bd51e576a11213b4d1adf5d0cc521d0ba49a83d671ea9724e7c41fd4452be4f9d3624533d248ccca3aa0f55f3cd9a038b868d7de48dd4aa268968f43aab37c7c44c4614f02ab860503eb2e321b9e573de6ba2ffeb7a3824973c35cc5de7ca3d719fdd5287cfa3a93d2c919d5054ed138324e93431946321c6d4b374c83162dd3267d614c74597377a104d35a4944f03638c32d03f2754c9908d0b39d9998a3a471c755fa2299a515df08c29949afe262971196879fc8057f85fd7c3258713c1263310789d63ba513fd3df8c21d7236b5186ff7d7c2e75e07d7e04c6a2aceee50db403d1b9392b740a30a35495abd286d21d7782f3bd60569c56be4eaaa25b0cdc5c69b6171e3a86da9f50ad746212114d6d1209bd9c030b257073201ed15814c6aa2acca4998de6b020995090b9c51c6b55b18ff7d35e090e65042fdc8826297263f799bab207e458119431d70b01dbc4f4f7ca45437a8e0d3ffa1e5c6aa7eecbbf2e95404b663886acfb059ff279c2b164713bcf8cdd013bed17ee1cfa103846c2d44695fc28ab3e0ea0dde4ccd952ea4f53cf4e99b0ec7028364bb702a292db50072331e5512e3a27ac0a1b9b3390bafc470076d61f6296d33c3fc5b7f5191b16879d1296ce0d5ce4eec55e37b521ffbbf6f05ffb70f6d1313fc7e8f2821b048b983fcb1897496c6b79e5c6bcd3fe3861877d66a24d30f54fbe688f058051e91f9589059dce8628ce8fcce10581722661785495044b07d9b9393b64ae341873a0f4ec241b34631e3be4cdc654084f24e2a134ba7522c0215d8febb4e429a58575be53786fff63f2a97ce103e2c4faec138ec975bede170f422b307c4f9a6891969884351951d70f5263dc65ee78939a720869d14807b59ca31d03fe3cabfc8dac47db50db23399075322447392d5802fc38a0dc4c62e9c85ae995839bc4c0656a14a568a4a54c4d04b7bfdf88073f5d577dd1fc80a7739eceeaf0978ecddb7cf7e5fddbcb7b9f3142ef73faf52fbeaa3775936f3903405eebc34bad5c72b293e0cfea5aaffbff5d787dfe8e41f89346cedfe3ddc7e4206a5ec857ba7d52a0eebc0e3ffa9e06ff908bf045ca0a0b837e2139f982ddf132abbb923a9b6d8624a55369e4ae76257f321646386410cf965e3be583e22bf4ed788a315377b7559a7861e980c02c20a9db191b7025396952d0ed052aac8c17fd4ac03612e4ce5a5afd9cbafcb40e86dff6f7b77748cd559f108e2b798e217ff2f0f4ef31a567ce1c908a43275d7ec86b7ed658997d5e5ffc64ef4abafaf889730f7cdc3c206dde7c3bfb8e5fed83e13e0d9db30f29a928203682fdd2f3abd4ed6602a94144dd3e07fe466a6c054edba6a63a44ce6e8fa3aecdc4d72df56c9dc49891b2d82bc68f91e7ef84e84c3efdb69d1bd68f34d69078b2c460ec0aca5960f2add29b512ea07ba3f6e3d33e24774fe7855f9c8697f930fbc47829bdf2be3de7de2956185fea0c6ab94bc4cd5cd707fee79ff6d6bff6e1baa61b1917874573ae9fdf5fea31ac3317ce053b18dcab2f799c43e7100ebc5952d653a39799d37ec18d86381ae360c07e6262c440bfa3ae1c564c17d4690b321037a4fe117b3a5c3ad0e0159c73cec3c569c6d61dcd5d7f9de876c706deac84b5265c05696cb7292fda478db374799d0a4b5fb004b6ce1b72e589fe79de7d8ff1b8d68829cf2f2ef8eaebdfd2fc3998c06719176fb5c9eee3a4fe002777931b291af5f8f88e2bec5fe7d01b6cecd76e61fcdea7f37d02cd9f3fe09dbd790ee495bf5b18ea59d6788ec158e7355e8454635e232da11ac2aa70539d8025f587158350baf899f1d65093b1a38642af1abba4a0904217c5026c2c5c7d1da9e6692b0732c2259791518ca8a91c2e9e8cc040f4fd9de30739d2e823bbfd71defc1aa798ec4f732715b055ae365ee541dedef9fe6ab7e1cf57cc4a979cf692c96b9cf2c7ff93ba68f86ddf78bb2f5dfabc49e2a0cb4ddd25f578f70afffc0137ddf5b9a7b96ca0dd2f7cc74f1cd0f1fd5cba68e99f6b340c3efaebbe77e9cf2f5cb2b086dce5af71d6a30fb9bc6e61383fecd33b2cee6baeb98fffe7651f3f5a679c5066122b77d9b33aeb83f3d763f247dbbdd49dbcf1a3a7e79ef58cf326fc1dab7a1737daef76feccfaffb09fff84b1fad5f6991b2d3e731b37327eba6a35fc03171575b64c7428318b96bafd044389564c8215f39b25253a9816dfc3181b39552e677e13c636cba3b11934ba0b416f45a06d08b28795f027845942398e291c4c88504878c582b9e36772ec3aa575b4729ff6d4d19fe1a4ff08dbf0e718f1136becf7bf7fc573ff119fdb4dae8e3fc5094f0fc3657cd087dff9047eae5b706df77e7f9f567da51cfe3d2c9d3ea8e577d6702b7790954dbec200c988577a120922181b53ceb9c758f1252ac928d4789dc6e12888db2889fd2f182896ba1d22bab502ee9792eb2387ba642e9e106d13050a2b14412fc1dbbcdf07fefef37c54d778cabea56df928bdef9fedbd8ed52ef1f7dd78b79402fd454e0b8b379830e69869597821c43be6a844193964aeec428ababc710e91fe06b24a6dd22903d4450b5ae2917451bb30e58c3302f1400e91a9c4d2198f728363362450517f1909b8cf212a19080f77d75efff2415d12f3736d6e6674fa13dc0ec7079d77fed0fed7eeb73112089e6b97ddf1568a33d7c3ddb56b6cd2edb8d98679831b598db69cf10341c1c0696133d6350bc87f08fd64641cd1a8e15ad49b81b0dd56551662c6b80f353e849a3b81a13a45c9404abda326fe2190fa414aa797082d788c74269241d5bc0f6e70d87c5ec3cd2f5fe73e967fcf79bfc6c57d82ffea41baebe65b5cdd9bf13b7f07e03f68e78f1281a540058ba86da7101958fb36355a1498f27bc27422ea8e2d63b5c74eff9dd4fe24829a10c69fb30a2ec3c65ee482f0bcaa0c3690259fda0be6e8fd022aa1aa0d540edb8b290fc87acc18e775e0f2eda3f26079fd1b567c742bf774a92bf28d44dc1ab347e17c7f6bf39a6f38af9fa3aad1eeca79710f77030eaa62981bad95c54a46807c0f29268a7241862748a68e498d0f35c67eda7121e43133c0cf9ae24fd5a7ac1fe0f3ffd0fe750fb8accd08d6793dee2eb9c153ec7aad9db8afb63e91a5fdcc0d66b006eb55ad5d1ab36d187fb3925ab75cf85deef63dd681b530bf6db1999b8217e102b493c82d8e9c11878bc24ca2ce08996529e1c35cc894436248cef60b4024afd4409cdc6455172c4c89eebee77ff1e39fa8a778087799f9f23fec3207afe3f772c6bd73cf6d93e3ce8cb46e79598894fad64a238f68f53d35744aa63c5dc61b930e7e9abac0120e2cb8575451c5479181865470373467db152fd205549df0709982a28d8c431fd4e8187895215c9d10ef69c828892277d43fcc5fbcc541fd8c6b93bfdfe7ff1cafcbfcfcd41dd223e2a49771baac99dfc7eeba8eae38a2fb3421ddd99e727db23d084567e5d07757d3e29032cb0f62e291ca2211937660ca2da1d8cb29418a39bd74124382e2b0387686846d9f03ec45353aa8a61ad11293f940f6184853350832a72d33bd3199d61676efad49f5756edafbacc13a73f5f67398b5ffaedff74bdf86ef52d1e9ab6ffafdbb4b9de93dfae15b217083cd16a455e18a0a1bd24021a99d21f36c6fc9fabd147fad89fef4fcfe409bfaf5f9fc706b7fcc4ddeddaeb3fef6181e55f3677b2ff31a66821f17f4dbbd35e7232936072138213030a8c19b9c3e8d02807b2a340b9c220dc4ee317c466e71cc4cde5cb5f9feef520f1edef21db7b87e0f17fcd823fc4578b565d89de7e8e735272ff55cd45e0750c72c0e4c56e274491d93439fac289a458e6386b5639269b151ba6db0e6080b18ac44375f212408f57f286afbc2f5bdcc453386ec5d0aab2d0723530119ce4dc5292fbab09276e022811b2909fc43dd4fcd412ae07b7ef2ff5758889fed5d626ae5eaee5aef7fbfb638e813419f20373a94535f04b5bf90f1d39e3ae3ef0197ad40f239a83a4f080618d2560e502504f991c57e2198e639945be1b1111d489145bbd17ce03ca951418c439f8b628f5dd4870c85916311ec289afc09bf5373981bbafe44cde6e121f5393fdbbbda30c6ad6caa2bcef73ead2a4ef573347d1a2514d7c971ac5380dd401c0e0bc8c380e97d6e681889d6e2ee93993abe2190c411d20daf714d4c0996d3ca14ae8269e9730a7a47b20a86557ecc68be57b1b212d60b3e9575d290a982c4bae27c3fb0a1ac3e51cb303c660e9eda3adbae966e70d57abe6feef1d2df64a6ac56955c53a332f1711c27a22d1880493af8dfa90bb62bc7f2254715651086a56a13636326f5ce58d5d591948547001aa542955945dcdc6967496559b4c6cd8ab54ecabf6d97aef53dd7154c60ebe5d59fd6afeef21ad59fd14a7b84df4b053c262239fbbeebcfd77ad6fbfc5fa4db6d54c13405c823950cd9d497392f5281ec35153d0e6b35acbc162d1d1de403d951a693c5e0ef03e76071e69b4bf6752f28dee346b9ea386e975c07496c979cb5b132d13aa5782bbdc2672e99e2d267d1c3eaf7d42e335e309ff9e54eefef7b3dccd6e738b8c8dc5e67b7eedea307e5a21afebc386b68a15de6f2dd39be7afbdd85c7ecbeda0bca7718494be8d908577dba307a67855ac64af923678751c8240a747088980c28ff76c4155aa70d0e78859c955354a933db2783edf118cfe666352c39af43a31aa4d77e593ae31d8b799809ab88aa31ce009931e63f4abfe90ff580afeea8fe3a8e177c70d2f05a5ef592feb2dee0f57effbfaeb72111a7f3870f652daf7be6effd5850763f175dec1f0288f7c1542d12837419ebd6c4944dc2ac11e3789e976a4da0a4bcde4136689453e4ce4dfb90687f8f876f5b217841bc62ab06eec869b164ce684b40682475fb2c0438f286878ae1248b6d2862d985b0201f6379ae98ebcb7dd02d9b3e4a8ffe62d3eb9d54f0caa62ffdb8178b79b629b70bceb19b435ed0ca8291a9b661ad7f64e0143fa0055e8f35a552a4b16facb81d6768638615222b4a9cb9514c55fd04c252ee22966f336d57a9ebbbb2d26b36e91aeea84962fa550ec6058f8303597769588ddfeaa3dccabb6af5124b5ff3dd7f8da50d5eaa730ee9528376e512b95963ff10de5513ebc4e4c717debab3cf6ab0bef27d7dd4af53fc78b71630a33c5d0c9599d5fe775a72b000877d0e9e8c8c5747225029eb5610531d4303d3947227307cc0aaaf470237a3dc4dfa68409c962a5db2271895cc4cdd5670ea9355531c83b8f83e07b20bebe2bbaaf87655619c893fc43eaf34d8fe32ffcd45193ce307f8940f75818ea3e15ebd4ce68e3501ad4ca7c52c1ac8843b5ff709d54c9632250336a4f8ba0fa94a798365aeb18dabcd286b2a2bab674358229137f656b1d17655eaef847253560ce65339c34e5fa648a7b9c19b94a326a95a6749494af4bb3dfcef6774cf870b818bc4285eeae48c4fd4d9ffb48974752d6f9d8b1ec593f4c26377c199fe3636977efc135f9227a6b6bf9a8ca7518d672b361b2503b152d39e11a06d55f51635d5f7ccf0018dbe8ee4a4634c74b69c3ef50bc34769adc2c8f3eba47640c0e541c6f8888d365998e1888ba72d2b311253ad431ec0a466db5423f9280dff37ba842ffc81bfc62dfabd8d3396dee5cf89a16f3eef56fd035ebf3b67fc275f76d1ff3aef33d79f81f187bab89b6b2e29038b3b7ec111ae7929adb0f18b1cb1d132fe0665d5e914b063168d97cab09cccc0df79e343c6240da2b121196ca4d742e6e2670ac0801d6084a61af1a1f8114dc6bb95c30b1cfb930c10cd6305312b66fc1dc6fd8318ecf3f7df3fe7746e92fd6d7dd76f0fe21978b13b1c943bbe68bbbefb0e1ceeaf55842c81ad4100c42baa8dcc2088683c481a1c32a4daacee7ecc41db50e01bcc1d8d14f47de5d984695cac4451ce0732e4800cc1104025ba5d6a4883713497e0b0e7a6ec22a7176949646226c77c50248408ff010730c838ec1263bc4f0dad5ff6cb4fe474c043b0010607671d33a36b2f3a4da7fe5cf7970ffb058e8b32bc1743a025f2674b174e22c063aaa5cf2bb890a25d660d9fafdc5ee75ca3056ca974315b4ec64b2980b530609799781450ff9098a45a4eed21a8c65630b51754b75ff27adc50de522c60a1d8eeb8307547a768adeadef893ad5397af136135e77716b0b8e002fe077acd26de48e117599d5f3101e859feffecfd6d73a33af62e0e7f955379fbebd9e1c1a4e35d755ec436601323370224d0d4d41420da600426367e8053f3ddef026cc78e9d38c9ceecfbfc4fe545770c0849e871ada56b5dab399bbe747f779ef7b1365e98c3a8d4b3dc0b14c611952fad99b2856a5e066cbac633a5b467ca0256911cf68bcc137b63dd0e3882a282b2a8a2023f839632470aed239ea130dd962e62a26e76259c3d08d84132b602113b507093ce86a8bc7c256ec707f68b88b9a9b22225df625efa1fe090bcf4eedfe1177c56ee695f1e70729f896d562e17442673aa824ebdbee822eabb8edc813234812cf1a1ac312a6b7746453ddbeece7d04a189a511c486e032506215e6d06177864886fa807a600011c650b785c8410e73e90081b1c8e6e12c629e0062fd8a7de582ee9713418afc3ecf42955db3db575fe42bd6c4d572f1a6204e94d3b6bd4fead1c4e1ed7f30d61122c89c19124cf40eb2945fe1907ad630d25c06ed208182a54ae9b82236546907a7603c19d28e3d8bee824aaec261af03c4288695bbf153d8f7d568122424d71304a84d4c5f40b2cfe5bf8048394f017a601925c457625a5fd8777d55a9bcbf6d5c6fa3409836eb7f5b2e577d622dca2648de7aaac2dc2ca940d2b56c118aee0caea80c8690a39129820831f0645b6e87245ac7e7951975e0126062e90ee1b12577cc01106dd1a8bc84483083a5274e17a638dfa099329c0c500fc8bc6460285b38293f8c3713b6b92bd8858ba5cafbbb38284fca6cc6efd2c3808db1b20a84e47367d4363fb0309963eb81d355804dc5e01a9fcf8448445488cb9001593e36e56e06b8a5a80b3c8714fa68a7a34e3064862e903b32835aa81abc2de609b4730812de443858234e5b59dcb64384c8a37231a68ea658e77adc276db1ed370722947cf5102fe832577aaa343e167effc5fe707eaed5ccf5a0e4538ab74b2ab084aad37a5f4d6ad9c617d8ea259fe0e77d335835c684f7d5ade861c8797dbee515707aeb7a5ebc0babfda571acdfaecf1ebf4d32b4f487342743381fefb80f02b59bfb99f1a978d7ad4d32977cccf18fa2bd083850d93c95e0806dad54611e732b2813c193c1d815b663a2b23b8c9547e4a091614d2b3bd93eb933bab24534f45398185c34a4b3dedc2b8b31b668dfb29565c053665610111c0810b90256ce786e5e9ff32736e1d76488179c8b6fdbf8b9afb1191c97d9ac056b3f65b331d6d6bec015bb723e762ead6823afdfed4d8670832a5a526b2af9436de9f1366738e00e0f8d2d5135d116728c04ca43512bfc61a400114694270594b5a5692986696f81c747bd50ce6d2a2a7322028520380ad37905128337047e4478a5b0d233bccadb716b1db8f6319b8d1db024186d4efc58cee6fcab1c9d6feaa8be88ca7a8df5b1720da7ddf02a7f859dffb8ccd6ced9e583b45ed7f928e873bb723eb47f222fa55130440512b6b185a38591d23b34a0c413741ea308a18121c0592f3745bb6373d40dac5eec8ad40018de8d85e9c656b74f20452b33539ec299e2b9995cfa03e4b88e42fc4cc36e461d8ba720b4dd0ace0cf1c3bcb727dfc81f62655f6f737ba55bc957cc9f8be59fb7ffd133eba189793bf9585f38be201540cc7f191c7b0c136d6863d87f14e13ce07b5130eb2db08306a693139a451e15b67dd79a8a214ed616864f74466dcf79285d916137d93e017cbf7139625833a8a0b4e0d190c63a47653864281c683214a4e157e1f80ee74c2d06ee14e374ce3b7bd466877851c255fd4bec954ddbc575dfbc0743f1051c622765366be72668d645b7de0f77580afd035cfdda2f178158676ced2b10db4a2f3110d1a0c2eea84d66814a725a7d4c666ffcc752fa9ba8a8d987afda73be0a1fb1c30b3b02648ddcb3b3e59cd7e733febdfcdce33577a2d85b24e48f30353ad610c8e64c936cb32b229e765cdcdd4007f40c666fb14a169615f51e85f9e6b19af266a20c83618fd32d320b668ae3a98160722c766770edf1b66039ca1224da2f2f2e78ea3cac2957b0331bc3dbe7c42fce5cdb333360bee3cc6c8fb37640ee63b6749dbd9cf376cc6ebddfe1bec036b4c371f39587f9dc5795a6ed9bb5ec72bd76bac2c7f04263515e4f149933d20d8793a267abf9d344a12c4858df64b467c9c5c2453d93649ae0a9449da8cbb5311b559e055761a62ded745e8e05bad63127e9325b01411a8e2be04205c49670bf79147b3c609a60f0104c9036dcc5607aa3ad5b39f4fad9f197c4e8decd81a0d8e90547f3e270ef533c607ed2dd9a035b222a1a0416b3ec245a8643796b384107d8f98a0ea0089242b0e4628b78927b15591b16f33c61eb5ab2a459c2764b2aa8ea192bd1400128556c2f51b6941191a884e1191581a00c6892cb40449977ceeff6e63e7045eedfed0b17ec9cfbbe721e9ef5e4be16eef5e177cda70b3eb1d7f90fbe04e7b9efdb53fe83acae1777dcf7979eef38b43f868b7267480a526da9739a6be27ce43ab6640fb505e0ed8dcd34e2f28810b9c3518e5a2855b63ea741bbb2370607149d2bfa1431a42b90d88964c004184050b0cf49000fa6a22917b6a7426033a2d9039079182ccd2f8bdff35f8ce1fb362ee7baeff5df110be88db14ab0949cacc3afa569f1ee1fc3f2d85bd31e462ac28a4d87bd2d76804d6c69ecdae417ad800954ad633ab96309526c5bd30af04a6a646ce957d193e9449c2b68e33127af038ec780971716a7e0b1481cbf5c8a4135e203b9abe8566f8c11787211f8a50fc8ff9571d641d9e1ff422cbbf37ccf381a2ef8ad359c155fe33bfd8207a45e5b5ed4a9e16115c7b3e0e3b61544fa7ebf9bf929999933fa8b38dacce464c9422422983a01a78d609a633048ca4064806238f399e2d1cc58c361d0214ebe71b9ee08a3dc75cdeee3c422bf2643d27914022e1cb83cb68b79287745a8a0399881c8aed07fcb5fbe6e13ce2feb3586159e03739ada6fc5b0dddb01783fddc56ec5f57a6dbc8307228a4efdf15f8ec5ddbef8fe78e2fbb5bf6ae2a0aadb869beb8407ec3c6ee1de16796ab37c83dbe3320f405ba7c9f9debcabd39ef3825f1087551fe0e258b90e68ce549e6dafafbef3c65ec9b3933e79adedde5aeb1dc0b98ec6bdc6877522639caf11e7edfc9ef97f71ec7c4ace382afbbe38e1cc68fd562fec09d7f42c6efbc82b0b8841c7b3b74b63463174984a87ac4faa8423d643c7e2948a66b20819ea134ed9a0a1bca69526f936d043bb78241c340291c546822628833dc04703db46194451c7e47b6b3f0916be43889d45f331b7d5ceec3f6fcb13efd823de31c73ec4837218e7b99f810d793f1fd2657e99cfc59c3eab432d1b5c98b7c5aedc8faff738d7c9102a1637daea96965abcc6874eaf17e2cd1a583d5ccb7f46c212c4945f368f10e4955198ccb950d62c3765dc64a0dcd9a95286333a446ab48036f1424b315d01918051e2f2bd999110c376e828b495998ee9cbf3c84bebfdfb6de9efe2c2b91eeff4eb74ead7d79b6b72ddaebe9f8ae5898791e7c7050c86a43492640b93ee8c5424319d5e07a15e863860505b7269c2cba0d222176911428aa0632403d55edb4ed2f1ccee1c32c8745943be6d08faf0616ddbb2e0a6d3adeb9082a29e4d12e92940c4b1bf32befdd7e902e278667ff39f7df39f7df39f7df39f7df39f7df39fb5fdfdcd7ff6ff45feb346070cfa7ce46720ff9bb83d4eca3cc86b077bf48efffddd67587211d888d936e3034111f594ad5d1ee62e4bb666ca3a368a782bbdef7c08d3d0d4e313b8d5dd77781958fb313ff305be2058e2de1787e98b6c9e17cb6fce535fe330ff68bc8fed18f5540be590e242a302bf9cc8b0b21234c70e5dbb492411b197f91f3d5b757a2c48958c9ce3ac2e604fa75f823d3d2eb31d87a8968d2322a0156d3092d38fc621185a8ac259323ff039a499156470e80a1647398febae6d8ee774ce58f8a2bc092d90046204286af8ae238b218122a3436cd2a7f6b6206cb4f1102361120d746c77bc61efcea8881788514cd183006516f932af7e155ebb1e0f81da5d356d8151e139906bf9500e32d3d939d2de8fc04b95f29947fb42ecdc14323743d99bf1759bd86c47b2c92bb1817d512bc6184654959fcfb8ca3339286e634bb0c4c5daf2546e3dcbb3200e9cfb027cdbce96f2b98f9f6548706e138b83833ce7369894b3e717f8f69fdbadf125fcbc3fd52b795f95ad1adfaae08b7cab2ec538683931ceef73ed377f42c782589bfb5534066aaeb949d40b55890fd544f42ba3b444cd239cbbc60c4e5c1178de8caceca49010e6179ebc55032b1a9832e3827e370d2d32b751cee39437c642a70ad15c428986dcec810bb3f9da47d38ea7f2c47e8fcfd5a7742cb00e52bba00eccfd3e9fefe4adff69e5adcbfa8387a53969f00227b1275ef2981fe46cd7d14ad74976692fe28476fdfd761cc751d6b9e0ef7df8d6d7301aafea7c17302dcf757c55af7925de42f629fbf2799dafda98ed36cee8d7d821dec725605ee2dbbabe0f91818670a23d42b5707d2511a1a03d862aa9a0355dfb19197b3c5290a50cf52a9ae90ec8ad1981f6804413d4b327365f98f2a80305691308c0f26dfed116baea44defe321d8d9b0c513216a941d5ee53e8e81cacdcc57b6ccd6fe90b97c7c37bf4858bfaf9df80b3bae8fb7b75edf2e3aee5a99200d544804914bb8ca43465a55f168e2fe439cc72e151d43b16ea0153d6662123cc56090a64f8680de9da528c8d3734b6fe0012ca6903374d3a819cf7688a1488e1cae322c91e32dbee778b9069293dc3137cd1da75817f639475761cac6fcfc3b765e84606e38873661bbcac8f7c05a6c4696243b0a0d50f8faf7798ac8f6146745bebb919292d3eaf20275718c1011295d8c7d32d90371b6ca3ad2ea3a16903772c487d3f250bc2c8a33fa356904510cd144d177b00e3dc0a93400acd7b1133bb44339620519102bc2c6db92b86ea36d6072ca1e8abfc377846d5684d86fa695ce533fcd0b19c7c90d73ae3997e453f429b40ed96b5cee10adda52f5ee3db0bcee5cecf9d1bf0c1b0b70e3258353ea26ab7dccbfb2fea5380f2e3dccf81d31b180e31fd413dbed02f734898298215e0a295cbe526cd5c5e1f285b132b3353cca12fdfaf1fb9ad18aabaf458f5b67a46f5d07139a812810ea69b31070d7fa66d02bbdb0fb83c812a5b133e1adab364618944bc702ef036564c55aa31264b1707cfb6c3ab381e78380f7f630e0ae38673e92fcf41ae95d3eb3d7027275aee0a941fc4dea07c4831c7019ee520297e591c91a11515fa6c5451d5e07541e1bc81c6fc249a617b9b591c7882e288f753ca4f542d316dc5b4f152f0edce9af21aa0332859489b99aa34b00569e42640f154990b846e6c3b533e44f4abb0379197ed63994f2f9db7c7beda4d5c07ccc72958fa82c4da386807ecdecbf850759e4b5f8051204c57755dfc1444f46003376afde57c5ebff49f3bc205be949d5e602c9fc7d5053df122de30feabbe5aca137d97cc363de7c0f9fc38adfba9de23eabfc5a4ff0ac7cdb5716a510807da12c4c5d86040a782bb001ccf63dc9db98c0a36eb2596680b7ad9e502a631246f793d29542a14992bc215c5a3adeba0358c0ba2234a5c81db4cec26b6e7963aa87245ed2ec07ccf1614dd94f5b559c197dc44bb36fccbf6e27d2c7e469c87a25e835a7ef17a2ce86f9c69ecb882043027988fc60e2c5da7d14bd99bfe432fd6ba4b7cde87d86e97b13b7c9026f5be703c5ecb8f9d5dec7c1cdb3383f7c8a8fc2bdff22919f5d436795f8c8593fa14c0fca4bf1fd60848c913b0c82f84e48da7d85b53c8552b8190dab94a9c7c6b0ab0341ca61299319a28b2e72825e222d116b6b16f6b13cb8e36002b0b3d75395de9151339b761c6809ef2db502d862095328f8b7ee996928e85ed87fdfd5e620f7ddc7d3ab1d3be632db8acff7eee1cf9b4fce61cb9a865f867acd0f415deb2876bfa1bb0859c842970aca4dbd355241a76b409673d100e7b046644241591bc2cd95a495035b13045e50ecc0c0e25603de635830852a99bdd21148d8587f5cab3733b6472073a76855408740b5aae435788a10272b6706647fca0fe761d8f7e759e545f394faed4a75ec3aff814bfea237f551e0c3356f896bda066511922b090c8e489a34c5c8c9ed00cc8302373832b66be5c249e9313d7ce11b5a3de64004c4bcd63204816b5e98aa87060ca54d0d568f1c81504701a30f0b642021a030531521105cd886bbf0703f0e69af6f67afc8ef3d92ff4797ebd2ecd796d7bb651b942c47c2c1774a845ed38b277989e4fac7db60426fdae31c19d0aabb9ebc9ccf367cad252a3054c959ec1c35f086910abb9e3292e6724f2da4ea55f741675684ab774a86c0c34954cfb9ef3910643057474a42dfd0a728193b3008f3601d75d06198a2c31a9c8f05d78dc376d57e7f2d7d5f9c5bd8269fd6bf8fa9dbfcfa95fd3ee9ed5eeaf9f58ff5c23c96334001320e77394a102cbf686e0ae8e2c261b423e736d57d29342b732c5f66d32f093601ba86e870c110a6532a4223440a2c82095165e1648ae0534a23293ca9b0a5a9aa873b9ecd9f63a54938a26dd739fb40bebdf67b09204f36b2f3d96170e32fe2bd8dfeb1c04ed19caebb6d89767ba9778f676ebc0d531f6cad9f0c575005ce46ef84b58bfcd8e47e360873b9c1b5bee67f7d61e75c8180d359b3065826d49734518db33653ce6d91029a32da86c018a6c660f41068491e4a6104f6cc8070e2a814a05902ae3c08e5c174f05c0cf3b26e62dc053259c218852f08baadb14555a8913c413d110ce7c7fbf686c5d3aa7dec97f6f63358cb7f5fe40bdc60367ac744bff8a3358ce757acdba4e5565439ab37fb9fa809f6f6b6feb77893eeb1994d734840be8f270600b0967d88a1594c52fc3963c9cd1ad2d1791e7f4860687c460206f88a200cfe961ca804779840c21d9e828595b42b1346d2a9972a17a329b796977e695856c0a529f24db1efc4a5ce60bbde995f38f432c5bd27feb8c484b7c11e64490765c7e757e0f176d7824ed96638c2257983ea72b2fc4c3bd8ce7fb9fcb982c2df3d56ebcb3058be399bc022fe7e6b31fc7ff5cf6e3a8f7b588d5fd7c48179ff1f45ff2c3d8e5679f9def7a58ca7dcc2afa9caebc90ee353c5f9d5ebcd0d687f1fe7c0625bf96ae89efb14bb7b9b876bf85d9338feb7dd6e69c37d4d614d3f9f3399d7e2d8e1b471cad183b200faf723e8ebec8060b5990724520b0bb9d9defe89a6be36f7fcc6f3d0219e07d1b2ec38c8d50923bee6cbac0b89b620bdaa892b77a1208c140530dbea71836593c56b6443846cca15b6139323d9593fc21c4b6c516be9a709e2c3904297dca830db1a2999d744ae04c3776d2e5fd84fff5d1585754451ddae7b90306e12d0cd017c53c3c2db36de770681474870dd03f16db703bc6ee16085d0dcc480f619a1a36102c95583e0f2b7b305df82ad0ed8f719f9d8cd7b77dc49b71fc97f7987d79ed3eb38f63c3edf27f3fce0caad036e37b21b0a20956b7592068338f4358370bd917941ca8047d8c730fe63e467b59feca3c74bf88b3f2a4cc5aae6ae3bfec65f757e5aab7b8a22870455822ce284d25f7ac21d27c15cc7db550f414a658cee7809b972607b5890d45bfbf2c5dac1918071bdf01a26d47a9c529928d82ca4bf24c777a042092d221b44c5bf2a85dccb0daedeb1c19864e0f7bc2b67799bf1ee67e9614fe50e3af73773fbcd89b3e39b6b0248df1b6a4ed5c3b943f6e62cb75848fb5633ec1f6fdc61449e6cf508987b913c89b4d6801d3ae1ea480e3c76046191414e8cd928e3e404fbebc94604536b6a02424d372a482bb30d98e208ba2b118cd50050b1369a98fb7fd891d49b679bfb005aaeb8abba5b82bbed28eebb17309b3f31edfedaf58c3ee8b4b78a676febef2acf5d5fed8b8b5d9569f21d7c80c214c0cdecf7a86a76e75c4a2214c3ad558a0923d1bad03bb2bbb5c31b132665bd8e068aa157ac546082bbf3c5b0140e981c0ea310b91c198878b70385fe0344f0241e7010ea4d061778f3cdbea83de598c806b6ba57f9071f8d2c552766d1f015fe43fbf6be7c6a61ca4ca8a084dfcc40bf5e15afbf687f8973801a007d173e6021e20093aa3ad2bd21911090c552d369d4044785911ae2b010c3532841e186a324d911ee0a824726e3c72db7ccc451d9041c9ac7a1388470b3da183104bcce0f847cfa6db205164830713af8aaa2b5c921fe2ddf03354b8cf5ce8e23b38ec395f44b377f07d6ebf66fe7479b7e5fbdc95fba9f8d28e914d3bc84978246f398b072695d9f691e3367ad9ad4c0e965806ba398c44a8822d45c0d0539dd3b92dd307fa7ae20016a43934127647d5dc0c6744f5b89c8533268f8568491cd6c30aec436e2b523e47b462cbafc2b2fa6977434f7402f9da597735c6d29a5cd57b9373ddec737bf0bebca68f82925f35361e2b79c5b7f8ad739bc8f08786881365009106a1e06e748e2b8105242a6f892ec0919bd00914b55e60b1ad69470e428984e588f803e50e8894f829b58219f8655ba8e33b289fa8f7a581954ec07527a1cceebc54492d05e588d3d6bafd657c13519006c7be4ce7f8625163ae039bd8306d3ef6312ee52cfd213ec4e1dcfa4c572a5c5cb03146659076cb37f1be195853479b11932f5ce7a13860459e79d4f85adf7b5987109fc6a1780b0f438760e9e16b181879a55bc697602c9af3fd0667082b5f6571ebe7687c94c7d0f5d3a402b6340ed33cb31c4d240e91022eb20d4e29a9bc9503a52784d8ee84cc5debb2cd4187117f6654f620580351116c871ade80f5a1508c884363cb414b944a9c9bb2ccc7c006a296e001e85be9bd4479edf1a33c866dbb4a2d077e4a72d2f05320aee133b9ced9b63de365f8e41cf755b6a28dfd564a3d1c14c150637408f31daeb0e90f3f6bf8f8572465d9d8e995c4819cd7c402adfbe6a24fd25b7dd3b1878164ab7462cbdba12eb0b19d458559511989a305c4f2da16f392a66444d55ca503a41be946d0315de80cf561d9958d195b187c647a99bb08874c4396522207ae5c87e9c4e6114af2becbf1ee44996f8120c99fe81b9eaa6c79d527a6ec945f13871c560dbe7aa8b76d2e22cec3dbaae115fff89e58987231d60586b0bc59e83c524116e9002f37b68ce626af2123290c2301c2b82c4c8f43bf023537911875c2c14834b9c23452be302c7763586c43b82ea2099f4f643af6140dd8322abc4433ed615ee92c10ad4af9f5557be2f35a73e01ed95ed913a540b50b578898dbc4657b3b2ec8d7c4993a29b3e9af8693048339c160d1707d7e380e58b42408addd8af194a36e807387f2518410f40cccdf5918a8786677801541c3d2049a4db7c819f1a1cc669e13b9267a584ce4ed0a2630b3b3de1259fa863aba4055b425eab6f2389252b3888805c7a062bf7c01895fb43fd66bd69262c8c6785b9df0d2986fcb9a6d9b11169cf95c9ef7dbe44b7819da7e2329aa5a0effe36b6ed3f8517d4c3fe088aadd994ebea569ce118101e068a28e977c90a01195b59e95140519a2c493a9642428f292ce46c74409711419369b0742776c6589105ac1c2b43b92ceb134900947f944f21c250742213f8a91680a110c38e9f1ca3cbbb08eb10dc1300a322d0acd860329a698a4d7634837b828fe6bda1c253bff8ea2d6d70e7e03b59efc7afd8a5636f9586cb13085fc44898095209938bdb1c98f165861bfb0ac607b081d8a938d3f4c365606d79e822a570c1608f391a9b21ee28d8e37d4b0ee68e5b8ec8e007317ba0c05b3913965c9ae127162731b5f5574c2a69d20e53afa9771d2b36aec9cb4d507e28237ef55aea8e5c1f0da5c6acebabf8037f4a4ccc31a1808a0f49c1eb73b53e73eb606ba0be29025b623cf67cac275e61da4687dea44b661256588f2bead76b96086468f3c9ddb168de100cc31432b329cf254a6bf5c4b49a90d3282c053282b7796a5989edde14d27175c0c35ac404c30e1a9433d83d7ded611ced72cde4f2123ad4fc17b62f7547fbd9d1b7fba341094b4b5931f5fef62f57cccf77315b0c8a3227583c458a37ef711ab48225cbe2532f80512c9c333450733320ab2088cf9b9e8db6caba75dc3c5d2da9af5541d4b7a38004bcae5805aa447b99c80199b1395755c9b404b446bec00e025363fe6f4f2ab6403a2a2981eb0e1bbf39ecf73f725046b3cb9e83772213e65dc91be088fb72bf7be180badbfe9d86af3ff044620362aaaf8432d3153e5d167bdd8400f0bdd466baa30214079e5ce0073850d4f854430529283447b440a9a5969570c06644633b02155ef090ff395cde018aa7931e66cd1c03083898689ad1828e1272e570c032e02ff2dfc89bff349d55fe2ad4fd6bc5359e2f25a88569ea3f0c4e4df795ef15531b6cecaadd744de4fd99662bb783eb7f8448c58074d5c8cf2204106cd7a1ee2411666b4b265ca214bbb430cd841da594fe40d1f985d8d3891e7dbd30db1a782cdc9a2ce81c2b0651e597048b9ae89861134505e4d2c641b28d2ad4c6196da356c59fa0530f508fb327f815990b14d6ba3555644ed16ad8d9ead48791a47e54dfb83d34b1afb0a96d65465a987afc63ce5ceb9a23e3557f940851155edc24fbb9c87c95e27be74bf00fd867bf4635c5d789b0036dfd8191b609bf6410a1626ce5392d05f36d72d4c257ad23105c4b6451769bfc21904b02c5c0b1785e7447d3c804f084b599050d762ec0e88d43039ada06a570632bf3252b934b0c4035eb34c21e2c667bc1c9f9557b475a8a223fec6d1055f793077f176f126162cddd93e44c0f9a2b6c7d5ef6cf5973019bce43adaea6d3f7e56b436307ee93ab974256d35c607fcd965dfe1260d5b05226c62b1933edfe0475cbc5d86e6c1ce565db0e3e541c9af02953bf5678acf31c921564a3fdee7bbf74db810c7b2f1b1511abfc3b1736a8b7066f6651eed21dab8e6f17c3babe779ecdad657ee1276a643d4a07053a52218e641fc2a2ff707fd649ec7cadf1bbba82db7d6455c218a7c75f9f958441694756e2420c1e574bbf88591a69221b8f36db8b56c300c2c8451dce52d5be9ebb3a03213a6fbf6fd4217f29eaf4e3b7800b7700813aad2813d03693884b125231032d0d1671a246ab4822a78a4995d524b495176b64e5f91afde31afdb6f6cb18b0ee042bc3d702bb7ebdb657fffcb3e93f5980c5a1bf8dbbe2b6fd9098e7c61ded66bbec6b6834acfdcc7f6d8ffe6b87133773f2467f7f52133d1302744410343e8487e5ca8a05f0cbd01944c1b72165266ae9d573e627d3804b6cd051d52767f119c8f8db49b588a5c9a76945a33105b167d420e30b12a25bed8b301d7d5b04213ec28331d93271fb9c2998df38add8662496a7d090e6bc3f6fa5eac2d0f71d5f136fabb625e9e97dbf68fdfdfc58d35ebb5fec3312fb7639b94585eae0d4c6230d09280a31d1fe5aa2ed0271d6f7b2063e29bf1573e66276b749231aec7e1c369ec8337f5fbcb7c126fc731f8129ff3c6063ec69005438db982c2ed74d0b3faec700d1730f497d74bdde44ddb522621261b5a81958525423362e9763136538aa0a0c89635bd144797a7982557bebfd3c497f9eb67514d598d9dca4139e973bb7c3fb40ea896c09b415ca83ea28a69071d8a238fcec8404f359b7008e3211879d543c7e36cd147bd65906831c4f6c2ad4039717a4fae80b0ad523e90596a256cee56500a07366f0e5cc9e2a39e9569c84580a716632696c6afc41f6ebf653787ae8f9f97b2d25f68bffdbc3db4e37eceeef8293eb6aefe222aef86b2dc091258d91625812c6137292c332d262183a29e240bbb424e206800aad280caccb17925f24530313070a84c78d3ec12b3526c2fcb916991959b1699e7284a88a71dc2d31511c88ccea25e201852a3f39eb7a73069ceccf88d87b76c8c41e40ad1b5762d77f1e8ff6abb5e2cbb69df59e31f56042a5b12939fb918ccc98ec3e883edbc9ca8db01c4bcee725b82d329e7a71aef279247993230539d0f86aef8c86b032ac89dc0ecea44419dc9d016fd217028ebc9a6c06f7c013e1a763ea142d1f3e47c302ebb09640937910bdeb451e16530018a863d1b5eb3139def454294b7b8f0abfa7df9d7e5023af73068b1996db93b3eba8f716e18c956d379b8d4117474be27f88360e30f801458808019cc1f05450c86d40d1c303418733ca1d85a0e5cb92cca8284971f45f604446d8eaade82da480e87f9a38b980b855c41155a1341d9989c04a05d4c2c9ce76ef275f669e244ec859ef496dc267ab8e526f155b6ba8a2bfe2a4c91c0924637c2dbdc4f1bdcca8b7a7c0a633409047e8dd5261e2886323fa44eaf8367c8d407d1c2b558ea2bf99397329d26113610251657709e5d80c9103d51257782199bd929495dbc5c50041430982e2c61d4b1042df295684345c6106612940dc1b64976e5bcfafdf1cd2fc4bb3a8a75fbdc7f1fe4713bf3e9790f27d517f21bb4fac9333fee697d7658bf4ff8c4ba2c11483ae741d245b6d59b234b197b09994045e1cd84b03053c664a8f5429b2426468261c33c7034c71c52cb57b5c24824600e1f78172f4b323336b6ca754c06d5d0e64adf513a1e17087e4a17a67cbfd5b1bbf6d5bfea137beacbfd1efd7972912be3b3faf30b5ff2925bbff0252c26afc596bea64fdbbce53176e7f2746271f28638b4670e7b77bacc770285a934a319c8d85368291358810e55d13a70e60218406c08f76b9bf5323f1b6dc71c1dd27e91bb15c84d06ef6c2b52a8056c22735ba080880a1246981f428b7c381ec187e33f5f9d27fa57ce932bf5d9c50c792b76731bd7fe33fe8b7721e60b6016fca30806010f9cd036a4c096228273ac7350a569343005b0340598878c452643bc29cb1d9dd7742f1d893e033c14a484c860044577e3a9cb85c927a291f0bd5ac620f692431865204118b0087e15b7db2bb1012fce2570ee0ff317648c432cc65d5f1cf8708fee71dc2b3e4857d7b690a13b60e7f2a308b3c0813c5473e00da9462ac44346b02e402e40732944caa3afe4986432675a0fdb31b7e46d557902088dbc19c5a1a3418bcb853055449b274b53ecfd721365e3a644d66594808c3dbae5724bfe7b9cff676bde88b5314f5ef135fe505cf6577920af71039de8ef6f8cb1e37caeae0717fc693ebf1e5ce3b4163ebb6f1a0e124c1e964825d0626c6262c0b96cb435cb2e813c34752be041422597ef55a4a2f1046b099a31993a0a1fcc604667243245658455650e66d49bc8acb02bea4067cedb88cc2c112e090bca80e50ac5940367bead5f35b65ef2e61cd9d53f6fc3147d514bc60e2d5de7e13a8e36fe0adc005d07a95150518b82661d39bee65a7cd6c77003a330ee164122899e0327763a5d9b0aea51995b2366ac0122a347916570406434a305b60bcf70e0c812b538a8220484ad602bba10aaae08ed7c6cd9ee86a2606b72f9c01ff446a07ad8920a785044d5a3c0f3d042c2155f88737db0feb6614ffa9b6c6362902a9b60d8f8fcef7fefb83ddead136ec70eb46c8b3d8533da0f70ee86b2b4c036110cab07ad0c0153849bc9e0431815b12e83987cdada0614ce17f8dcbd8e63fd92f8d8b496e31a4c5d637f88a8da2d3cacefdae852bd76fc351f1b8b3d9a44b310cd7933952c92c9f5fcb1429c97465a8c260e7380ca8986c31693febd6439c91aca86e40bd29838f67a62c1948a1af005c07cfbbeb46de51126cad24f25d98a0b0f2afa02a779cf9e21deb5e4b5adb8eb2ff3cbc13c1fa4f5bf280a84e9f3399ff90293b53b173cc5c71dc7b938e7baf3305db978531027ca4ff7b4d1992f76e8f4185195324815a9899f73ca89bc3bfbb3df3c0b0855988db11605024abcab78c20b679f9f5ad7a284947cec3a8011953518c217f5d871a17e8c1bd356c0c493d12354d113660c0361caebb2b6f6e4cd6662a372824864629406334db76c25d5b9aee23bbd8127e4bf3c4be70862928d580f2bc8f61204a9923f22b998c1594fd1191a2375baf045205b439059292b2657b850cfcf00228e60e99addfbabb866771cf7f5bed196dbe0f93e60dfdfc5981d63646f3d5b714d1621c229ae3f63c84ef39c9a0540422421148d0291a4c18016ae88886fb1c4e6d1d8ac1ed68690730143224c940e1c4ccbb1c00f90a071d6100cbd84682e36369463952f185c9869b6612378d94f9445bebacdafe38cbf6a8c1ecaabd73dc9c5db659d6ed7861fc3fe58402432cd89924b81850c63f6d0014aa443a4f368d8fb65f35a4f17e9139695a58928f086a8d0d3c27445770d068ae5cf34e6237943866c66a380a328772d153d51ae1048459440243151b7d8ea172ab6d18c0ee82b3ecb6c7565ec555f142b5df21bdf1fb66a74cf8ffa9921d4014396419e56d4d26640601564944d14c6eb882da99d170122f370a88cf514e85896a061a19ecbe9958d490c3969635934a5568f4cd4d13a9cc942a044ba9f900e664c404294e802991b2c91a0bc2d8c8abccf57b6fe3be41e7f1bf3ff7df3e326f7166156dcfcf97f6e7e25d39b3f6f6e7edc002f0deb5ffff9cf8f9b24f38a781dfe41c3f56d92fd2367ab699cfde3f72a0bfebc2dc234675e112e6f8b320f97c122ce8bdba828f2dbdc0b126f1afe315bceb33aeb38fb3dafffd2b0f062b6ac7f666d2127297fdc2ce32abcf99317eeef7edca4731adefcd911b8e6e7bf8bb87941e004fe1f3cff0f9eb3f8ee9f62e74fbef387702f703f7f72e2cf7f70d29f1c77f3e3265efe9bc68b9b3f7f7b6c19feb859964d9983707df3e75d47e2a51f37a36c7ef3e77de727cf89dccf1f3780c55972f327ffe3466f8a1545fefefec78d1dd39b3f798ee37fdca8cf3f9d7fff3bf72877f327f7e306d23a53eec78d7954f51e4bda2fe970dde6721e24cb9b3fef7fdc3c14715a57c50c839b3ff93bf14eea72f752e7c70d58d677badd2e2fde8ba2f49f1f37fadb490f1ffd9f1f37fdf72775fefdef55b65a86f4e6cf7f723fb81fdcbffe53f773142e9a16aa1bede6369aa7e1ed2ccc92385bde6ee68b64997b41781bc4b7bbf1f08f2c9e46052bff11c4ff381d162f46c92d9d07cb9b1f37a3349f2f8a5f5e119d8cb1ddd3c13c686f5bde621a16ed6f389fef7ee95e1144377f662bc67edc9885c7c243cf365730f49a8156a755e74accc2e53e755beee17210e687df56b82c5ea4ae6fbd78439fd3555ddeffb9d955fef519d1d434ce6efe2c16abf0c7d7b765f375fa9c7e710f4de77fa473da648ec2c5326e5a92ff83bf6b1680bcf9eafdeaf0e6c7effaf4bdebc27f7edc50aff06efebc6997726de562be3dd64991d086d589223f854be2ecc5c673779c2397b77ab9dbb901c0833a816ab115815990b20dedf7464881c6483ecb77e961c0fc3d9d6ea26c9e8f2bf7e26dbd85f4d681c0385fd44e55bbd6f5ab298f08ec487cd6f8206d21748dcabe1759b35d7d8627c75bb19ba1dc575b15c7cf7a9d519fdf8c8627ee0d533a04b3a3fc1b37cd3df5ffa8debecc5e497167daba523ea45adc5b052a370d32b41aa91aefe16d72f47ef3eea4812ab7e5d2a15ef869372166af71b176047e4d8668491c7d4739d68d3ddcd9fdeeb5f0bf06726caceaef397205618168dced5527d779ee934f9521ec4566a50d839ec1eae577bc6c03aaa28a0e72de4f1937eabbe9483d7bb6dfbe23aa36e2c37168b243c846922a5150d6aa255f522c35f42fa37e67bdebafb587a58438d395971d7d7fbaddd1b83ec4c469dd6b47ca260e446d362ee74fe372be0a85bc1a0f61f32f1cf2c128ee05bb765b3fc6f3f5632cfdf4327d4987f53fd0f98d36f1a8cf15818372e21cd17b1d878b4aa5355151e10b9de9d83c0a13ddefac9b3647ddc21720efaba81a0b24721dbd16178b7a7c509515fbb677856d3e4ef3eab5efacdb69a7ea3762067ccbcd21e9b52e393bfabae7a33fb93a511ff7e9f6ae3b18ed5c82bb6ceffa1ba85b9e08ec18eecbbd338f16ea7108d165acf446cc7eeef3433f1d682a46c249de297acb45f999aaf2042aab9dd5fdd86df919927c5a97a6af30bf1369f770d9a33ecfcef27809e9380b0d72386e3d1ae7ed1c7b8655bea8fb816a61f7bef442b4beee3abe0b657bea22ae9df4d131741b3447c17b71ff4db86e6cecd6c6b1b0a7a268dcd4f897ede00adb35c590d1b409df770c813e826368a98b956a5c8bff8ec6fb0dd5947d308b8072e7fefb5f169d978be06d89b94eb0179405612f260b7ce767e7bec377f8bf202db772cb6bc272571439ae23750fc2b2b01796f9bbfb9f3f3f212cd7d57f4554e65e11957f72075199133add9ff7c2ddff2ba2f24b29f93db2567d55c48deaf4960cfdb5b5dc89e3ffbcf9e3e65f0779bc1d3ba7e2f8b2befa5f34ccc38c865950fef9bfa67111adfc3f82797a3b9dff631a17f51f3f66acbc5d4bc7d2fb3f6f02168759f1c7747ef3e3269867bfe369fbfb779da05c1661babbde35417b9527d390b63f17613e5fc6c57c1187cb1777caf67a395f14215d86bb52f693f2f4aa79f75f479ac43febea14e1b6b8f971132e16f345adc1fc4eebcb6b9ff7e6f3db344c7f2f5f4b55ff793d8ff6e9edb2982fbc6958e7345f94a789536f91f8cd9253b7d1e2cd87f5ff7136adf379912e2e8228642caa0bad0755bd6efcb899cef364fa479cdd965ecafe580bf59a326ffebb8de7ab2266373f6e92fbe51ff1fcd6cbe3d40ba2380b17655d4c7de376112ee7ab4510debcb56aded619d5ed9385c5ed6a51e7395fdeb41aca6d3d2a1a55a5eee569b8cdeb1fabac5906db8eaeff148b389bd6ef2ccb6624378fffb5570bff79e3af7e37f5f6cb225c36e32ecd17e17279eb57712e1cdff85d0f8de31bd32ace8faf2b16fbedc82dbcfa636f59bc2c7637dab1132ccabc981f7edc7a6d91ed4510e751d349bb6b7afc902ebde78b3038bda48224f1ddb31bb77156848bcc63b721dd780bba7c998cb1382fe2e0f94e947a475787d7175e46775dfaf2d172e5172c7c7e9052e9f9a27eefe82ae81c5d1c7fc032f2f8932b41ba3bb99678e1e8fa4591053b6aa7adc4754faf6ef324ded6f3360be634cea6473f6fbd65c61f5ffbde32bceb9cdc8933af9956873bd3b97f7c1985c799dfee8c5a87ebbc994eafaf19bf16f3629ee95ecceae9b5abb61f17c16ab10e97ef49bbf0e22c9fcfd93bd286def61da90e7d5b4f895db75f7b671ef8ef499587593ecddf9fb29e20b749586e16de87de5aa4f3c507d287018d3e929c4dbdd47b57b3ecdfd8f7ff7b5f38f481c7a6f3455c44e9675e0e83e053af3dcf94f7be9b7b4112be6768ef5f580ac969ea308d17b9b78c83dbe99c2e6f0f8be8f2cd64f50afb8e14b7de62e195bbe5f8f5b4c5227c39e72ea5d82d0a51f87250be48bcdfbc2e6cdfc1efe9ab0f6e978197652fb7ebe304c53c09b3371ed7fac55f164da290e5e1e2368816b540f9ced4f99c95bf63c6fe9ae07348355fbe23d1f912f54111aa1535af247ade0cc375bc6ce5ef77a56fc596b792e66c95fa67f3edd564b7811744e1bb13cfd9cbb5f0f5c4b548d52897ef4d3f5fa45ef1be067cf9128d7ffffee02bd3b888a7d97cf1d1fac5745b7fd947dfca68b8fde03b737ff68992ead5f333af25058bb377bf35f76761f0ea4c7e993aaf57ef60ce9acae59f7beb36f072cf8f595c949fcc6019d3d06fa5c877bdbe08d7e7abfcebc96be5e9b585f63c75b1f0b265deea151f7be1b6d56c3ffede4746c5f35bd3f813454545f1ee6e7e7eebb0cc05f334bdba285ec860192ed69fe882dbe5327a9f66fc4efdf9d9c6f0e1176ee9bcb8dee46f29ea67891bd1e159f9b89ef41dab699bf0a09c5f4f9a868b8485c522bed6862f93bfbf31cfde7ccfa27be1a5dd20fcbdf0d20f57369bd3f301e8af7efff6d8fc360acf779be9bc5da6fcd5eff6c7698238a5de229ed7454c5f3c9af961163695d9d9046ee3172992701d67fe6a9184f508fff7a59df543569df3fabf4c7168bcd4cb97ef3111bdcb8c14a67e483f6970ba9c6e59d0f9cbfabd629a7a4eb10c17d3b87e5acf8f6692a45e11447963ce3c49b9f5b2aaacdbfc1fde74b754cf99974dff982fa6b7dbdbbdb6cde69bdf71bbf45c781c78cb427aed59e405912770af3dae15febd81e6ed0447e33d0e197d25fdb355e8d2d37303cea554b538cf8bdc6b9fb47cb52196cbe8f6ad76ac9f3fdb199a9bffcefd84fe7e237d92cd375934df297cc789ea39f56c643b7bf4fcadcd41c38514f962be2d5f3e5896cbdb701b069e7ff64efde859c0cf96deef300abddd32f232e12a6bec4f0783699cfdfe63cd1ddfd9788b2ccea6cb17b79f2dab91d7b474fde7d6a32c5c88fbbbb7c122682f8ab45ed5e3b4ddf29abf07e1bfbd3ad4b8b9dc6d03eda3591ed6f3fac4f4e3b1935b41be3abefc9d163b13ebe1561616c5c26b4cba877bf36563fb38be95cf1bfdf0c8ba78faca22fccdc2a0607171727b19675316fe66f1343a2975592e038fb1a6abc26c7de9d1ae070ef78b7059b0f9c9d7bde8c4bd29bb513f3f63d27e25599dcbb335e8cd54cbb0b89a66edb1987abbd3a077a63c2c1aef30bbb78d94b646f6facfad1f4f9f7f36156c7eef2cbd696b7bafffdca62b56c4b9d70c91e6c6d36a5e84345fc459e1f9cd92933526a37a02ee84cffdcfe6bffd583adcdc77d6ee5e3dddf7dbef8bf381793b73db5fab65d3a5bba382f3a38366b49d1c22343f6e9765563406d3e74385ddafdba03d5bda5d3d1beb8a79da98d3cf9eec9af0ecfeb25c9e9c5504f366049f9d5ad47f9eb3df8debfd69c68f9b551607addabefb75bb2a7ef377a7d7f7cd653dcc6f7edcacc38cce17b75736aa77a43ada22de4addfca95795f7a6dbdbe6df4a7cbc65be912e6af79537529cef866f24bef2c5f550a4d9b2fe9786cb65bb1cbf96f030d8a7ab66325d4db7dfa9de4a28dc46b5f6fc46aa9866de2b8feb1dab5dea2f3d6d64d66518ac16e1ad1fd378b17ab5b59aa48dbef67bbe48df4ab41fa37586ef4997d5f9fdeb059af39fbb13e37fd78bfbeefcf604dbf9cf9305af5e18f362b15f30ea976ad1f65fdfe8cf2f457f2e17c133e8b345d7feb72034adeaf847b17c1b4b7348f58c3ce7f9bf0579de8269eeb8af449ed755ff469e7f23cfbfd79e2b6bc233f2dcc3fcc617356e345c4e0da1bb6a83816ea62696045f289a607ea321372599b6f6cd87ec121258ab968ffdf8fee9713a9f3ec63de28ba81cc9918d9487a9a72a2ba26e733f0da6478181972395ad68da5d106c4ca9c038afdf632e06f3d1b021ee638168ac460a9c7b8e3eadffb9b833254e14f94e6f498ca69c946269d6a2967b9ca72adc48ddae89a84fa91ab13a7f57e8161e96b2a33ca72e9692918a669eda6541d9cbe9509f7a58da50c79852f57ef72e68c86583b8f338eacfeb7f5363d88b82542946c362e00b12479c88fb6df666fbdf23559eba87f6ebed0303affaf1c3d348ee6d5c478b7cb3f7d317b42782c1c9bbe3545b9361d2967d5cd7b49b84662f27712ff2b3e4653d7665c0ee48056b3f6b82b6ae9a77b37d5e0a4f1c4d1a0df7c415bd843441d658e40f7346fabd28287b911f1fea5bf74b3a529555d8b6f143a02aa58bb9692874632f45333ae48ebe535afa4230f5d56e468426ff7d3efb3e2d8803e7be00ab914ad641fc9079584afd32588efa54741d6da5959ba926b4c1b5eadfc481b3f1f45d65cf095612e268d56808e7c4dc79361cb59fa7a288a8a80c362ff2db13798827f9edea6ab46db71bbf2d1117aae8e15b8c97fdb02319a727fdd038682b07c7eed33c87da9aaadd992f6ca607c7bdf69b2d82edbb91faecd848ea761ca2789c82b56f76177eaa709e43d8d801919fc2d817a76b4fe83c23ab31e1fd545fbbe976edc6ddc2c56c3516e0da15f53511514e0e6861f414945241fa80f39a003afb76e0f77d587fe7ba9fa24e4be0dc8cd7ba1de6f51cf255fb6e24b773b80d1cfcd01da975d9a0f14e18f5a3c3f89ec4bdc39c79b4e6d33db9cbce217b3d2e7b0784385159d5e6c7af9ab9d192874dfdf4bea96320749bf9dfb63558fbaabdaac7dfa3faf03836b9e20bff3d9afbf153cd1fb561f16873ddc9781f745b60696846477338622e862cc8f4fcb7317fb4db7978d78fe14f93815f562cedc7494eb2647e34eeeaf1558626ebf6a779df17a03499ce9390cb2d8bebacf66de561223d1e8daf766d60dd7efca5df5cf4d3877cb2994f470daa1f957edcbbf2ddcdda954f367977b2f9efa1c26b95e46d51b649b117633be2df880be73981e7eeef3bf75f070cafebff7960b8782f715c97ebfcbf22c97e03c3bf81e1dfc0f06f60f83730fc1b187efb0d0cff06867f03c3bf81e1dfc0f06f60f83730fc1b18fe0d0cff06867f03c3bf81e1dfc0f06f60f83730fc1b18fe0d0cff06867f03c3bf81e1dfc0f06f60f83730fc1b18fe0d0cff0686ffdf0ece6cb02b7f0732bc2ea899c6d345b3cbbd03207e92768faff979fff36f4189efa135ddaf83893755ff46897fa3c4bf17a2f7ad0fcf60714d4415317b0d90d1158d6cb2c973dfe9ad83cc988665afa2aa521e81c7599074370d403bd3a7bfcd5e1aa4dd62d4a79768664ff23a02ddeedfa9a8d363414b0d9d4d36f3c70370bd3f9fba8ede82cbcb7dfa60358ebb31c56c49fac1cf7eca8a1d88b5a5d2eef77e8e9426afe37a35d4cc0d983d6dc0a5dc48851155e5e92fb3a5dcf553a520d67caa893027022ab572f338eaf766d4019c2ff02c485832891f327d20977a6564fd8cfbd99fe67be02c0b326dd4826751391a70d3c7a171b7ab473e1a70ff33ea472cc8467723b905443f9a0fdd5f3bba5fda97eaf7d741dca4d981348d15c152f2d84f7eeeca6abeefb14fb5135aefd97c0fc46741d98b464312f92a4b8ec0d2d9b8ff30a7fd64facbeab4b4d543c0b98ec63d36a05e7db57fbf6ebbdf66031cd7fc8cac3d019596d86b40bf4199aca81a313f9ece030195344527df30eaf7b871d65bbab833d7cb647faf89d2d4d47b0858901116c4c921eacb38ebad03d1986be57df6f81ce56d15086845fa51e23a303abe4f9ca8a1fb7e1c8c367aff289f06c88c66b43fcd768e0e2bdae7edb0eef372331d0b79e50b9df5495e4ddb36edbd6cda4a44cb93363a449c3356c4d14a5f1ccdebbfe3fe4366a5f7d3ddbdecd13a8e3cd5e3c66977f1f89cdf4974e7a69f1d14f9fde812f0b6240ee0fd030038598ee44b40e166dce6e7e5d66d366dc7cea1eefb369766bedaad8879fcbcd76df3e875c72fc6efe3d068f2ff6d263ffbd3fffd5f05fed6226d715554d927dacb28779dcedf29a3485fe8cad654fd5b46f99651be65942b2bc25bc2c99190306c37fbbd175bcbf97f2218fc1cc907ef8ae5a9674baf3b5249e90bdc54bb182fe2389f87a791aa54ad278c7e286f1c5f8c21d1d4715cde4f21962aea686c348473d7d979201d7bd3a860dd78be39b0dec067be8a223fdd4aa3219d13dc9906aa5205024a46aa3ca5a9b2f4b031250e617e66acfaadd034d7f82646c9dd48ddc77ed1a7aed9135cbccdc9d1265c6f86f5e2de08248d87ced1a61db79b55e389b3f750b3e6533b45335fd4925f074fb3cdc1cbe757fcd03d845e54a5c8c7f65d2d6c7998b2200e76310ade10a2e287e96f6bf9785cee5e1899c47b2144897dd5ae05b5c62b709ceebeb1ddbcf60258e10b6071f0721ccc8f3c1e9b3aee3deeba4d1f3e8f879ffd26dcecfd7a3f2e88d9e33cd53ef6689c5221ca5d613a0d84684df13639eeb3d190e6548dd6d431f642c19127e2deebb0d9b48febbbdfecebefda7b5dcd7ddc9d79dca16e0741d01796f3204515c55b6eb769d71bfe966265f92c6c6ca617bd915a61e2925099ff57bd7a963bff85eb71d24e931edcd5ef45eeef0c9476ff85eeea4dd5bf37f9ef4dfe7b93bfb6329c454acbfd142c296ea3f2e043143250bae5fdd3637cffd444aa5176d1c652d471852ddf46c8e9f9bb0851bf7ddc4d28ae55628deea2edcc7c81df78f5bd67d3c549c41daa2a2511501bb12741963e7b28f5fe687916bcfcfcdffa31ee59b50a5aab6823190d2c5bb10e51cdf6f90e0f3ec3f52ea9d8959e8dfa514230899a95dddc4c350e59c06c7ca815bb1a6d74cbaed5f70c22bdd407b2d0f854734dddb6a03c4e373d4e271da52bf57eb01ca9ddb249cb490a568c6c1c3f3c8df76d9bee2294b59192ea762a7c417a0acaebdf3e2ee7535bec31b751617bbbe85bf6b40dfcdfcb0896d83eaa59bdf3fb697745daef3b2aa7b98e7cdc982ab24064155551d17c83880ad26f9eb3e0a83d88537fe76853a7a977dcfa5badb4deed8355e3dbbc8f3425220eaaac8d22f52ca9c5e3f7f5a94930cc8314cd68bfb7a60e6cb8046ae98762c0eda4baf5ce473df11c8db9225c0759725287565a6aa354ed02e65f2bfbb80e8a9fb612908bb7cb9dbf7f5d9f26cad4188339c160d1f85cab87717dda066957aba5150f839ccacaaa09caac92c81f0276ad1d9afe4d953c10ec8374534b44c48936b544d2f8b767fa4ee281cc15b6d1bebf83b2277a0e9c8f546535526b297a9b136c4c35a1ae43306d826e9b9de9637cbf8f52b593f0e184e2edd21022e60a45f5be76bb7f1ac968b593eaf79ac2d4cfd0d2eff7665e3d3745fd62bfc083a427d96d24b7e780e3efe99743ffaa277d919e48f9fb685e27f34e5a9bb516a3b299e740db53d93bbff5f57ed1c48657231ba9a813349261bdde48552ba54e1bae0daf2d9391fe43e66249d2cadd587a51378425bed63c2cb53b73f1f6837543ad76a6b6e6cea0ecadfdb8c7fb19aaea31e0eff27cad4cbbe173e019addfbfde1fef2a3338c9f364dcad7cae1d9faec0383b45f5dc5ebda7dc66dc291adb699a3b336e4ff454b41aa9d29af67b91af6ef6ebe1c675e03c287bb97fca71521207f241dad96b6dfc8b79b18f6a68b6819e117788129ab6d1e15e9fc775fd9a2889b53630ddef8b8dc953e82e691bb9b219c3ae031911937a6f6aa2e269e5c3dc6a2259d66b74d2aeb30258ba0ea83cdcec5dcd7cb1f791ee86bd9298dc763c73f3d37e4595b52bd7c412471c6d1df4dfd3b66dbf422c355c3541d9633e665cc32fa3a2d2177bf5de127b789bd3613275eb7e1310f31b4e8a666f79b4cb5ee4a7c614227d6a1d64829ee06179ea8a1adb45ee9cfa82db1e013860e362c046ea9e97449f92b45b8e54a55e4776c718b01ad7da69b3a6a2aad9bbd4ed9af240f23338270ecc5d0e32922abc3f84dafe1ded74cca5bea8cd88dd1c47e48108999fc181eb805a73d3fc84e4be8a26f5783d1a87476b1dcc034159fa6a57dcf1e1ac02a1d9375754dd4a630c9a40fd753f931495044b33e2e8cf3c3843506beb5392b2e5f358eb75fb19f7f85fd008532f8b7f87cbe28fd24bd9dbcae069d2bd3228491f5105bbf7222fde75ef3e6eef15ee3a3cd795eebe4e17ac6bfe414df0fe6eafb389a278cfdf75efde1107f0f0cdd735c1e3a4df9ae0b726f8ff0f4df0749a3f2b81ad80de90eddcd5821a5151ea3a684907f369e0a02834a5dc2fbbb12f82b51f7777e7cd7bd223be3d175651f99e73ab769c87dfbc26dfbc26dfbc26dfbc26dfbc26dfbc26dfbc26dfbc26dfbc26dfbc26dfbc26dfbc26dfbc26dfbc26dfbc26dfbc266fb3707cf39a7cf39a7cf39abc8ba2e49bd7e49bd7e49bd7e49bd7e49bd7e49bd7e49bd7e49bd7e49bd7e49bd7e49bd7e49bd7e49bd7e4efc06efce7ff070000ffff010000ffff492c7642b8a32b00`))) +var _ = pkger.Apply(mem.UnmarshalEmbed([]byte(`1f8b08000000000000ffecbd5b739bc8b7f0fd55def27566cc41382655fb422081400247204efdd4ae299a2680680e110709edfa7ff7b7004996edd8b13399796a3fd5178905ac3eaf5ebdbaf9d1fd3f3749feada86ebefccf4d9afb75d2867fa2b0bd4df33f4adc4449fec7b7260ffaa7b36477f3e5e6362eb2f0761be6699257b7fb629756a51f84b741727b0afe479e44718dbb3f82e48fa7b15c242a3f47b0383c4fe4d38d9295c5aefeead7f1cd97b7b2f3e946f7b3f0e6cb4d7f5527457ef3e9665604375f6e6e3edd6cfc5d14d6e36fa328ea7f3cd79a5f07f1cd97ff73f3e7cd7f7fba316b1f87375fea5d139e2e8cd0af8afce6cb4dd55ffd7f282cc31c8579d07df9ffa2a48e1bf8675064b751f14794d4fd1f9860dcddb6dccda71bb990121c567de4014ec2bcfe332a6e3edd0445fe2d89c6dfdf7a81aeaac3ec747daa92a7577f85795b3dbb857d18e2e737b324daf9fdafe70f8af24777db02375978ba5ba65188c69fbbb02caaa42e76c9f9e1e54e375e57c5ae0e51159e8a54875989fd3a7c7a3584fdefb3628cf550e47578a86f3edd84bb5db1abfadc64fde5555d06c52e2caabe2eab306bc3ddedf8e7a9d00f2bfccde7b759987dab5e93eaffbc1ec7f8f4b6aa8b9d1f857d4cc5ae7b2a9cf9bb14f685beed2b72f7e6c3feff248ffa789ec92575108718c77da2bddaa36488a928d3e8cf24bfedfc0cffd932379f6e9262f8ef36299a3ac1379f6ed2fbeacfa4b8f5cb24f38338c9c35dd727d3dfb8dd8555d1ec82b0177bb55fdef611f5f59387f56db3ebe32cfacbd2afe3db5e4ffb1f832a44e1a1ec7f34799d64e1e3af5b14c2263a6947ffa7de2579d4c75175435f1bc4fffbd3cd2c2c076d80cdb7a11cb0abc36ae81959b90babea161e9392b9bef1add7a7eb1bd13129afaf8f388163dfaafdbef0b738a9ead38d51e1825d57d6c5e5c7ad3f26395e0449190f8d76ba46d70f51e53f5e84c1d34bc4701ccdbfb8719be475b8cb7d7c1ba2bdbf43d573318c93b24e82c73b71e65f5d5d82effc1c9d9af8f9a3aa81350e1f1f64887bbce8c35d5d0593ab8beb0254b14f3fb962b8bb27d71ccd5c5d3f4bb2c657f574e028fee9d56d992687beb3e74181923cbafa79eb57397d7d0dfd2abc9b3cb993e4fed0cd2e77a2025e5fc6e175e4b7db6a184b2ed7e5d0bd5e37345f77455de49a9fe0bebb9db20d933a68766d58bd4776e727795914f81db2a17f7887d4a56dfb2e716af69f852902f81ea932cccba87cbf64df416ed3b0dbeffc0f85da65c5ee03f26180e28f88e3c8cffc7755cb39c4b9fddf1be0d2063e8e8a5d52c7d9af040e83e097823df694f7862dfd200ddfa3dae7001593fec2881b66c9aef4ab24b88d0a54dd5e2c6df5a6586f86df2171ebef767e77b2d9afcbd6bbf079c7fc91c4c972c4e173cd7d267c1ef17e30e607dfa2571fdc56819fe7af7924bd405da461fec6e3ae7c5e8c5ff067e21097e1ee368877bd9ffc4ee9b2c0ddb704e3bfe72d5da48aea1d422fedd807fdaed163fe89d0e38819b649354e2bde253ffa3a6f8996b8c9e08b4ef9aad86de00771f86ee1023f3798af0bf77e5856a07747feadd8657efdbe0a7c1e0825dfbe7d304894d4499417bb8fe62f4187be641f0d95a3f0f0c13005dcfe424abd89fd9560698d93fcdda10ab80d83577bf273e9b237f1418187cc95bf16ea36f04b1f2638a9bb5f8ca04a50084757f35dc17761fbd2cabf2edecfb85e9ffa3d97ae777e5e95e3e4e363016ec709fac7c37d442b1e4345c92f2415d7f5bb9bf931d4c5cc054596fdd428fe20822adcbd31fb7e235c15bf6f3afdce49f7e352c98703dca2a2fe7995bf35bb7f213cb80e8f33949f8bbec39a8e829719fdcf45b37097e2b0de253fabc3e7e2efafcc1721df63747f10e8a484df767ef6e1cce6057aa980b0f9f6cdc7c56d1cbe1c6da2623453b0f936fe782a9064c8df25459f44f4ecd11686793864e6b470709b3c9348c336c961b34bc35ec3fffad1c8faa1a5a097f97f2e71a9bccc2fabf7ac2bbd6bed29cc60887e7195eac772558d8ae7f97b653deb51a20a7751d23fedfbc7d04932bf0ee27258957d2279f0f363d7d7f91f7e7432d505f6f3e8cf6217dd1e6ecf53725cecbf25a3e9f9c1e3c0af6aeeb567b11fc43e43bdf6b8d9b5e17915e76d812b7d4f428c5e917f5c3afad1d397ab3c3f92eadd799aa55e2b52f56a4554557cfb563df6cf1f1723869b7f953045dfde904ff3629fc7c569c2772dd4f7a9c795b8178f1ecb5a04e90f0397bbe2d03d7f5075d56d7808031fbe08d33f7a74f0f3caff16c6a17f3223cf059b7c58a4baacb226f9b73f5beafacededfe5491e55cf6e3f2ec7c6fe50d3fd9f5b1fe170c79eefde06bb60bca8b3deaa27d938e40d7f2fceff7875c9f170791a06c647db32ecfbf593f5211f3fb91594cdf5e5b7ac3eadc35e6ee5615deffc611df872afa8860592eb5b6531cc0faf96209f06d985df7018d438a99fdcae923cc2e1379c44f19354abae0a7c8c87a60af3f6478f4e2d70b95f87558d8b27a57bd688e7f5ef61faf92bebe0af88f5b13c2e19bd295585f54f655a1f27c83fbde47aa7e4c568bc63ad7eaca46c5c99efffdcc2247afc396470f87d5a0ecec605fbfecf6dd6e03a29fd4145861bdf9ba20e51b94bf2da8783c9c98775a5be039e9ccff3cfe1bfb32e5d6e9e1beb74afefeee7e1f7d94b8562ecb9e3afa61a9af4f47ee1e5fb8641db9ebc79187edc565d5e0fabaa2fdf4404e35bab67ef25ced78f2b7c75910d6bf02f9e9caaf4c5fdaaab9ebce0088a41a35fbceae8ff3c467fd2f3f32b904f374d9e04e334fef4ebb6a9bfd1774fafef87cb5eed6f3eddb4618e8added4f06ae77485d0d196f490f7f7a2bf35eb9f382fe5bc2d743e81b72f138cebc21f172747c43f82725ee5513e555ff2f0bab6a34cfaf095e943f6a86cef553b9f3c8f59620731bf7b3e937a41294fbaf3cee47b0d1f4ffe8e9e0c35661d0ecc25b98a064d7bc5a5b83e8307ffb56ecb2b784ce3ada47f81eb9bc8fefbf3fdd6cc2aabe7a29fee4f5f65f4d9ed47ff586ff872fba5f7dfcf8cafb5591d3cbef579fbf76fff47afce9f35331aede69bf6b21fd0d5bdec73c7aedd742fdc050d6bbb3c17c143abf44d50ad4b7e597ffb9790f72a1f9497ee61afe0d18442eb402fdb3a9dc46c59f598186c4ec70372cf97eb9a1ffa4ef6efef39fff9cd88ab7d1982fb71756a1174cf26f45ff1785b5df8faf5ffee7261f519547b14f3755720c6fbed013f6d3cdb014fb85a1279f27f7137a420f77fe1a5ae8cb0d4331f41f34f30775bfa1f92fece4cb64f2e73d4bdd3134cbf37f50dc17aab7d849f5573f293a354d3fbc7cf99f9b59d8de7cb99b7034f7e946c98b9b2f1366c2703c73f7e946c7499ede7ce10705e8f37177fff9f3a71b2b41375f688aa23fddc88f3fddbffe2a7d44dd7ca13edd18a88f94fa74633ee65fc0e9589a09c5dff59783ffdd0b4deb24eb736286419f06cb533445d3d4a71bbd1aee7ca6d9cfd4fd67fa3f9f6eb41f8852f793b3e8a5c8fff97423be5fd4fdebaf266faa10dd7cf93fd427ea13f5df43a3c6e18ef04c8467223c13e19908cf447826c233119e89f04c8467223c13e19908cf447826c233119e89f04c8467223c13e19908cf447826c233119e89f04c8467223c13e19908cf447826c233119e89f04c8467fa5fc7339d8693be76d2e89d3cca15dcf49f4f37c8affd9b2f7983711fd7ae77952fb13d8619927a1730756bcca7336dfe6786de46a71ec5cee8d4fd647246a7260cf573668ae6ef189aa33ebf60a6bef9b8fa2934c5d217688a3e43532c4bdfdfff023435e4fc1568eafe15686ac29ef126eef33d35a1ee28e61dd0d4b9ccef80a6ae44ff2f4353b7a808aae7e4d4a36e9d9ebec5463d024ca3a29ef8a553433f0598ae89a451fa62c4c6cb11cb187f3f31d58fb79e852036e89fb34157f6e2628d6e944eb08043efa12c51c0d59662a26d1549883da68e01831bb02f96361363980874201b3192eda3224b1d3085da730cac2c8c5659180570f5fe3786ae5079ae81836e1f2139c6a129d4c8d5294556b1b238c76ba78a181f81ab969e7328c3cc4e15593a8ad93c3298fb28608d0eb9061d6456a9c82aa72c541a665c09b320f2643af6193b5a89420cb375e43131f6987a78e63b93214d65a1e280b52b244b0d12852890eb1c38eb06307ca4c8a084b2d58851b1553a41816c10f9ee3a420cdff9acb614f3976929326e94459f9f49e43bdc11c9520517da98962cec7d06e1209b465e861bcf55b99528b0be8cb7be286c3d67127999f5184eb65365014a6f532c3d19b58a8c301285dc778d02394ae3317cbd62e838c8ea64ac477e8c3fe1b7d059b743595c3512d33e6fd69007980825cc41eb337ddb5ce7c7ce20abf679cc612724c8c11590a78d1895962f5b5190d947e41c28dfe1f2733820723964a611c870054ca184995e21a7cf8740f5613c866f906c3768a14590f14ef57dddee42eabb2af658a30df2b41233bb2f530a9c75e4b95ae499c20276c2112d54da636daacf83b24085efe88522e3e3a04bce24828eb4037d7a2e887de7107bd9010fed20eb6d7f1fb9fad846ce245adb822ae67a091d5c79ae1221f9fe942f9df21c2ef55c3555e443e9e56a1ce4691e744204593d7ad4c78b3e989e6b9490e162285b4b11db0d9271a52c74da63a208c9b806a610079d80a1a362201b431e02b6ef1778dbeb70c0d854d009254c84c477b838c8705f27e570ef5497401c9ef7f5b9f432e9084c2102cc7de4e5760965a3d7511a663ae53b7cd3f70fb448a3e542c7c0140ab430f6c1b168570c2a911cd35ec26d2143b580e12bcfe1f21583da15838f016be3a0bb3fea9b94d6c474e9997d7ab80322bdf75c950a4d81820c5f8d75aee2c0b5cb60ec870d104f3a9408fb20e3197f6cff18268260cdd3086576179ac2d177e812ca52a788d3e5a5ce65a10d986914c8d2d667a41c9893a518fdd77fddfc269f272ade7676469874f00eb8fb0ff3e1777f320c75477dbee3ee3fc88773bdebc27d7e7475267f970fefb3ffcb78383361d8cf147dc7bfeae9dc5d44cf257ed5d3f9a128c1c3091e4ef0708287133c9ce0e1040f277838c1c3091e4ef0708287133c9ce0e1040f277838c1c3091e4ef0708287133c9ce0e1040f277838c1c3091e4ef0708287133c9ce0e1040f277838c1c3091e4ed0cc2bace99f20c4a3e236c04583c236cceb9fecb0792d7846a878ea57b6d87c15177f1ba1bafb4cd314cd5017848af9bb08559ffd5f46a8589a66eff8c9fde7ff576171825011848a205404a122081541a8084245102a825011848a205404a122081541a87e1e8e205404a122081541a8084245102a825011848a205404a122081541a8084245102a825011848a205404a122081541a8fe4584ea09ebf4cfe354bfbeff264d51d4bfb201e709a9fa8d1b708e59ff1b3b707ea626d41dfdffec0e9c04aa22501581aa085445a02a025511a88a405504aa22501581aa085445a02a0255fd3c1c81aa085445a02a025511a88a405504aa22501581aa085445a02a025511a88a405504aa22501581aa085445a02a0255fd5f82aa5e3b4174013b6106659e06a220a16c3c1dd2c8edc6638d123293a5881186b2de42c71a4e670c1d9e0e12a1016e309cf879251b2b925100534820832be0aae3c9a4a6902187db2219b73011b69031b022eb314c84a47f0659bb399daa083d398e616654c0e472c80868797ddda54d1fbfef3ec95fd45f43c78e61be1ef21764f63190f93e4e1cca7a855cbd44995d0da72676025c33871639ebc8700186b97174cdf8ea6446bd82ac9d82d3b35586db5597568aacd2481438c85a91c7488db2503174780698e7933563ec31550432be5316631e2f279a5e9d08793aa1b144a2c0facea11a4f3b155a98ad233fb78f481432dfe14e27b30a95e7e04659801866b882f23cf21d6e0b197a38b9d2940ccb12850eb8120d5c9d0aba49743a09733ee45fe6f7d0b11b342d96866c33c039b48138b61bc8ec182dec0eb85ae4e569e439463a9e243a8f903ce463a8ab4b7bd83cd5a7b1ca50eb4954e1f7e5900fd8650d1cb0eb0630f7a52283364804ec0da78102ec8da7c056a7326f21c365beabd68a8c296581da20ab8fca0295488ea2e134d5451f9711ada26269bb42eab9c309b5bd3e75c8e19a317f52e339871674420bc653382370a50be793454fa7590e7ae789c26c334f23c82a91c71c4ae070d4d589a2d5559b5c9ff8ca40a6c64014e880c10de8845891e918e6760ce503b772f40e3812059c7534ea9331f69d59b1143321f2fafe92eb2d94ada5c7da1d14a7b5230aeb0dad5b8a48a78a883e2b598ca17c68956d1129795f1f8754c9a95c91f64b459cd6a6886690e1a83ebf2bd7e002d9ba5364691ff47967a4419f564c7984cce4491860d2259815916606913b2d2245a41595d2f1cad55be4aa5bb029fa7ae8fb403dea79ff378ea12b54e0459873ba064609b7839944f92ec0abcc9e78c3c9c3d6f3b48f816c6f51667701835bb8edf331d9ab9d1088c934f2170615ccfa7e4673577db8794c7f3c1175a8c35e6ffbfe24d3eda047e329aa706c5bbd1de47b1d918dd663edbaafa7d309b06829a2574f5bf5192e463266fabc0e27cc66fc64c5d4cdca152ae4a01226f4a0372bd6e88063b5d0914a98f02964f4a3daa5bff944d42726fa3418fce490d4d38031429c9fff9dd3e04f302af3fb60d4cf1f3f0cfe7a7fbf3bf68e9fb0647f3f82a2121495a0a8044525282a4151098a4a505482a2121495a0a8bfe2cf101495a0a8044525282a4151098a4a505482a2121495a0a8044525282a4151098a4a505482a2121495a0a8044525282a4151098a4a50d4bf85a29e527ae450a1c3a7c8393c6125c5a8cc61373dacb6734a8cca8173f45d152bf2539e6b64d90c7c6257db8031762b07b52bd6eb9485d7adb656a34d8b7f90d9aa9aeca7cc562f7366b626ece45fdd4290fd7dd4d698f557b82dfa8e805b04dc22e01601b708b845c02d026e11708b805b04dc22e01601b708b845c02d026efd3c1c01b708b845c02d026e11708b805b04dc22e01601b708b845c02d026e11708b805b04dc22e01601b708b845c02d026efd5f04b7aa26bb02b70083297f6127ab4c6fa1c96f878d0487cde6382ae8f82390ab1a30f72dda2a11da2a8d6e4ef68a1c1d1eb071d43349336555b4ad32f3286eeb6c8d165952666ed7bb4d3e652dca3a388ed7a1a32118f3da5c336bd6c8ee7931fb05004ce473d8713564d6913f9bdfc1ece0f932927dc6db23db6883455c5b388ee102eb88d6bacd3c603559370d5ae8c24559fb69995b54b0b737d4f2799983cc8e3da66a8385c1290befb0dace9b07f3597a54ed1bae8d8daca2d754ada014171bacd01bdbdef99be9d199eb926dd6868ec1dc9171e3e4f6c2dc6a47e3657aa9e702ec31a85831a85db9fa1eb84184b6f3463327fbe15e46b740140a6d532e753a9d388eee6a2957fa0b3d873668570ccd68cc4140ccbe0d98faeb666b949b79fcdd627575c968b439d3265fd765eebb46811ca5f118be5e31468c327b0b98a805cc7d1db002469dc068e6a42fef504694159c9ff0b4e6a807988399e180e58645b6bf30aa0d259981ab1d97acba33250cb48dfeddb191656f52d63b7ea88c877fae8ca8850caac0d076f416bad3086da78f3a9bf08667d1ca3a337c6d0bc4f556df58ac4e6973ccc2d97c6fb8c276c9c685bd9068c8d0ae33135a27b5453d0f5ee82c60f81630073c94c5d1eb4014184d9cd0abedb4afdf063a7c3aa4997b132019e9465675e3a8ee4c476b515a3250ac337d6b3bda564dbdacf6bc8c678d0df80ee8750b284e0ce7d69b6982dcbe0b93a1fdf62fd2cc0c11ce043190020661af5d3234b0248bb2e4fb6320d3b69fc73b3d0586251f52b4b05520efdbcdc6a30de78d72b236ed3beb4b1b0ee9a468e765fad117f985970b5eb8459525036a339f1fad19b01c8b66fd54d71c879a684c591a58f28de4fe08e8f4dde93cd315cb74f1dac92c6ae3a003ca00762c4334323bdd38fcc260050975bc16583cf62cde5a325c114ad62eb4e2f6a5ae0c1b2fd6be6be0209328c82a7d1d5ed2d5c6f456e116cc50c63168abb20663c446c73b0fbd8dc9c00e5a5ce92ce69ce3cc3b93b6197da1b6c82a97c1d6fb816efe2cbda7f6c6640cc3b674463fe27a75b43a9305d9c35c72b51cac34db9b784ead23a73a584eb95ab1f657308f3d2f955a7df6a22fee8284dfa345fa5a9dee0d2c01b8f5189b8abb0d2bac1d8beb07aaaf1b576ab58d60f9342e3407701aa303dfb9efe04c4fd6ac6ebc2c63ddad5803878bf5d0ef5edab3823233955952c6d23eeab62df29a6ff1ac99d9bdb21c80030e48b2272b063bbe2cd5aba3c180cc108294537f9a5672eae35bfb219c09c0db087e60a75de820473b7a8ce596147255c5dccc8f663ee7744bda7b3488cd542d0249dbaded973ae9b34a8b647b82c6beddbdec67b6065c85d5b6aa059cba34585bf7199c6edc78b662055d9b19954dd97d7b2bb66dd7eb3c98c0999a07e9cbbeddc7095cb519c63d466f61a6d341aee26153dcbe7ce264bfda287b6d13edb5ad32d166de419f59dccab1f6de46e3bc8db1f5b6eb4e338736f503c7069b2cb6358a5736f3e8082db432e7c6d64f4bd3488119a465ac67b6b0d9d8ca92d2294336be06b4b07d59cf740b64bb83099dc38edf4286db2257ed864d58175e6f7b1a4da43a6d369f6833a57b984d196db3a61f4c1a6bf2fcf8e0cc298f51286d3b7f5a775b909aa9b68796b4d665bc732c9ca01c6f7506947e56ba6666a4968b35b88d5570d497ebad3d0b1c5e7cb0e76fd71dab62901db0c7aebb97f90bf6da66da69c775a78914e56d51ec6dd647efe8b1fa4c19fa9de1ea31c8d6076db6668cf9616e6d0457b3f177c7d545bbabf70f92d5a10d62c20cb91ad60d3ba3ab4d26dd819763600d99beaf4f06ff29c8ec0ccaf616cd9417eda91fa7076da61cf599b25f6d8c4467a4589fe95b7d1b505af2d42e7879d4c139d7f82c72d6ac7d58a7786264650625b4b419a971e638d168b582329dac595c8516dda10c31da4bbbd0f88e5d0317e3de3e04994d8d36e22a6fdb69af6bacb651a887d9ba5b39f383265bacc7481864eb0918752d3366166bd8aaa9cf4bca70a5a3cda89925c78c3e3774df92f6e60257be8357ba1bcfec39e758b4507a96747ca96b5c091c1a878eddad58a103ae4185e6d0f7fa76acb5edb4d366d34edb06076dbb9ee833a5f636f33dd8a0ade7d81998c5f8996dbb3366526da5bcb6b638df63a3832501734d6bfbc0a92d9d15d88d5c2f408e96f068dcf999feb0a20d2e60b897e3052bec40c7e32057db20d7867a7ab88c83405aa78789e6961b6d3ba7208bf67e9eb281ab8bc0c1130fdba6cfda8565496c9056b4ed22cda00d16cdd62f743990eb7cc5d85d90f15dd00d65e756cffb4ea6b29e8b26208d4523e59c25b5ef7cc9de6baeaaac2d8306d83b9a164dc1d43081ec1d82adfd605a9c0467d31fa447e330933a308c3f74ea3b2083324e463fb8d785d16e1b739535e6d67e9322ce7278d19455cdb2f11ad1ba6dc9fc6c632353b754294cf16ec578072895c9da96f41fd4630ddc320eb2f5e087021967203b94deabbe0c5e99b380f5195ef6253cb1e7d52190751366f5ca67a5cc96f93c60d45c6790bfc100e80bdd3424ecaf8e3fa85bd6e8756aeb2f941632eaf770b4eb871769a6b1ecd329a76d806a24758718630e525af0698fddb0068b5c49b4f3b23336f1c2da828591473b44d9938df5d2ae5fa7396ccc2de36cd06973727c992e45db14e61e2ca3d0b6926a583883299a213a5e78473b7132b0daa42505d2b8d66cdbb11de4c3a4e20cebe5d8f546baf4d9df8729bf80589a6f3648762cfb013176e1c8877cc5d4b29d716d70d43bc30594491bdfad1c7cb569fdcedb02e5073ec6112d548c64bd089271a371df01a7b994d568cfe652ba1d74e17c7db0727d6f586b1a1e6310d0c8702430438e9d6a0b95b1e8f90edaeb9db9b1b7a1acd71b1750eb977329c6730e9ce71ce215a37248b613e4806cd8b89ee1aba73a5c2e026b4edb73ad1d6c889db6de16cbc6d1f8ea6fb01e6cf5834ec7209c8115940f779e8b64d389b74012d8973a0cfa79660ce579ebe598028e4a830ce020175ac8ec473f4b7ce1fb305eaa6e3796d421162f75ab6ad70e3df369c4684e49e947b4b331e2d654c1980be12bb2ec46678bfd9ad5873119761ced6576b7caf80e747c8c64bef61d6d484b174fbe4fa64fc2143b90b22dcf150cc395e6be24d11a2d653007dedaf6a8b573b8f35860afd97867635b46476d67d883deb6abdc4e80ab349055f315235190a14b6f9c23522ffb259a6b698c21a37b5a5773465773803af81eabde595619070eedfa5b2c980ec5c2ed7432cce3eca0b5e63f4a8ba6e1c22881ab76e7f9f7a9cd1448d9b595c68625814de0da899e075db855532db5bfdab9d681ace40cac2e4287cffc794d879671d02449fd419dd5c83950be637741729ef73e9fab215377ea16c8b460e0f9deb6aa89e51c12c4949545719c2615cc838c96fedc58da5640074c693e6c8cc3ea387d5926b68c8739e1e0db9fda27e5cd7016d130532ddf291fc26d5cf979d9a054d7adade4af53bc3629d0684c690499946b1bc1d352e9882ceaa7f13f1bf718c4a4ad9349b3b523d91ea5ee42475702e630316658d4f2b2d425db72e458d6b7c251c7ba1b2cecb9b115069f1e32871866c1299da80d58dc78dd9371f8f0b09972da667e789859076d36ad3d664d83594a0ffed4063c1f87cd704ee7c00d683b2d27616e63dde4bf9bd89074d7c67e2e7cb7b3c35760f26598aba27e149690f1582d1bc78fe7f909e527e3e3559ee69d365bf779a3b5a3573f386a0a3229011b6fa26fd6c7b10d2c1674156750d80a3653d65f085980555adf02d54e0d1ccee9d86700a36f54bc918a6e4dc7a2cde055b01dc69316ca52033aae0db2a00d457ed2eb2c64d5e3335f93d336ca5eefffceaca39e509c971999e7a858df46b43ed39ed9fdb4d5dd8279d8c447b8c52b6f135bc02ab70f16bd0a32deb61d7058a76a8c6cf4dd7225cddcaa5f2d19d4ce66d4bbc167c870b362f40238fa6e957b8767f961fafc3cf43ef046eb7493ea3479dde98ed5fbeb9436b39ee5476ff50c27765a0a61c6099e8577813b9df80bdb42cc616959badfc7e9677cb662f464b3351cfb688370fb667e0e8ff951f6fd5c413fce3b7da3d0ba484d4036a7f46ddae90c4874d91bc689757ae83c0b7830a33be07a3494d6bb503e9470216dcd59ec99c7b4f537828066eac4644ad73f1a7b3d2f8fe31a1fbff799a0f19d497b3adca341dbf9a36d7eeadfd2dad6a2569b38f3366be661a3b0205328f0ccf75e33f78cefa88e994a77309562d3a90fc12c2e906db0705e1a6bbad86b1bf01d325eeb31ea832e0157b7f1dde87b3fe62774a41a8a1ca3f57628e9e795ca33db1aab0f1bdd5b67f4c196f1719d02ddb68d5a93958991513b3f578e861c1c362937095cb45f1e6d41b3c1028d7ec063fdb33886cebe39afdd6add659ca842db162c2bfebad9e80b6d4e1dc1d6662ca760370b7b19a4b685b2d281ecfae86c6d0c67b80119b09164fd34fe67fdbe3037e9d199ab75601b6540a9f2c6b62db811928739a8974cd96994916b16f7102e2436102b7abd911c83b5d5afeb7fec83dfd8cf111ebef07bf39bdf47b1cb510dfcfdbff9d5efe4379ed5d0e7fc970f6b98dc73ecdde7cf77e49b5ff2cd2ff9e6977cf34bbef925dffc926f7ec937bfe49b5ff2cd2ff9e6977cf3fb2bfe0cf9e6977cf34bbef925dffc926f7ec937bfe49b5ff2cd2ff9e6977cf34bbef925dffc926f7ec937bfe49b5ff2cd2ff9e6977cf34bbef925dffc926f7ec937bfe49bdfbff5cdef23c8f4f8d96f204b5b9f9172600a1972b82d92710ba362e93bf41eb22aa588d15234d52d64380ab831a54485aa64a046a2d2df6f834e598a111e3fd915a7c9073e234ec4245d8ac97dabcce3186646054c2156e67a05593b355c8061be6e86e7924e070ba10d72030351902ff94c84a3efa0c6730d3ac8ece34354b4ab6efa7d3c7b422b96eb67d7a6307eb6f14cce63f866fcbc8b9b9dcbf93cec0f655e890f9cf27e2a433994412c2290db8dd7c5a7bae2a4f16f1a8de8a8b25c75f7d13219db6129eb2dcc87cfda9af525ed7df493b82fedb44a2fe12be554ffab74fcfbde7c2b62f934afd39fc947df9fddebd31e10ddf7d4e74a145ed4cd327b9af75f2befb4781e4f9fd6500749ba1ce31214cfe152285b85c71a13e5edfa7fd10ee7722a8b6a293a381bae93e9dd57f35226c7730e2590250a9851f9d0f5e92b91b2a12298e16a08b7c61974d78d910b9def701448e236e8b80d928d5eb65244b5843988a18cd3731995858a3dc62e5166a7ab648a51a28c75def7ad35eec0d03726838e8911e6c5684cc35af47119d9525430c28746492e652bc5e8315c9f3731a796ff2882791996dec1615e0d7123c4c8539fff4d1893fb7d30e690730263121893c09804c62430268131098c49604c0263121893c09804c62430268131098c49604c0263121893c09804c62430268131098c49604c0263121893c09804c62430268131098c49604c0263121893c098ff5b61cc8b0efc4d22333770c01a25cc82441c08cdf71facb2624e24595494e240040a167075ca94a506c807acc87613b076075c2d42721c23f142ca459ea36f812b504127c4cae244a63d253823c460ca97791a5d88bbc999b87b92ce72b18e968fe5686c318dc27da1aebafb686d0ab5ef702574a46a250a0972d711caa4ca77ae68bfa850cf74dec396ba107a9bcc669762ba149d931cd6319ae3f952542dc3d6ad95653b86c559abcdf4a024cfe424830b64ab50069a95c3a12cd5817cc0ab334d38e4779d2cd797b41b8bb1298be1e920d3f152540bb430f60fc97d0b657eeb398702b23af5b08df60fb3693ba417a57d9dab3007adcf587d1d63453630c870039c75e49feaa7afb76764e123b1f848538a9ea3ef00abb6c8e1d2a5985eea67b9a9060a5011e7bc2273251485cf6294aa48e464cf356228c638c89572a004736a2473a5a13d4ee9d8ea157df85c276298085774226e82854d5d2845196198d99de71ab8d71598bca20b0ec70c94e47c0cff9a4ef817b953fcb3827fa43e398cbaa854c4fb5691e93260f53e6c1464f60139b8ebeb14641843d938f67d65d02fd7a08043ef912850b0138ab37e8f6d819b93ae9d75aa3a97df77b85c591885d7ebe3207b22995de5a49f468c16da299c71ec75d477bcb11dfa3c5fc8e76b92558d3da6ce838ca761b62e96e63e7a5ede4b5bcea81fb7a5ec154af6981730b409d72251c881c30d078f8033059c08edd3b63bd563328d360e3e060c6e40376dec737964ab589ac2d697edad7fbc1f74ffdbbae4c5e8bf7ee7469dc3ece06d1e749c3f9cb6e4bc3b43a00c3df93cb99fd013fa6fb0a0e3a8f61a0afaf98e9af01cc35f5050e68c82d277f79f3fffcabe9c77af92a0d46b24287d6636e9bb7bf68ea6e809214109094a4850428212129490a08404252428214109094a4850428212129490a08404252428214109094a4850428212129490a08404252428214109094a4850428212129490a08404252428214109094a48d07f83041d46bc0bf3993718ff5e72ead6984f67dafccf0cbdcd503d8a9d41aa3b86ff57b6d31b192a96fa7ddbe90d39ffe0767a13f68c3b719fefa90975473104a222101581a8084445202a025111888a405404a222101581a8084445202a025111888a405404a222101581a8084445202a025111888a405404a222101581a8084445202a025111888a405404a222101581a8fe2d88ea0a747adc424fe98405ec04c5968cb5320734cc74ca77f8468c4a1738872d6468ac2c8c5659e016b94a04339b55e6a8bd96554cc1f2652bf232be84b2dd05f22146b2351e3ccb1a25642691c7f0293085ade74c222fb322306ed915f9ce64e930976dc41ac0f0916bc657d7f7e52ae9e3c7c727692e541cb0420b33e338e46f1e5bb6343d6d5d661fd1426bc4a8d82a9d301fb61493f93d7486837997c6b06dd7a10d44a1016e1081cc8ed162dca2cdcbd3c8738c74d8ae4c9e4748b68fa7adcea077deb2cce629e0ead42a43ad2751c579db39971db6b81bf2acc8a00da2127b8e5e2832c0e3c1cb56a5f4b2a2b0850c97f9ae5a2b32a694056a83ac3e2a0b5422398a3c19b5ca62d8ca2d5a45c5d27685d4738dbe1d0a600a1d72b866cc9fd478cea1059dd08244a0fc67758edc713bb771bbb5718b444f14669b791a4156893ce6500e07056787d2cbd538c8d373fe4a243eb695ef700c646a0c44210b32be3eeb8297ab2d62751c24421b24e767431e7bbda9fb3654e4430933eb4e8ccac89387721f2173c062a6d341b68ffc854105b3a25d31347795f706b8710c5da102e6b82da3980991d7b75dc6778a4cb7435d2e740c4c018ee5d3db41beaf27d9683dd6aefbb2796e1f1f8796221ab6170c8e7d5a4fb77cf4192e46326680491ffb3c7b193f593175b372850a39a884093dd4dd8a353ae0582d74a412267c0a19fda876e9528c8adfbd9ddbd91cbc49245e4cc688f131dcbf4923d2bf8f46ec33fed1b37d1f7774fbccb277147fc7111891c08804462430228111098c4860440223121891c08804462430228111098c4860440223121891c08804462430228111098c4860440223121891c08804462430228111098c4860440223121891c0880446fcd760c453128f242274f8143907acc84f28c41c76d3c36a3ba7fe8143334f270bf7caf7f6f19917b1336bc54ea87f13b6627e1f6c35e4fc6fd05613f68ee239425b11da8ad05684b622b415a1ad086d45682b425b11da8ad05684b6fa157f86d05684b622b415a1ad086d45682b425b11da8ad05684b622b415a1ad086d45682b425b11da8ad05684b622b415a1ad086d45682b425bfd1a6df548303d0257812c6d7d46ca81396e0d8664dcc2a858fa0ebd87ac4a2962b4144d750b198e026e4c2951a12a19a891a8f4f71be0aedb61fbaef1ba0d3a65b95c17cb55771f99a72dd114596ace5bb359e7add9c4c972d8eaab1394d3366f85c71a93610bafdcc0e162ddac19be41b23d41e23e0a32fba8c8318516d3c6caec6320f34dc0d86e90610ab84a356c05674ebf8f79e14ce04a3470756a690a9fc50877c0d51a53b66320dbdd524c9bb563a44b519d0de572386a651b5c205bc94a9c26639afc1eca520913a514a34275bb7d045cb5536605afc87df9393958a825cc8d6cd9a7dded2325e557ae3c4996eb42f51d6f9417e7bc22732514fb7ca42ac8686a95827d90e106c95e0159adb15823ed65fbb4fbbf905586add9824b39ad08b16a8964eb4e116d4649c6bcf4e97c5b97fc3f07c55d0cc53bc8b82ba3336265f777ecbf89c7b1bf0f8f1b724ef03882c7113c8ee071048f23781cc1e3081e47f03882c7113c8ee071048f23781cc1e3081e47f03882c7113c8ee071048f23781cc1e3081e47f03882c7113c8ee071048f23781cc1e3081e47f03882c7113cee7f1d1e7769fcbfcbc8711889fc70dce4f3eb15135368210cc7870ecff2e198cf1266412226e9524cee5b451aee9dd9b80838dc11b92a0e3a81f2658952e6a763484d0187b2bd45aed13f637dd728206b538a6c7741c6772b51e8c070ec28775466ca5e9b4da3e148ce858ed1421b38bdabebc81b8eed3c3171eec0c4356206689869912ddb47744937a614b11ccae03b5cbec2eb5259544bd10571904c0b314a55d44d2365468dc77b2ec663513799cd5a99bd85ac9a02572996eb4215dd81dde347be6fac9755ca6144ab3870ed3e5ca1a448b245a5524475a8c387e4be7d7e3ce8784cab528dbc5dba14d703f7172db3e7dca0d53fc341ae4427de6e299ae9528cd276d5092acc41eb33d67864eab9bcae12a10cc78a3c8f02d6e8efc541b68e0ce63e3a3187a7b6b23b31c2839e2c1741f4c823ea7bc8704760a3ceefdb2a1998c6832296a34ee04b59c77a5ce3472ef2c24172a2e7e83bc0aa2d72b87429a695b2084eec63ba145daa40dd186f5faf033339a322d40de9d370b11eea1bc876d697a77fbe4ad5162cd266cd1cda80b1fae74bd1bc6f95b9740c18bb43a2b087ac4ef57900321e36e40bf6aff38d48e464cf3562287b8592db0d7005ecb10606a280835c6d8344286172613e7fc0338e710f79c33a351c994be92d90ad48d95091b69dee4ff543ad52102359aa401225c8e170b8b8a4d55dea7bd067033f24538c921327da711b244b1472f559ffec45ba698c3da76f236e01dc5ef7462615e6ebda5ee03d3095529951bc222ac9f3bc2c45f5a2078a6c9440141ac8aea380e9fbe43c3ab5658344810a5d010f47049f8eedbde23d93539e96dfd6bff558d9cccf936fbd81eba7b36f539d4f45cf502747bf9fe9bcfb9361a83beaf31d77ff51a693a3298ae63effc62d0ffb8c7f10e99cb067f892fb7c4f4da83b8a7915e9bc3b8b5e8afc2ad2f94351827412a493209d04e9244827413a09d249904e827412a493209d04e9244827413a09d249904e827412a493209d04e9244827413a09d249904e827412a493209d04e9244827413a09d249904e827412a493209daf924e8f30a797db25940d1ce4da9d984c2320db99e7da159a1551e0da71687225ecf804b27a0b133ef31ce9b87250bb7254da770e297095e5ef02b2fe368d35a13e80634dfebc67a83b869ef01fc6b126cc84e1f8df7902ed90f37f90c77adc37ef5ce6776cb177254a782cc263111e8bf05884c7223c16e1b1088f45782cc263111e8bf05884c7223c16e1b1088f45782cc263111e8bf05884c7223c16e1b1088f45782cc263111e8bf05884c7223c16e1b1088f45782cc263111eebc7a0d3d5ce7a8c5e00878e5d16e020d74bc84cee94d9b4d1c4c94111b5c89663ac2c2ecf2290f19d22d331cc7036ec1297e3183afbe81c8f18155b45320a600a8de7d05859d847e0acc7700ba3f05d2d82b2d400d68e016345c3ce7e9dd001576803065390553965810ae04ca220b333e0aa18663a06d362abc8b8e9e300a6603be27edc354fc654d0090c70d5a3eff08d98713174ac3b453630c8241a2ed64b94d95dc0e0166e8b481327fbd576be14132ddab0c2b09b9ae7ec1b651e63cf3950be286098197bc8e0062db453790d1cc8873674ec5491010d337ddc85ad1b76528ba1bc8f82dc6e908c6be06acd10b723718aac6245e6fbbc75be63a47d99bc3c7d943539ce73e86adcf9cf2861868e8a2c51a732569ec3e5c819763dac800b3014274b5fb663b8300ac3e1d240e64b981bc787a88814f950a2cc6e80ab1f1f92697b965b318ff7c564dad7690c64fc528e55b1e7f479b08fc1fef7ed78960f8cda5b5c5d3eba0da7cdcdeecf341d434f3e4fee27f484fe1b7b9c8de6e1d52dce7886bfe33e7fbe307593335347dfddf7b73fbec5d9fdab481df5d3536b272ccd727d89c9166704a923481d41ea085247903a82d411a48e207504a923481d41ea085247903a82d411a48e207504a923481d41ea085247903a82d411a48e207504a923481d41ea085247903a82d411a48e207504a92348dd3f8ed40de0d285a4cb1b8c7f2333751be0a241611be675f5363f752d78c6a8f8bb0f6354933fef19f68ea127771fc5a8ee271c4d7d66ef2f1815fb7731aa919bfa558cea7ec2729fef79ea3d3b939d4afc9e9dc91e45094645302a8251118c8a605404a3221815c1a8084645302a8251118c8a605404a3221815c1a8084645302a8251118c8a605404a3221815c1a8084645302a8251118c8a605404a3221815c1a8084645302a8251bd4a3bfd1b48d5ad319fceb4f99f197a1bae7a143ba35534c730ffca898f27ac8aff7d273e8e59ff1b473ef2d484e2f8ff678f7cbc4545503da7ab1ed5edf4f42d7eea11721a75f7c4389d5afa29e4744d2d8dd21743375e8ee8c6f8fb89397fbcf52c04b153ffa29dba32218fdb292a9df0001903afb2f2a8ccf50ab276aacc6d06381c1574828c1c6e8b64dcc2a858da8c5d790c5f0353a060277090b53b45e630ba8ee36abb416521749029b1c7aee3d3168b096470055c750f658902a6903dc65f6efb3814598f612224fd33c8da0d10872d0ba127e306c8f6a44fc393a86295f025cc0c1c8adcf7a04b9b3e7edfd52290db8dc71ac3d68fc3d68d8e1dc37cbd44f27d1464f63190f93ece3eff70cd1c5ae4ac23c30518e6c6d135e3022d8c7d702cda1533d605383d5b65b85d7569336c17d9091a64f4188a020e657b8bdc21bda5984a1992fb3ab127c0d169d4e7b91322980bb522e326608d18ca876825f67567451e2335ca42a5612250be8c9fd69d7c683d46aae0221db660046e8c3dd6a67c87cbc54c6802991ab6653ccb79e26429e2a18e3be470943f6c65894a28effbb07bc8ea5859184590d95891ed062c84d61fda78b2149369b44c8468c54cc7ed33af9e2b326883e4dcd68ff95b4545a48845e4897c011ca94272d45e6fd5e88982e5cb56042edb3e9eb6d494e74fb67454e4cb36965b5fb6b7fefe65bc50c6bd3ee280d5a3931e3d6e7929f67aa2449e29547edf567d1b77c2396ce43131f698ea5c37cfeed7c72b7d8b3d46efd3c0279d3b9559ed208b8ec05522cf5d2f1d26a6d0627ab7eaf86ad001396e03767df7309b4eb457eac235a35291a5064c4be82f0c2a98f5fa35b69b2ff347342b26da2cdaaf98735df08f65a1a962694e22c7e1e9535ee980b1224fd6e9203b44cac2681559586f68ddf244a17f8e516637685af63a4e0d6d70d527aedae34e8ccac893852d64b823640e58ccfa38f7d1ca8e226bce6f6c715a03719a879d3a6e8dba2d22051b2560ec4e49f691d2cbb3460b1dbb339d75f2904c136d36efb4e39ad6b7c1e4c15479b513825ebf565694af19be41b2dd2091a64257c00f8910070ba1f21d3d1e6c40c27f0f18be791ac6aa7d677da7cce6b922ed978a38ad4d11cd80491ffbf6f118eb4e91c7beba7246bbb572ec89e7d07b285bcfc39cd34d81eb353ec3f5e932c0e470284b75201ff0f3b40356c0de93ad66e78d2606913b2d22457e4317a67ddd4e2f7d123852ea0f3aac9db6817ddce6f4697f1cda77e930c336ac1564a474e50a1d640d3cb621879643bac2f121b96f118bd855c6eda1531e5799de4293df7b8ebef31c8457afc63139eb23eb3b874a59a83860851666eb0831b8ef8b91291996254e696da64516637728c35b600a36cc24c67370e5396a059ce9593e56646106658c61beaeadcca6821c4763df367090082588ca173644196c9e817b9b091ddc00671df576dacbac08f6759e1dda3e3c10f7919749c3b6bcbd0ea3c146d1183a7c179a7d7d0d5bcec6305b2f477bbd8ea0ccb78128a4c039c4a1d9db386dab48060efaf267c1d02ecfc78b60a1b67e666f51dfff33bd427dde3b2156a49a8619a694c5101e2dc5498b64fb88447eb8df8f49cb31fdc873264ba7b74bb29d0799741a075f842b616e60c0aa27bd3f8d6173a982a2100d639c2864be73c0a72d7b877e3c861552df55fb766c833c5d7aae8ac73164b21433a1b70b2dccf516cad672187786b4d74b4f162231faafdfba4dee13e76278f7f7e7f627df7e5ca42eb3136642fd8bb3933eb1df363b19b24e66276476426627bf617672310d8f93138fe19b805d4761d70f2e3c0d4e1393952828b664ac9505157ded075757a27ba3b814d1769093cf1398a07cd817cb55577c1793e97745c22d72956874fc0d69709444a1e80764383aeb8f1392641ff90ec740a6ee1d42d6778d4291edd863a2de813d20a737c69365efacda725c069d7071229e3bf280d522df358ec3246061f7f91f068bcb8464a13d0ea4a749d83829590ff123262efb7481a31790b18fa7fdd6fb41aa1d06ceeee4f48942eab946dc977528ef1c53570e6e0973d0fa8c9df61383de0956993e9f5a041cba4462d0a735a4b75e08719049b5b2a86790e128e0c6d43773701487dfbd13ef8dcedc048942eb65c324af19d314f69eabc6d0143e4346fd0e1cfd49d855a6b660918e8378ef78b8763f40455ec6a7a1299420116298a7cff3714ac3e09561803370b8583743d8fc1c97440357e594854e05d950272970751c6438868bb26fc3b81fcc6172c96fa5c838eb1da1705df413a069204b9de75051c8f0c9e0082ca8ab7272156482deb1c80133c47f8ee7dc7635708d02327d3bf793a669ee3b5c06bba05244c47aaedaa8dd3e5219bb0b32beeb7f03d7d8f613a977a4dd4f2c52e0aae7b63fe9ff63fdf9723fe1b0bb60ff2c3ef6541fec93f84e795d8f75378f2d5b9a5ee9f5b92cebe7ed70440bb584197ad20ec3a4467a3c73e1499c0bb54532bf85cc3eba9c6b3096790386730f1e9d59d0d7e3c24e4e8eec0ef60e940bf0cad56398190964a3d667267d1fa3fb36583983feb65eef28267ced39b8593146ebb15a0b58bb04b27d5c315c0b64fb7bd0713510f5de91aa1feb813eb7e14bbdbfb237dfcc4bff1a1cb127f663da97e57ef964e1a177aee5035e3ed651a59c6cd2d2143ef7138c677ad58cba12258ff795de7645d7f5dcebdeaa6fcbecbe30b1fe759370e7f628419e168f61f711cced0a8afb484bd2c1062ae2751f3cb4a0e34a98817629aaa7b27d3cbd93b35d29324743795f2933a55c6eaae5e9dc060ab96a73d283c6cb70e3b92ab71c178c9ed4ef7251f593b44859e82d72d52dd8147d3f196d7d16f76d5f0157c957fda44b9c466881f72799ad2fdf5fee0359a2bc4d11818bed14f8a5997e1673eab3189535640c1aca56332e88a854d04d7965515dda4b59f472ffa0935cfa41ea47e11fbd93f8e7f049d29bdef24bf18bdbccdf719f3fe838bff6b1f4fb1c67fa373acea7ccbfe23ab3bd37fb3b9de7ff8ddf4c13e79938cf1f709e5f5a8a472f3a1c9654af96f0b2f332d9c5b226a305552fa7120d72db69a39993bd920c4b680994f9adcf8012cab6732da79d9e8fde03ee80ab250f894005b98d4ff15e96a4824eb953ced65e547ab961341cafdf93c74136b978128972a788ca7eb59d379aa854577155bea36398eb637ca9d4e7a10026d5adb6d3277101d9de03874b81c36d7dc73ef6f2639d5de27a36abe8d354437d389949bb8eab97cd3c473aae9cf2b872551ae646091d6b581a75b7d346ef2607253acb0bfcb37c30c6cff3d240c6c0f0dc4678d297a7d19f947d1a29b94e07b2dd8d4b46d7f9559ee797f25ce1b4b43ba156dbf9b1af9f4b5c0bea343253e7f81398f129b0f9d3686a1f579490796e3fdb01dc8a91bea384de4286de0fcb57c9757bf7f9ba7889e372b139393c6f8f7e56049903034e4bca8377b9d0ee561ddf010795016b74a1c935814cf75e5d1b6441bb96411cb046ef95b49e53322b476fa12bf4badaad3aeae5bdcd7cd0ed556ee461f2446fce4b73255aa443fa0113c7fa66dead1cc4ac29dedee48217d0a833edf971bd316267ae6ba6632470bedfa3b971d067aa6874f79db30858c8c689efec397f363f208767b58d708724ad33585bf6dcf2619d81ef5eae1e9daddd40b16e2c794ffba9b1f1b382b6253dffbaa13eaaabb19f7b277df31a6da3347aa25ceaffdb7a94fd66ee97d7fae432740b1676055ced495d828cef10237540b6d367693def837d3b3eef831d70f5162e0006a30e3ebe5e63550c18dc7b93dce3f235df818e9f824c3a221967a1c9679055fb99530a9c75bb7a7a5d0fedb79d36484677271b35a69b9d975f31159a43ba475f9ed3da46a9ed8cffba3c02d79809b19517132f47b9898b4920d7bb502e0f3a73dfeac7a8f3e8f9c1dfa6946ec52e380aad874b1d5038061276355ac0e838dd79ce64e71f25633343aa2595ca66a3a7ded6768d2df86acdc0445fe07a63cdf9afe6933ac1bdf70cb3d7fbf6687b27bc329befaf6dc518c795cdc88699cd37e8f0291a968a9fd4dd3ec8f84968d231908dee276d77fc07daee49fa7d1fec6782e122ad3dc74883843aa5c951802d9ee8b8ef70147050e7bb0637d445ae17dec63a68094d851bc4426ca72b0a618b9556f65cebcc8cbf0b983d1dce5102f3d886a92daf8fc257b855da100bccea1897e102b3be2b18d0063e626d17a5dc02a66aebbbc652cb51192e9013387c86e8f80139f389bf0540dfaa95b5a1f8a7ba65e040b61b20db8dc7e067e3d998ffb7fa8f82273fe82783ceeec77ae1be9fc7172d19f4fba3b6f8e83b5c3ad850562d90abb5fe381e5f8fb32fc7f9cdfab7b47fc0e0062c541c307ce72ffad9373ef66defbb5aad8993c330067dc4e66ef08361af396d23cc3799a45a32973b0ea76d240183aefe0ad8f2103029872c8a82b69e40daa2c30dd83f481a6d2c4add96801450a51f6412eb9bb50829e3c1b681e86dd4b93f2f0f968d6d2307ba2183dcde4c192d3d183fb0b94c5f4f68a1d2c0bcd605bb1956825ed4efb96f8ee3fed72dc57cb41f076c597baeba0d3369b71a5f39d7e3698d2f7ca6676d398c6bdd139dcd87f6a85076d2c1ec71c525c8ecdc77752ac8d306e642ede75a035935eff528cce838c8f43bcfa9da610c16e9012b0892fbfa599eea711c573e648b9d3916351c27611a5b9b2d288185bf8314ebf6161750025b80055bdb82a396831860ec5a8eee9b12f2cc393ff11dc97430968c792d21c6a8b48dc23939cef5cd7407321ed85bf5fb9a4154904b9bf5061c36b9fd60512f6c710a5cef99affaee7136050ec0414253b0ebfd1dae018e4e3de9e3e6d5b8fbefe84dec657dbff5dea32387bfad238c9478b98ad1a00fe7dfd461f0c5cd0fd9f5066616b7a27069997c11a6b87036600fe646e3a52a156ed1dcc78265b22ad066c27ac5968c25e9b5ee0a5f8dacaef43ca60d565d401c372b1a50f69c7b002947ad1de03f98f7072b37b02fd7c7105b5ce0e896efa4fb1fd97534f8aa46871cebe776969192de0ff51c9d5a39871630fd981efca4de95f194dadf50ef3f48bbf78f622fd7a92093b648a42bc8a0dc77b87cb519d3fd98dd55451fab9693c796b50005b078c6605431600eb245e3afb653774b5aff6e2d8caf3057356ba61d41523ba68db430b3ef2c57f03d5672c0117df736baa6cb86e8c8f45d9821d616eb589b299c8fd5896e0b337fa32f918385deeebe47c747fff6ad7abef8bd7f773cebd31aead5cfbd5a4f26072d99301f9b3314478081065860c1a3d5e98cd48436e6cc945fd8125e7a69b04319d75836668c8d50eb0e5dfb8c76b0e7d50ee6b1102c84dd9a3ae8a6b5df7b76410159adec547f8014daf8725c2f99faced818beede2dd3ae37570347e65ce30ccdf568e81813bad812bd19eb33fcd21b497b6a28fb3f7f3447ac07556ae4e0d3888495faf0e9fc20fbab77f1edecff51626f4d163620c9d798d166a3cfaa45773e5e77da5f75b5db5ece7d68ff355a5d192d7ec2ca06166fca05ff6fdcee082939d3dbf75f8415ad5f33ef9ec0dc5f0f6aef775828ec781cc27c0557198d525fce09ccb73b8a36fd23194710e7f3667ee46bff0efce999fa639d8f026607afffc500266529fd2f9d8989e0b3328815560c70f1aad2ed619bdf21d350518dd05960e74f9d0f8a94d438abbb337b6a5c9bc64e4420644fe4e77a5a5298138c8ed5d90e1d49819df9175f8aaa5c0db3898b56d69126cb11bd812e5d9387e9062d37183df39a69ff437a811835324478f7da0d7e10f8ec530d7cb952355be839ad35ba897cfdddef6d8939fcccfa81fac6ffd923dbb4e735c171974a0d7111c8ad4299d8f8cddd4c173056cc9c0db6c247b43eb077414da070b97462ab50883bb078ba2ada334075d45d90b758e18a00317197a3e6d838cd69163273a6bb84e561a9aab4ef4f9a10d379210a46a0e18fe60b04216b8526a6e8c0e325c0a8e6f8eddbf34d7fee81ac9d3bec3bf78def7b761ec7551091646f1f3f9f76f69dfe7fadb8f5dcfeff5fdfaf0d17e8d3229f3588f3199d271d27a03d862af67bcbea222c6a00c3148252adcc60c9063c373ea859f0215a55c67cee74cb8d19535e51dd6146e368b74675987c3836c5826160ccd51762665d88165c8deff4fdeb7b5a7aab3edfea0ef6011905ec3c381121025964012c81910df22044a952af0ebd725dabda3ad1dcef9bdeb5a4773e8a42664f36cefe77e34bce1d009d1144bf7baf75a266cfcf072ce4ff1d041be99efe3a175da8152b076fbb45e913a2eb80f4e70e3b7bef9bbbf1dd63a9d80e19e9d741438ededbfee0b7c217f3eccf593f309063d7ba5f3f934e610133adc93f07773bc4fca699c8b7c075350a77799584485d3a60a58f8b4dea6252f85da02de67c8b79a3ca98c87b4a78c58c075a961c493a6f102774f03c3a4d658e1058e5dcbeb28a53db30d2fa1461310301f00e13d4211317b7fdd6ca35286dee7bec3bb333b40d56552a2fafc1e1f75eec1d6e7e193bef18e79973fe509985e0d50e233b1a7c14f19eeeeec7f6e83e8b2d891fa7e2e9fd9d8ee47bbee67becceb31075bfb8d8e0a8ee37cd7e6767d4523044442930e065e9f9862ed91268c82a2730b274b7bb76365fa6effbe7d07951fddc11029abe1f3e7761d9a8cfa2bda75bdb0e5a08b5ed6f4691e073def5e7acf6ea262a6a7059a7bd46bd3d279882937a3dcb94f4963f9a6ce033bab84b51d0592fa2b78dffbb4d6f01459a8d09595e5444cc26952ea411c4037d6ee363ec1bbd8c25e62f2bd9bcf3a01b81198f29ed37a4e2882e7f4fc57b1d7481d6f136d7644f894b47b2bafcdd7f7e14776c2f28f72fc335f8376c97b19a98a5a581988d67a9ea8ca2e52b32cb1b6eff7eeff0cb0fc0aedd25c692f3f7bb289429cc7932ffd89f65d5ef0a7e74e4f185422f5e91e3f8daf1ced9bf545e7cd435374b02b6f3d22416a359520195d31d4453d6efd5c6e567916c721bda54c3e44841201ee346a668a0b8b1d56f405d2a27dc4cc512a8b911bf01155eb1869ce9c9b266016469166302cf12208cd0da97878815df90db97e5893c13ebc39d80e5178b40167727426d772d813a38ed4f1cb7e3d9f59efafcfec6c7a77a91ee82235d3ffa57c5f9696e87ee50ffee730ee909bbd4ce66f22b59e04392c0392153cc8962874663c94a33834725f110f9898e3a7fbf3a95d1f223d29d1260ebd2f7326e83afaaf5f1dec56552a833ff6327ee34e46ca05767abb08ef000275e9f677fb55e08dd272bc5ed16c13d8b5c9caa608a0dbc7fdf7626cc21a3731739b546d250f7f7f1d4fbece5a28890aeaa8037d6251994e8633f1ee3ba5fd41de701314e3076c43239e8afd6a6a4454d19d798f7154d5bb98ce7689c41bdf846150d1c2ada89a14752b88d72eb43b100502125a235f7a7b8fa19b946cf7848d54a48ef902604202e846922e2256c7a9fdbbf703a97c8c2f7fdbc6189deed565fe684895a104add4775fc58fd064a45ec5ce7833e6b0574058e33c62fa63a28e9ad33817f9992914334c9c793c95eb18408961c6e31c2e83a933f1a4940ce22cb09a3529a5ee2a7a8c34be24395ca78150a996cdc834f3e7aa9c2604eb5e8114c1ee3a6282794cc516ab6d1d832c73c3dffb0052ca0244b87dcecffc4ab6a3fb88b59b4fe57989b6b10f8e71d1c07d89699e89a5466abb4b4af2122f7d9fbf7b65d7a41adda7d6f8c5ae19f26e1f7cd83c2dc77dda812c2d85fa79de99efd2526906e4acffac77c099dfbc8f42b739ca27b789adf12ed69edeebccfd3fdc470b770b961dcece8e6b4e96f8e025b73dccdbfb3006b7674d6cc95e58e32a2d61b3080d9996480e38aa836e62e375bcfed4071f74ce2234b2b442325dbf1a737278af0ff8a7fbd530862c5ee3a9dceefd3a812c2961f54e9777e7d714d449299b838c7b59fbf7fef3e1b9f1e382e9524cc0f6f02c67a397f53c734e52db91c2c6fa8239bab068ff125f70cfd9135da28a6e282ffdecbd2a470e723374d49798bff91af7f75a469cf2bf9faefff19953fceb34b6fa41a6bdb19d9dfa83cc3a9cf9f7326de26422c4bb48858fc961edcababfd4267ef3f71f6322796cc16dfc859f76b5f8fbc9e65ff84fe3fe0413a328788a26488a124de12200d2c725ee5725305302a658330195d14e106078f94c7395da092c703befd183c7dafb25bc535282156ee3ca03b39e579912152d0cc23a584d671d61f83e2970ee571cb81569b9e4da8ffcb2b77ecddb38c7fb73f624e36cb739c9bdd3f3e995e22217dbc3aa28e5ee0b7b583be5a2feda1e1615af936ed0a7c3b88b207d74d7a3eea2bc23cd42b740c853411c11d4780aea7d06e71169172b13de105b586e2f4a6615adaf8851508c55cef06d6ad13a55da2209b338299d2d56dd3eb68d1905f23181bf37be32a62b58f75158dfa3290a99a9cf38c8f65105b59f60158fb6ffb34e38274f0ace1cc0df606e3f3c33e42fd397df51cfe8af56300ab80f9a98a12ed17096aadbd7f2aebb58960cfbf431f6cf2dba16ec2b2c80f778f0bbffde66c632aa6875f01d4ee336c738927991ddc5ad31142a5693007b9e4a17c8dcf644c2a52beba95b389c12275bd9c2f5a8334d69dd04ac56707e386b70ee4a67eddad99e96ed0e4be7d153c6a6d0e0436a8b478f8db3a4c77bcedae5d2daf7a4a80b91a38ac873589cafec2ed03fe328deedd70fe3a37fd649952179e8986fe784100f7176366f181aa78a2290276abbfb807b3e3eb74bed81c2211be241afb1266fcedd6572e98c1e6bbe8a35baebebc47c92637cb1493ba5fb418ca7c76ae3ad260d8b0ba024c454037ad721756c20934f70415d5ca098e53840306b3911b7cc442aca33854e9a8728476adc8dfd15830b0a7eef09c48b15154a42da20088cf55c8505a5188ad2e95d6ac088dc75e2a0bbbe130728e136627ace99d79c625adff181ff1e77a73a5962c1c748a5c582814c58e87e880b7c9ccf09ff7c19e6ce55c701a7f4d68518d13cd26273d47a0cac998d16c896594a8926acbaf6ad76bd828ec98af1de9f1a0bda171b4fa511b21cdf6330724df8b8b2bdbdb0efba2074f6a432420160466ce124a60c30a9ef1925809cf5af5ef278df90b3eb284412e5de618dbedc830ffed50ff72055898a2687737ed0c3af3f2bed222797e2db0c5f3332c6da5992670a828845c578e669c526cac9c6579a4ac899222aa7c7d34c8d2ade45a5c47e65f448e50b0cf1262e1b33ad0a352e8b7d2ae93c2edc7dacd5eba0a45e608b9b956d8ee250ee93de6b5346cfe4a8dec4a793d772f5ad2cfb1636e6b0f6202df7efe5441587f85eb0d963a48e9b8586f603b590e6f40b95cba34f3a7b23efdee8e88ff272a0eb39aea59109db9107f9f556afff21beae094d74fac157eb383bf80a035ea7e4a1b34b3577fdfafddfc8fdc93b9d73b0f36cb93fea0c67a04a12ac1d68b8beb9264f631ecf9686406a1bbbb4f2decec17bd665e23b7722667a965645c3c34ce107db9a8d1fbf21f33fd43efdc86f3955f22e181d098b3e0e367035e8813fcceba01b2eceeb3e600b29fe7aec5009d7ac1ccf57acd97192ad6398ed03b55d7a15b4831269ccac177e39aed0d4818864268154231407dcaaa7be85ebd8aa1f5c136f9332932410ebc472082af12c50611914b0267db64b005c5c90d7fd59bee83b71bc723c3ac601beb01dd7d788b73abb95451f8ffa6518f7603b7697c6ec389929827a3a29c40def9d1db70d48f2a88b0a47234aab52466daf6bc2483a0f7125755c6676aa348f519f69e964dcb893e69e8408d190531ea0992ba33d9e5255f4c6a357e25b976553bf1cc7494f1b5fa5c0a757c571bfc1497c11d3cb1246b7910afb933c58217fb0b53fc4df9ee308077fe463bce054535834c3ba3ffbc3b38ffb3af8c31fb144a75abd33711f2cd352695255def09778defb1abb67d9ba605ca69af71c9f5c9ec35caab2e0033eb4ad5fe294ee3fe18bbfded35230bd788a21bddbb3cb748f86eaa4c4832f9e961978ad832eb893bbbfc34b907f092f412eca9d1d31ca0e47257f4001bfa5d4dcc790b4be5a5b4181b120b5c5c3baf555dc79a1b4b829a528a01987b0a34aa611b55d27c4590624db2306376e19292e349aa559135c49e496a05d598d8d4abd8a95ecd60d60b950db7318e5bfadb1195de8bfaf132d93e7b07ba7b8dcbf847f39e61206197c1cf747b85b647abd97f390e75eeb2b634e0a5ea45add601b224f112da29c2d348a3c32eb508fe63e699ba0dbf67101b7f1348b900d4d6161852bc877553e1296e362026e8876d7b91216b1a59b9152ab227080cb3813ea55f1791f7132c758cf39b975ded73ee2f9da77f572ffa6ce3e231f6893a8f57731bea32be5d3df611d0ffecbdb792c82bbcb650401412ce54d04c43250cc3d0f85e1dbc68d6b82510aa5252a51a14a3eac02b8c43d3ad885bb34bc57d114334ffdb523d2a8926ad62e14618b4953473daa7d896f4890411120c24da545106542d51965c0c601373e95117fb52fb21f9883ac568b1956e20918a88717e189f2f6dfa995fd02677ad8b7cfe77929366ed8c7b0d613a680b94636a9827a02848ea7b20d4a286319f5d8e46a6ca245a4b60b6ec91bc6e09c8674e605773d29da8728178f44a37652e2c253325be4c67ddc350b16884940e0360542fa3da69ca52aa691ca20fcaf96f517e2b4952bc5f8bf85d33edae297d6543af3487a7d90e3790c394868065d8bee0248746ca2874885d632701681a9b7d40296a7eab61b1ae5d2c28086998535a1902937f0943fc66aad2d99d9fb0cd7a4c2aeab904ef4688e2d09175a56bb1abfe51febdbaf8ed35e9e8ff97f0fa77ddef63e87d3fe2247f9bf74369fb1d15f603a3ee6627fe4dbbf1df3d7c18e56d252ee17ec68779ec6b9e84c7a21557d803b6a711c48b9f4195222396bfd6ecc31c0be1ba40015428f80d1f35eac97cc29682e4d114290e6b81239cf7c0dce9805ef512ee2a5291bd28b1087f780509e071ade729976a9aca1604241d53f619bbce8f063cefd7fe7aca425ccb90fe4ca3686791df7ffeb5a5fd7ff6b99756eec21e673e6fb533db87959cd299353418d1936799516598494bb4e14d459f47494daf77ba4d5816fcef62ec47bc1441b5b800bc89b80fc5251608e12820029c02e00d24a2c0cbd72bfe7bd39421a2d13ad2e22925554697246f81ae5b0c5aafcdcc6f02fcc719fcd19fc191f13a9e3c74885ca82812c9d3cf118bdab1bff8e9d533959a47e38bbe7ed96bfd75dc7fd3ee67d9efe7df2592ed355519e81c46f5c973a374180420cd18d28b30695c259e550e712afbdca5319c5db48a10b2fe47d12c22993b5257a4f5de55187ca96c5b97c704309094c7b57b903fea4d97a12ee59013c976d47c964ab2dcd2c73cdabeaaa3266ed76113a59528a27fe24ed4a75ff97ca857ce0b662709d58a47961f1fc52675c857b2952611e5b348bca561ee4e4899174c0b59c9f97a25e5e67086ee31ce51e119ea7c15b26ef3452ddab08d2c755e0d88cc03828db9a50d4f2d291c4762a8f9aad501a2366194f08a249e5645e85e7c26c720c66cacabed784126d026b3cf7baa64f151e8b2a025e29ac2591d575f1e0689ba8fa717d8e987ef90697b77e1f6b14524c867a6a1931e52447c859bccc899be3b8d63ee8393bd835b88eb457389b73f83c95ea62fda99db44d3421d31265a94a9ac3f3efb969de3dff9868ce503fbc2a49f35c3ffdc758e5cb5a2496dcf0373890d9bfefc7ffe11c7ff41fdfefcd1771bfabc4eadf8c79b85b150fbde6701f3983cd10f75b5f1af7d32778dd586ee8184cf2a9f0c77ba4390fab52187320d7c86a4b46b32eb5f65a14709690baa341a6e15c3a2e410b217fef4828bc40d6b3a4186f85ea9018142ab7b9820b79830b10ac288ca2a2dd51083d521957d5b7a94d9bf49d9dffdf5adff35cc753b9bbf71c49d791f51ffd87c41a6b3c74f2284472c11ab9fa9207ea0c57c38fce6abb132aed8e7912b0e1e19103eacc7c1af707fe84b0e192d94e80fa6c179031443d5a0661b640264501843d61638daad1282e9a5da2dce9bc1723624195484f73a7dc47a5b321e45ec5b0e8a8453412d24d44eb5eb0761405ee5e00538bcaed3eb514855972965ce2e3fe6318449425d6be894af9c8bfaae7f23ff03cfe54af6f930938e8e4e2189f7ef5f958a37319263110b77385af3d55dea7c50c5045acb1943255912254407c154a5439b73191374978dfc60c759c8af9bc37322f10ae5f7290b20ca6eaaf8e4ee563a41939aef04d40a1b29259e94a68638d4aaad43685b24f43e79cbcf9d2ae7be900707cd7173d7df0a5ceeae9c33b77f190ef7e8389ff3346ad3ac836f9c8cf9c930b7947b67199656939bbfc3cbdce657e66277ecc71fef43c359cb5c7fb7f3c4f2f9f0ffaabbb90a388ecbb2544c4cb4dcdb5748d025775017d10560b0385f4dc6a0b42e03e2275c4cae6d60f2008082f5765d4a7d201c4a2956fc1190f91ce19d9b030c37390aa44e33e869021493b6e8e0b524adf0d482f94fa9f88655e5ad7ff2d8cfa3177728d3dfb8051577ec0ef55c424bbe1265eac2c44e7aa63a480ae13257389494dc2a4e6da10f2c068f954048cd24757c9aa48e15baa8a35b6501998a217ca78c618b5d3225bac8a545fe59c3216ed5de6e9b4e088cb7a444ca55dc13af87f1fa36efef937fe4e769cf6f1f4dffe4596dc06e6a532e43e519b9a5bf01bfca2e4f10a31a83cb6c69b98e1ecc841f832fe227007ecdf65faa8d8a45d73cb274de8423ef7ab3a130a6e227f5c89c25992106ea8255b467118d8344e3469a4aa5453a5503c06436aa21bdf4cf7683d2601ab7b9ec39c31a27bea4c47804e31cb1e56b9988952f7e2ded92f347c0e23fff378d34bbdf5f05efff90357d7ebf8d0ac1a9d89030d7a6c9ba8b326b560c74f39b059f5cc5df29eabb45f30a74e4ad8ad5ed74355a3eecfcf0fbf7f9aa7f79107ef78beba84c16d1cd672111ad913ffd27fcee5da8ff22ce316aed3eaf7f373e81a77cfff3d5ae4e667fec40b8edbfc7a9f78858e1d366cf734cfd911fb7fa9dcf7c1d0b1e38bbb76a626ed8777ed34de515717cdb14389d2fda046090873abe110772c37967365ece20228b18ddb40bd577851747e49d7cb69364526329834809b5317434e39c8e6ae69f67ee52ac404761a3a8fae595397a6fb80ddb50b703f12a0be61d418a59476cca293a81c4fff9edf71a8df1c7233dfc3555e43d7b6f5820d98bcfeb8e6af3e070336ec32f916164aa48e51a4c92d0768ca21af93b2aeb1e90092679ea7b85d54b40f2b2288506843ac991e1499bf00300b245131a5b7cc4284f9e31e49fe801560a2822e8942334e21f74dc45d532c3170415c72248071817cfb997df40fd9d0ef39932fd583ef6a7dbfe00db80a46fdcd98837d96584523ac212ed02f82df3fd08702f3de99a725ddbbd4ddcd81d96386644c6b853064122846b10955af4a37983aa51b98aa5b454aaaca8d5f396aa2d6c83779cb6c6f448864b1658e286b67cbd0a968604c3815de2ac4f1d21f9395946d02e94f6ac69e3a36355188fa5798cd3fc4189fba81811386e23526f2eff960d01fb927c7fbc1872ce1f61b3d1d8e38a6cafd9b7ab43cb1c68f5ff972d7aafb39d5ac9fcedd61dc4beb7fcc06f7ae1e58a33656f92ce91a9355027b521a41c1779e2a672430473fe5ce7727a38b7328c7f700075d396047bf5ccbabc55986b56c9eba01a6eaeb757d3d9f13f7c5056bec5a5867e638f0c28c7079bf1395b3f59442a3365d12520024457fc59c5813b381abe3ed1abeaaedbc54aebe6ec1fe3536e77d7dfbcfec9eb7bd5e063fe36d2bf8812b7fd45f16abe07ba121ec9a75bc2ac4cca546ee9720a630f3096b30d13cc0087f106abb4f21ed30a52585648fc3a2453d757c86392378ea132053021c36695a51601a5bf7a3a8e0665a0aeae6684415b3f5255c931c9ee3b1ff76ef90ff9c38943ff20550109fcef67ff2bb831d7b292fea09b33970a61f74e35778bbee9453fdfb7d7d37eed1c67acf1776b26f2f8b6ff8a4a05362a307a44ab0d0b23562e30563a8c74516a4b66105a5dec7eb5fc02dc68c426711e5f8864ce92e9199468ba85f49de2414ef8212ddf2424ce70af2b16d947e37a628b85378012ab7cf62df441966ede2277d299ede35296173ba97fff3c4c3f1d77af063fee53bf77b9758e36ec1f4ecd823e94b1c8b7205bbe9f59847397b3c1743efa9535f20e5b23c1abe5df9dbde0b69e8aa6627147dcd8acc1104c429c439576b5b90962e343a092663109528c6b9bc659663267d56f21cdf2e6dc9d2299df0dc905cba2341e88eb15f200db0b59a8a8205f2960368334b182980dfe54a7f7ab767ccf4d79c5ee67564e8bb715fdfb5170e9b53af80eea2bbd6c6c4798835631d90f676a1642eca337daeb6f7c836f70be5571bd0da8a73c767531e2d94a60998d9cf5531c75374330742f30318af0a3c5b85484d4966931e3564ca9b55a97b91daec99053497e9ce92a1795c49ff632cf10f7c25e7397ad6311b3dc6d5c53ec5704ebff43dfd8123ec0a36c861ee4effb24f4e7fb80b17f76b61e6868690c453bce1a0ae16006db1c6cba8aa4ddf362a5211cd2310072a6852eaccfc521fc5d0897d82165852b20ce03a95fc3e28740505d934a0822ea9d17ba5a3bac0303d5053df72d8caa6664ceeba24c41f723c89660c9d978f7c367f93a31bfadfe9177371a9e3639e8ebde4e7bfc3a5b7bc42cc2651879c95e46fb102e7be3fd58fdf5d947bc5122e91097c5ed1392759895434890a07f9058f62b309b06d6edcb231bcd0992416f0bd8ae7a2e0101167e2922cf641a610851b44c1f7dc6a6f96617dcb42318aa7d9165bf8519400052ad9cd7b9a736b0cb9f5137e2e2c130beaefd77f563d7360fd2d3eebee47fe850a9ae8607f7dd9c3271a623d57d1750c6487b53ac5cb5f7d56d401cb7e999d4311e0455ad45652d455d2e3515c39b314e21b11187a5a641e5664c36dd4e0690158d9568c2218b1da487267ee6bb5199b981033d563c5219cf126501dd7add25d520ac94abd4eaced260091ee2969cfa7827eacc9fdfe1e5dcce9ae8e9ba11bfbd07792367188956ff55beaae5207b64b4263970c9d98814c9854c453efc2f3f33adcdffe52ec0429bd3e55894ac86c932abf5a6a8b9695751f01d889d0d9636a38bcf8b55f68922712d549cef142734c5705b722c4332169e729f0deafe8dad566ba6bd365b46e024cd14410b22754eebcbcd83386cb28c43d29ff9affe160afe75138606af75fc8d1fdf57c8597314f7bf00aababec2ff311ccc62d9a6d9a9bfd0288075e7a205075842df82058da52e21424479ffae1df5ca73266a217d6b8fb464eff3df7fd4fed86475eca2ad5f02e7d8a07bd9987027ee04f650169f669293688ca7bafd0757f3a03075f57284271d78d890227103d3489749c5505274269f7ae94d992012ba1c5c807862a2aac264ccf96108da89ce97e016264353701f1d4a539eadc8a6f23eaec63955ad7e574c73b3101fbb41cef5fea05cef1ff892e6248f28a6e178cf76fe2981ff273208b55d2704b769ff308d3c73884e0a5174ffa691f1e71b0e12cd2f0526eb90f9e785fdff63d79f7372b0b570be664a94a8b389cbdc598feebdc6c6837e480bf8ad50d5cba5739efbb589527fccae9dfc1b157d165fc6cb596167c83957a44e9acc744ee988d6fe79a64388874cc669aafb6f5ca72324e60c80b077bb954698596c97abc9b03a9a15c569e140151f06279b81f102eb939da08251aad0aeaf21c15b8d0b70bb519c5807ec4427d3f1fba5fe497f61238ed0babb32f7b005f2d267ddc8fb884ddebfd193e0747ceb00b6b5eb5b90a8b48e537c4ce72625167de1b6162733fad663b576d6d5afcda4785a7218a466c1a8ddc00e62b88ee5d2ad62bfb4e5bc17a82956dcb2957b015a9a95a8cd232ed122b7ba4acee69d1225c8032928e2342f1f735afea41e602202cb95d30f955ccf40cf6fc87fa5273e422a44accf64d1c9ef2516fbfbb94afaa5d84b8742975b8066b51f0d665b415768603d61a1c528a6d9145fd5fae973670f33451e854e2eb5ed5d7e1fd7c33e66097778986fa05831dd7a21ff535160432ee8fd75cd16709340a32850c073888fbdf2311c8bd47eeb5a487a38586190971847a4150586f6328ef45286ea986590c8c090ef18cdbdc420cb5689ab15549a7b8a7b51bd64b64611cf5d95e282d4f8f3576df9103dd2a3494a403ddc1f74954a579cd0dfb6fe018d24aee85f5ab494bf8c8ad71b3089f7282c7b5ffd3fc4e7d132facaf8edad46a1d3c45fa329ced1268dc8b52cedd5074cc365c1e4aea1361b0dc097c53e7d4a4596a29daa2cf8c25d35d628d7521f9de05ce62a1500f57f011b106ae4a5da7aae0acd07b5261ce880ca38ada4bb3b90053ff8fd51f159c41e5cb3e1357eaf5ce2d9a9d6aa64fe39ee288dfc6a4988dc7601b0138412ade24925ab8a07960898605d4c4aa63475a567def7c1ff937bfc6bf5da5bfd7890bf5706e4fbc9f817b791f7b328e96306bc934ddb9ccd4230d6e56506a6e25a354735bc4a20e15fa822ace1ec30cf3e9ef9d20db9d0f8c964378bfb21c2f0a0a1d59d9e3aaac731c382ca5708f6db4e53901a89ff591d278948c6da202c482b37dec7f8c7b4b4ed8cc1ff5c73eacdbc19fb61d7990c1af72ae5ff3bd5cc5cfffe3f8a7f33cc40106deeed7b562c33e7797f4c400950f7011b0baf0c9188a9ccf7d824cc66427a662ce35b35f28d7f479409d3099ffb1beedef636e97f65e2a38a3fbc5c1666070fbadbcc7dfc70dde8c79e2e495e904c834a45932f9516f649d4f658e082ce210b208cc367e59e702501ce5d28cd56c1ef5d92357f4ce3541169b7482356ec6a4d696b601a80ad76e25e3c4badb246593a5caf891c9df1b4c04f1e86f3595cede2dea1bbfcce6acaad5a08846d7ad7b9427bb8636c77cfa6b3cc007feff3aed401185580e3cff25cd5ff539f853afbe375c117ff8dd67cc501cbea9cff88841559d073ef4557eaa97fa848f7fe0e0caf68bcae8120def8e3c917a9958b07af59edd2738d2eb719ca9ed436cc12eba30e6f9743e57f6610fbfd1f3e62ab58c4f7d86078ec8e2f53d39cda3717fd03b2430c7b395296f236a706e665b5f3a8a0760894dc958854bd18d012f94d15c73589c47ca923a8e6fd779e28f55ac094c64668929bf253674b0147d12381126a00b0a0905143eca71cf02e862d2986ec58de0927ef2df8e7f7c8ca37c57d6258c76fc4b3d3670475e81a7f8b08746c343a7e2fed11e79f9ac9c78722e9273969f23ca9542e18adcce813163a5025cb5794c351ae0ca8073558744011d521445e41247aa9820e0aaaed23c2c7a1ea604d458c2796a3a1316deb7c4f63628e76b56199e0b4c2db0a574cdf16e4980e72bf44c1fd96feba2fd197cf8b76c0f5ed26e11e2dde2a0e74bfd2093be837be8afb25f1fc73ed91c5ca66b70f081f244d51f07f977c4415c86710a0c87a8789968b4f76d1ed3a90363c2b7aca4b147b2090d79b0b2c022d504f3145a2ead2c444a13722555a22043b4a060d12316e51c502077abb27958b156f7b44cba663df199f4bd1c3ed0dc03a44ff714f07318a78bfc7f6ed1f2702f17e141861b32adf0193df64fee897ce4fe3156cc434789d911fbfd87799d7855dccb38bf15d072291771ee6c03bb2e028aca25ac1d56901d5d37b1088b8d570a1395518b722c97e6b613bd28b8aaef7d05765e81655a089e9a8a820ac919430f49d914c4d4512c8dcd92982a2df86439d9f64469b60c5e9567e34577bfe61f38da037fdf0360886d7a3fb8c7437eff5fea8bf63cded37dad93921697f7c9033a0b9cf5aae20555f12426634858bbc7d2b159ee8154e5fbd4fcdbba89f3b9f77fa18f60c1599bad182d8ef11d9a2527bdf47e3e3fe82fd8af2ae73e615017936def123a4d43a74ab5df4acc50e717e3516c6dff42977817f77be3d65839ca86af7af3916bf9adcf39ada37c7a1ebf413fc94313659406e8065b042cadaca5217c48cb011774c372e8fae44e2740605fe22d26cdd49fe28d9f3b3b127297955b8d940e663657b0a974cca4adab722d1e70034815c59d1298e6dea3d1265185952a0e72cff61bf9b14c3af81dbba8bc7f9b5bfbd7735f78272c5925e5d7f95e77729d1ccb61df63261e87d8fee91c3c7f3ee2a52eec53446dac88904b948990f611e573afdb8e7829d85cd199289c285610492857918636a8d47771816356711000bac480ea2eac3708d2bd0fa1890a6ac6d2ddc79531112a323c8dcf904577bce2faaa7072525cb7063361f2313ef5e9789d974517f63a7b5a43fe8219dcbdfaee32d960d37d62d1110f675fe57f0e3af430d7bf96bd2234b63ccc649a0fb99fd79f9be3d9f3be9ff70944e55b78e66be2d69d66aa3f19af5159979182764bcb553cd2defa7f6bf731b08bcbef7277a703deffef65e83b1edec3fd793b8fe688a3beccbef3343109a0037d7af07138c7c56c4f35e98b4adca7015da2107ab1e5aac4040f78cad78c890a97ad83a8d4b125b6f3de5057b6096891ad0332b652d25648cd4aaad58d083282e87d4bd8b88c2d407c9639e20b1eb56ff8ab838f9fa8d1053682778d73fa61dce31ee8c5828dcb17bb41398d77518deb4684691b33ddf121f7081b67b4a2b395747466799dcb641ef84d9e549ee269b58942279c2bfad40dc543006840cd713f07582285df8a5c18b139d28474f5d564bcf343791fc0df80c059eb4f9a7d0ca1e1db047c51e37a619c6efc18a9e439de852e8f41c8b4035934d4dbc1fc2beeb9831fb3bc8a6d4cfb0583438f84e8e0b71ef633749b880d1cafd9c16f781aebb21c493b5f155b2d081d1c051921bdf110058ee602b90cec9a72a59e626014c41c3337944c94f4262ef447d2dfe978d23092ff1ecd01ba1153a759e5887bb96346ea7637d752202ceea4fed84f00357005e77e21905bc9eb7203bce2eaf99c678ef6434c2034ba98815a58527d55b3f5beaef9bafc386762aab105fb37f3fdd08735cbd20ef42b06d689daf69fbf9bec170c6589d50e9c6eb3d7bd583ffceee1595d72152a71c8e522ac655afe7a6ddf7d9c6be8bed21fafea36cf3df7b61fea305ff461ad9e62de87f5427bce5ef78f2dcef58f7d7a7ee0d8fa7c1f9e9ed5b35443355747aff94d3eccf93907fe36b6ada4a56cf8bb3385fe5873ab1ffc0525d1867e528f031e2d444a74aaf9faf3dfd3c7a81c8ffe7026afc2f3369b7e66a35d8feb2db1eafb2874d67f274b3f72bbbd3d7bff46ac4af6afed9657e3ff28269552c498c96fdc3c9b0581d0e78a0cd994ab81897a1e664562f31b3a859e5fe816511c1051e89280ee5c5342d167144319a2f5af6eaed26940b9ee87681d04d93428dac82dcd1da1a2219aa1afa0843e2c340f5cd5ffcb23d66e8f1c28de5bbeaf33f26c11223d61ce2eb1bfc90df6f3d8d57f576e29749b017773b8f74c0e72f56b3b6f768d3cece1fe284907f6e9d0871bd7e2884d3ef77d73d27317c62fd06d62b5152b6a25a274b764a066c4c90313dd534833dfd41ffc22ea0994bd4b79cd4d4ff342516376dfc6408e7c95626a212530a15c15f0d69fd2d807ceccb5d2ce67c24b72be10ca4cf1a9378aa9b317c5d5e317c3191ef823fc4f7bb2ff24277bd2cffbffcfce3bcaa3a1a796d845e157b1e1d947fbe787f66fa4c23df74195a8f064ffbe994773e2bab8e87c2f2763e0b36c8d7bb3f334f4b00a9c39a6a986a772ef5bcec1776211757781662c5d4de6492555cc5ac26d81101ba918142aedb9740be971064a518898538a527aaf7bfeaf1e6bd06105a87c559fc426d41697c8e77f2c9e76ec67f825bf66771dde8737f9efa77f1f7bba5c164363fc210de9140532c753315dd15415a1b364e6768f0b07f0b28923755c63251db9b620821a209677601918b9975322acf6d1cd0de84a3a41d0dd5105fab482f7cce2252bf75d60ea15e99a8a30ecf944d6893ffe1ccff59dbb52c2831dff9076a0134c576206bed20dfbc5c0adf7d7baa18c18ec1787cfa103920ad7a73af073df37ee64a45d7a77bcca71c8145361e169a08c1b4f85d1421dc3d4e4b7643a534821d7316b324f71f0d29475c4229595238026db4d5236c40fb98e8a4c67760de6bd0b52ed4e49012cbc1c6b4b335504352c2fac6f532ba384d56bffac6ef8928f7ce83bf629774ef9917fe3f8ec395feb756de1a91fd7f9be832f58d1679d73be9f7bccb8fe125375cff93f0799ba4d54581c731158461a7ebea7277fec236fdc33ae277a5c7ec2171795f2f11c3fec997332fcdee1f9232f93fe70698f415ec25e4cc080ffe3d6c09d5e2fd8eb9ac0ef60d3ffbebee5eb79fc6a162acf52cd6bb8454ffda86817fb204f5470d0a132a9bc1386fdb27b4395a6f281a810a37465739f1542a37d668992af2372a779340be2a99307936d1fe7b40c88b8a1044c57504cfc1c1534471902e26669171d5f8f01090ce92a33951ed6d9f4fa04b800593521819c51891d9f7d17c3fefcbeafb07c5fea88834f74c5fd78872b3cf7fd110b7c196683457d4a4d3d01505fb2fbce63d984fbe3d992f2e932805a60818557a029f5c71536c78fbea21b8ca420b69116f4621298cd833b95b3a8a73346f49b2543b6ef6f372babdd6313395cc1591c6296f6bf7b8f627f39c5f89bdc15830c38dcb3441d35a9864fbcfca7d8822acbd5b7b8aeae80373faef543aa8e1f0fe31f6de6a7fa3a51f3aa38ea8f2fe77be2c8baacefc536b6bcddb14fc5565f9a599c003c1556cbd212ce84c5ef11cd78cc6a272ee1965968833494d1108388e901b6a51b84d9a36f650133a9e95770b6323d2d0991bf34bdbd20a84959bb116a3da579361295987db747fefb75b9605fb4454eaebe2f2fe3bfc8a8b842bb64fd66af9ad3f897c9a6026d19d137c4faa5095bc6696e4c82d0f1a9e664d804c4afc4833fe585cfe02ceac6eb85e2d45e8063b700fb956d2c58e10034a5590c248b72a30800d708732c37770e32ac892d5cb9543ca4923eac0ab874cfd64d7fa5d3e18378a57bcfe9be41865940a62f3d6bcef4b41b7c91925bafe2159ff6254607ff7e1b852ff2257ce278fd7b9faf75273fc1f91ff73f2d69119de2a85ff646ba866d799001a123b905f3d7baf2691e27fbfec2be580d4fad91c2fcb11ab176ba24a0480b19f0ded304ac6f532827413926cc6c2a3a9536a399959ad972a1d61c57ee2631f98658e33a05c526b0d0245070e1038e5850a81ec537a2aa7baa451b4cdd1d329b4630fe3117f16d9febd23ad1d3faa8b07c2753bfd3ab42fb7bfff98fe3bfc8f41065bc24cf31fc835d7aaa0dd32ec43a2849c0a7dcaec9bce7a354c11bb75446a4e7209866ccb7b3a5500ad5afe87aae123d9092440a6cd27e36a2d33b25853873736afb12b225bbdf7ba0d80739ec8220bbf77b3c42a5e85233ea3c09cb79efb402f0eff244bdb1b7bfa86352af66675aaf65353ecae66ed4a24b796e999826168c8889c2b9b2579390062b22264c521f2ba8e024435e201441b81b154abf2a509c94dce1b4be4dcaa6f454394f991e125b8294cc760b45669e926abed52e4425d601c5c057b9c255b38f2bba7573fc136ebddf2fef3ccee22a6a8ebc1e72cb9f6be8cff789f3ace7f5d9a5b6b35bd94513315ca49ff76e7a953f00db4415d5abfcd399daca417fa8a294bbd9732fb3733c047fd4abcfb93274269ff4f2ee40a695f3dcb379e051fcc4ff5b84224b4bfd158fc1efb3ba68c0474e40b3f2811685c5a77daf78d966c246caf31c9eb0a4ef6b412c59c5b6d72461f1b6a7dab137757766defb98e94feba77e8c651f6554c45edb86344bfce77d7ccfe575d44325ce5fe7f6cee4db64a4d18efb4fb69091a52ff557e7f7ba423209b97cd53bbb7f17d33a8cadc44cd717aced84fffcdc55f26f6ef0fbd10da2cb718fe7ced1e7b8b7abf42ef938ee5bb9c543a74bb459731aef22db325150995aa8c7965e70553769296a3f106ba1f08517d247b7c4b7f31edf2fa758f5ca7643351426d5fd2e0074b1a48ee4650428e13b5cee3b3485236a4997932c6493b14a0379132b98311b721a660f812666d131d6fa4ddd7c7c3fa1c22e29cf706d7f5ceff7f7e26fd75b8b42e771b0339ffcdef7df07bf2fef7d16ba2da6b012c4d116bd6c85e5b6e9641c5258283c3475aa00df27701aabf71b1fe23c50e4c265f21199802106ad88c2e992d6533ff4f6dcbcd7527b06a24296c86abdd4cc542fc49e5b492d8578c935578b6da85da28bd3afb9873fdaf73fb67f70fbbcb6b6d93cfdf685dce130d2ea7e69098798b8a3554de60adda4404e228dee5302f415443306b3ce37c72e91ce8806b31db6644ef33b6d399588148e4ff2bb8d6fb99da0e28686741f68aec2a8abf8553d4988338acb7a4a0b6784276763d05fe9e08e87b47f15576c3f6035bf2583e436990c7c01d5973c4bddb5e272afc71c644f9d58fb23a7814a4eb8c1cbe44e4ac6bb258936dc0434216e1758688d4c674d2bfee82bf58842e3c153950d91ce9e07b8c236b5d3aade0453d160cab70b153f308a805b8c0b12385e14b87bb71829890637444df5389ca971095daadc779422965eb72e64e06c38d67ebeda8b838e3ac542ff56475dda3ff2a30df2451dde75ee6f3d601ac34146ebc77bfc661ecdb117d465f87c4a1c731960c4cd5f6aa438352a888e4066b8169f78817c141ad4e65a66a3f0aea5503ac4cc3261bbbdab0a18fbe34d50411d294ee89b305c4d33ec9b0813ea0434a06465b97bbf94e6d2d26fa2d2ec974ca801fd490ee3cb38f4a7b5bee762a82ff986f73cb883cd74f4038fb897ee7bf61578e1637b65ef5ec17ebad4cfde4621ee85fd0d3ec3c9a8bd02275099585039c8b2e3997cb2b94f1cf6c165bda2915d7b2b13ebb189f4988c3aa1484340e4fa01afa2feae5b28f421a575eeb2f1a31f60b45a8fb7ae6d846901b729402523773b57d64e04c8860768e7058e866db15e15320c8a468b82598ff3ac8ba7d10643278cb56fe70676e91ac8881df1ff9fe72fdd6b702b97073b933398c7c7f8d2f3f8831dd45d1affaf5bc6b89b4e4593f452f54389799ee931483b910b63de3b4b04e1032748fa01d960fb5e67b693c5e4571b33f1b89c422d2ee50c297cbd0c791000a112c697c2024114e0992b9d1da1b84b65568b12535682abe25ce3d06d06acebb1efc9ebbcdfa57d55cb44739a05c399b0cc2f634fd7e9e1c27769a934dc824ae49ff6f2f9b3d21d7ba65d942b68dc1c2e5d206e134221a54e15f77cb224c20d14a2908a8681c24b37cfdcd8bad353223827fa166ba6420b1c51d6ce5781a3c453a74f4c674983cc4ea7195c95ed8ed1fa36664eece742418ce67ee85844add939dec42fb1c921d293126de2d07bf6e9d1f9fef86779949fedb68f1c8943ce7ec0aa3ee7788f381bf78f7d5a2ee2fc7dfb3bdfb209c65dc264f18cb3fadca6efae822b7933e6d3b902353fde9113deed32f94bf3ac0a2c6583a6d059f4d9866b14a3c978e712af27859c9112dc33c26d641b8f41257749c541e46f15d776da48a10d9d7a1b9aa7ed8ac1d855660a0ac4282a9dcad3d094977540ac424521d9d19eab7e0f293a6b0ffcc156bcb00f54acfe6a78599c705f1824a59ec7ea783ad4b01d3992eb543bec8b7eb10c493bfd704eb7a9f52d3eacabf0c9f1ca7d1ce248b6f1c48bf56e1e279d7b013f16963010661d04943ff89a61b8b9b14bcabb51aa38989480a272fbbe37cfa5354065aa3ef558f9325ff83e36f5c3757aeec3775ca3e7f10fb2d6bd94af62148710113a535626943ec4c0cb25a0aab2e105f72345de72a599044cde7af2f786d3ac5e514f8b2b54d102b52e7336b4929598fede270a0c124d4c90420b611bb7be053362898598deb5aefcad476cb6c1265e5cc0517b1f85c8492aa444acdd121575716828e775ec4b9faa3ffcffc116656f6dd1220a1d2d66a3171b14fec08e95a3d1319ff0fbee3ff6fe2e1c3835a2477762fcfacfe4f7ffdc06e647eea8efc8dc8a3e9e7040dfed977d955eb91fc71d642f484a34f42338e1c54f78f9cb7cf515913b51c09b80de29cb10594b28b728c84aa2a0d0cf692f2472058375248d1183708e8bb6f18af19ada749ae606e2395cc4d4d8a5a6404ba2d7b8ac6b469c6954f22c0a1c2b9ef2c33b6354c02595d871cdefc608cfd5f77c598f7005dbe9c3b8873b5df1d06b0e77362de563aacafcc4637269be356495f3480b4571259cc6841a6e212b9739f6d2ae1f1245a2401523aa09ee29540625d658c089588ff300208935234fc09d92c26cc68b86ae4c7d41cbb191967a87c359c703d9a7a56eacecccf6432723bdfc493ee9c23aac2c7bcb9de1be8ff5df47439d926ca272bc7dc7b3f1df8bb956a9f2268ff2654fec2be8db37631eeef870169ffb6afc24de8215908929867e4e5a94c38d1f169d6f5135b0da0e592d08ca7ac235dec4b9d7ba4a9311626a71e52934cf26083a66aaf2bd6f6d350a4c1d03de7229f55578370a80bb0ba691eaabe3d15c73e6a4d03789d92e90f6392fff8567712f18d8bfe325ff5b7bfbd2bee855628dd75ff8e0434e13fdbd0f3e8c35c435d47617ad95d3ef5e643fdc8ac2d331d16f88d9ae39133028754ea69452c6e73e931db552650e322da0c28e282c09c5dc356b9954d95254dcf1c1ef9e06ee4e9810136038c21f6f7d3b8b184571121a5102e98c87d0f0195eac0ac7bd6ebd30ef17432eb37de9fffcc2f5f8beb6f291976dcdd5ecf3babf523ec6163dac557ff2b3dfcba8836caf5ff7bc3e71d42b1f79fcf4fc555dcbb91cf330ef0593c7fae183fe09f155392be77ff439af575f1887288b18bad44f399edfd0c8d26f608b873eb2d7b0bf87bb02f651e8c8a41ab88cdecd430197f5101dee911128b222004e7968d4be941a99228394babd9a6c012d75220267e64959ac4ac726530f70d26a6ec83b57ab27aec6e3c0a23a675e9b2aae1e5bfa3a52c6f9d21f076901f420a03e81b08b1571832c182c69bd1357e7c77ce98d7e45dcdc8fe467c4f6438f896ff86457d2a5ed2e2ae176c1707d38cf4f67e2651e3fc2cc22dcf30d37c7349e8c475ea9eb492f73bfe0d227cd263069ee12a8e3ca3cd8778406388ae91d7059d105052d56663b0aa0887c56c3b804adafd24090c6479a61b0b22629a52c015e17e5cebd08331658825f57b6cac7d87faa87740ffaea6f75e9e8bfbf87b6d87d258796fec0097a8533373ed6c91dfe1b1403a7e96538be99c6a9d80b98010ce448a8f221ed0d49d78deaaabfd439c8662e912d2db6236ed6b798d19c304e12d63c465aaa7b3452b885b48582ef5756310a18dea6d450623b1ba5b0d6e3b046ab4a564be89084d01e77cde73c8717c6cc3d1bd5498907bb272d339076e3fad9de9f8cda73b158cf463709835da4d559dc8d07ddb408719d30dabdf13b3ed60565919ac91366bee321043c7ce63550cfdb0b9f71749f74fe7b4eb3c39abce33d9ac9d1197ea3674e8a277bfd350fc287df4cacb1c643278f42243f70029fe30f66b289d9b9399f7f3e9d803c627aced97b8e8a733945bc5b849fe0c73ec6139ffcb026b56097aaa4492c38bab29d3ebabc37ccc7be479ff7759ebd8bf5ffcc664f4b9873c6413201e5b1aff3db790c7d9dd723f5b258814e92e21eb879b68f2a38620c3ec6b661b210d5083ac5d204066770e2059136074eec06c6340860e3aa0ef128b730c1399f5243105389021e222a3718dcb731d123dfaee3559e1124f1c4575ae95574999667630517d55e3e71ac7cc9c9f8f77ed27d74ec0533c4164e71878bfc629e3b85287eeda9246aa0d207049c0d556a3b2de97d5c3a3701810fb8fa0d16802f88fd1b0888f754910c99f5cc87f5c2f5c79395e558a4c2e54243b51738010558ba5399470437b4c29c857588895c7bd25556d54fea2e3ec4f8de72dc5ca7eefde238e8c03dc160bf627abe60d92e519befedfbdff36c0dfb7dccf3b94d6c8d77b1f6720ede7dffa37e378c447b2a0d3b2e9b519a0b63154a4c88aec7e06eb42ab60ab1b98209ee29a90d62434d04bf554af88dcbda352aa8ea07a44f81718fc85d1b0331e27db6646601021b95a440f1d2a6d192e81b4670ec95b35d127e170f30f013ad6326ea6ff4ac6faf5477725cd75256f173cffab7f338719e5e1607256de049b70bac7a1d140ee179d42da7628e990357159f73952bb1128194f04d42d06ec932935486b12a9a7b4ac65b7fdddcafa659c1a79812cdddbb105529a04ba1ba0aca4dcdcfe5260e2817269d26a6d2f1925fd0cbe67f9da36758735eb6d957985834b94e9eef789ff93662e9f35d3a8eaf2897e5f7061f09ae5833a793317649f340a1c8856decb9220daef220e80dc5071c30491f624ba03437b558834430809229377815f598c820b128451a8c6958ef98892d6ac21935f11499fa6da2a43b5665d455a89a98c0fbe823fd63fd883ec6b2bfccc3fe7d7ce31dd7cff31ebdcce39487bd2cbe91c730cb502fbb6032a65eef2c1278d722b5deb91af7b176bf8fc23aa30a1da110db29ad2b141ab7aea2d315a1735acc5aa46294561427763df5947149430e134bdcfb2a6a5060ea68d24c3ce0a871e0f8623db63fc6372ec24828ff82afb98dcb2c4bcbd98576e72013f52874ded7f59fe93d76957e4dc3feaf18ec92f5b34c1ec63ff523bcd0efa4ad279d360ef08308049903dc62452f52026f5d686404703b55b0ed4b3a2121df2c19a554d16d228bd653b88ded9ac7661b268aa2f91242cec06362731669d18e11da44bda305321d7985db21933ed2105d80d5fae7ee32b7674d6cc95e58830ddf2c58fd0dbdfabedfeacff6efdcd803ff9985bb05cb0e7260c735274bfc831c504ee35e74bfef5d2849a2dcf73c146daac2d855758b429ca112bb81e269a90647738556dc7495b932cefd5cde8a40dcb0026fe9d4e819449e6f669dab229d331da7c06853e630df148f0b756cb180dfc425873ec86c51d5cdb958d59798ad12f63c8894a7b57fe651fce0a31a59acfe7aedf35e1a9bfeb8e6a121d312c9816be3708fd9781d7fdd53f42ab8fb33fbbce7a193f381b3e630df81077c90f5df9bb7d2fda01f32f62abea676e625a6d07cebbe4785f4716eaacc6c0f77774dc3083042f5a07747883535e90d87f4eec8ed6119014402991192a72344b9820b1ebb25bc6741dabbdafd3ed68a915f450a9f7227593741da35da4fcec8f93bf147dec6efc86b45d8bf9b4885796c91265569130deb8ebe1133b88efc1ee25cec18c35a8448260c3e0a4be6271bfb8ff31b620997ca7786b2541a9bc442349e0a3f00c2f77b3115f94c23d250b895f118d29eb3365b6854227ffce06bf503678209999929513a9fb47049cdce2bc4e392d4b15fdeb5bcbfd322ed374015020b855784a29b08886069a1bf8f251ceed064c8e9f43c9c3571f515fee3f723ba0a1fe571ed8f712dda3dcbe58ff369dcc9085c1a771053711f575cf2f52fe09b74818013520bd395e434b6f6a355d940e1376e6241e89a92af4a8c44c8d744c1756a67135219b7498e696ca7235649e829345b4e7f8f62cac91266d3b8aa77a8ca1a167a8aa74a9795dff62ff5d4a25dfc65ef91d995ea4b9ec71b64dc6a9069b2f891fdc25010b1e67e65393455a12342f8c02bae46800251ee77b8dcf768eacc514e475c695d163a7c055190e6b24dc8fd0e937a3107ee28d29c0095c049202c16aaa9c57ee3f1009bae092aa2390a9386bb2ac9262267ed97afb00c403059bcc448bd733dd641ccbca798ea5baea90b75ddf37aaa1ffedff33c3eafc77f3fbf1fc9b961acc3fd1121adf94439fdee453a6a164b64922a5539a8212235e2aac885994d22b56611dbee9793668129bf278aacb15d5b89f474d2cb8c33d1a4d33b40baf19a947442255e2308092ea11f5486e2e77223a8cc82327b8c0a1d066ab3f6d5d9ee2cf6dc7664a442e549c713ab955188e4cca6fb834ee216b99bd97837b39fed853bd419bb746ddcc74cdcf370f6389b18b7898565ba369eef54da194d141677e2f05b26c88475f7f8d44f783e29ee6236ba8b54da090bd6c9dac8e3d0c90503bdb0e063a4d27e3131b4d892793c31eab433364939d692b5a1249db1e6beb14fcbf13ab1681385b88ebad1dd0c22c97de3d5de45a3c590533c3c37ae16ea3087e79ec6338b1fdea1e021ce62d6f68bb777721db3d1b93809884feb34709769c7cf97e9e8a7fe2360bdf241c119cf046bbfe25bb956dcabe6eac14e234d54150db7681985747be45d393faf4be360ae0f8220349448e36bacfe5297266ca3002e101b1769ee2931a30ba1beeffd7369cf24d9a4d6b81313b08dc2fa2b0e8e6bf9a675121abbb4f29ac48237471e8eb7f3b854c6bb3e985015dc1248239fd53bd76f1e59d1ba9e942429b996d8dc8bbfdf73f6dbb57097d6efc60c80ffcbdebb75b7c96b61a33fe8bb41c274d497c5466062e4227400dd01f2170c02539bd8985fbf870f49d3246de2d4efbbd65e7b5f748cda7122194953f3f0cce7c9ebe3bfa2c8e17bfcd9274d1be306fcd99d8afde3bf7512e3f5c957f9751ed7eba4886e9d523ee475b7cb60db2e915df2a92a82122549a331e76c93fd491fff73f1fb7e5ede3f04b4bad64efc82017bcf36dca0ded766b5dc1e6dfac51e3c8d7fb1011faef31d6d4052a21f54909ab19e28a38551c5e7841531ae55cc07b492f51f6dc05f6971bc55eb56a65fe49e6d5d30d557afc5739cdd7b1afc37d05d69b3ba38fa3997dac4cff12f3c4ac6757ee476a72a558869b813a22f02a0be2c19982a4d080585944ccf5483be472679c8995fa9b86591677fc9114a97151a52a3c3295a1fa24387b2ca6f996158cb4ad1ccd0ae64602f9c6e94505209c1d388a35ec6eaa39c856d56bfd7f77d5acf1bf056e98734ba3ccb935e4d702dfeb48d4c3bca5111de19f8c0a6fe8f65ec8f549df7a901788e0a67c97d4e2a12abd81f25b525f81441c6edd11d505f16319f8a18e3284652713ca128d9300715a2ca7772aa36aceae7ac92e5428c1d1ae3d91d04ee3b18a98fecdbfd99f7c8faf1017cda6d6a2eb15d48971ce6f525be7cfefabc77afcce106003bf756c6f48fc0f3574be4fbcbd87728e340311e2da632906edf70915b44632dcaa2521cad70853919fc9635be1d0c120b2e49a8f13ed7c49d835687b1824bee808c114f310b46dcc681e3fbd9f48d18e82aeebd2befd6537dd76f9400fa63f5cfdbf832f9011479ad40269efabb5ebe77e9bbb9aece1c30fd03bbfd77caededdc2c26587413e28ecc28ea5641430ce68079428b615917288afd84783c612cdc65900d91d306dce9d7b9281a62e2bd82ca223084948d2d65f83ce7120aa14b52e687cced1ae25a7ee4de1497ff3b9d8abfd72afc2fe7e24f9fd5c33f148bdcc0dff8596f0f1ff7dfe3eb0bc6e1ba9edbc069058e3a4a0d4c524357cbba9d44835e2986a20424a3604a1ce93133a43691710873a3680343b619635656339851322100a552fb0f778695a6bc5885f5d62025493256d404b57e1adb415aeabd981615bb46cffc3f5ecbd3c3795fa3c332024f3d08ff46dc745e57abc89baa3bf7d79eeee157f3f95c8dafc584fb52c601cc1d62494f0302759543665213cf961e594554c5bce69c88f11709663b39a8839cda232e742798b555ba8d48349e07156884263fb8599941c97d59f32d75b9480c8e175475594c22028adbea8ed5fa21897d6b2ece5a0aa7e7df04ff619dd4d3daec32d8eb448cba0cfa3fe4fb9cb06ff4d17d7ebf6470bc95023dfcd45079da33afe6f5b99e453f9108c5a9c1a7a1e67e28f034857c16c4fc41196d10c5762a042a309750c5ba61a6a673181c32373103aa3bee7429410c70411c56f77b39fdd673d1dac4551d1f8a4836a86093ae633512ece8ff18d69f35206ea757770bde86ff624cc26b8dba77ebda7f8fcb7ca1fff3b8177fcee3b407575772c9b0754f5c8c252db8e064c24c7f2ee316449c331eab1fc2c3eb6c9859b8ac0625ac84525fa64ecb399a1d9457cce7907b78aa56aab28ab9a9da1cd96ec65b579ab31d2d651d3065e35256aab43b126b16c5ef6061ff77f74bfb91b8fd46775d99fedc1fede7621e5d473a34f3badb3336dbabd8ae724866d45171dec87558b57502e5175a598502daa195b6182fee96a5edf35a7bb2cc011d0a146a7bce20816af00f64d505c4c08398125794859198b321291d8bba38cde96d359e135875a9b0eaecb196bdfa2307eadbb9f6fae7ba9d35a0afd70839fab4d245868cc02ea95b9d98efd5009dd7bd919fd5fe3bf122b19f77d44503f0c57c2e7eee877398273f770e6786d07220834a312f8472f4283f8cd70b9e8fb246d6d455348cf55c086210a00875fd7e49e58f90a23681a049eb64c40dbce34ed7481e18caac8042ba602e0f33937f2115b069ed3fa4656524839fde5de3e7fe0fc543278da9530fe6477afb6e809df965cc471b72f40b4ffd8ed7ea92f5f318f9cac03c103c5a3881c95d394b4401648c9264289ae5aac37fd405ff74bedbf90476e5f85d25c8dcde4c0531d209b87014dabb0fc4a4b7b4dfb512fd56415d29f7be4be071cf827d06f5c34f1ff4f7f3bcd6de0711d86103cc85c346a2ee24e54ae7b103e8616be232b48241a59cde7f165f6a5c595f3f7eff8ff00218b7aa473e8ef7641fcffc00c6f5982f0390c13622934cb823fd8c8d7be25a4158fa6b32c8493ef5fbc4e810a909c806628886599487bb682a172c4e761216eb250df6d9c08012b2904d713737fa2a9ae61675fa21a8ba3aaf4723cc491099dac686cfe5cdfb9a9fcefa2f5c6c7f1fff7d7b38f1877f2237990a6b502eda662eafce7dd7fed1e77dafe67ae66ebc4d8ea87de4659222ec1efb9f33af7acc19fdeee7176ef1eb72480aac47cb29fa910fca4fa8bd9102877303cf68f4750899bf090500a9be3739b021135ba8623690bab7e606d8e029d92f39061942fbac2a3c3c95dfa96867041476eee845a6138389420600c759c5a774f0bf6071d3fce5eb9ef427ffeb4dddd1474e87871cea4a46cff5116ecc07fc0ff5a2e4473be89d7cb443eaf16bb1b3c767f020852ace9ad9e08b8cfddd87ee9adbd8be57633fdac1ace64d72d1db5dd6fc901d3e8383350ecb52de2d358242fbc582390741d5281c64c538eab02329479851ad7e4486968213034f6706ae39e64edb45e2eb9e455dba64e381d3048a69b15d3adb3e14fe6441fd8ad4bcc9901de47561e62e8f22e32bbc82ebe17f457bfcb48eb96bbccf5ffdb24ffcd3b185b5cf9e62cce3ff3fd3cf6458b8e2d348c8f5222e0ce2902df3f4966a3b49bdf6476eea4de4611ce975bf7010cd5d142f35b2c2666608eeb304c81f3c965f1256144b466cc2834306d82e30bafdf1394688ff500847b4d68e82d59e94767bc57df98f718e9fce56c3bba43ef7e1ff99fbe8663ee583126025e3d9e39df5f8fac2437f5d8d0d4fd13415722307a917885819c27be91196bb3ce015e895c613c2e517ee1123f224625568e2a9b3c95d2b5d3868a1ca6ffb604a30abf64600d09c39641b0dba24a65ce453b9105aa59cf9dba45289888b51f6a6b6dadf6a0d9f39ad3fe3933caedf2ffadaeff6abfdbd7ededb633f9d4390095fe7ab97b1fd75ba794cb37de654bbacac40ee801d671d58c4491fea36c40c4c12d002aab188ea0ea706f2829adce52c3096a5ef656ee77166e9689a8c98c9678af9f3b00a77c291facee86762d5d50be6cf53a3477c9aec69adb5f4fe81b5fd7f416c9f41ffc7bf18533ef6bc3cfebfbbe4c4aeebedf7fc9e38f99040bf5c36c588b036ca8c719218e31fca25fb80ad7799a7f781008bacb44749dc3eb02618dd4100c2ba6898c087acf687dc1d8f30bf07b21a9b81533c5061ad6445bea8da4294712367044515df2dfe89bdf1995a547ce2e9edcebc95e4bd9cff70232e8637fce3cb597f319f8b46e195b97f596157d9613ddb2c05f64201e699c94692815a3918e408b779c9b7ac297a5992824cc6504eed921ce3d881cce8f49b49613b95319fd1783662f5572384639c083e8d0c32092663141afe77aed50fee29aeb4fd4fe4feafed4d3c3ed38b06c9bf67b32ffa138fe7ef32feb9b7185fd7570633a78b03aa286d1c03bb635395dc667c3684a6b34f340a89988dee60e70680cf45e9d7296f17142863d91049286f03077f09413b221531e9c0463943dfb94946d2f1235e7dddf19293548c7a05db69cee48d79b25e739afe6d8cf7ff02dffca2b9f7720e6fe6fee14dfcf3476dddc3a3bd787c7dd97357f5b31b0709c997a4eab88a91c1e84957f7c03921428ca719b2d719553b1633830bb267a0c5f9d4d9114735a9514cf8b440815ef7d9d4b6a8202b5c85c6b2b2eca5a79c9401b870c0f159cd5935be2386b50d90b3ffff680c372c05586570ffefd5881eb90f264ffbe4f2fab24faeeb279ace0d1c860d9a736841e9e251ceb4cd9ac2a2f0de5025e29cf1efa151eca5418a0029294d7b4e1c8973b32d736d97b2960d8ef95a01dc30070764eac7dc2cba9cca36877a5896f7a6f25a164c91a1985adf36ff79eaf5bfac413ffc7f0ed310132b777995c4fee17d2dac37744f3fbd077f19f7f18e3496b1ada58b0e798dac0bfeff8a9a860122d7f24343fe901599e4603648cfde336e6fa5c1eb658d68ee7efd5b6cf3308f7591d7a3a79cef8772d2b7f1e7cf9c148ff9f0a7f3fbeb7c2efa4257d6fee50f06f96a0efb5926badd5284a3bcd121aff45c55e36956122710dd8ec648de99b25f8af60717b20cccc28a4c126297486a16184fc9201aff21e7882e35aef2018f966c7cbc3702ee04164572ca6b1564b5fa73edff43f1142ef2c62fded5b1bf917ec7cff1cecffdb277afe5c5eae73103b42694d46a50a22828f377b46a05d672ce5c55324046e46f9fcd59f777a584accfbac57f3ad7c18dce753b9c34151a5ecb9a9ff4c45ecca30baecb3bf573ae468b29d7aab9ef0361e90595c1b22c9c14caf51d44a168d09dfc53efd4c79fd590c04267c2e994e717e733ccdeef917fc915f917cf2d87782d0528e6313924f1690feb67cff0adf975a79e9c6b352a5c7f151af7403a5872cad9c2e94b228ab512f766e4ac470ba74814cf873cc67e00aafdb21aa7a4ea6a51f15962da71ca0a3e37dad1b2dec2a0d493bcc145b21a7754e8198b49bb88156693ed084f79c45c36f00ff7cc777a798ef3ffbc576fd22f7f1aeb78ef6c64ace12996be5a4b555ba9b1dee1a9a474f5d58a808de7266e13587c61547d57bab088416464289630b28d0ce08506dacac1e7d150cc595319693ddbcb6931903ad804881801d232d3649dd32209b49f4a0337782011f38a2601d7f0ae7d8007e4958df8b60a5eeb467f60ddfa42b97c5013f0cb5afde14e0437c2786f9398e8dc0cbb9f7fff689b5fcf674ed9f5eb1b2bcd27dd21703b96029f48075782e185723bac804a182798c4d88c4cdf0debaec32ede3036c6bc2ed6b9287ccaaa9ef3f0903ae0c7dd80da54283f751515b50124205daefd24acac1d01bc493891415cdc747d7317952944cda3def84f2edfe0267cb257c63a971ecf93dee92ffcc27fc67b84b7a879be39f6d1b6bead1d6f5cc6bd2a0e72896345a4f43b215a237574c40d66d2a1a8e6e0de0ce3d6594ec94e2134cba6e18ef162a52826734346caf0dd04aad51d6877c4455c4ef94c192310989c08a7b7d33837713d1ee8aa1309b51744a0ef7c90874ff1438916fedc07ce4b1dbb532f5206c79b54b03f6afebda5effd93cbf92dbea93feae9bfe40b3fce639071d82570bc4ba1d68f5af98f3af8c1ea74ef5d6ba7769969af4e3886f7f38037d147cfdcf12e77fd63fcb93eefb767afcfd8ed6b305b9534f2814d5119d572c6a6f65dce7cad4adc2471b8c99dd69d0f2f315befef89a5778c8fc3dfea1a7ce46c67a6d2798d8ba34f92426e7d8ccbf1efb18b6ff07e1feff437e673e174bcee4c7b41d5ffc0253284431e78255d0aab11d76d951f3a9a01f44321340d206932d8cda543bca0062ca3c8584e4987a9bde0ac9850d0d2b05184b1c25a525b04d4b703a76564206d0265cad8fd66896c2b9d166fea74fe6d0eeca48739b99af3669b37ec9133eb1d9f2cb951fcd01f5404ca44e0f5b9e6f1fcb5013fc19d7a970db28aca6f4608014d1bfe256bd41d03c19023ae3904d5dcb8dfcb5ab2cced12e12a53d4d546c64ecf19ee728ecc10de6f24eb07c1c63234955cd0aa4fa9ef26e2de48a7684218982ea7a4e76ee1250d6e3fa3b3ba14689bb97a50938b2efae48fb8f57f507b1a142964270cd7fbb5ae9bf86f5d223a7dd21439f96d3fc7ff943f2ef281d43c0c4a3ba08d5a87ac5fcd07395d96d29153e206b5d52c6bb64f9bb5a95cff4b5e850765207107bf5aa4e68bc865465eed374bb63d6422dc47ab719d725c07312e02869c14157d4ad92603d2a486b193ec9d1cc6b5fe1ae4273ff685e6c24dfdb4ff4e4d9167ebfe9a5f6b90e2e8c7bf97c3485ef36f7cc606998f7af05fbb9fff372e3ef355b667150c9a8535620c4a811b3dc96bb4e7f4decaa7bc8e20df10ea7773c332b38aec12632cf28613a2837e6e4a4d85aa960d0f13687da734302895536516f1c26d6773d88f8870405ef93be272ae4c0622a76057d44f7ec333f5f87d4fe7f7f899dde39e9cd7edb518c72e11562121eb3ea4b17b231e884ca08744287da9951f7d8117f3b8e019afd0d85d3063437862a6d0301525bd1c94bbd47cc2388791eb1f32d4961fcb6f00addc6227bd0f696f1efefe3e7d1aeff41c644cd619bc70cc1ffddb8ffb9d8241b009849572c6f618e211036dc7ebf122a942830b674787f09fa9dd5d89b1c984ee3ea0df7d137da2f358a77beba4677ef9bbd7e5e2a6b6c8ca62c89d6aa34c7e17b0af900daac96abf60221f31af5863c75a44eecc8c00f6690d1037ba9639cc6055f73d777b988af6e1ceb03619d75dc6fd864d935126023370d707227ccd1d19e5a63f288888bc02f79dd4fa651ee7feaced07ce6b54e36d1abde88ffbdc1d756dbfc8690e7341deeb17e9e76568de6ead4175ee8f3aafb77467c73537f0d5b51634c998b323836fdd19ba963c3032d819320e879cfbe91df8065260af43a38b845724994648092273ce0b22f42ee4ac9f1b7d1f347c088c70a7a6e84ed65f8dd46116ab38619ebf0a4b35c731fe9e98ed1daff4df70cbecafd70d7aa9efff2effe9700b5ff2b427ce75c51307d065cd4e35c5277dbae1baf399987e97568e9154bdc1caa25bc428c89d024ab3a0212cd81d28760cf6694a8b3bec8e7609d35556e22f0beaeb39600606eb3d5f8dad6cd2c5e954c7c13484042a9757a8cb0c2b9a43d949d74f85c094199abf7d3edfab613fedc747fb76da93b7e18ef9ccdaeb721efbfa828ff840affc4dfa1a8eebdf260770fcdd1356f3a76dfe753e9fd258116b400436b2ba9b61883aa9935d4ef94c42b04bc4be97834f2247deb1c62fa8498e76fd2e77749f9ac53aac0b7f0efb3b06f77d56813da32148912cf2462d0827df33a0502ac083446b83b1ed9e55c548c5c53f819bfb849d7daee3fa6e0df106f814d066b5ee92989467be96e7af8de113f8142baa0ac1185f2f631452c49934432b2cef07860a80753ee4cdbd416309234f521e4b96c171937b6a470cf29d7367b364e4c04a7bc6eab17167eaef2124533a2880dd22094c3b964d0853a026618dfb746af32b72381f38dbfe49fb6c2ef82877d1c3cf7373c2d2f5f332ffbb3cc16a7dfdf9ae7597be9fbb3f7160e09b9cebe31ed4837ab61f8ee35ff2a7e04afc2b5e086bc1b93eb0cab709eb53c6c361e9f2945155670c7c0feb1c665a2d32d6ceb98b9bdc6875c2fa41a16f3bcec60e6f6c2f376780c22249dd229183acef4c6444650152bede30c447a941e2042a5f38bdf9414ec2eedfe2cacbce39d22e3f5c1f0bf15ab52af66b652098c56a1f8ad09235f048497e484644362d9a3ff9971f780ea7bd99bd5f433c735efe3ddefa69bc93cf70dcef02ecb28bfec3955c8d49e4b5735c6a5b41f5204560f1b89de525da2443813208483a2543aa0959b8e3489605cb0d756010cc88776fcd01ef52a6bc0563bb8c1943d870262b4b934655b4f261de209247e32872f6fba5a3f592c9ef57d89a751263ffb16795417c4863dbf83cd746b14ba1ae9278f653eb73f522663ddf592b25f2e79f812f3f930a75b4fd7a2e7c6b2e889635029917bea7dff9900a502817af67cf74325f698836f6493f5446d6410a60cd9e69a0feba775ee53f96381a996ff4af0e2ab6f799e91bf9019419ec77cf3e0fdea8631999c9cff5a673adeba51ef3a9ffe47807c80617b266cf39b886577cb2b15d2531d17361ed94abebf4a7aeeba396c66f6231bfcd5ef2493cdaf7d37eff99f3f9f9de4d62bbd11bbc0c1fedcb39f9ee67df61bc97c23a3eefad14d84863a95f3f9bd739cbcc3cdeaf7897b9bd4ecc535febb99fe79c67ec8eb6f5bafbefe9f776af7f4674d2f097dfe38ddcf9ec1676ab92c20767acf779dc53ce7c3532afbb0fb19b36ad140cb51891b5ac3551b5fe925792c858328e8a9972ad69ce552da91a050cada5c18704902f58b72beafa7566f411453690809025f38d742aeb056a11d3923353c791239df9a062458911f06bfcdaf7ed501607bfe52cb8e6ae7923effc61ddc047cccc3fa81b385c7b4f2b97449ce22901ed21656d9c09b920506e33e37e84612f549cec6fdf6375ad26c19fce12f800e7b5738b7eabeecc750d860b0fe475fd5454ba99d78244934054f910957e31372c71c27931be4e9bb6c7623c924661250cf345aca5f064493d0c33208bc869fbb91980252a7cbc1a27027d83ca5b9bacd4a3908d8dc8b5283d8c0de11137002ae26eff678cd04772a44ff67dfcea67cf6b507fc66fe5b788d91f6b3bc7fdfef8ffee72ef5e95a7c921020923f51cd8a944b2c9ab9e51ad67ac217be13a7dcafd3682b890c26f23e0f461d55639425b6edc1f320743191744a27b8063fcc01c69458322cbc606d243abd0a8f6392f5c598d8bdc28aa25b31c023ece4df59b3ceab3bad6a3aec793ff715dcefb4feb69f2fd492bc20bba048eb799f95e1d8d3de05be02b4d0c72cfdee50d19e6e278ff8e4f78e037e6d35dfca6ebfa95452bd24655c2d1069e7e1b51a6db30465331253bceba4102762031b289d90e81b6f729348c842399d46d77075ac40d5ef2815059c905f766866260216a50042eb7b09b80cc55415e7793c045498010cecc9bf2a5fc7ab73c719ffc7dcdff5a8d8dac1eef3fd6c7eedc00df61ed72efc4b9fc9099f693c6cb35f75a5287fbd49334330b223c4e13381a785dd4a9304601d03e5e6d8d1bae5391d447bb965c9ec3d5bef5fe82e978f4abf76af2f73ef5ddf5f6e19009b44de3f6b12efa2ff5031cfd1a5064aefe221fb996cf31f6cbf95cdb1770e6a3a8799a0f3cc8071c2b07b7b951c4f954d3a0527c498b2a17dd9ec0ca08b5a4cb127b498c5a42a55e367c154c591f549c2e1b92f058f1b094535ce979a2d146503fccead92e63a1c181dea5158e14c42675fe013ec24f7264fdfa0c2fbd8a7fd6b60637c1dbbd1af76bf7629d415eefbbcb7857ade782f3343464142154d1c6afb9677b72b8df044c2f22915b813183cb8aed135e605ec98d1a504c1a05e94068865a4b010613d637988debc041fb39b09b04fa540d24a04d01295709151c4853e110dcef43f64face7b53c038f7c1ea0c84ddc4af81297f1069f4f748b9e9357e31eedf213874812e32115eae1a28f798d0e97cf043096539e0a713f9a1b28a19ee42cc687284ecc7cf0a7e495b6d43fcdf1f8f45ddbacc1fb0f728a9ffad4fffabc3cf2b00afd909bf6f1d9fef29c53610db97b9c9bf138e675dc1c9477a1d16e99716fe6eed8a6b59c2ebcf5880d7a58f0e010b111980f244d4a5c88321864c98705d27d06d197d0905f68d56f33a3e70b6f067885bd3b2337391cf7d49376c8db1daf40b9a4d8c8275f0731b5c3ec3537c77f9c57e5d933fe908ec90d6a123fd7ef9c4b7ffefaa25f721dff4e00b1453c6c45ae3232519911558ed49846d40f88f70d32637bc83c0595eb3781f76dcf4aa403e443ee21170bac8979bf8906bf921affc8285a4506c1bcc22e61c466b1b4eee0d75132c8020309d26a5c5dc5bff379fd92b7f2c1f5d18ece63fb9099b6ce1b72a97b3d69730effeb9a273ff7eb09affe112cd82dedfd46c6fa8c8ff8751e977d7bdd9d4d1b6e138e39051ce775ef0b675c474ef7854ce52a4736084c22d5148f54dd2e24f27d1675aee4e13e73ac1576b6230e6666e0e08278c55a31ab513c380827df10d86e960c98d46c075af23435899f09b9fe477cb0d7fbe58a3bc5bae6debe01a6efd5b8cfedcfc38b7bfbc318bf33c6418ff8d40f302733e1613bf774cbb92d2308e2bbc147916727c2652012d540a3aec62edb24ac75435614d9c08b8cc9880ff22e70c6df711dec2862a3b0660636b9119af70762ec470b518c88318302e12e32f94d73c1bfd5a6785913aa8996b57e38c624793ddecbd8371eedda636d2878591bfa134f44f4f2b3bf9eb55ffeee6f63c8ff154e89f1c35c585a4dc0f6b87fe52b9cf13f85757d35eee95c642bf020e3b03bf557b8fce15aecebb90fb4ea23e4cb252d8639f0b789e14382b819818266a2fb4e1c502da764ce4ceeabbadf85d02282ad0fd42593b00afa24c6123b8521eb2251900d9cab4d56f5456a20262af29034ed5a4d7d3f6df281528472265f6bb67c38fea8cefd7a5eff758646a379593d5c9d138256f9010cad71132cc269ac630c79d2d2ec2e7ff71a7e002787681f001547880fac1a0fa4d40fa40a201ed8205cc7fa2397c29536e6eff43cc7c7bdbfcd20aacefe0f39d524b377ef8e13cee5163ec0efc63f9d95a3af9cb9e3424e4e76d138d5594fbdd3e7f1afbb4b904fa1ea31289acc259bb0da5b89f90da47567cf21a86985402ab67baa5bc86b34c93cfb2e4598dd41a973cf1914d07626c68435f65d5a4b0f5748e25899dc1d7b19e0613e48cd906dca5aae83d831b255f7565de4ddfc9e8ac92e81e821ab9ffaa3dfe8393eee8d17bda367fcd5e1ea58d4fcd61dc74b20bf68fabc7bce5ee2053e75cef20928136195525c74830ec6ebf7ceb6f1ca1ef9c00c4031a2606d2c1bdb0804af84d6e9b291eb9cc902371c3211f4aa513ca1f63c70fc4a393a9500e190b53f164cafa4f0677746bb91469726835edf19b33de6f63c72faefdcdd1b8968bd80f91d6d7c21eafe8a9eab0fdfa9f0cabaf13e117873ea331127ee8e777b936e5353b18b0476a75e963377c3d7eef57b063cc69e57f62a6d02e85719f51f82921ba9a947096c6964b6131cdf8f5228c5d2edb174d59068fb10386a236a6c461e0e72d72f708d276983a66a8ae6998ba7a9d321d514b348601696c8e515000a8edb54af0fb829f472caf16df905d5eeb17772f1bab7e31ce33f9d0b703cf3eb794c7629e4cfcefc1b7e62f32cfe8f9ff8e096f8359fd0ab7a5e5c26a7deee7f5d43efd57ef8748d17de88b7eaed1aefea8cd7ba0a8b5f061677fc82235cf3525a61e3173962a345fc0dc8aad3a9c10e59345e28683919c4df79e303c6240da231940c34d26b0173f103358c013b060c4d35e243f1239a8cb74b871738f6279941348f15c0ac98f12b7224d7d778afd795ca5db4c93ed657fff7be82691729fc7a5cb37d22badd53adee3a1d002375fac902d916f6da34810ce403b1e45427cb7abccf6325d46a6c11c35af3124db269b1e02e98e6d431718967926d0f770637b926f00ef69a401e04143b597d7f5050ae723136b9b693d0d0df036f6d2817c9530fe4fd879ea5914ec0497b38399e138f1b1fb88b6fc259f0f6d8675b7ee2f78d832e11fef1ef02e5b20bbfd815fa4b2cd92b8e8bc8b104d5df360b970f389e59dcb38bac2e8c04dcf78be97f89fed2e53be72efa00dfd6690ffebd26fbaf639ef7f8e94e38738c5cf6fa9538bade899a36e4154784dbd19d59190b6f6d0586b32722dc2f79b15a78b61d36dae3f0eb2e1db814824869da32587d3d90187fcf6137448ddf63d87f8fbce2b08c7d41e1a897a2f5703db6f36951a49efc1e71e42cbc37f4c2afc401e5ae2e33f81343fb67acd54dee827d2af0eed24f727aeecf5e77c127ee840c553d8bc661ca5a2f1cfc2fd44c76cb32b002aebe7327dc88f2db21a970931bb2564db113a8a8717d6fa6666265872ece62dc2db5eef30a998226436e580d350b84bd0249cfd97353f34c177504f924d7188af81fe126ffb5cff51fe2a84debf1430ef13a73f5430af9415d9917c85dfdf0defd8357c73be2056ef97367b4cdeaaf973d62ede63479088ee7f23a3c7e956bdbc845b76130d92b214741ad0a299c817bbe456a3d895cb2880449229800ea8cf629227831f5a9702a6389a4af6a7650466fd23ab7829af5948730a3f847c871a0a81474509a800ade41d011c8adb77af0dfcb299cb89426e0200529ce5a9117acfcef789726604884d44ffcce50d7cbe8b9e652fed237ad331719c7bbe897bc257dc5fd747ed63136e4040c32f6db44f4edf2680b0e7fc4aff74ae8323d803a33fd2e89c34e1df73dc445eef2ea171ffb35e67e97d5ba3ceb2b1bbfd68e7ee33bffc6d73acd7df617ba9de7fd0d06e5865d0ef921bde01cf2e6bd1a4d70f6f56fb3e7bbdc24d53cc63aaff5195311fba77acd1fe6d70587532ee22adb49629460cf3609b20f6a8ab162633be47c4239db73770b5230db0981a794f29a6a1b2d6b75d20e8b4a3e93fa7eaf6abf8da67a96546d93b99625391a6859c1c86c1f12c120e5cac153b517d50c24b164f94779204dfb708ef9c2eee44ffd4bdc11b9e79fcfea049cece9e999bf7cef6a9d450332e0ec5529935cb493acb4677435e6a12055587f1d49b03e44757073ee846b73bec7efa93c62cd856f29f7d5df7f03ff9bdcc41fc86b6e28afea92461bf25c4b7ff95e873fc1ab402a6906d3c0e22e38840d72a3a1e892e8ab498dfd901be4cb1c484bb9c4889ad91e9ff8f8f89d72eef7cad85a993bb3d2aaef1731b95b323de2b132186b670aa24350f9bd72b58d5d3de5009bd9a0efa8db7d21afb58a3ebe56ffc2ddff977a75fbbc1e9732c6c35c587ae9913681db2e89fde6633d8b3788993c7f97403e9cb4ebe2c24805decc053a48f371cffc6e7e9fd2af1b3293736ada24f54893d7fef7843a6654e61b1517dfb967fb1ce938612ac487b19dbae3283874f6dde16b2fa91e52d3ff2245efa5d1b8125e8b44ac61d21420a9b88bb57a081abdcf216611d4f3a8926e56a2e21d4efb0fd9cc0caae319fc40dfc44d746a8ecfbc39aee5a97fe2d9f8171b79651f850a535618d4edb798f55556753e8df33e98dafedd508c225d4458a838d0c8e4406ff854b651238bc0f593342669049d9d70c08141bfca443ee4a59f64356aa5b7b658cc3b39b5057311ce75bb25a5168b18bfae175c81d9c4d7f3e9ed8ffb5a0af690d7bcfb0067793f2fef6f706e4e5c9b7adef83a3bf3ecbf98c70977f6b0b84ec3cfc406499559902c2ee659c38684cf009efafc0edc8f48a3f7b46957b25a6fc281278c914d60f238d56a9495498f292a22063ce516b1e07ec23dc402c64066b4501eba6d5aa322a8c67769d409d9c82905cee81d6eab8f9c0f90c5dffe1ddcf379acd3b35602ec2f3a4dd7d555586f8aa6dae4534c4913f4ccd3869c8c7f08810deca9bd2a432b72b50c4d542db8bf4d069ef29a6c02946c16487f51a5fcc14a3ec9dcedc091df3167dfcb26840b4e466c6afb94b75eb4ea62e6481e54be9b7ab7e5b293c2aae6625cbfe27a7d5dcf3a3e875d569f7942ceb149f02b4ee243fe0b7f580a7cc947bdcb37738bfc28c81a7dd6e03ef9894fe35fab977ef25704f20756b7955c753fb000db3bb3dae14acd2364a749e3bbf3a1d8075a3709b5ef9847aa9c135f503f9194ef52a70dc9540f09237751d587aaf966dd19160d1bfbc01ba9554d12d1e85556af0f89998ca8c1abe0358eea73fecac7d6669fbc67ef6ea4657f1eeb741f81dc753eb516d914fda0151a72474f9821fb44879b65b405a41e0f196c1739927b52564656f7fe9da91c1edb3d9b6a9d35ea3b77e56c39d575e0aa3516d6644125cc265bb8e4649f1bedb08c6d4d1bdf944d1be6550722676604d7e0d0dfaf695fe26ed649382e1eeb628f31d2dff6175dab7b9abf8b6f4ccefd0f7f8fc9edcf7e081aceb9a2abb97e31a6b351e4d96bdca88101f93dacb5e4c2f2e4aa9bcf0765066eb1c86131cc2101c4c40b816c1e1afd0cf3c2ce458b94ab4362aa0535ac8097b61156f7235a8fbda4b43b5585206af82ad39ce50dff111984bde5f3bdcf11aa2b19813275d14356f3edf37cceef75aeaec9e127ffb5b8d93ce65a09d6654297793d3692186f3ec24173035fb757820319812e15f89099a4c8e1f678bfbff57e77c6855c87e3a70d2fa8c605aee5360221886a4405475fa27abc09a6e46ea94910306ce31a79a99780bc96011f70284d64df19c62184c55e68f410b260944e8b16a3d64d0d9f2ed03d600dda10c79f85541db05be8b4c4f3c56b9bf3cbfa8ae7ebfbeb1e7cc1cbf01873bec8eb5d8f37ac65ecef72f31977eccb7d3c79b1778f63787a7fd18fdf27f1d1af1d3fbcc899fe6e7f9acacc1f72171dfd935d76899965cd0f99899fc5c72fcfc1b7177bff7897112bbf9ca1048e1f72936fd51983f9b1677219f3b15efec82ff2620e4fdf29fed85939c5c0f2dcaf65cc63fe20635c26b17ddef77fee15bb49efcb9fe770b2d5e01cc7cb53ff989a0070bc831288f65284dd651ed79d238182391cf7e9f4db211305ca06de61b63ee48d1a78b53f048636036da3842911b98a058d74d5b4b0c3181f02b7af95463616642fdcaf164736083cff0b36090d6bc299ab36498dbac05def64bd06a232464bf1d19ca65f7ec4562dfe3ea776484ef7a05f5e707ba32bb1ae4352a92667dd8f00a089f48a20a9fa4d06c13683c54635d85eb8aa0a85e64cf434acda87b02eea6cd54d985734d8f54b5cfad5029132d4798f6355a88ad412f25108559940bc495d9caa469b4b8e2473c6b78d3b5caef309d0bf6a1a7c7bc02ff3f3675fa03dfb009798e3154efc57aeb3f33dfb96b6c5a90eb3bf60c1bae37d9709fea0bc735fcbff3d73f9f457d6330ec9b9e652666ef5903657726a9bbfd1dbf8338fc94d78718f634917ad329775e75c03ea4e31d25befd3e0b436d7c5c6be48596161a39f4b4ebe6077bcc8eaaea4ce7a932149e954c2dcd5aee4f7700ec3210378b6f0da291f145fa26f870c5a65ea6e374a132f2c1d23300b40ea76c6065c494e9ad4e876021556c68b7e29401b09f2196c699bd5853edaa8a7dad9ea955d3df3499d7462d5ff952e3fc593f92ffc7eaff8a78072f5762e88ce3d5f271019327aaeadebdc405bf74acecff35eabd2d8dfbfcf7dc46e513738ee9d4abafa909fee919fe39ff6d3d5ba0118a71e3393c3d7515e93756a140937b1bc83e3e168db9859eda35a6f9469cfa2c357700775971dba2077799103e22edc3120b13fcbeb5ea6a662c164bbc9eab65dc6dc51756052434accc341890e8ab2e833266fdaf7f212c731d347ff73768b5e93b7b8bb3eb41f8ef63e9f58271c79669efca38713df85f9817eb7c32df2337f9cc3d1773feb717bdf1e72cfdf29777cf269e7b5dc26429d39d20f5762de59db863589c2c6b102aeb6822ac0aaf55e7a81c9565dc5e9b7434a6510c16a949778a2385a535d3cdcc1ae93ac5fdc19bc8edca24e1b8459ad87206eef96aeb555f47e947ace0ebb6414a06f070abe0d21b723ee8c6faa17f6dbfea997befdc7faa7feb7fb9c9edb26818072ef3be58e37eff73b85b7e9e5f8fdf88f7bfb4dbcf3a92ff0da5e0e2a9b14e015460c265cdd8525a1a4f45355f52b3c482b34fc1f892981d4c5248f2524f17d1fb97e17017ba3623228d8c6415c2cb8f66530e9aa44f43f22aea3a41e37b454df03971b82e36d52eb827064d1f80dbef2bfb18ff5b3fee2d5e8f77a281faeff5cf48eaeabff3c5f934b3cfa671ea69be85c9a2f31ece7fbf2d7f78c8b1ee35535a05122b014a86011b5ed142088b56f53d8a2c094df13a61351776c11ab1d76faefa4f62711d08430fe9055601136f63c1784e75505d940167c6acf99a37773a084aad640396c27a63c20ab31639cd781cb3757e89bbcdf33d09ce3b1479f7ef1efeb211ea438c5b107f5be86747f23bda55fc6bcf8e4a7739f37b238ebbf5fb30f9c8e527f961fba1f4b014cc13a871acec0620678958f300b7b6c8c3fa68d623eeeed0f6080697e9b6771f99dcb7338c739e77aa8792dde2415c1061bad4c7932e2757558c62d21868c29ec5a51854094fa0b36be1e445d740b5ee0849391745ab474ba22875a930a1fee4c9d88d538ce783124b09ba5acdb06d42ff2d2b6b02e5ae19051000d8355c543700d0ef5fd58e517fcf32f39e57f019b92b9ed3a89fdd5d5e7e791e75ff46dfa31ecf8dff7199b3f750432576fceb8fd97ef5db406571f3f4729d0a51cd417e5b633a2dba9aa55c11c5904b0df93410719e4e50dd7fb6dbdc6a718f27a7f3f3779f7be46d7b71bd5d79fc63bfb3a310699e08793eefd75d8bc9114ebbd109c1010400a7993d3fb5160e09e0acd02a74803b1bde19d43d6793d06f2a4a570c90b1d46d76a321c641cbeff9c5f72717ff239ab8bbfa026c659d7f5c37bfa5c530bdcd920b822f9a0a200acad80aa98696405ac9885544d12aa9c855b4051e790330632d65ba9d18e189728a85b10383a492ab54d581132b7df88a88b69a94ca2bf6d14e058b860422a679ff0042aadbdd77d85ff9836c641c6a4cdc4bb7d7487d7bd859fbdafcee35dee2b231540e7ab6b39fc4feb32a7a8908b298f5383f7814e0e49d5e9e5641c50e36bcf6b9df07a74880c252525a188f5100a22a5db76798d64c4f9c0eb2e51b4f88e5dd4dd0df71bccf92a11c8cba6a84fddaf4612233be4f68c6ac72000afe447fbb26a0ef2473cfbbbbd58e12d729597f12efb3cc6ad6caa4bcf5578950fc0a97e88a6f7a384e23a398c756a603710fbfd1cf030607a97430d22d15adcbd3753c78702491c21ddf01ad7c494c6625a99c255202d7d4e8dde91ac0261951f329aef54acac84f5824f659d3464aa00b196cd5598d33683edf098e30bdeee61bd856eec41d6e403b58e9bf4139dc63a9f075925278ddfab751a4550173b55932fa4f6bfa73437e74015698d28e5c526a8c6411675235a69cd04c134e6130c7599966a950ef24b4a7d77e1282f8c8b5642fc401cb98faa62451bbd48a0b2a28ab46cb21d65d5f820282f45a50e27cd868f9c05886a193dd7e77f275ebc495ee1a441d0250daf657db135bfcea3c3a7faf695fccccdb781c1af7b6c74a574411741df3bfa38b4290833da0386bec73516e9c0e982f13e60c926f7ec15abbf9ac1a493522067e9762666a45a385648579d47a67295d696cca82f14b741088a2ef7b85435980af4ffd7b7ffa7ebdbe73d79cee14edf3b1bb31bf99de7b371fcb98cef9f9f8dc77974179cd5755cd62ee2cc90031768411b3e57b09ba4a2dd1defcf906de11c728cb56cf3465a0ca9ad28d524e4c8c24eb8491d0cd32999e0baf7c9a17b602e592795ac23e18777503162f8655e938142c4f3c176ef403ba16f7297bf9b2fd1172cd9ff39c651d7c7085827263fc808fcc8e1f8e179acf967df29bc1107010679fdc88900f649ec9ff5e17e33af399d9d30ded7e93a3a40acbe5a185a2b6a8c809a8c83b98967b80632a8789140f98357cacc2b5c32580132c52b85fcef41a5d28567d701dbf69c8d4c51ea19666b8061f1836b7660713bca4b34a287cecd98bfa6a644a9d94ea900cd07b5a53ea8a19c1fe311f00f69289bc7bb195f87c90b33c8bd48ebf5c229e6d8f1193d8c8b052735d6ad1798526787b18d412b72a00fcc706054160f4baa1f92124f022e0fb9db01baeabe2cd818e158d584f23daeee0deae2b5e0ed70f40b9950aba80a2d8c5af72d5e927735483c1fcc052e12583ce64eded1ee7e9b2ffc17fdefd3679ed6ed65fdffdfd1837f5a3b50a542d6efd7769d5b6a4274d2d5b5fc650f9de771d186bfb236a792c0d1a3b981ef12a3b0c2b228b1a737b953781143907afabb32c6bba421783e14d51d20243550b5983abba4e23f24b067792d57090d7bded83a376766aaef776a5af074d24581c19385e0361bf84a46dd0fc6f56b0eb79b6ac30737d786bfc28e5cd6e6ffe796f99fe19679d4798fb19199fe7bf7f2fec6ebd7e526d9e535fb651d2fef75a75eb22bd793bb385595c234ae2c558f2bc224cd211b02b78f53616dd25577278df14469fb61e1a9288ac99e719f26b15e2787ad919bd8c98760c031df646e572b8d4854ab600e14cc5811f07a6d088161d004266398d00fe300b15613506670bc4905bb70907c248714de021b38c838ec1238dea550eb475fe7f19e7e6b5e173fe83a0ca1e015abee4719f3e784ab05afb4a0acd369653d28d68e3297f782b19dd0b84a40389a1b96ce68b5cb04d8e5e67d1f3476a9dc701478c1819ad53e70ba8568da430615163a009940201a66bba50041207c9879f2c37e502a889e0bbc4e84f520c57b3558e7369ab6266ea5cbba041645565bfa5c837df99ed17f42dbb6c7bc089731e949c5fdc82836049296327d10d4d967b10c58231f98b83782d5d70d81e349e6c83880b303454540a83f5a3aed5e54b2ca686528c8f6618d76bcc491325a8b98a8c1b1a218f2fd121118a0167e86dfe2e3bcbc4a9f39fac92115d6908ae08f5ce26f70eb3f7d7e11fd817bed3f8e1dc1ad8456914d805ebafa3d2d82e146fdba275ee844ec3b1917ad7adc83cfe671e953bcae6f974b1e95a145aa60c429fabef4544abdc24f346179452075ad7a3e48465c3512359e2f3c356265f1251f9c61e9d9236c162b3224fbac2693cc2d167925dba0e258311965903b99d17ec7a6325284839c860722dabfd63f3bc679a908baa41eefdec5c49ef8686fd097f6cb98a767ff9cf7e4c27b7b25f73af267e9646c2f3cb2e7833a287a6f659ebf4d0133c2187f115ed84bd737196c05870a10d3ef32af40d8248502b2238ebf8d280a23d6e31414f6d2699932d15a9a18494e66cb7a3de02a042104330950475f731c7c809b1119193ce9b20fd9099bfd6b9df1a33c35579eaf332f0e1857f2d493f9eefd7aab7cf41b58ded35abf9acf055f78254eb5d8307d7f3c67715ab5ae9c16416e90bba0d1646eaa989b45919936ca0d34e11425b2eef0c2713669f96db398f2bb90a97dee853daef121e06a2d07398f84bfc2ee78c3a9c4b9d8c3b01affb83339c827633382fc33b8e7333791f081ac9fb474ff0ffe1457eee5b91dc0900ad0662e7aba03ffb096c66b1de0bf59cbbccba1ee52d117e733f86c3d5fcceb84ad9b8c8cabd6341af7f3a120d8f1b718b5f390db3fd2b28865ecfb61d5c621ebe7294421abe541d5454dca623337668700564676f48990ff23588d9b6c40dd82da7e56aa0772f83a0887d0a41aef8249b7575446aac28c521d1103908ffa4a8fdf5f415dbdaf1976abbeeaa7676ba68218e9e497e77d79cf386b7f5e974b7aa0269a61aa2bc970bfe0388adc7e945364abe11e44b565602f87912983c84431aff506d7637bc1db4d868a8056fa7be6a1063bc96119fb2c6040249cfc08630479a32a59f3149bb999300ca32a3495506fe2d5def395d238e864c3b799a75ae991f5fcd2539ebbe3366bc2e7dad0affa598e76338dbf75c9d177baf4049c7ba8fe7d5dc1d35c84d5cc9b13cff8ee5cc7b08eebd87da40fea86e7f7577cf7c9b7344e71e61f7e7ee9e1bcaefe9b22354d0fe33617899979dff6730335dc49cc3924151d90cf4d42a9b66d06dbedb2c26d021290c6becd6b8282e39e6df08364db03d6dac34d618706981041a6aafa3a929a533eb5f9b222389d7c3db0b8da2cf84dfbc66fabe1f3f2772e9ca6caf38be77e7a40ef1f82c999d3675ece6ed0bbf2a73ee8ff3866ed0f7b0e5cfad5fe9578f4624f7fed8d38cd4df007f98bcdfddd673e15af5a8bb898a64ddeb3e96c0863b559381c72cf2e976c7fa0953e04626d2a633d2c44b24907b955da7f6006f87207c19705c3deb2d40bc16d9d396483a7fe869a6b7867a2edc22b7ec86a3bca80feb23cf1337e038c3310de94671c1799bbef92e373f9c58f7dc5a3584921dbac66dd719d73971f947bb1f74f7d5dbfcde7ffe7fbecff60bb73931479f35fb04f636c24b16f9c3585df9defa7f03c697d0f25ad46d8194f6423476c607be51219d456246a6b170e6c97b1de8d8c714438aad5501838d69672bb1d8ff11dabac91aaaa1da18195c7accf8d704f4d1247147f0f073b91464733816365b6ad021a88d7789eff1e7bfedf9b4bb9f4dea2871c56eff7dedc0607f07ccc275f229f80226b707b8903aec0a1829e084ea2980f499c1f52312eb9ab5782a2bb343ee91c2fb2e1fefabcdbc90fbc601326ff599de947dff4527f2f33083a292ce35fe30ffcedf84f77dd5bfddb173cc715dcebdc76296f89129daf20d82e1c32d08aaf45ac76495558d2b49b6cf86fe15ec7e078372542e9ec5d9b1e3c2c26b7e075fe65ccf3d9896d9dd7a839aec79c9ec7b9b2b61bb0980494e11d617a8e5deea8527e2726d95038a6340e0732e97639b5ad009261e900204ebdb968c16309f8b4d0a4f2017541cd4abb155c7f899ca097b458e75e3bc5ba1d96ae0fd8543a91405bcae48dfb2ec7c7f8eee1f4fd05efd298183f75449cd7dcc2e7df39d570d21a1d7ef6fcbeec113a8f9f34bcb97c6678fb337ca44e1cb7bfda8857b939d3efe68214ca757ec6a12f7b754f1cd5e3432674f5a46ff44c2be9c5dfec644cd619242f35f25ef33008f6f43cf0e4f598f9d37d75d2da79fdf337b8077e3eb7e001df4097ef139c90bfee7df8568f18ba3c4770bc6374228cf7f330875b6824bcc51ff1d46bffe27de3fc0cafe36647495dec16ced6482bbd8a1c34ca1a3e4aa9dae1a9ff3dd76d4356e3943b569983f607aead283235cf44b7a68eec170e9e4531d9cfa1b4705d10d1f034e3df7659892d516a116abecaa7e4cb7235eec4b458675c8737ed1facf1a936ad62d266272d8f0b36eeedbcf64b2e88fff31b2e883687e890d7c8fac94bf2962e917dc820d6b91974d9e9ec9eb8d78bbc56c3e5f7dee83938f194fc82edbd7c16bc79e69ab773e8e739bdf5796ea462df1dfdd2bce665125f7c85e64923f34a7f81ef65ec1712f20735790b67722536fa161a931fc3469ff257577155c3f0c0793b892ab2116e2fb1a1565153d4b9c1467368c108769c70d693211825031a5236828c7f8309d5219f6a9cb162b270d443eee1924180238d77a42c026ae8839a16404ec626f3c82e6df4809d1cdec13fc71937b05b6f739abccb777b233f4f584d0c894ee0b87ac406bd9ecfa5d7f5ca1cf21ce075d64827a5d28d5c7fc56b09d3d8dfdd01b54b6bed2e9b64930f05660e988535fec26b1e4acdf7c4690305c7019fda6b35455b8cb419567895d2621f55084ac69174ad4de4e970c9493887e00baba5f90e2ff49518de3f9cffabfdf9d3f93464fcae96bef19a43e293f9dcf8149beadc7ce6379e5f5fb8c2ae3b7701f3eda491070ada8118ce2038997213ad3271df6367bf178cf781c3bd88e1640ead4956cb8dd4f22e2b15cd9b82f012f9816963215abaac726b197d358566075eea8a9bc8cac5f6c09cb1b974fb5530d595ba6dbef66ddfe9659f42f3d2c73f6b8b9c7cf9ff0c0fc213fe3f3f1ce3b07ef79e6dc08757bee3276d03dfe7eef8708ceb1238de66e6ec711fbd988f619e79beaec3e2e40eb695f6b78b181b8a8d67aae6f31c8eccc8b5ca48fb50956c1fc4c84f049e2f35dad2c3d70df5d42819aa4de0390765f4962a89231b692ca6df7604d90f4163f7d4f087a8264e2ac68d7054b488baefaa51d1a7ea4b2e1ae6426e13915ff642f86a0dff1d9d4252e4ef7235870f010d6e817d3192d83ef5f92b17ed656418f3d219aee5160c2663199476a880ef73d1910490298395113244f343f73d64562a1ad533a72bd2d8f642839bf9d4d94b84701adb42699c2ac07908ab7dc0ab1d85dd3662ca8a9cce4d1d5da6f5b84c0f9d13416b22abde26b7cd075652f0fd5cf05e8933dfc46f7db9477e9fcbd9fabfe7bce16b2d22776ca4423d3ce24567cd3957f29a2f48eef215d089b8f05335675ec7d71aeb1264f54573f859def2ff9e7390afe34cd8ef92477cc149972879e94faf933878fe1d5ed5a55261ad65ecb72fb8fa8c579f8b83c7be9fe77f0fbcc2a409fd900ad0e6e6b3b9afdef8dc6fb06bc7cfe3c31bb5dd277e8aa738a3ffdde7d4a92ff8a957e74dadd23fd43e9fcffbd533576e71c84cdea493a738669897f7bfcb27aed2577c48a77eb2e2a99fec845b3ebffe84fdd8bda1b1fda8bddf660dde1f9ff1fbf5e69bf089ec92ba3dae63970a6bc8dde31c4ebae6afe633a7e735be0efbe398b9c367d2bdef974ee78742b125c79c4015d0f87eb7f494231abca125e2722ab5045ad2122389fc18a3f6ff61eedfda53d5d5f771fc057d0efe2448afe9e150098a1207211bc81910ff4508942a2af2ea7f979b7674636bede89ceb7bb0ae559d0e83d93c7936f773df98d916228833b26c1e9459ec29e2a3a9e1aea7005b1465035a5ae662d97f5c88fb6d1a722300fc060ea6ff795dd590a1dbcc425c2faef2c74c7ea84f96e8b4349a14eabb531fd9cbd7c6997fef26ffc10cba4110535252433daa653f62e3a2c70c77220afc908cb211a50a50e1015e000f03dcc6dcde2d8ad49c1a0f805793152b00214e7f12517744b50f0323e38926e3806713af239cd860c5c6f580873a4b6d37be21b6f81e3ffcff9b5a46467cb079427d49f3f20730f7cfe39dfc8f27fb699cbfffeb1c31c4212c58fe03539acd85d3562974f3d8e0c20b1a3b81a8c68ee47f19d79f3825ce31f4f51e9e1fe1b57835e6698e74239fb40df706fc06bf8549053652ad6cafc86251b420106d1e3bed8a50b7903a9bc62335f58ac60ea8b615dcadbc122d19d295e7804e013491457fb0e028f4603d951dda09ca85ac88c10c3d17159f4520dbfa397688a977bc6cd6ef7106ff5a0f96110bcb9a8976afae60978f77cc6b9fe85b719372f4661180755a1dfb735e8c6f98278ea89bd6e68e6afddbb31b28610fa43abbe3e6c0f3c645c7b4b79b8718075d644aa632261eacf9e81788cb763667294c11cea423f73127f9a2aabdc0965114f47b11488d84e9409660ede77ab2e0f6760a70454703e1857cfb3e4efaf2dac05bd726d9836fe4ec2ff8d7dfbb93b6b3f0a3bcfd47ffedcc5575dbf972533a01c2760d5cd53616d68e39d99a22191143cebd7dbf5af0c97e66a2dfc4c1335a5816b74181c7729950cf0a10cf28d4034a894f437b271910febecf6233bb9b82fa518e718e29afe6a1b616cb46a6f4d7ee525fee5f6b24de888b51ce3f4f314093966823af728eb113eff70fadab84bc370bdd2c29d539967df73c0dbe4d2bfc18d7e29cfb18ea3bacefc182f1bd27b019410559982da3429b18f09507d5ef05e54520882172b22763a9e9183da42599b261e3c5417fb2184963c1d63b5af0e5b473c7bea93792611c947a9c86ee80d898d272dd4b2ff20f7c3baeadd33dd82801967f6aa6e94fe5346ece8b2aa70f22780d2bedfd10b727d92a81cf7ec571dce6accf7b5bafa4e1f6e6885b98134fd97dca2ae2a64183bd91b74d8dc64e7536a276d65306c9d390533672733cc29ea4bfba59a73b19ba8f8cb9eea2228fac7a80a46ca6327cb0c8b0ff9038dcf279c6fc4279ca54310f532b79af3df537ebbf49cc81f1aad6443fc4b75c8e474f76dc484c9e9fe3dac3e74eb165789ee3b2bed9cf3cc6d442ea532ee073beb6f9cfd809eba8fb54f2eed4dff5f2b5b19be5f7b7ea601ad271ef82b06e55591b126a8c43d7f4c41aa4059f28db1dd0a269e49817b1ad2cbfe0595cf4769e906821b2cc67fa2185fd19ad0ab8a0e92a603dcb337499dad250a0b0e210d51836f6d4cccc00662435ace90d78cd7f4db3ea881f14244b2b375b04e070a77fb1ce783cd73fc09f7158375e44a1bb8fc2a239d8f99735c74f9eef7cfed94de77f5112304719a605b76538980560b21248ff1636126c4c42258a5d322e76b422db18f12e32d31517200b1c3de0c0efc5635778a1bb9fedfb13aca395671318e4f837a3b6c5bac29c33639738c893fabe979646cfd33f6eff8f674d3a2f6ae77f7a4c6f5b7b612d13f3be498f38676dc4a1bcd60bff54dffedb380824a5bb5d0cc12e3d6a8e905a9dfae12fbd7fc6b3de76cf2b54f35987e7295b77d2b6813407c8638db1107aca4317f9f960bd70ac716c0027180f8c20572d2eb929d1432fedec3d0bdddf64ace65199b981c646c2ea951c2142509679cc0a7c9a652477075e58af6640ef163fcb515b2a61e5ca39ccfbdb5ee24b39ec2c4bf787cfa93aa95ed6c8deaed5f367bb8500cb04b6af3ffbae9ea61ee2c37d20dcedc2e1c52c1cec63016ae568f85a87e3c35e86ff39be5b1de7591efbf4aee7407ea4f7182425d1f2547f3eefe9e7d7678ce56db598a472235129538c5d7b06fc6da033bd106a9a0a32a29d9c0bfdd0d2510483b1dba3413fc6f010b3b85be6a04d62f47624471b3abeef92b19ad290413f545341232b7648bd7090c3581f24407754d40807fd9157fca8cd2aa47081fca30bf38ddec8639daf3ce14fdee363a4c3974abccdb5bdcf85e265cffaebfb0a9e308687bbe93cee614de12c2f6ee360293c9388762fed3a0b4acb8f0ae44f3b8412934855a13885934e0abcc6a1aa71e1963195c340131e19d65699bf6064ca2e75d25dacb3bb44bb2c30c86312f4113650210d39e4251f3024312df18c9878427f5677b33961bb9ef95e6f3d93751af2735c7e014f7f1117fdf735f1f7e31efc46be894304cef98b630fe87778ed14b33229f49ef0014c511d32a8ee94897d6212ee55b56080ec93e53f3d3ae2edccd07a81ea26180d743092d4a769e74330f029e7d85626052e5b2034109577885306c26ee7a9e05e72f848f10f90a02ef9155cd3adfd1369a577a7181b6da4d36f5eadcdff5053558583220a899e096bab1c5dc6d739888db326cb5fdbf1d42199725893947d2316b23ee3ab2ebddfe0e14957ed261d64d116583fec58a54782a9212ef12a1075290bf59b19fd2640d9a32714968c9911777f2f7282c9be89a8689a38cc8662441eb9b0aab45011d5fa0e9bca0f0cb7514edfc636d8f8a5bdf7850530706900336366fca80d582666a693e573efed25cc731e3b681def3fc55ae709b4ca58a84e39fdfd935f71ceed5caa71370b81f64fe39e348f2f6050c3c136adfc2671d0dd22f8fcb3e91ee471f07a9f5ff84c9d54d88844bb96c26f8ef5f812ad9373ed323cfa0eef6bc871e83587fbe3ec671997b96074370b759696bde7ef3d7ffe02f7d4e1f36da69c439c0b5edf71ba073ec0d082f4258efd12a6fc89134b905a96d13376ea121661e1906a26dc2c85bc889ff350ff0ab6e6077d49ad1308b26479f1fcfeff9e6b6eb9d1de98fbb86827ded7eaf14324da6b1abedd0fd599cee7ee9fe669dc6fe9f253627bc6047218191e6b7e0bee3a728cef12465acaf038a55cf0651f5086865e9e7641a1bd84fdb3f2603d489cfb9e1891968c49a11c3562392e1763b2a436c70b8d7b5eee12e9641be2e0a9aad85e5154f24afd288fe0b927ac5363bdfed3e3e7bfcf471ef904dee1e5fee4573fe357fad730637c1f0707dfe5aa7eed8f70f6a8d0ad6787fdb337fefc4dfd63ffc96d7b46ed03c0ad05f53a46911575452f45764b6cd4d03131c5c8decd5964725b971cb6a1c775917459988c501d534425cb6a29f883676713a9079a8edc92f26c86ab875dda653a329a6e2ee4de37b9175472236df7d29eb9aa01a384651d31d36fee865bd728193ef1eb8275147e2117fe23b5af77e39efc927277e6b263877baf77eb99f702e0a43a9bcd0c5446b9bf97633c5e38202639aee21cad7d2a2d65a63f88d11eec4f9ff19be31efd61fdfe5bfb36cffd2d87e7de4b810f36fd3fd2d979df4f723a87ef9ee79c0bfb32f6bb9d719778ccb26435303d68e1446ba8b4d706463395808f2346f07cf4258e1ca0842eaedc5fbda3bff2f7f8f7e358a739e0b51c1ae7efbd299fbfa25a779e469a72654d0d1592a28f12aa7b49d983818ded74345863808664a49a6494dd51c49b60b9b63c60035a443b5af67312ba1b051b16834c90c2aac5c8dbca6a30c2252a5997d9b133d94af3c164b9d2ef314697b98f4fbfe93817c5613fcce091fff834bf37fa1ec779fa1abff84fe9aabd1af3cf1a3dd9a35b75d58e35f6dfd201d1c2b67b69413a46954c6d4b44454383b2992f3431bda258b18e8729743171ac91b275c800ca1213cf7d8143654b10047d197488c555cd032a3751d9547188d042dcf724501b0965aef26c9042dffaaa2e8582591dc1fb262afbbd83df7f73aefcefcf82193b3a8f87e0186fc9f739f3cffefbadf6e2949baa542cc7d1ce678d978e076ba28b7d00ea408c245395063457dbb8acf718b6660c539888dd2e2dfbee826a29434ed35c4d59e7995e85d654a7ed1c7122c2ba126c6d2d4a3d8e20df7313c5140294e45a5ce6dafbab1ac93917fe8a0be2626c76e4287478962cc113a6f52517c47b1df5633cc79be8182b3de15d5fe6c2fd4bb1e3536ee9e5f3bcc3491f71d7a63e3cd3fa555efe437dd9ff3916d58cc5a9272971f4465ed75c7f1b7f7fcf5785ba9007bb29da3a793a03af9ec3e8be6183e629045be1a0750a94203618ab70d013390fbc51b68aa82e13543fc6a5f65491099f2b498dc6885983e763fea8501da6b9ce5929cb48ac578a638447f72b0a273d0add2c41d94e995a73a12d62fb903159fd70bfdb1bdeb89fe544bb396ff7668ddec7c3473e91177d0657b1457fef37bf1ef3b06f4e1c264f7823ca6e8f91852b71291f3195bf39b77731626d006b87168428563b32acdb0092bd1f6a47da5aab02d97188f6dcc84c06db65c2dc3965d90e0bb4f2cac8f0d0a099db352395c65e09da85d38c716955b191fdf6282a67b0bd2146fed770996fcedb859a8c00dbb8fceafadeffd0faf22681f59ff5dc1b6f9fa3990f6fcfed538e1f4558e7dcb07efb74a0958126e9f86147c36c2798840aa670216acb63d6d83333438a7ebbc8230323394af6fd80396a93e6f69618ca98429d7b504ff9b826739b030f908252db60109989963c610ae12bf5b79f589febdc8bff411c0b75371312244e7bb659e0d8af3c0b07db839d3eacdf95e76cce39e5db3020956e12ca562a683adfc4949bda9e87681e09fec8736c934a3ef84693277653c4612d235673c5b2c17c8403ead44b0c2daa98da48878c025b41cfc95653a391d870b12fda8e433ec3886bd949c473193171837ff3afe593542d4f39e3f591ffeac33ef6af72a0fa3fa4bbf9250e54e31b7a9c915fd44b3ec2736cd70fbce28db0d94e8abec7a9b67d58e7118b2caf683c5a219630394a8ab44d9da827c79c2f6c395626f171816c5c5aabb84aad8862573a3a50f6ae23d4353da3b663c6b60ba7e854d1d73fcbbff7da969dfdc1de87f5834fced11f3e9c8b3c196f38c54ebc32ff9b3ed9afedd127eeb1ffa867e335dfd91307df33f7ecb77a36062a94333e7699d4682e98e5462659b21ccd66408f399ab4b86390983a67635c6138b1a292883923200df91e3b0ae212cd52964591b887183cf4020128060a2d724e78897f2ba72d79e7ee45c18134fd8b5a06dfdf9b6f7db7c39e61ffab3db38fc2c1ee6b1aaa93bf8f3d4c374bc703eb98f778fa9b9ef28037e4590d066c2bae1e4cbf428f629ccd63a01d55d83bc62c405963a4a3f71c782fd6eb4bf3121febe6b24e1cd64421d926425fd32afd29fd05f370efca0094b168f54c3cf1e21f6cfbe5e7fa961e03433070b025723e4d342e538aeb04602baedc616cdc5b0b9e1a0955838558f7669dc68ba06f9391de2645a355f08f851d69a605d8469037b47389cf6ac717ed2629c87c0a6a9bed9b382e5080439e7941dfe7cb3ef9c9fa542c0048cbc3ffb22c85f77feac8c1e59eecd758d84fb505dee85fbcacbfbfe36f7d85279d8564fb86cf7e71c6d9de782eb342eec1320ab1968efe0266e3476c754f3a691395a89382d4273d82d7cf712b5fe549f763406999a1a0203ad6b5e4b97ac074304c60e679238dd25c8b88692dabc99eda602073fc9b08b0f361f34861d16187cb0547d2e719e74e8d5848e240935964443b425d1e00f23085fd8ed86d270dab4ea8be619ffd6b31de1f9ebccfeb8f3f625717e3c37d73e4ba398f6b9cb9746eba57bd0068ee093d10761d71a106c2e9599cbb8f71c85694ab8705e75130c65056bfcc446020846149847960ac7733033faab1cb9521070bdbef79cb7ee303b55476db11583b81408537566e0afb051ed77b6e23f4171aecc75ce16d674a6789d3d6d77b2c7e8afbf579bcc3ba589168d7c77ac577ce10c5a6b4552d516da594fb7efeab8751e611ee013e1efc66c01d78a67a14365a075ce178cc1baf6c82c88cb678846892bb3ae1f64e8e75ce786a285e47d4e18fca68e021ce4a4db9944e2be8b07104e3b91aa9c14bed87c3ff9ff3559fe7908b411985d88885b466103daa137feaee708f7d8dd7ebeff39bbe23b3d424b5ac8a6d246a78887993705027cea927e2dd7bf494abbe2d6fa5a06ff439ad06510ad43ee076e75392091b7b8120cbc4deed944d5a3c728764ffcf5e8c533331b3652c76563cb25b25faa64707770a797b6272270aebb95fcac7a8723b91f34d326c36ccd981b820342e1f0047f85dde2a2d79ab84de7fe0633eaa276cd9b2d77acbdee7fda9afd64d6ed34a656949f435fb75e1fefceb3593657faf20da4b871f6b98af5e9f7cc51bef1fb9a5fb35e486bf8bb87b37775c531a753c1f0f56b1993da6546d675ddaf34a4c3cf160e1119f7098ee12e8c65428371244f20efb324c7753883653b86e19db99011fc4816d74d299006e4490825f70312256c2c0e0a26ecacb393607fbc4ccac9940851c7fa157e827ec91f1e1f807fbb44bcb7e6f11804c3a64ff2dbc53482c6caa0d17fe96404e53d630bf73a7895977c988f70874370bc43784c99167f737deb27fc7c6d176eee8de2254758a50c3756d2aae202dd4c62ffbb5b21ff60aea9e02b24da034856d8188668f5817d02bdb77f7fca767e2b33dfeb12f58a7ce718e8ebabaaf34553e3f4f5d2cace278164cf7419d7286577bfb3cfa231ad6bfdef25e1c7385e77ca037ecb537eb55533d27dcb73c3ab069895ce65895109647d140cb7df35b9a759bc2c252cc30128e9709606041e56e8e3c40c635e648a2d4a8e3b444661c34c3c42073cee530a2ae1ddb75cbb8e6a4929838b2e2f417f48af76b7b45bbed576ad64d14baf9a244ab193c9c875fcd891fe2daf9b27f86f3d318748b12646989ef22b1de9e3039e0c45971f0a55f3f53e37d83ff53d87ae8e96cb928324673594ba61f65a131cff54382642ef5807bb9ecbc4a6652eb90091c07484581ddefc50205426b44ec062948d61e9d58a2d215a6bf56b2ec4b9ebb8f3e54465a21ea53d9d28acfd90d98e7cfef23a28f3d89c7f8086f93d27a5d2b1ef6aee046d132aadc730cffef738346c23dfc3b78f217ce7f9ffc84dbf07cc2da485a6c03a1c90c667781c824ae060571aca55f913b6c904786c82cd5c5ce43bfb68b4afa0c1a20b5fb4e0c777031e6e3b4501be1f4b6bc228c1656492b3290fac19a7528500e7f884d7cc7a96e2340ea980e6e3d375974cc61a25c0dc13a81aafa029fcbfe87fa182f8e7d9ef327fd9f2671fad53126d81be7716fc231edfdb20e38aa7b1c0d60ecf0dfaa504bbfc26ba2b1a480afd26543633d3028b4f614fdea3c18ad78a1433aaef542a39d2871cbcbd48c4bbba32352f83a6b16555d29e0af22fa6b3f1775b01871df87451754bcfe001b93c55574c50e451b8f4e36f8ef312f87b18ef5d9b88a9a27ffefb67dfbd0492d3d694a96746c8f21da2cb8b682a23fe6484fa3225da9d2da30ae21a183060bd0c4d06bb9bd5e25553648c783956fb43860bb5dc41f0ce9b86b5ee07962281a3b593385cd1da124e6a15ef9651fcb8edce8df1efc45bf91479d48a0d39067c9f065bee55defc3f1ee7fd26d48cd97dc26fa1073968bcf7b181e53d8dfcc429cc70e6fa2001cf6ed71fd9e31b0efb1c4676c7dd1fcf11dce759fcf6ddd313f1c89b696f02d07c1bf554b7c35e69fdabe40eb58a8cdb7fc415eef7cd88ac04411cd71400cb709a05e4a47868b0a8d0425eba4ac9112fdf94233c047832d6172274b7fbbc8791b1499884217c4a65b4bdb37e28a7bb4731d61835a014e16e389c54d4494836444b38869fd751ebac31c85bc4e2f63372ed4f2cefd1c9fe5e8af63ab5ee125defff78bf9a10b3d37ff167ec3ff200ebe6a63db281c68e6c88852c429c0adea06db39d33529d0566979376706601db2e57e6df0b16b2b28b10c15c1d5af6d5a02ac045f629384a2ac8917ba3d6cb7db054583b4702b09fb2d3107651aa222a0649f40ab7887fdb9e09bbc7cfe57b8af27fdc3c35d139eeae25f598b0bf8abbfc80d7da96efb110eebaa9fa84a5446660403580b5134549a0f3b5cf6f1ccb887c420c3b440c622cfa074321289661c17d25585b50f6c1b2e289ef846d4fa86ded071b162ac6de70e61811e104f4c56814178ca8813996475e48c1c11edbdebdfbf72fe9eef3604e2d0bd94df7fca075eaae39a177bf39fe2b53d289568d7e7b3db9cfa14c02e817aa3869fd9f8177be3ad3666f0a6bfe195edfe648fbdfc9e77bfef024eebbd7ecbbf5577051ff0565fdd5b64cc83b4435500dd611a621c183a4ec66e292bb55622ed5196ad2268ede2ca035c0f1a3a42be2fee5709b33b0fb11d4164ab1c698b7c50789af314643be6003f610007b90c71977654a081673cac12c7adf9bb18e4a7f6d6a53aacffa65fe9bcb6fe8bd74fb9e6cb58becf6cfcbfd5aff6da8e1ffde7977a5e46775b8ddd6e3040588c951530c53cd88ea302cd38b42d2f778751e8759eaeabdf4f3a1d2f72eeef7bc6aee4d9dff212ffcdbd6612eb98e7fff3fb9f9ea3c1c3137ee336ae1b77380fdd515020e685ee322eb520ce641f8fd18c14d95cb0b6274db29adb166755167b868e95e17724977335ce9602d5c487d686c1a2a54ed39b1ada4e605630a775d2d164ef554af8ac756387c7814694bcc7397db68797e73ebb837ddb1cf6d56bdb667f5a1b8984652502195fe41ffbfbdcc8217e102053ce8983ecc5f8671ea2dbf2206ce477920f4a6a205785839534f984873a4f4bcf48d983159b0f3d516a4001afe312213e56110664a246033933d43ce814f41c94cdc7ae9c8f6cb840ea51e46a1f9464807956508177bc902c30403b052ebc852fe0f3b8c53af83b59e2e8bbc39d148527dfe3637cd1a08e60bf8942f2c437765edfcf6b5f51e8e6f1f89ac6e10f714942b48f6076c4749cc73df74d7cf9bcb5b3a0c9e3c29d7b42e2c0217a6ef7405a647a116675eae0198135f22f6a91a36e71f0b7a1bec6dd7dd4f4fc095b9b9a7a13c1a63e7176ff197f467f6d6ec9ab7a01e861aa62997b3d6f5c18f3b1bb8d2a1dc5467b4750bd92764b3db8be984b504ebf8985d7a4b0d532fcf55fadf3198702bae418771f7fff9bf7bec511baa245ff918cd1201ea9dd623488b861b9d38e90a8aab7319f6c134d56818d425af1c2ab384c8aba55cc6f67e63d88a8428cd738d0fece17f82e65eb1d133d88615fce00618c222fd27c16893a4ec7bfba806a837d90a35121d946106d92f234779f632ea21fd94f2fc73c9d216e24106749696d93a5711ee7a6f9dc7123437e513fcc85bb6282db02e9478f599e57b8432178c41de4c5d00de2b0e8a87e305561059e705b6cca706167fe1c4d5631c30d19eba16f12108f5c9fb2bae6b01d278e5e09c76ed3d1c0e39c4b0f90e21d3eeef3f8fa6bbc164ed1a8930e5ff787cf815de0e4c2eb045a7af252dbf09dae04de264e7f3f0b3148c7476e8b977d4aef7a9b22d3dda6a6d744a15b3dd5513fa80f5dd43abca42b78d25339d98b99c8b6096cba37fc736fb9c68a74091e0e6731816a1f09e3451ec9be8c7372c87e26b23a35c9569a6e96046027433797c2328e35f83dd846e5c3eb3ad6dbef38d52d4efd88e1e4c598bf0ebfeb9d26703cd687316af9ea7e7aa75777883b320959933ac8883f8dc3dc2616569d08ddbde80dbbc48fb24d966023c3234ebf530edf7ccaf376ec9726c62200cb45489e35b67170bc7bdf7ef72e2dfbd561ffa6fb4f7fd75e8ae39db6577f78472ef48a9ecec49f7ad4c7f3ff9ad3fcb986ff591fd25734082ff1679c9feb5d9ee3726cfcad3be3cc9f71b06b30cb1267fd71cfc12777e5ff237c1a5fb06d1fc5411f72679cbff3c92e91ee581f73fafb3fb98ed79a6b6f63d05779888bbea084b1f8e78a8f90fe4c3f024450957a7bbac78ee336274dae1beb9c28ddfb061825bcce7c0846be89dd88d519b59b9e1fd6be32a20e4319c514cd8899cda929b5b4fb3b2974471dd22c50bd89ca761c75f821b5b350086bcd86cd8c02de1315ce16e5bde10115d122abc478b04cdff34f7e1e7b3dfbd7cff5cb0b9a474fbc7a2ff87ddee9dfa24e8ded3f7ab5177474d2906b25589388437cd337a210af26af75dc3ee86fbd8ea1bdccfdf791bfe35dcab97dabbe7a1e773b0bfa677e43e3fcfdb7e7a3a4d3470a129850e2fb90cfb0bdee9846734fd723af7025676eb6182bcfe7ee28e57543456d90fc6053d0d4d3eed21b673b5eb65ba2dd8d6ff46d65a2c774ac36bee86749477652b4f3b9b3eb5851172ac7157bc749fb85b8ef7caffde1fd7bbd6e97cef4db3bf1721eeb8266cdfb3bfabbbe6973d43c87a09bd1d3f7de5e1b001d818dbf1836222e8091301b527ebfc7b03fc0b61c92827ba4c0b1c809c5286b2553bf858d21ce33830f9bc728c730def7838540330e7eed1822b3055746c25a4ae9603985a8e09c2055ba9dc7072862f7fba32f7affe57cdd32126d969458cb21f81367ff07bd105189d691b07229fce69c0b399c870bcf738ea96ee3efe812803567ffecb80d04ced503cdd120116e941a6b632150cba932e2524f12c7edb182c4d41c4c3cbb09e7413392fcde88b43b88f8fdce17564f8d06c662e4e2b41a0429522613c857865e071ca3a0cc24a7fc9a66f2fb7ba9449da4d1b1267b9d0be2addfffadfd7cc4b1e3dc3fdc57a7b9fef3baf18293bee92df794cf9a5dc4f53a707a3d35229497eeefc0c6d6144ec0d46866d294011ecb7d6af83d55ba302ddd9ab17a9776aa0c0cc26258afc8d8b57059d7ded8e541598f3ca7b98b0a4b33bb351755d6ce1d6da5ce3f8617227dce855f984bbd8942d79a89933efb71eeaa6bf9d7c9fb7ac3b7ee7cb74e4ab45f04401f71e8c7b3629df2b0979fab39f3d8de34d7714172653f6c032e49a4eb6d50e95502f9242ab328b5fb6b5ab82d31ac5c816c1a18f55676fe9e503e2168c015408c41f2e81b59118bec31ce0776e2580f92db6654b64b3e924560f733595883987bbd04f6497005fbf43e1775e479fe42de60f2137983337fe4c13e9fc63dd66f97b7e298f9108f399b7377bc28d37d02c98ef009f44a77a800f694e69a18de8a433788cbda5a30f9404c3c4b4aafa7cc5fdb84fe5ac508759473c805eb82912b3cdb07aa4a7749e116b4430fbe516f45f90f4858a315bba137e3f31cc22b7cc2a739d4126789e0eb08a2ee053f667701abf1e5bcc491cf267c81077d5fb7bb58633e71585e8a0d5f6ac27dcab7f9462be21497bfd38438ecbbd71c122f3929ff5b0cc3c5bcc97fcd4171d54f590a2acb386790024e3c27e31e6b1e4961d92ce45352f2bb9435455a208b94c495a11c1047b7a9561305f03a2ac1901660928e7816776e8947033fa1d994dbd2a2d46dd2305b914e6e246c26b4b35bb9ecafff16c3708ea7bfe2bb5f3e17dff55b4ee31ee6fe7c5e3eac2f5eb5e9d8f63b3f97a1ccfd3630fa9215b248cdba2163847d43b5984b313339f6d9648f3b3c0d58dbd0fdba8b0bb48e475984c7c8560e31a481030fca9e725c8f3070c7ccfbbda751113b961d193554d4059e9042bdabe35cb141d763c1f36f7c5d83fcf4ac9fbef3b2b6f5c136ed6fc71a7cce1772714f5cee85ff6e3cf77afcc3ded089e83fbea841f7bebb47fef7fc2117f6c86b3cc0cd7c02ff6d0eee5fe409b9e65f84b59508034c4db64a0ddc31a02c32d22d2d918e75d4115bc2d8c6b308b633e9e83b21d094877ce2d3fb8e15ed6394ab0d33f9382949e11bd958e5838778dfcc045543ca8e5c533ae80897228584475020743967772916b91c675fe1f1f8c4a7bb70df7c4f7bfeb5dff08cdd79f9dec9d7fb4e3cfebfe7f5b870cf7d27c7fadee61dfc9b0b5c48379ccb0f7dc8177be3257fc644f7e05b0d87b34db8bac73ee0e1b8ec437d8457fb3ef6f089b3e460ab5f63c568f45d1fea7fcfcbf1437beb357eea25a7fe957bd9ff0cd7edee2381f521164e1db479b61fd7fb59fe5eef0d5e1afb183b5e78ffcc414a6fcb85c40c0366673629d53e40f76630722161c51687d96e91ff32171a4ffcfcd78e8f07409ae821e1dae025c0b48b8047b3c637794045ffb760722d6d3e4c4683caa3f7a61272bb284916382a0c2096a49c402f44e3f8064d96cf31396e96386813415eccce18a5cfebb2789b943853c7fcdcafd33a0dbf80b9aadc2c82eff6dc655ffdef7b4096698972199ef25ce7bfcff7f88d7ca6790692a0f13ceede518a4382f09d2ab30697ca5de4c8929a2cfdca8782937564f0991fca2e09d148e8da519d0f1779b4c7652be25c3f7aa1460ca59d67dc8360d8ac7d8d76a200be27d6bd64b836e776967937683e5ee911a91367f7427ff559eff34aaf19ce2298e9b32eefd1f73fc4d1d7f9927e841f388f047e90e2887b684ebfefacd1082f3fd7d15edfdabfcefa8f1ec4030206a394f5633152c1c167e6c2b2bc42499fd7f3c4d18499a88c4aeea7a51a308accc040758c74e303be494b3454766d04108f594e7a8b5c9964d97889518fa626ee88aea1caf9501a9115881bb409ae604712a7bf39fdfe93bed95b2db537776d2543ff1097eda5404f3a22e0625c569efa332388f2f830f79037d11137815fc47397ec41a31761f4ba47e44d2e2671faa60cdd3c0a0fb6f6f079ef530c4052f6f78940eb38acf52c7ce6a25d5cee0771ffcc8568ebf879af9ff9d5bf9feb7937775fc8f55cc0697cf7ce525a0d9f75b10f76ecd5f31c733d17f39d57fd948d5f442b92a3bdcf6be19b6c9b8ed43eaeeaca0f1a19e5642db58ed26ab0c6d086bc04d354b39e3aec638a468129fd194026b3ad3870acdfc9582db9d3485c12a86ce92e0a8999a989705c2f018430e4eefe2d1f381df3261dbece57de9237b8bc2fafc63bfb9fcc1d5c7886c35aaf1353e9b4c4590a5913436ea54ffd9fdfe98719a3b918bb1477d996b23ec21d9ed3309b619b638a50c744dfe430eac545b34d8c7b4b76aac71c0499f64d6f24035cba2bc61e2041c59e3bcc64215f45bcee94687b11f5760ad86654ae77a96318c2d193e49d6f72c1e67dbda7208f44bb9e89435c7a8dbbe687341520ce0e776754ea8d3cdf3d7f5e7fab1e69d27de34405aee3b13bc45c8da3424a19e25c8d55c3ed269354ee29d4eea20477de11ebc0c360b9de45cc36a95d972a440f24c45b4ffb5652e25d6448635100a2c675247397104301c9d59400225313eddf9db9cfef951b35438fb6e970bf1ee2f22e16de8736f7927ff1aa1ef1193fd4fb3ac53773b6a891a23d9db12316ebc5eb831ddddfd8d7ce76fb39c2cccf6dd3732c93030f7a803f2aa745d4609d74da8231b48b581d89b2f91d50042893e5a28cba54bb8039bc0a1c349121b6a4602b1166640a52c84c19108404d67c2fed7ec14a1d789475caa83ff71f2e9c99e75acee7fc5b3fc317f03e277ecafdded4ab0e8a986577d226b38583f914ba8314f06562641eb3b9cd8436bd3142920e5a39525470bef18cac8a0cb9e6502d89834b6aab4e19fd89107c9c16d96c51a4d622975c8868e709dfe285c452d73d661bed02d5f45d0de22b35b7101b8b2396f4539fe4ebf9ed4bb112ccb631d445f4051ded7758db6fe21413d8d4d241fb3356f169fc43cc74332e601e34ddd4e8175390ee78514f1725328903b21954d02f2c928a86c521921c294ff17abb60a88b43d905940c22ae986fd613d2fd823340705ce1d213584aaa47515e989c61143bf51d363298e8c1caab7e6dd5f8a7fa53fef4e99cf666afbb6cff4e7983f31ef8bf0fb811cb14722885653c7f6e79b1ee5a254e7f79d44429f9538fe6ffe1f77c602ff429ac2cad8a9758e2fffb449ff0f8fde7df635cd675fea02fa7faa82fe7e09392220edddd9fcfb16b5aae791c803a29e5f64bfc1a3fa163771eefb4a78b261656997cec477d767f0365af4d1292bdc807f3a9d1f748018c784c5a0a1f0c5914fba0e4cbf9281b611b0f841e002fe71e41924b904d3ddbee82ca33980dc669e86e3cbbe61e4f7754dcb733f0d053a0be137cd04b39df0b870fa3b23f7acf0d78054f04dbfaacb57d2dc772c4a3fe009ee82516e068fb5fbc3e635c6eb31b0b4af2c400f942b4153370c14bbd894b6dfb150fe66830f23b77499dda22809844003fcaf53c40932d1368cea9449cf5a3081039333dc8cb7a4c990f09b328114833ae273e2876c4b0c6ace38fb20026bb62372ef82eeb3800c6310741aff359fd906d7e39e6f33c3ff5861cfbae6ee5e5a18ac8ce9da625df79dcdb4e81dd118175cc6b83096c33a47ab18da05fa52bc2ddd2a336f4aac848a15e05950b1358e3c096ad18fb3dc6b4881dbbc7453b99876ec5e96028b9f2172189e7419f2db46e13c4df71537c6e874f18f0e7de831357d4bbfe87b3e64e1385b87b8183f900637259e3e46437afe42e61bb3d6148aee0c97ea457f4d4cf73b259c7719bd333dea0dbc6d26eceda8d279a3270fe5911549b8cb9d267969318b80e90dd5ed66d3b8f1dbafaaceff35fe9545dc86b1de3ae77cf733b5fb6b193631d5180070b444ab1ecc3b46c4701554c318b0494416e7a5fe537ff14179f087dea4b2c79973afd4dfa3a17f53967de61ee4d5ec850eaa422d76cb8f1435cdb8779078758e2e4a79ce7fcc5739cf95a6fe4d6963b6562e2d975bc28d4c4e3833c2841cc511630d11066fa4030f9a860bb4b11df13ce4b8ed88e84458b3bee068248c1c8286040a70cb862d8b4aa203c761e7a5121edb454dccb718f1b761b68b46439ba8d0bf10f3fe8ff9df9a1ba77f8b13f3a7bff373ff5cf5fb11117fad1afead2ff44ecf576dce31a9efafd04de26c771fdb32efd6df731d32ef2c1a08b7355aba0df8b72be0d80ce53434e9839d891c2daa4f0618ba9fb9b6b120470622cf42f90402b52403a9e598b44009618564ea11cfbfb66c40ab293c57acb29eb614762d9793d5164a388f17500ded53ebec4019094a839e7c1ffef74575ce90f7ffbefaed620fd1f5ba7d3982fd7c8ca12c1ce7c88fe4deb23edbe35edf040f1b48ba86bd2d28d035b03caeb1d777015170a50c4b68ab9decce4cb08d4cefce02315643b776489ed7f7a0b2e7798b9a5e7f092751920a22f938eb7d8963d0c899cb37ec5988aa4813ac63ec05f9f7fdbb30ef2f51e82f64d2fe15fcde99f715fcceb9f5ed7f3dcdea6af9f0a3d8ccb661715c0a3fbfe848ea2de2268d6f188b4deb0ffdb632026e5c39ee97b2886fd59c240e6ed9b2a28fc6eb16c426514ada86a3b18eb4e55684280d725fc174cc27ac31cbc4a51d6a80e6d02aaf3a0ac2d76d231fc606edd2ff408fc487fff2957519dfdccd3df87f9336ec5ab4741c3534e1eb0d354a24cb70cb66355cae5a22093d45181a26ae073f43b11a06545364daaec81e9daf58dc6e1dcb73ce1ee7999cd69e583b98d3107cc62633c8caaa863361909cd2791963dc5481d8cdc46bdaf9b6ed331a913689db8f13e8c9bfaa7bcaef8b0d673d1e799ffc85c1f63792d5fd7792ebd7fe694b8bf690d8846736c8340567c2a595662888751e1e2a090516c37948ced955736033f7487890302bf92b92a24c2cc1d7a2c8b039019cc9003669007e9b477f3b0fe2d42d58b47d99a3864a34a802964db69c773e9f491746eeb23940e5f47a17ef93b8f67ffffff357f699b08902525b9caad8e4fb1e84fd89b261168239fb8d45fbea6d1e6e8a7dfc411c84c5e927d50c84d50aa2d1e678f6991edf8b806de58ef0334180702142904f69cf23871946406cfe2026dbca29e2d0af24010f149a757be265a96e07754ecf66adfdf48c8e3a4d4eb78dffce6b91e910e1718f0cbdcdce5910f7e9b1cf34f4027421bcae1d774378e36f5676c0e38f8fc3aa9fc460a50ab313973065f7eae630cb0bf958fd12d3c136bacd1706ae2df1e2766caebc7146292567c9fdadc0f84fced0dfb9610168d450fb2a0bf2723dc50931bc158f2b4c083d8ae4194e3fd9c0e002d272b6670ea571c7908c9c498581ed2852c9191828bdaf29fe6ec1368e55178ec87db5de773f9110eda57639ef7f42682c8980990a54363771be7acdd7845b34e73bb9b01f5284b1f506861e2a04725d29633b76039ee6eccb96c9352d6d2c44662bad7e251f083f352c64275cae9ef9ffdb517cf71eeb5b8910f19e1c01cec255c0321b221adf4c4cbf9439c672631fdfdd4f081a7b1e93112b042dfa5cc35e9f8d75e08db4a986c04cd666c2ca11acb2629ed1e3333c1723da5fcc188cd1a9351d4a3f964afca3663d56025991cfc10eea448cca37ef536fd8307bcc449511db15642826408cad7359277f99b26128d9e1db5763eed390249a95b2558f38403fec375722937fdb176d5c73c53eff5865ee05d3ecd6927b0bf8ac5b5dcd0911be9277281db639de6693f1eff364edc4eb7d5da6265ba4e6ca8e902f1c033b89b80cca0fbc6e2058373c697d868d671982d23c1071cca2163134b69d9d1b2b74df68d545d6449c30d19c076d0ddefb1c8082dc97c6a2a673eae1175a24eda729e0cfbab85d3f00f78a1cff3c71fafd7ba7e2cbf769a375167cf77ccf36be3dc9b7ed35c62b56f32e9e072a107bd080c7410ac771cb69055ee7ed6e13501f2b7e7b836ee385da07b381fd96d6466341ea130aab21e36b3d82fd4cc135c289b94b8c2f57cec565ed93e249a3fa6407a94492c4b3708426e5ed18abce4e3ee65008072f47a26f41762891fcae91dec64c88d58ec9af8a946f0fabd5b35e6db59484a8f73579aa856856c3dc15b35ce0815ed4022cec958655177dbbd9b96fd2edd832c2d15fcd2dcfc80cff372cce3bdfb8a73e95b3c62c0e752cfa05bd1225b3387f81e970823bcf246199887834190abad17de6f159244a17b13031f2ccaf641880c28a31f2a2457cc7691b2b3421511884cdb98237927191e6351b48ba2674884f2f9786052a45f710dbc9acf4aef94f3cf097beaf49bd94b3e9fab39b1bfd7d3894cd74ac7643b0bdd437cb04d82670dfde31efcf8f9be531b04d00b07eb80f9dd82eafd0cb67e3c9675902333d5d98e3adce24c8f7dfeb0674636179ca0281c3478ff4fcfa77a43d160bb08a548473808f67dc46cd926395f91b0de2cb8aa04afe729700dc1b5cba10b4897cd6e3dffd2e1d9754d5efb3d3fcfb7ec2bd15178eadb398f7bcebfdcc087c850960a4cfc5c1531b43829248a8cb64a780188ad9604e29eec2ec531444715bfa6dfd0fd1056f9ccdd72b8434ee31e79e26fc722477394b56c946e3d615b9189560ba44dafd2516a7a2d16d11e17d68c1bee8ea08cc8d1afad62eb6d0006ad44e861e1b87e440b0b3bd96651d639a1ae4839da91315ecb9c01dc4dbac8687ccefa63060116f4bd96d6377dc2177c2e57fda4429e34c70ef3dcdd505fea7e28c6fc70fcf33e3dc6a027beb3973528e33cfed7e31f69344cdae051dafa37092318147a4490aed3ca378352b5debe8f7f06ab02eaa3f6e99bb97cd1b771653df86e76b83bc589b7edf33bef2d06e6bb6bf067ccf3bcbfd0af38f7dddce6c75a72a473cc501187484460b20aca3a57809328d7760cb369d4651b69587bcf06596cf32131a51db3da9c8f078043b4f42a1d27cefd2a299b2c35fa1ba17fad0853cce7bf60aadd9d57d47741994d4555435a44bd7798b16fd60a0fbecff1ae17e0b9def7b476f8a24637c994c39a04ba8f5260e3d55abfc3f3e8ee0d67fc07dfdb5fc625cfd510d42f6aed6feb52af6aed272cf2cbbafcbbcf9efac6c6bf3687785139fd13674329d791502f7ee7e4ab7bf44b5aa2def0d88bf8d7bec3d39e7ca129fae6390ef1d6cd9ca41e35b25ec0fa1943ba089c76ca2a326242da0197b172a439337949e9fd2ad5f211e7bec50a3d5994b8999972ac000a842d0d5cf4fd9469879bb8f1748668e8ce03c60d0e26108fb1f4588b02c3dfab02fdfe868fa05307e8b454d76cf2857edfefdb8344f0bd84ec799ecfaf1b3cbc9d378f140f1d17cac58e729361e307a86e30c5aba4c28019724782664338c669ae301e471613b8f27345718e67f1f21fc84d84632649500d86bed6771e1f18d32e8291ae776c8409365a4bd2c1efa4d398d9cd53befbd25c96329c34071f3382fd4d723c63ff4d4decf2d8271fe58206d9b76a639eada9b4adad0af144e99a7905af49d9c692d783c076b9d2b897b0a653408e88887a314acd00a88a74249bdb4090906d3d2097b8e2a110fdbb18d65632d6a385c37641e1ba3177879ea8051e718abb41c8df71ce5dcb191e7eabdec8e070a7f77732748d0b3d3e97efb9bfc7541452c83a29d9295fe6f0bd72b44ef74f6bf0feb9ceda6ab7612c28c6a99032800ffbc46eefa40da8ccb338e0359a8168252a6e4d0db72223597a343224cd665e959ad2519bd46e0669e1da3274c7221c603c92aee03a8f4b6b25d1604e45edc79d1e602d1d3fbf5f7900cf1294fd1477d14777c9e1deb9d23b709e3ff1a53e901f8965cee39dedd3615d6fd761f5026009ea2e17952c3824c398f51113ed8e68772c721fa450ee52fb667b7da176f6dfcc49e220eb65bdf4eccbbd7d9edb79f029be4bcbac89426d4c3baf250cb769a9ba7444eac874a7d4cc1ee2cb71df560d4f67ea7a7de067e2893ff9f0e3b97e1effdc4f72636d0ae1f9d8ee1605d198660f29e76d5cb91963fd66a11f5a6aebc99ce390b19a25369ff9c6bd111b0ffb04204851bdc2c05d329e4165137cf00b528a4b051b316778a42a39c1763bf06c24a6b05f910a0f29757fea2cd71739b53f3fc35be5e82a39cce335eccdfbbac137efc4be110bb539e61e8f7bf5c56bfaeb036ecfcfd68b8f89a142a971a642de455c4efdfdba274b25a6862554e146b18159c225c4265ee1d2dac60589452501057c4e00b7bcc3ba21be0b10b271c1ed587bbbb81a0c15c403df9413ecf0adaca4b528dc9c15e4a7b4ddcedce24fda27cf3dbbc6953503a9d3ea85c3f7deb51cdef067f05272cc7789c37b329c1cb9145fbd3ead99710306d4944656047663d2ee574f15f7db28978fb2c4a3a4cb726c238f1ac56df6f753cea90bfcd2c33718c36fd9ded77a60c77979fd1c0d3ed6d06ef3e77c530d297251c06d938ea524c564c74d1da84a3da494cf7188fcd8f120b3c12319c9a510aa2265eb62ae2de2a8f5b41bc0c5d806bcc89694f59d94b5158659c9cdba513463983fb44cf4cbd8012c10997b01ab73c59f3bc45d602b975fbfebf0f08d3ec0f7e6fbedb8276eafd26f1218bde8c53e8d77930d091aa03a5427859e703d20094442b1ec8e553a92a3491b0b8ca7106fd4888c16850f529dae68e1b50ad6bf39c78c9ade8a3bcc24451f62033dd05c41d6e9de0cf6dd85c83c36e23ecbd1646a0e1e18431345f98ff96f49f932d7e45f8be375ba072fb46eafc741f31ff153783713e8c84319097ce4f992a1d7bcd4d67d1aebb67c6d3b5d146b93862e8968c65837788ca86b7a40cfe9b8e6d2a847040c0a66f785176aa14a7e1717d68675f716193682e5bf7a5380efd4c86d1639967eeeda115c6fa7660a9423dd34e80709e00352a1695028ec553fa6ebf9a68ffa45bfee5b5ef6d03bc68fe9d8ad13a18d3894fa55dee65dbe4982a4c4c6e1fcbdfbfe0b5a2012726326f4e65893a9701d7d9e4f7a88c257fdc5efb0da476d91105b8970b7c9d8fbf4b71df36e10ad9353ffcc9fcf5ec0801f3e9b94bc8a4252ab92358b92ef93fd6b9db10bfd76af78933ee85d397ceea926f5f279c13b2e8c73beef305fa93978a51b3e7fafa7f0e2f32f79362eafc3f3674bd4a55057c9f253bcc6d3f3beceeb1d7bc0817eb3a7de69b33c73b855837d6292ad1aeb9d0c2c232df5518ff89526cd857faf84b54cccfb0ff6e49b7cf78d3a008775be813bf2429ee0fb7ece8bb10f77cb8bfd73ce87ef6fe77b483916c296775e9e4d2855d6d4d0a11849486ddcc9302b92b1bce323e40785e530c30511471ea37cebd91aa92ee304e9102fffd94f211f512ead20c44b4ab3112ddac82bed2de3aa61e6c05a208d025498fe3bdcfe153bf51c775de3157dc9bbf019cfcd17ecc0f7352d0ff79791ec0ff19d6ee2932db81e6bbfd5b2f8ee1d1692ed2c1c1cce58ad1c0d4fd89f4bef1b67db7c535e9af8467f9d382a0e2a9271f18f95082dfd127b3ecc18176842cb7a4a72ec8bd06b79a90b32520305358a73b4126136931cb1c8249e2ff89dcffa13cceb192bee77b2735d09061b5c34a69f13978fb29a550378252f7d5bfde4921dbfa40b157a8d74902103f0947b7ab937de6b551dcea4a99ba8ecaf5fd998e5153f07e22c755823613ffb42ffcf8f702fc810e7d191135b6da3f098a77af31c674cd34dfbc2e8cd4ceec68e3bf6a83b4a616d79458d78a7ec7938984495ab232e33b6efff4eed5eb71078b308254a10299461802497634165884bb60ff840274242026acd196845ae07b30e8f53a6632ad42c29dc073f4cb7b7f63bcb3033e499a7e43fe0937b590f7afafb5b7c72b2ac5bc53c3017d8c606b67827415a5851d00d1cbfe2650cea3c817a4cbafb9d0204b0317f142366790e1e624e8cc4e9ed3d9bed399b186cdf0f7dee8a5464912c659c8c5c8f968a4ea122120ddc40e8667645bbf37dac25b328f48e9a1069c537473daeeb791af347f67289b2747f780df6eac83d064ef99a4befd35f1b7c336f8bbb0ff82f8387a4f08dfeef84e14c0cfb5b120e1c0a7eed3172dda8d4ab88e121a3991b0b54625d6f30f5575368adb8ade182cac98267772a587738c43d3cc644da134375d9188fb94f0a7447cdc103e7e8312aea77f8db2b7dcfcf3a651ff6315fe8137dc6aa5ed2fd7bd92371d252bbc4135148f14297ee32f7441985071f5f5a7fb0b46f73a9c79af2e12e5c27101587fb2931898e4cf2bc57c24b38a3a3ced3d37d1d9dfcda4ff351324b4dbf39e136c891232e0ec0cb3e82afe4c27fe07ebefa1c077b719cb79920faacc50ed2b26822d86f52a7bf91c232cef5841b7b47d44c1a4d283bae799841a6ebb102698f54b28c4a34c1068a18bcdf47c66ee5c107200b305e688e7d330bfde2a19328ea22aac2459e595e196d15b77792e221d6aa4920b13dd8a79892478e6c2b4092054c57977b479ee7e00596e38abdd8ff50adb3449d1a82f7b8924bef9fb059b7d5d844d4a5dcb61280acb978d8fb221bcaa03f9973399a53645207ccfc028f78d0af88dddf048635102c05f1189bb453436a378fde484fa28e4f04b3eee6028f8360bd5a38ed8ed8d89506c9e29088b4fbd5f99c04f311219fcd715ce16db204dd99fbe1190fff74263fe7fcf811ccdb792fd75d027bc7b82d2a5bfd8c9f84ba5c1cfdd3ebcf7bd6d4ba51afa57d90c3fe916733ee8a5e80ea2db7b19120b98f5866c8f21e08a4ebb8d08f9168a308aecd1422aec63c4b34b617acc50bc79ac40847849169cab21e19a92605931e190d800f419b388d191758ccc7195446667e693d8e71b1aa65754d737a72b8b3c04fd99d0be3bfb037cf6bf46ace0fe3df6667e428417a1e83c1169bc412d564e71760cfb4da478c606ed7665cdc4369eb2c70bc6db4ec0f63661b2277713ace7601a8878afa20128de4e56427edbe50002d493ed91fec5122b24276288c2b97c7553da0f9fbbea92ff6f21fefb64b77cb5b6ccbe9bebcc0595fb9a574bc9739a14f746d709d08bd8ec23f7376d639bcc2af7b5abbb4e44524aef2ea763fd4cf74da13a1aba583ce7890d7cf71b48f37f7333532757a8608fa3012ed68ce4091169acace3715aa7fa7480f69d967c26e2a3ed263c13327b5b3f90cd69254de2ab1e58a39fd3a05c58a3a78480d52044062410be87372a7aabae366b422dcdb62bb6994909f9ec714a25206b79dc783effa53e7f1c2f87fce638833595eb08107dff9b6daa391503992e39a4d3bd94b0db2f24aa3c73a09e82813c1389b2ba38041c59753c82caa358b0cd4a4dda4c747f7468a48e6e57c1c6824e6e261e783624773b4a7347b083ad2c3a5daa776b4f7352aa79ddb2a203fe8193dfc66f28539f636de91a3f967f6f071de9eee78e770df18dd2cb7e1addc16d2c0eb8867be0fd2151dc946716c11c38d3977c73e243ab0c1009b0490a25d528aef7c506f64a1b528fa9b18ca51ccea36d1ca5f84bcf597ff6c038146a45393c46ea0822ee6633e9315a9228a1f95d8ed31ba8ddbc2779ee7771b891ace4ef8e53a39f7e57ec8cf5e0cfecc9379f0bf336b265021c7934f399a5fd64512a75f49f8477ff9039dea4c55b27eca879f780ddf73e07d7417fde9e16317e296e7dfdec8ff8fbd776b4e9469c3467fd03aa14152e3e1a03448a40d4d6fa0cf80f60b42834451915fbfca4d3293318931afdf53b5aad6c15befe89399eef4e6ee7b73ddd71579fbd498bc697d1d62ee0f75648f67011871e46dfeea11dc5deacd9db9d1aba04da3b2953a34bfe6b716eb38c2bd7c5bbf93af7e39e7ae117aae4d39308f98ec88fda551167cfc96386a93fed1b8feb747fd8ca585e599f3fc5d8ffc611fd107fb9855a27c5f4f092ef2f882239055f4d57f38699d875fee752f38d0ff687767877db8a8ad48476de6215867f53bbef96fc472ffeef5d7bd9487f8e13e36fbddb86fb6fa787738db67d5707fc41adc9a67e0c3b1a8ad22d3f046387283a1a8135a1a712d9d5083202dbc92ecd75a327ed664e9ad13207ba69b0f536dc8c25e85828b0a31e6a49a58fb45d0cd216e88c3260c3c6fa5a2e6bc6a6da6f28e333648caa1113ae88bb8e1f43b4a1deed3eff4608d2efa7a7f1e9bfd7327dfdbedbfbe3facf1adda8d91df61066b493d63daab4e3a7e978d861183a52622db641a08430ac789be5c8510174453539fab0db201471c3a3183e3196bc66114ec84bd34327702e25255c8e982cccef520c2815f2b238378260cdf485cf885ef81bb6f604bffcda9fc7c5d5dfbedac66c7bcbf7d4b7fd5497b4e63c5bcf607425301763d3e57c10af3b6e7d42b646475245203aae53177bd09d1ba90d639f317433be188cfc6d960464118282f9c8dda49dc7b80190d9391f594f558d01e3fce4baf0deafce5104b05756e7f9087fcf2fdcb2a06b2633cf977dde76b5e2751a9753a02fb989bf5556ee9fd7df8b7de8f79f4abffd6dd38e3716ef34d323adcce68bc12366029f5f7c4410b647b0b568b4da8350306ad9740d75654793b41708d5de66675b32263d96226d6531dbf7086805f0e4b4abc2026fece2f075a6ac015d5333389267a52419f69cb3d63886797bec9cf7a92ea63cfe5099b74ecbd7c8bb75e7919beaa9f540937cbd3fb29f3f9b5fdbbe45dfee9fe6dc408b4277b74f2d7dfcfe3cc657d5bbf070bcac0443628492f8aa02a754c4a83dbf64e949e35e3a69145d96a6e67603e86945315840ed4b2deef85c69aa9deceb2a83402252701938319849300404c156288e141dc5b8f090d0669dd2c62e29bc210e8a27e7285effd5a4ef2ebfea24f727e270e877f737b47ff21e642bd9e0d7ff12d5fe3e02f6eb337edd6b3eff7b52ff197af763dff7b87ba50951ef6cdc0fbd3dbd6e5d2455af6dabf4d6eab0d21b709e63636131b99091deca5a62c09911f1251c7fdf37eaab1978c3585cf879b9060345f0cd7be6b455909d7194015a7cf5b5f355e0ce84a10b40d886760572ee6a58a48d91a3199f4b8c8f7c9385e61e84589f149ffcac1efe12c3f6144affa6277c0358a6db6002ae6e8d437fc67fcf6c83d79239e31a9a11065b7433ad8ce22e1cd19ac66ae5ab1ded39166af0eb690f246053af350d8daf342c559051bd2c346e883811fc997843e1bb89a9852a12766082c4a534b19ca91fdbca7d51033d7db7347e902b2248deec53faefa294779ea74c7bcea3b0d86fdd7b63335bcf6d423685fcf41de8597586cb34a3bd6d5e3d3bbf7d767ed14d7dd864568fd02ce7c209f52ca20635e9df46234a3d2271ad568cd22a289ca2f723f719ecd8c4a21a8b9c686adb112c78c778f73e269c9d8eb53db9b3192bbd93887f3aadb72d63c25dc4bc2426a88b3228c3c87ea0dbf512323cf0cb589f5b691afb66e748c192f35b22ff9dbfe8e1df50b1c1657ad08c1114f95eddff1125fe98739ac3968c41b06e22a26e50efc29efc63cbe9787b397f0732d80d89f68737e95d38a0742ebdac73ee8c2f0d720d125a024d8a63db47de07921f4da042a07f7789796a699eaa62eb9bd42636b9f71045316688f2036fc48e5bc402334a6c6dcf11642437da08b170aac06150c4c41a6cb72ddb16b58d80fee57b6370fb1f8fa8d73ff6b0ceb5d782c44ed6fb28ae5a96be5d239e2c3fe99c7ad3c21768b1524d26e0861e225342ccb2fac6d5a3d0f32cdc3b4020c55ebc18d7881fe9b9cc5fb63bdf80e6fee1f5d85a3dde9ff70154f8e7989dbe2c8bcc928c0b4c08380b30973d96816b1280ddb0a2baf08e9b00e350f257438a2a3567147996c2c5f325df2c0b0bbb86af99c4bcd1f5bdb80a1add42606e658cbece124e630105aabcdc6f69e8e551e2f5a1bdbedf739b9aae1eea8c9539d7af43f3b9b1f69f7fc07fdfc17e31edfee9a6dcef5febff4926eefeb0ff9500fa206f17160665a3ce07c07668e2001908f28423ad53a1073b5a06e1e53da38c40123a27b5452b4f76d50f9b46da833dc614d3349a59ca4522228d1425430f74bb14495b717ccd6036a726697bb4ff8a98e9a6b87796695da64fa8947ec3f58db8b718f6b7b819bfed1daae1868f6a912088d3d1ce80a06c4f3440f17b8cf1f926ae8113aace7501a9c2228a8594a50eacc8db7b1362482ca5dac0f63e45a71e888298bf25908c43688bc4d56b2bd5f513333bc4d10e503aca97dcc7cf3d6d8e4362daa3c7fdf437a117b2ce3bff07cfff21c7c994f38acf7b1b6cdf2f4bf8a47df8d79b06fef7400dbf338b7f5c56b2097630cc38276a880ab302af7a1c374e2747be4748054cd4818a24d8aa0f3b536a7d436923ad058918f10f4ec4c17bbd0591b0cd82606a2134a99f3e8794080bf25e3580ff5e1e0d1f01e6969ae52bb9b22e34efe706d81f4ac31fb56b7f8d21f92eb54bf16fb651b3fbc47cdef38d65197f1a8df434effee8ddc3f3a1e2b48ea26208ea784c666a95201628c89b2f192c8a3a20f56dc95886932a75c6006cb5d58b1cddc367559aa291d23e6ef875ac020a1b60253bd9bcc612e2868da0ce66b46739551e809bb7d08caee5e3d4097fed0db9dbad4204a2bb14eb85ccad1fb5cdee5cfe5ea707e5f79853ef09337c97b8de2fe135e934dfcb7f6c20735a3d3bc4173ee4ddaa62ed3de6ba97ecdf72ff46e1b9f6a27dfc09bd13b71171ecf5c9b39707fc48d1ddf8477f3684fba51b7e51d023af4044038d0d92ea18d90e0771f306f838de7156262c35cba0f6d4f08b75960f0fb1043f9b2877a56a087a0403a2f3b35e7acf423349ef17c1357e829eecb2d353c34a71aa0cac259d5baf302e7b457497a2ffb708c975feffc77f117879ff7f27404ca24bacaab7e2fdcd4d146c47cd70a47ed4f7eebfb79fc080f45818baab624802da7463e4a6bb59d71f4882be6857aeb63ee7741a49c8c047bca3043306ff8987609f16698e30171739f81dc4b4af69246702a1802219818990d9344e18e31b165636fe157399843e10ba0eed6379e56e56bacd44f8becca5d1b5ec3c998274e9e3bec93119c6cba11b4b3f0c829749b66462115332c8dbbcce5516e24bce97d87f14723eed33e5e71fbb90b23c8c33e2fc3720805475828dc26ba59c85e59acc0656c645bece48384e448385d475dbc9cbbf98ed7aa9997e061ceb30155b8c511721f2f35337e76974aab3ff85a479fc5f09632f2b7c91b26f7f7c627ffea0b9cfecebc027956a18798afb747ff66048ef8ec374edf8ffbdf3ed1f97eab857ff48e7cc921f7391ef99fdef553dee6a3baf8475ad99f60b0bbadd4d9fea4610a562252fdd7f9f22b5c6dfffe7c7dd4e1dec43a5b9f6aff5fbeaf5a7aec19fb0c27f001efc751dfc65b1f35076ba4a6bccbe79fe9287f741f8da3967f250ff6acbea68376c43ee87778fb8e9a8ba266eb2917274e80f7f3387346c537ddd754e14d58d0fdccb51659948b989bcbccc622d34b8d56c18050a862ea59a8c856542d3bdf46c8e75a1f2b6cb15240eca0125108028273a432c079ebf2023644e593b96a1e6630d099ed4d89c346929afb84dddafb7e8e6faee69bfe773cf5b17f6eaf9dfeff8449bf152fbd17ae78f2a160a81caaa4906102e423363c9538cd625e022b29c50e85431e026b87224c33283d56e0c7d0ce93b0b7b7419d2fb0f234b118f609b5f714482ac86f33d6a19d32a171a61e98c6bcb8f408729b1b75e5aef4297fe9371cf6019c72c07bb04cf5e1ea7bfbf2bfc784c7fde0b09f73b398f27c9beaed9f7dfaf7fb1bb9894ef957e5f85004586f567377620491322983b3396fe399db4c11b47469333b03ec316056270dba438a39f302aee342405996c03750908cd9c4e76d3477b20151b98768d70be58d7991033e56b304289b97de62aa834fb014c7355e245c36dfc8277e603b7ff4e61ff30371a5eae42da7f87e1e3feacfa01d0994bf274eb320a5474511ef6763f988b907e7b57814bad0122d061915ab94a2ed8ce736ad2d6b5eb64b4687eb70d12ee7e3bc1463cca8e1ef7c88ea0cb099d47d0d15b611166a951026a4cdc6a9aded457585ebff326f78fcbd45d5e5d730416874cf732cd6313ff230ff35bea6fd807719ce79fbc84643ecd3f685415948d7da094d59421784f496160201b8622f89235156d84662402a3940e95858a28e7b4c15491dc690011316355b6e6387d970c26c3c46b6f9946ad996d739f335a6a73608e8c739c2cbfcd2559bf0bf731afdd3ebfcb69e7fe6f1139d7a502430cf51aff664346441ef4d53f8dc21bdd9fa8608b1b1dcc55193338d0d5084dd8c35358aac275f33d99cb247564e3aa46394d50ca76e330eb461c5220153472e431db588d8261ab5a300787a42bc502e86ee271ce2c7df65cee13ebda2edf381eef1ffb09e2acfaac1db5a9ec63ff7cfde88ffc8a81766bcd4929a1a6cd4d28cca9970a1457a2b8819e2d84036d61a1628a827bd528cc919069ef02972b0861f38cf7da60f11d21a8c396bd3aad35985f4295030e5fe5e6a6634b3bdb15f60982ad6cbaf79692f7cb8c4c1fb29cf0f6b71f4a3d2f0b01657cfee5db0811f8f7db4bb65b600cb83ff971efd3dedd8877a1ef7360cc0d812cc193efa3a33b208e5bc401bac308d8928893db49181baf9a88542c763346a9f626d6912831a73d5d8290c7619c809b5f34956a062ced9864628c822b86065eea68be116ab529f574d85691b63433ca4977eddd7da8515ec05898fd8e87f3871ff8905ac3cd17fbde73ff9da4fb958c3cc39c42ac75edeb588fc2387f0f5bcc77dde56e14edac451bd74867556c1761a592aab904a6bdca40eeba77cb848161feffd47f33ef74cdcd82b0947b2f2e81c5a6b6cc84952f87ac83cc7272226ce5060ee3159308123f5e4f7cf20d115f16d45fcfeb9f7b92828c0330e7188fa67c06aec60b5dcc73c17a8f7fb7961ade6247f94052e51a9368f00f58f86bc518ff4c3737f8376ec217e3ac68c457288a775d6c6c73e69f40d1dd9bbe4b78e3f33e5288ff55c4d23a4520e0ffb569ceff5a7f33beacbdedc0788f24c59abd4412c19cb90001986bd1ccb6262506569c2c94502592f78974f0da650387c098de64570c9a5caed8c6afb907670c6ec7d50cacd8c3649583d77a27f3662e337403502534dd494a1871848323be3ab6ff1ad8eeb718eafb3c5376ceb6800ee12c39d7230274c7f34399ca3e37b76391f6d77c4e85cf2cb7cf5ae6948cf5f64c5aa69cf2698ae0daa2415903d30c596e9387f4834061eb56e1d53ba0b997a103600b2f20876d46e6e7b61660f3708b2a5ecf3644ed918737be08ff386a960c06df432af7ee973070839c6e3847689f8c43f3862652a75add67daffceddb78c7b8cb553b11798d18fdc83728a80e57899b2f5884f230625d52095d5688c948aca79a58fb7db00f8b18cc1de913a8f63cca09352666c6c1e354638fe1be3d9cc93ded451bf20e8bd130477ab9a20ed5f0d84202a0bd844d40dc463dea707ce11b7c9d9b0592abf24f4eed83bc5fcd40c283631de29dc6f53f7dfbffdc979de06629b8597cc0c5fc6edcf7df7fd83ffe01eeea877925e3f8bb1ceec871fc2939f5d55cdaa3abfb3a4914b2699de9023410d106095d16d2ce47b1def098af77b3513bc54c2ca9a61aec364eaa0293f62a175cb6d9f819d0fd70412b36620a2f108414573024b5a51d623dc9544eaa7c139726247abb08f5c9f66fccc2bb5cddc718c146e8071b41dbb82e5be1b02a8ed8fa1b7c7c77c1c9bff1ad72cf9c72ac440541ea1ed7fd93799de3971bb407a90676d2417a5cca2d2a722be37617f66c2bdc89861ca54243ae6ecbbda9f6a42b0cd671d4fc573df64d1a9d748b53073e9cfae9dfcfe3d65a911f8211d3c113852c0e79b3f5c376c3cbce0f94a269258cd41541a2dd183f7000b2eaf0bf3ccfbe8313fe9797e9473960d5cac83bfc6f194727acf03ff368cfb9fdef734ef3769910d66755bb4df5a69943ab606399fb058ce35a21c6e82abd4d4fec7dbdfbeadd8aef70b7cc2a75549d9cefd39ff14f77087d3b0760b7549f7449094aa1a04f23f928cb06861a9bb05ed40c645d5c892fefd0f77ddeeb357a697879e65ae619bffa654d22e1e6521c7bf1afd5232697fc823f3b8b9bc46187f53be562ff8c7fd6dabf4dcb3dd90f75acc3188d862275ec9e198d4928d219844f1c2a15d25ccfe8702a1db30b2a0ce60a4f32b7d951d63c04115a851a58f2c29b3e6a6c13548a10a21e3040db900a45222b0e8d3c470e1682351e8da092e0632df7849bcdf5bcabbf41ffbb4e429356e5f9bc96edb90e7cdb9ad176476b2ba6a3769ca9dffba456fbb92b6a9fb78845568c5d15322a6c66b0fddcf1364c059d5430988fda685e281000d513aa3a1e3112941d7f049615b3c69dea819100cf0f81e7c4bdda621bf4e1a86df1cd3a146a17735c660bf3baff7f27edbb24b272e1e0fdb46a4ee7f2efcfa7d8f9c6da800f90fd6ca654bdf8aeb79843cf9b479e4d280392b2703616be70ba9af1ccc40a295ee4a56470814ac470ef35b4f62cbf1788338103857699c2ce14342a88a43e67364829762535f59059c8b73d2f1da34f6a03aa9f72b817066b4fd8dfefe8a9dc633ddfeb349dd6f49fef4efa1db7ad2b815e52e035d140908e8683a060aba0c41ba495abb8f034092d14eaf620339a25a66acf6d0c3884f6541f2a5fcb1f09c47ee2c2a5d0649fb9b29e5359a2123ccd23396211e452a926d662c3afba95d0f026a4f9bd74df3ee311be92a338ecdfc107559befbd8b77c891ff55d779dbb7d7cfa79ace6d5871623db282aea8361c53de7ac26d5e82726dc635b36885f86cfc5bc30e0648b37794330dd5689210e4241cc0193715aa342d2825e69508d3453be3958ae3d25b213bd6b80326a2c449c8d58e384b3383cf0301d1ad359de654b732f3ac2edb6ff52adc2b7f7e5adb4d1c79e6347aeb57f8603e3f8a99134259c839eb516dd9738e4d4965235ca49036ec4337d7e2b23418108a51b69d57329cea999155c16e0e599332354b5d91d0926ec3de4302343451d244fd04845ca8d4ee14ab1024a434520e345acaf84a3efd863cef794dcefa61c777f42db7f71dbd8ce3bdd9a67aa7623e78a7fff61fe0d08ffb97eac3b5e07073ccd5bee9497d3cafb32dbc912fc18b058451a2b171a0981770344e7436f123b6915ae3879195700e73c4842e2355534391a9eeef5327367ca25a66b7098614308e6d5a753b31fedd31de58d8912debf350d430a7a3b6a515e4f4f0166ae6ff6d5b78a56febb2cfefebbd9cdc4397eab097c7f99e7042af7bf8671ee7deaddb301f74d96107214172c6191e51c39b8aa80121639445f285bb6899f6131315652fb91913e289c46e188393bd74f3e954672e1acb852ccd7c6ac826839693b2c611c6644b0a51f9545aa810a52cac16478a86d1150ce2c736b148ae7198decdfff2db582f5f6d5f91843fd21416a26c2832bc5506e1c877d94eb8a80cedce6586a727b6f7282a54cd4b7316475260dbf4e60cc661bddc854c34588f0d447f0d30f58210a052d6d93e2be315b1e53803cf1a56cb8174d0ded727dd8c7605af6ded6ef64e2fdb633cfa0f77d097b1db87fccc57fbb7ef11c35de86abefa09ffcce7ac65755b4c37d5271a57a2c7bd4c10cbb9b4d520db0f9733960dd25a54c4912488d49473ac61203171bc6e4ec44b406013eba04eaa78c034b465765b0be66bd22881842aa70e0b52833de01258a4f23649516a71ef258fdacdf1497f7a97bed33731b9d410f8f19abf8df97a4fd4dcc5e73e8ac94def871f822e8ce49811a868918f11c055e8c0a5e4ace38e3f10c67245e86dda3ec7fdafd93a750f3e065e4e39da0a87b699336cae63fd2777d2593bac9300a9d31909c75a3202678e596bfbb73ffbc53ccf79881bf4d7f82f83d036c6244f12a010d3599711f6f4d8673a1a973d020d9b8d3f8bcdbe7386823bf1eebe8df77a7ece6727b8bd364c98ebbb782a6d8fe252b5c480765a7623bfca5d547a3bbf8645a83147b86c8b5c9c48a2101b0d27a834b15c0cebc4c94dbfb7b68830202a58cdede5963878827ae513d7df87bad8a7c5336076379d53db0814bb97eff1eedefce153b3aff1ac1cfe5e93d6483bf8028207edb187a482ebd4bdc6e5f7fb92f7ebc7fba73699810fbe87122370ee8fe8d6f337bfe4b3ffaeed4e7dc437bda7062ff281cf9b1e692af79d56c5e0f736d07234ed911554ad9546ec858f65445d81935e00499093bae596f0b5865ccba4065bd3c8da8476a6a17288923277b90d77213537acc03881654f81dc608a9efc7a09eea513fdba37538e9bec7ddcf0b16ec1b9af29ad5123de7411fc6ff4c51cd6dc544287476d9569d4a8acfaf51d5b77a7fb7c31f6ebddde082ef393c605781091b7fd110684780fa86c1e6824125ad966403c818c7c8c2a8c29d734ac10a500cf98de4c43a6047303cd2f025d5040c30a78696fe147d098c4400c15229e39dd20eca1159713d3afb023b85c53bbdb27aedc09e64d492fbed66dfaf85e6e32e79ab65970c7f7c5dca56ff7edf0e79fe0303513956c1c72b19c45b9866dbca6ae5a1365c589dbbc64865a852e42a15a76331b92cc81d15c4133a8271a671e8d817861917888699ecf29b630f3f729a05b5f6b77a9d32c43c85e244421a9942df572870babb972b73e7ccfd39ab57175e2cefc22d6322e39207f1c6b6d24070b11bdbd51af9fcf9c6037f2b58de138e162257aa166109b29443be1629a39cc6725e8a44223ccc40373b116ba02d23230d0d85e658e99cc6c3893c5ef9d3fc688963bcd07704a6dbc0e7b556043ccb2b19871251346bd755cca9847f920ad6ed58d389e2190724f658b9bfcf83bf0617f38f6c5babfcb518c6ee5c1f698ef74de541f9828b2500ad85412a5fbd44be898a1a04289a4266165b322bcb570ef95610dc7c85deeb1dead306033419ff519442074d928d43c7b0a724784ad1fc2e54a146a74ecd96381eedb6623f815cdcf8fedc7598bf5bff24f5fb17baf7ffe51ac5b6635b4718f8ab8420f733787a1f2b604e405d11b4db8bfbb70315ccfa3df5d4acd8defe6f9bc32c3ac7f5ea5111b258ec4b1e16de21aed52e319f031ab8891ed42c74469e555d86df4b4640847b8c3367bc4fcd7e066acec87efea15cee3bbe87daafe9c4b3dc4d47dc2b17af5fbff99cf598be6369e2c5c059ad0e0285eb466ac492ba5ed56925c112eb4c0603baaab3de25d387761851c684f0d51fa0eb20f3e31b273df1fcba7a4444ad21c65451ea63d1ea71ac80545536c4f76538d8d8372c899de5009984eaff00c7e6853ce9c71dfe90541f7c9779ef5d7cee7fa95cff027362312eb10641d02689691404b0da9230a312dd03823d682320bc6c5f32ad1e29ed136f12bd1f0d27c62067e905041c4cb5d6034635ee70e76e513227917d06124ddbc0c94c7c97ec811834d5a4023295187d5ddfa732f3517aff98eaf1a10dfea7fb803e6e1d8eb70e6e27fbd13af9f4f7ba5dfe81fd6c26d162160208b30f6f54e90da630c42916a684d9dbc45fa104b8299702dc24bb0f3c3a18d75b90a6d8fce6cbae7055cfbae42c299e8788c1f48090752c30d89e201e118a4761b12ad7149b5db5162fdc4bef7730e16a9befbeff263af3d266ff7e1f5f3195b729bad1f4f351404359c32ddd4858306195516ad7393e8cf9a2c2063943d055abe131ace7d288530ac29b605ca8ca6c89455884ad428624b09504d6de4e3b11731236f33229a4c57fdbc7836a4db507f0c3549e5f25e71d8f7b4053fbb1bd8cc1c56c691b78fa36b31f6bd74fa2fc67df5878e3c73c281fbac82e6adfd827ea881d031bd40132fa2c4a30c4c7ae15a3bcaacb5d05835af0e3efeaf9bdfd753afcd6b9c7fed7c7fc003ffe3353af6fcbce5405e6dc93ff339f350dee6b3b3aa21824fb6a99db7893e34c538dfcf99c543daea44431b64075da20f51c6ca95aca199540d1395dfcf5d3595f0b726a07a9adb9a865c946495d951861ea88e7bdfc84d62788cd91d0d7ae5b31271a1751b718557e3a3b3f95f9fc9776751ffe919040051b3a49aa833832d630a46a9663eb242f01058750c109ddbf4b63378e2c25f482eaa13cffd55ffee0eeb71d245886b56898a1d3964ff99c7d9afbb2187cbe46036664ad6cf9dcf4d3523c29f17b99de862f9a8c380d7f051dc86677cc9f4e1661aa12271581b8740cb2a785c8f6fe8026a77c10e9f758e623d5729b75be97af9c9ff3bf24f7e313fed58b3b9911f6d1057de381cb332008a21160c888360e2e42019cb49583c0f429803d6a32ed3ca9e13eb8180c6097591609a1719944d08e936acf387a48ff733eaed331d2ea63a4009cdb1744a536a2078ec9f35c4bc4010c43fe971588948e957fcdefe4e98e3e358c7f3a733532eb4fe768c8666ce79fb38ed039d6a83ed8cb60109877dc2d172ae6c8318229e536973dabacc81766ab7086bc84a9d6ccfe87a1002cf444eb3f09d609069a278ec2d2ac796e0dca4896b0ff8d80b7925c7a2cf34aaac81d0d1257feb4fdff68bbb7fec31b85ab74c1da889a3b6cfdfe7fe2a0fd41dec46974b87f57204defefdc3de7d309f331fd46def96d4197d3426bb04e01555b00c742c02cdd4120d180ce498d90066869c66a51825baa6c57a8b890678e2e45d622b1412c8d8d85b12be5cf95c3542534b01509212563307eca9ca47a41aba8ccb9cc1b29bdbf7e29fb7f2586f73a1bf6a9bbcf1c9f4d7f7f2889f3e6ac2bce3a3f9ba2ffe2ef6ede3b10ffef6879a32ed79dcdb62fd12cf6819ef53a65ea4937b544988b45f03311ac648830fd87dd65203e3d0d9695300e3b8a63d0d870eade50857a88e176d926a38673c00a12b6788204059ee075c19a817db4c1bac5865ef48c97202323dbbc4ca7e8d1be08d7eae61e9d3c2de7fc41994eac355c2fff0c17fa47f73b31650eda998ffad6378e67a3c71e1e81ff2d347411bebc36da22bf5a7a7ee0defa05de3954c9de136733c9556271ebbabd89fffddbeaf537db88b2bb689f5232eefefcfb7f65777538e6bdca3c0e7e8519479e0db4d17544cf77599cb51bb0bcb783b1bdfd0ff5affd1727ed361faba86b94e0da9b20ae5d9e1aeebccfc1eefc23deeead0109157c4115253deaa79e49fd6f3623eb7f62f1d7d0fd72fbb1754408ddb78c34ae110bd1c30d594d9be2529802f12c2b1afe33ad5dba9b0b1eb5780a6046af3316e11b1668ce623021a12d412539a9b7362719f78966f3714f7b889759150fabc9a43cb4cc6f9b537f4f2ecba1e78edf3bd7276f53bd552d6594d5f7b878f6bfdd7e716dd867138dac2b0faa50b7bb943366aa9de8079651aa142c4372c26986cc56838f11d5131a75b7198d71234cda3ce3a9fb1711a412c35b47cd4999f01f5c4293238294d9f977b5cc125729ebba06428309eb58ce125d6bd3ea1b7d9c23987ebd4517ff8d046dff045385c891094c9776297bbf820204f747ae4333cfa1e7fc66f4f1a20b7ed89e89123d8efbd6f7733a9e71671265b54a20754e212d9f13eade48320d6cbbc905a5c377b3cf68c80c5abb4578ea0e64410bc27a3d60c7baf1563eb71aa8b86ea7197e9761750bce42e6c50d86e592d9f483854f86e1cb548a5077f6bf19ebbeeafbdfa670c4ba5153ed8fee6eabff7fe5c7cb097f1477d533fbd67afba2b873bf6a6c172f69d2ef7f28bf8fc84e99df433864731c344a8589fd343dc6fb1d958ed101753c15be857da96d472839d614180d84b061ddadb5b59312474fc209955a4e510f93d46a844c61c6683a47cdea66e0e63c2f64135b4056386246c12c28b7ad9e7f6ec5daeeed3fbb489b954e7facb7f545303795ac15a846017477879be577fcfe3764c1751e851631ce96d8b0caa653c33707de49d61b2cc1759d52571ff11a60b28e9e45b71b59fcebe13b7eddb7887f3d78a082f53fdadb7e6db7d1a7e0838d5c1cae766c228dd211d0d28685a560d677119688cdb5bd207b7bd79477d8eabfec5bfbee2cffc8be35807df1f3429a7adff030ed2f9d8e26991f7995daea4c11e7dfa4ba7bdacd3cacb29cf06d4cd97c83667a1333142803c5201c8b4b6a136d568d93e654ea727bcd93c6ae62a65aa4d9957d3713c48b96ff8ce728fb9a7982dc2ccf07aa9432cf8ad79c7d3ef269ceb3a4d689cddc38768130ed494e3c5e94e1df556caf8a8d314183773bc52af0dc2a1ebd7e52ae442d11e6f13032b39461d55cb151db31575f27108bc780ef30da50c08a83ac6214cf8d062c4de12d7decbc8eff168a8f9b4a9d21e2f3151216630c82a6f84b435c8b461312f1b1e461feb345de8c65cedf3f1ef61a38e7b278f1c18a7bb7a5cdb53ade195c7b8bf951323abc04b40f082b8389c399a99d16e17baa29e43344e60b0e2ce90a4b06966f6524b17c33ce478e31b4bd3afe89691c0e085c5a7865a3f02b99cb16c87c6c2159ae001075ba2265b518132568d8801222163eaa22ef4753df4edfcfc732ebf8a510e7fa789f7e0705e77a96e5ecf97de2b46e1aa4db8df1efe6ee60c37e73ce907f3f9518cf282282ba463aec2b1cc532ef8d4b041e8c836d5e1dae7d99ed2dc0995b78fe9504ba3e75d585b5ec6db41627bcb301cae4385d63e3751066d0df19cc79167909251a20f23cc559b563841104e7de84de62e1b5ce8475cb7d7ef78e2afe9aba3bbd817b34939d4cef1f5df9fcf39fcdb7a07e6b499300561e2aa8eda1d638ed4667432f081154b2222dff006c806ba2c739d02a63367b8158665a49ab40960f8d15076a626bb107a5b396a4da2a132d07e1992e0251fa31dd38586aa360a4aafc8f8f38e5dc6283fecebf78e3cbd53ce069903377fd6fa950bfa6baeeff3de35d977b0638b7b60c7409356aa3dfcb7f3dbf03afe392f426fccb369665a9a8c475e18941012d860364603c11a8c74d1123a1c895e6c9866b661d9d258977d58b19cb848a3a321231ae6992dfbac604f09cc9709cc6b54c5ab2cc28f3397357cd1062cca5718ca42682a26ee276fc3c5defc5ff3598f3dd169e4dfee9b32512711db8b5a5ab2024666c372c6458bb5584b2a66b36a37b8b156b54975acd2f3ef788ddfee0e1c066fe31dd7a01a9682836d7ac6c1a1dbb8b5e2d06da6a85096d4e54670df645133c90ab88afb1ca63ac0c918f789c278e60c4351e434d3e49eea6082dd67730a589b50e9ce28dda654eb839a51519a0ad7b224a5a76735c459380c437bb79bdb4acda978ba57fd24d6f36da2ab328efed298ff576beeb4770bc9b3bf7fe6420bef139ea077daeb3fd605a9ad2337ba08cdbde0c09cfca52bf4fe2c7c10d78703e3037df65e46d62e353c2ddb8322d5bbed5f3f0f3ee46a375891bcd34abdf819905658891ae5e24dfb747289273c72b85b651c6135e5e6563aaa4af809dffc176ffd1fff247cbfcf99c336c2619b58571ff71dbcedd53ff6fdc3377472b97e3fd53f3a8d7b78434bc13d20f6daf9dfbfb84b576d71a08997b95222e0a5c69cbc4a18d493a8d96305955498723bd7d212754c170a19cf5dc0f31a47a860ee52e795e7c795d812e8f9d4653583d00c6abc44553ce0250b996264cee40497c1160109901b74fc02dff881cd0a3fcad57c7ab75ee3a5feb3fe9e77efe8e8f7bfbc6b5ff33c7ff82e7c806df8b97dfc6bec375eed2a75603d25fe27988fafeca4dd4a07878ca03106cd3ea14d947231c3ba58a7daf300e91d9751bcbbba07c13bceb47fb51a3ef0ff3f8da7eec341f7fe0ded3ec4f18e3ecf799cf08bc249dd06c40afbbcccfab0f0f2a966f240836b41d932a99b0ef1e14068b91953c4669112dc150571919e02918776d34d0d1fcc61eea1c530e6f0b72edda5410b3508e8500b1d9390fd50e32e767c2043e674ff72537cee9b7f7c2e5f738cdfb131607ad4edba8f8dc974d6ca33dee6edcf846ed0fea39ea2abef761f472cc74ebca5b0295925f704e219a779285d2b8e096c68a5a6b10e555ca929257014567847791785636f1d1842cd212cf998824c37035cab2902f021735999716f1c12abe3b6a8880efbd0c12629b17b110f7de0afff3dffff13fea37d65b0dd914fcef5db581fae53e3bb7b402feba73fdd83cb391cf3ce97efa9761ef776fb4f79c3935a96dc561a1aff1e10aa9a2082633ec65b46db5e00bac711b4b0d1f4beb276472c038322ae9af611349069ac603d26a21433e64e3449c18c5720f71d66222706a923fdac6a47be03631f4274a96b752ffbffc76efeeddffcfdbe7ff40e7c196755c3dd37b91fef102398dbecc44db7490debb5ffa6bb45b736ae825de20a921a39e62e23b13ee859955709d7063e501e5aacb5fbc4af7011d7dec9868d26577a260f6719e4a9a31e5e73f6dfc937dc219f7958d736e65d33afe8b917e4f0be5ecee7f377f6cbb744f1da07c4f57b66e07112a109337e9bb4f75c169503e1c25566cb06d91ea7c6b2c73aec124a751135202e7e039f78901a8dc62133189de8412fbc50f77002ca3d75ccc55407368252a47a33a6b52ca476f1965c8ff3fefafd65e4adaff35cd37bf0e15c8c7b8efbf62987eb246ad43462fb74a469b7eb9f6b2663cd182b6f42399e6595a0992debd968dd85d4f4445ff641211e30b1726e038eabd6f09974a4219e10446b5e2b831191132703448f7741f47b4b1d59c40a19c8ee6673572006722422564b0d8cf9d8b26eaefdbff6cf71d867baaaaf69339cb44aef90cfbc18f770d65fb988409e19a811fae0ac8dfa6d5c5437a50aa7111e20d68864fcbc0d58ee4bc57066789e2c64ef97c8251f72d1bd8ddda435da7d938fe92e1a4d7fd6426d32c37aed737ce32949b8d967ce616edaeb98b7d5e1096b03ad5953edd9c89ca1452a319eb9cb01ed553f63fe3ea40330ed71121728e785df8b82f533a8ba54870f81261e48d9ad53ad633377025889dc472d33983eec882bac80355b5682624e90968d7ef57c6c05e967f9ab3fbfe7377480ec7bf47efd59c3535de3efcfed2977795b2ed0d791895d64868ed4525e1a2191b6508884c4f3b1fb5ba7da7a9fba52978e57fbeeef1d2da0f2a1a733173a8823858de755d87ba550e8252570116a18b1123998628b46c27cd47f0de25ee408089094c352b8f7d2d54479eaeccefadd7f6bcf5d60f24ac145931ede20d7db660edb4be79c4f78cbf7fa5fe77bdff6f988a5fa4eadf90e7c036ff7f7a8dd77b4e1efe771deefdb3096a46616668811c05056751eb7875568b70f782c1619b4806f6021c76820ab6626a0e7d1b075040b76a96d2e90bd1e3030317c1be5d8cd97929ab564fe9edbd9eaa8cb4581418ca627054b12037b29174b720537fbb9dd325f6de675ae81bbd4f62fc6fdfb7e6de208f509979bb316c46d9c8c5c0dd8d8f311c313ee222b7355c39825421d448fbd0743d78ab94341c8cb9e846d851cba8a69e30434cfd39ee5291521ebc5a36f0f9f50e56f09a483a0a21a32981618cf7baced06339e0fb036d139446d68b07bf5587ecea3799937ad126eaa6964ed53c352598dcfd8a137defd8bdce017fd6a97f9d38b3bf85d4dbce166ca4d2547607dd877c1af9da77b61452ec63d9ea7740136220ada2376ce619b5bb123a79eddb20ba127e624efa7c05bc79aa763c88c10e424e5ed13b641391fe329359827ab6e1be826e674b9270e1e05a5dfc51112c8ce3551e5b1d469cf985ca56597271aa4bcc49bb86e9672ec79499df584409851517fcc77fbca8f7d051f71971ace71acd31a56e8c803f8b106c2a7989b08bb28cfc628625ace32e03d655a6ca6a518a322033ec8f319fdb21febdbb5865b38c15343a8aceab6310f8eef933cf845ced96fb8aa737507bff5d3f18ffeeb612fd7a90ecbd3bdc62a36f0b167e33cfe4d6f4f4cd593306c833b722d9c7644c6aac8c6ec25d1ec6dcac52c885893f4d68cd782c7d45b6776b3a42058898aed32820c4e619b02186676f322ca4c0f5809a42169aac92d63568f2a16505756a27aee3282371f70cd7d5d238a9896ea284f2bf34f5fc665ffc409dbfd079bfec7162daef0a47ea499fb1ff043672350c4dc2c043f7368eeb5cbef7ec20f1df9860ff201014b6d5e5b9acf59c9954ae6b5586654e4a8663ae57e276bc962624d7ddb2ba5ad1201200a68f332a36a21b83779d49a95d0da24eed5f2519bec10b3a6a1dd3d3167a7c5bc717deab5a4f638afba5bfbd1773147ab2336911ffb18afd8aa7883ee813b36feedf1f9d55e7ea7e99fe40cbfcae3ae7cdd2b53e26dfc826989a106b1de90d06846287a1e24bae073a743c2917dacacbd6fcb15af9011bac8cf1c2f47151a25351ccb319ca60e1a27760b659d4f428e685040879500487dd8246ab94775aee66386aee05a6ee0083be9a34fd4e0031df4d33abfc53c1c02e93cb7d219ae4eeff59b6efe85dff1d71ebce55826ea58d7fc608c0b1cf4feffc741ff7f1f079d3970957eafb7e67f8fcb8ca3d6e161dd77316fb76f79e2dbf2685a6277a319b44ce43649ac5390f5d8146315cfabe12e8b24978ba1893573c90a384ac7f98c39609c11db40059a08bade3f6acc600aeb8f7aa7b0ce7c9f203bad9ef752178b8c0f0da6ac38d0d493ef2e35e940f18986e929ffca8fba058be35a44f81b5ccf77d15dfc70ece3db74e60dcaf6208f0fb6d265daed3840bbc58505a80e274489191dad0722f24156289a397093b8b8e0637b70536c5a9ff0ed7f34c5aef21118f7386f7f8d793a7787757bd5c53f9d3fe346dd673bac9b80950c6266858f46a9cddca5e96bf60ef3603767f962e65a56502b97e9bfb649cf04e75808c312fee2d71e47e829d3db3eacbd0ee9dd53e8e6fb79e471a20f3ac11b1755432b1be779e28aa790417be6a29bdfed84a3ed199b781d23760f9e0dc36a627dd8c6112e8e758a779fb5fd91cff3b6b77acd09c45360356129c77edd3cc9c5f0c1efcb8e69438a476de28fbd45a0cb1e57429f3bc3983bb19e8ce54a166afb08649be9e08147701f4452a002f5a4924f739b6a739b9519b1a239631bee88a9a0de9e1a42dcca1996396a73cd6ea2c5c1b6dd8127ccb09af4c497b94bb8b99d9278e31fceee6df8b332539696f17645f57827b918f895cc05b77be67a26aed42874f02ce4380ef518107bb04b2046b3b147b85d6a73283c59d1bdd43a835499e957b4232cd053825e02867c490427bd541894faa30e5aac33f3465dc22a3ef6b67b4a38b0907f3054fff2b6fff5b3470cd51b2f54c285f90747f32ffeefb0a7621d47b897eee45dbec4ff170f501fd7fbf0ef96d308a9ac52a79a5be4f57feab3fff2321cfe1e040947ab2917c73a9d1c019056ac8f75b87b8d39cebed8453e27d3879b84fb6d5c0db76ffdc9e79cecd7eff7e11c825e3a419be96c9f9ceb54272ed92b7d828bfbdcfdcfd6eaf41e7d3abfd6dfdfaefb8c231823d73230b4f6728c90a4432b606c4418dd31670d1230d9728ec684b08a280bce2b3926bdf710166c22d4f34e565e138ed5242e9b3a754c5330d893a2d443a3d9c49cea84491b8de58e971310478266d5c7f58bccf54e18bb1138bed7dfc1a3dea12ebccbaa93cee6941f35778f36e19fef7ed043260825968e54de25a5b7f1ed7c3605cc120e1ea57d5ef3c27b8c6fc3e91ee6a449b76ce35a6997feff256f06bacf59dc8b086bf3102ce61156476de28bef34708aa16eb29d0eaeb39ddf2b9a46de28a3623a73403eede51319a31ebbcb2d3bfc9e2e7ecc8adf1a1a0d31a38d168e2d23ecd53a2ed40b716d53da8d1946399306c661991b7134d90735d4126a6b09451135e476461b3f311ae713ce985d560d0b11a1239ff2dcc54dacaf8f5a55dfd31ffbdf735e99eb6d639df547dee628d74ef60eee85e19fcfe267f33b7387dee6ebf7a9c118312c9cb8b8ce2aef2926b61116d94a46f913732d8f4115c55406683fb4126718fafbd67adcffea04517d62780f82776e120e4bee3690474a8feb1cc4257390921bbf56bb4c4734d4d5342c85931630bf957bf8b01ec2f054667c0b8f7f0f5f609fea727f5ce3837dfd33fef9dedf560f46071fcbc57eeaec0071f026d41492bdbdf3ed723573f3470e2740806c4f231971de5254a94759d9bb58e58d84cd340e8731893c1257b8153ddafb2adfc45c95f34261c941e94311c414ec79d53933169b99f6b12e61e61eb939d4b4f654fa1dbeb27030b8c35abec38b9fd6f3dd3cce75c2e7dbd6b49736afe5807230087513f83a0c1109f62c6ce3992dcccc361fe24a3c3e6afe51f32de911607a13cd9d81ee13dac554216ce025032ae410776c0c21e2c3475965abd469f298784f6155ae5825f4401be2d995baf007b11848a3dfff0d079a711ceb681b2407bb1fe1956867f0ba5c65634470ed77d4559a180d5f38471a72e54e1681193a4a04062c67cc5bc73d4b5885573e8c5733a81e64215e68c146a9b3ee19f45a6aef3a5107fa8ce1011d5b1e618d1b2eda88da82f9a5e724aefc3ae6fa7e0d50a555d0a67a7cf4510587eddf3d0917fee3a566ead7f5b9c33ed6eaa81b72ddffb88b5ed84e72d38cf56179ec6136fe8c7fabaecb89733b0f33e0bd08275e25056bd3516b4e7be1865a1ef0cadbe3c5af4136f684d0ed5da82c4db89086acdc73878254cf1fa91d98990eedb06c7cea8add2c6c6754f3769912ba8844c96163c695f9e257489fd94328c696f5612daeb640e6d8ff8d3e8e711ceb741f222bffd1baf15d9794a69519961728e464dca38f46b942546c337df8426a8b67766c22c75c87616b60c87619fb6d0a6e1a04e02a749f4d51587532669ba0287559ed56a8563473d16366a89da0e65eeae281bade54d27c84c6f06bfcde0df721d3519e39b415fa307f8bf1bea121955df5210f31f15d726bddc96f84fd29cebeb97f1621321984aeb544b5ec29104f41a504e3a62b16ed74da4bc377f259a6e7fd54c7001b68c6a1c502ad9b20965b196fa07454800d39239ae9b3c2d282f27940aaa11b17562bcb0084355ba48ad1ac662fa186e98dbdce279e718e96313737e2c8c5fa160b6b5fdb1b0844c4d494832636bcad74609f5ccf1defef818bcb22a624a76dca559155432d8ed0eaf85e7ff4fd8f74ee4c105393c44454a9dd52449b9c0285e765b34dfadf5a5837948ce1382022c77aaea3c8ab08cc7aeac82e085be4976899c106a7251ccf9ce741427082ab7644fb3c46cceb120d8f42db36b2022f055ff661af3eb145d7720857b543eee0637e398783edea245745b207d5112f1b05ade4e6f96eb3f2acd374e3fa839c8c86db8c3feffc0a2c31ff0552c21efdda3332207cbf409eecbd0073e8b232afd9d8d3711d0c020afbacb0d6a2163820accc60be9d311c4862ede785d4a8e6958c5975a27b794aac97a92e5e106bd0cc551fe3326aaff80e67dbec7f8fe5f7f1d1ce78c5f9bc0e6ec4b1f47129eb8cb62f3e8023e1e67e5c76ab5407eb54cf57b246d6cc9165c015a3bc2341d96c822aafd2453ba26e5e23c72b50e19533888b40651d8a642e4b5c099d0d025d16b18e56898312592b63cea0a0f6f05e3e512938dbbdeaa5bee10f471f72f1356975fabdffcf271af2effbc9ffc212fc9b5f33f03e897e9febc7a04875f047677ae4fd3faff1f1976f50c572e1c045ead077fedcd7fd00ffd66b7f76560487e509f7008e314bccb5c33dfce8fbf6cc6b7853cc1228d1846e6910bb55cc5d6aa9666e121df9e1a25d33857c548b5d4285e2e3782bc6684bb5e7c1bc4411026c40c7de36add032d9b73ab3e5c827413f7799939439f175ac982357a13e8cb9ab5aee4233e5ca1397d8c6af395cdfe9ff7fde33fb9a0b8e74ac8e7e6a34798f77bbe8b1c54d3a02a588acbde028970e7d8fa5fbf23d3c724b9649e45dcbfff597bd553f3f07c251fbec5867f933fe21ae42b762503842894b8d78ff6b905578996879cc0c241ef5617fb015d4287761a556d2b026e1fe1778d4559bee5b3f73589e01eccc9c21c09137c9aa4e2486a4fe68bd4aaba69947cc96956f104d08c4825ef256e745dea554dc0b5bf94f8deb7c1e16d7f7eb60dfb291b93bf80aa981cdcca19b63ffead5fccd391efb9fdfd62fe770bed352cddddf9b13a66c78e4ff9956621d7379e2cbfab08ff1abb7b569820a87416d9b3e936b4e24a0e572275cdfa08bb664e4f73e21c20ff57290156824195c12956f1ef5b615b49b3d6aac0a9dbc4a6a8868a57a3f6a1ee78eb996e47990b8f6163978e0c3df7b027ef701b342660fef152f7caebffc130cedd5b3f11986e68acfb5b8d7b9f870fcd73371f68b412e8f356cbc4d7476c2542f6ed5ca137502d00241aac74c3e060526b8f01259760bd40b33d0bc97d81040a87c944542c7d173173a5e1b026b2523dc4bbd89fc289f31e5097fd49631ef5e42a6c2b81ad6a4904fbec334ced03aae548e193449a4eee53bece33fbd07fb69f17cedbdbec0377d61a3c19db8d6ffde2b9055bb7ff7eff0dd8f78bb670e2c38cb636697bb80b75816220ce8f00513a4131d7a1c362b365646da639f68621194ada094c1b4321129bd5d68c092459e8794af1115ec426079e97e18b15a3ca208c3297806c48eb70c42260a4b2577e3d03cf9d4a7bcd7d177fe8a576b2ff8710df6b282d7f6ec833cda4ff7eccf98c7b8b262c7fb93d5223f69e1dcc2976fb78478936cdfbecc3930386d6da2d93d8d286065364034e890362c3ecc83bfc6c6dfc0b7a2bb60375eff0e3d9dd3f3da1ddf1992dd5a276be2fdda08956a5891f38478e65c41172bf994e82ac16396cca2a5417a2f491ccde436c8999b9761c906a10efb8433273026ab39cb9329902d775191687913eabbceafe0de774b9d3b2ac6ee739f121c86cea0bb97aef91937b58b5f752fdeeaeff1351b73e66063eb84b7dfc37f2dee705e5f39de78d724fadbdefdfddd59d37c7203ef772b623d33e6357e096d910486a86366393141ebccce4ce20cd59775e0efdbf18ff9bddfd6fc4a2eb062bde4e0123b7aa94f7217cdff3fe39d7ceecc60ed51bb65746b9d3d57496109c1a04b7bf124b8ec66e3e73e30204a58b00be1b24beeb3be5a72f01db93cf125d5c71cdc065db3bbd1b5fcd2ef4bdea71fda1c798e5fe4483bf1f6dfa6f78c7c67d2732671d6cbd0074bd32732a20a9a3ecd270191a398487be6e43aaf329d510a52da9989d60c2813d0af1ae0db2a8e4bb98e691e50a75bf1b08d48210dac7eaf2460883b60844b7b17b358974a9d38392eebf17b71881ff955ddd97be13fdec63bbf515a723c973fd2e59c12988bd9984589c63a5fc5fbb86cd57c34f489f6ab63958a5935d8879a1482e08047aa0f3816c269daac822264ac67551bcbff97bd377d6e55c71e45ff955bf97a779f30989cf854dd0fc1066c6270cc2081ba7ed50512db60c4b00d1ee056ffefaf183c25ceb44fbaebbd57f9b0770c2c24b124ad496bb0c2275d91cbc77ab9d601885c284ffcb1bcf7947bc675647101c4a94525c660f5e8159f860a39a03ef86ebd5b03f24b70d8f5d7e390c51c4d02f3b7eadd813914a6f371186a1c5acd38b05e30eede1f3f6c0178d89b70587b0e50bd94dade98648b14b92066a71012e8726842d2c5606e1117f1e09746c1932519d4b4c0c8a8d552af862ce16968c9c8d613141149e7c184debde28b5ca1c4f880dd52fb9a359818ab0e772876db3a089ff6ef845a126e4962dc1989fae459989fb124f412d9b240b8d6e2a1e69be5c08a29b5a1a15b0e18e91c5d792b127935baf32c55994b64b270c21c71fac690d0ce8cc3c84ae9dce58860c6466e8f8a811f0f2b6881158c49b5b8be7f6b17223a832a8b922bb108cffd39bf286e0c737282cc633da2360ee1721c0cdbd2c4cf9d3b5578ac5b7efdc09b9c1efb909db931e11027cf0359b6cc74cabb3181368bd63ad004c391f64654eeb0a29a7e8d778f2ca5ae6d0c3c1eb386b21858549c3f3244d213f5974f69a951c4da1330860abb238072beadbbafd0c4ee5bfabaaada7b3c3afa221edde1b4b39d8ccf707a1cc76fd1c8850b8065a43a706d614eec92f71835f792a1684ba168d6ee16d90c07125a91942e00b7f77446156d27668c51992d7894e9d294f3253a79e4840552c2c84890ead28735628dc922d12b34d19f5c006a4d72d730569f5ec40cbda30f773cfb21fad9f1e67762e874eaf2a04226dbd754ebfce0dfe75d8bafa01b35823a8b93430cd741d66ee480ebe39a59d34fc5a9763e05120ba37b41e784c862062c190db519af4ff584455a0c429743bf404c781ceb2b9b8b5963ac4744569fb49878f389986876b107f680872b3ad5ed8cd5b9f017a076653bf900afe48155958a6fab99c523d9e3f3b105d957ce915e896f7a4e53aa413d5bd95fb0feafe53cc31badfa6c1d74718b6cf208e172604a05b3a0c6d38c9304a0b81c8c714d12b09d31120f29aaa1a35a0b0b3dce1541984321d298e91ea4eacee3c1fc91cf048bb159c22159771e38736c682e172298eacdfa3010a73e1ae39881f14b9bf0dbb92bf61531d9950bf5eca0a75da9c9f1526738e0041a394adc8fd450f9029bde610db0b10751723137dd38fa5a2a9facf5c52e77a6b3dc2e987c654ee868ae684c00cb9d291175e1202db087bcc50d232231dbb9b25803595e2fe062a099c3c880796a4b61851235d4c732c40aa8f18afc82a321339741f6c84e6b032c0564cb960e55fac8e5067c27ffffdfa8a5f2bc6edb770ce1ff1763080f6bdad1199f57dfe327bb2f92438f78c7bcb1c59dfdeaf9bddfabebabe81e89896e39b14092616cd8c8c29c5d6bcadef1a0b0f6a2f21131c311a1e2663e21a6e9183b1ba896ebd0ccad0a06f3ba846badd61db0f69532215436cc8468339670be1d6a20c91808754e4b35deb675c382afc418708099417deb7365dee57b53ebf76bd7b63cf30b7c63754a46eca1265f1f4377e42fd7c65576b5f13ee72b8ba0619ae3b05cc4a50c18019a00e926077e5989c09a69582047468639f46cce5881f1726b25a09c9bc3d287c33a184b155674068d973b5cab4f81f5b03319c10b52758b18d6b36b50ba0e9869d150f0edddde4d51415e8be7e0688c4c76e529f2c64fc007ecce5fa28b3ef7c56ad7f0b37bbd1def73f505b0055c7b42196c23d9b4cba9c790d8b35915d378af292c67c92ae75339d3c7d3ed2343b68b64af805a8fb478ef5a925d0593f011cbb9821446d027846a921afaac5bdb29790c6cb24735e0ed9a503c096db2123d92bee011efe414970b7fc436b2777c3a1bb812779e10dae5616bcff56b0f6a6f9e035ec99f76849f9befcac739e284d01fb13450e87b39dfba5c8f7f3fc77c9b1bc985bb123961ded9c52ec7d1fb4c7fce9f0a2060ae1682116b0360c94fc18478d624545d6ad83836384b1192598d6c43210398e8b3f9840cec5578876ba90e26e240e7c3c8a8dd9d9f18235f09e73846b916039dd8c8f43920f94cfea4f384f1645dc3d6a23260fed91c8fb5cf09b95bb191cf0ddff3a3d977759eff3eaecffbec68d979dc1db3ff8d7ad29a1d87d98c910664223a3aafb2f3312d70b25f03cb10319fbb642cc76e4a2c8f2207f1608213b608249b278acc83849516c95ed580a85a12bb86923c30a9c16318a698011448e19db7d238630cc6be1da63664e79ff4f70c8932eceac5707b8a5abfff37725125fb904c740647e7f678a97a67df3038a11bc40e6304f52d52deb5877e952daab997fb09f98914d0faa17736fa97e3e9fd263ee91f13ae6dba6cf68fe3c5b982c6a18619e3514ba931e38903f830f47951c68c3c0296eca2a4d4e792b4f6560febf9183c2e6cb2c393c55e4ff44a032443359a99508d7465b80616d231dc718b78f8eb91072c1e0d7993032ff6d03bf2741bff7aa82fdfdbfad9bea6ec5bb6fe1e6fb8c41c2d3db80f8f3ce4ed7c9f0d1ffafbba6aefa33573f4dc87b4705bbfaeb8cb0f7d755c0cf379db2cb3c5e6fdc0b68c913f363c9391175e920d00072ad3561f01236b265786b6ac263845198add81570d47da4acf7545b8c3c9def456d32de2eef7be15ef4c38e0fd186f3536946c4e7df2eb87359ed89c9da2319018c18e89fe9a3decf04d84a3f1876a0d7e8deed9ed818ae53d6874f9835fdc63fab8904fd1bb8dc5cb53dda231b2f5fd1ce8a6a9ec07d89245522f593311187d823993479ac9cb0e48e85a4f86e21ce46b5f0e352ba64ffe444e75c9ad0247b5359b852e307e2d1c9903298951023c9dc7bc6beb9c192f7802c9fa9371e439aed884c07dd1e3bbece255d89dcfd1cdf3988317f53e266a8e476ce8a77a3e3daf57fcb1fd74e9b3d5ca2ccc47ea1c315f37df977e65edb8ccf3b9bff69c69fd323e79f69101465fcf38ba472b52e0f1c37601896dacf01629c693665387c8fadc9664cb4bf6770b8eaec00ae438962192ec3de2d55f9813a8594f3968632e90e4b165ab329274ceaac30400ddd6647067486c36ab5523300be1abf229bd2a7b3ecf03901814353833d906673be4a88c07417d11c3f522c700e872b2f046e5f679837bd8c16cf550fa091890466efd083fbd3657b0f7997e375fcf17d2e9b4cd5fb76d6b029a4233b6b28d376fe4a7f760ba1c2bcc277ddb8540d27f915a5e682b5d245c31301c64634517acb13a379de9de5b11de5c69028acab59eec393b112ccbc9d6be93090b86dccd6d01d90a280ca560b4a47c0a56ee1ac3dd2050f2c4acc32d747241e372d11e0303582ff9eefffbfd15df58238eceb88efa819cd55fa3c3be4efbd89a28724546efd09f7ebcbfb556609ee9892dccc7c6d322415c206bac36316268a91b9be61b9fd1d819c76a465c3ed93130508a07640c84c031d63e0b6a93aaf36082d41963d77347663547973469c80026ae2d46db4185cc6c8e5d019edc790e4104e45fe5cbf8df5e2bbb199437987b2fb6fa4aaeb8dfe747873e8fb2dd81b7f631429fc941ba3720304c07d4ae832b0f0e5740a111b4e447cf696b46ccfd7af929bda81d477f3e387da5eec66bbc1e8ffab3aad60f9da57e6abc97c7bcfaa2dc5faff67fa4c757e35c3e9b7f412a6d09e990caacc750de87bb8131d1e7060c11e1869139a12956c8f67371e73a8b1550b990503f7dcfd748dbccbf2496eda2cf430d1a8a13396df032b3ba7e3ee74f4f34db3134cbd6b7864d67ba0224b2424f066fac2d6e6859cea23646e5165ba2a071461d482c0bdb9808790e1cc48271488d58652d854dec95984340ef4c49db232bccf0241feb34af034565ed31924c2817968dbe8c3ff95c23070b0d2e4a04d99c4c0c7aa6eb575764e2de060c7e9deaffb53acab53cd697f5ffaec13821834e72d7957a296d9ea62d4e98122932e39a4779bdbe924bb68d3ff4a0d1e6613df7317ed9e679bdf3d7e3818eb5c03b7c5ccb5fbb3ff82aea51a36bbf787e2d26eb84b76ac09ed3ea6773dae6f14150581de4cc17e7fd57db7eb7b653e7fff74535fcaec5c1f5be542fef5bed375fc9b1f7ae7e21bb49b89d4b05e3c534322579e0a760e05964ab8fd5274cf3d488861e90841566f35f7a2298264f810fcbcc92d07e2ee953d33176330e097a121a30059e0f1eb6fe4a17e08ac20505111e1b7741342ce138cc7c40172ff4cc2b34ed6a3db857f7db41df1856c86459a2d0e250ef629abe62ef3ed09e24a438a1cfe213afd4a36b70e8e8214ed5b03f03f8df071fda6bb06fe4efe9fd48aed48d3d7eeb6bf6a6e7b9252ef5e94bfbdc718ccf6bc79cd6ee2b31793f5fc4e45df2e8f6dff37a7f57c6fc5eedbf2e36e3792d8cdfe63f17fd7736e70bffaf3e16e48a9ff6fb7c28d628f016712e796c58408b4cdc381fa05497e7a3e186c4e51ad8006836aee78ab6c71c9deb545ee88924d8f242b0203b5dacc2899f8ab5cbeaa565e796cfb8034b1aaa385d0c085c6c092b323e970bb836267a54a67fb726e0d5f5f0eed9fd555afddfb1195fcdcdf12eeddacc583df353247916524c458d408238cf51b78f2cd97a095582d45de33ad46d899d2e12fd0e24608128d81952ae116ea881b19891b15ce832e517b11e7956b83363994336909122accd095d04c058cc38f6ce4e10ffe24ce08b68d7b3b5daef43bbe3ed6fefc3b76568a7d563e8fb75c0172f75a2bf21071205d4bd3e7a76ddd9973fe783ceec17b11c91547d82a93e59583a0292ee60a896de5862acb1880c47da19365117ec72ebc7ea06256502e27ca3b37a15c832d4ecb8c6128b3caadf1935156635f180a5c239341cecd0bd57ab0b8b27035f99eee6d060bfcafee543c078ca30beace3f3a2f6cf859c7c92d7961bad7a473fba5633f96d1fb8e772e77fbae624dfc9889fb277eeb1a48b84aac5dcd119620fa7240133cc0d78531156265539b2b2779a23ab2ed46701950babba5f5b133270eb78ad4da48a307b81ac0c09a588998f1fb6862c6eb454dc5b8c5a9b892179709842899873b37c2229313f69f7beac03dcd55f78d72f8e28f2eebd58337d34d86bd557e862468895d64f87711d91b636004bfb641e5b663763e34a9345de8e29f058790524ddf22c435c00bd7e6486a245738ff0f2c2e4e41c4b646c3864a759626cdb6c8e65c4d96cce0300c69ef5b087e6f0c9e3f6aac1d3a9c9a0cc84fa2f9fd3d78f8c31f36335b12459f9aa1833a4008a476c3387a13f7a4b0e3ad4ddea71fb9aac98185ba2d0d46ff8da41f61b5dddcb89cf4f4b04e5436df2ffddf9453d9727d58440a1af6172661f4f7b5bf773192f2185cf1d78026e78c2cb7aef8a7c29efbeb097d38da780669eeb53acd295daee09ad2f6c357d7bfa8b31b1b99fd0b2597f27b8e915b8eb35fe3a787cb5c6421f27799245ad57e0baf8b0935ff6b5da0b6fd8cdcfc7fd02e7a991e164c8a23eefc1cf4ea71cfc0d9df24a6dc18fc9642fe24f7f5f26bb32868b1a90c7396a6b175d3dc77f977e873a2fcaa662649a13ce4c5b4ec1845ac026a925b183191ff2869cd71e33d803b8e0102408da83da8086096ac3b38038376c0300c95d7b132268f11e2caa72e48f4a2bb0f7eec2163684cfb65e4ab3192fb3442ac147f4c9f3f19fe4a76b365c83e284293147efde8d0d8ebe264e8528a0f24db66eeb9e56cce5b535fd7cde0187cc3459cd75053d195ccecdd8701158a1b588436fc185c55cd2759d07ba5b0368d93bdee6e5dcb6c43ba3c66b7305208e4ad302b2e43361a8c5fa1c8cd1cc94c106484485d2b2d6652059b05c04b10c0228ef16347faeafbce793741137f9b62d57fb8a1c50c7fe3afc8695cf83f490337ffe89787343316c33bae7b015cea1b24f31a7ae3c0640cd2c259f931b9c83cfd96adb38c3c3d9cefbb9f7bee4cce0a2cf564e68e31b0fb4d2723f9f3bd421bacb1b1560169529e79e3501aaafe899af94b296180994f24c67b2ca640c756e1bbc3f2a2a17aa0b08f1ce7774deb6c3c46264c106b8f6e23cd51c11e90025646258a62d78c42e5750198e34064d0247841eb77f25af9b91fb695cfa13957d676df12d5ffbfb31e28c07056106f71569cfff4ffdb77121a301f7393ce67368dfef4c1ea5fe0a5470923b58daed024b37edfa41c00c3bd357841a9c6c78ab78a08dc12f5f2a04a3463b9b936394aa3950f4bb20de4f0d1a86333e5c81da284da0263edc8fe67628d8e6fddae688a6c9ee9ec02edfd8153c6e1b39c0ed6dbe33a7cdd71bfaefe74bf8923833a2dc97afd93f5f7dd69d6b7e32e72ddd6b2be02ed20517c40bd64fc585a7ec3540c389110fea1947047b35dd627b28b94c39b7526a5b70c190442db59a4e01949f3c5bd67559d4b125520ba0f18c35d6c1245bc3248f31a7b13ac442e0d0bb4796eeb5b1f8766ea62bb4d2affa78bb115bb95048dfd523ccafc941dee33945ceb2c489bc415dfe832be361d8dfc839cee9e081f79c8c83632018ce74eff264857864048a1a990ee6012c6ac40c051d1a2a9a189e3e512592000dc3b04252be7864f6f98c09077a6a08662dce0d385d6b31190750a00b867df46cb2c7b12c2d587deed561fd557abde768a59f82d23dd866e980ffc07926e3f3a0d30bdeda3fd5d7d4d323ca9075b965375f6dbf4cfdb9dc2aad2ce72cd2e50038310ba43d63b1ba4924ba7f64989d560d6b93312a28e99a39097943d1f704e80b2dd1188dd9536dac6de76d9d8adc58c4f48e28b919ac90e231390d56549a7161811c2a42d91819cc9e276c0e484d8b776aa97fdcf6920c7764746ea797def1496ffd244a9480fa855cfe32dfc5e04bf657ab8bb0097274a6a56be7d7d6c3663efa6cbe292376d35c0d5299f35223f56c86c529de7b35a80c3b6416b13c37393626d0c80c9e8e0c28ffb2560f7b1403c15364d18461ed33e53cb090a057a56aade2da846867a4060f2d9a6318f31eb358071332f364b9b6e24ffba2b73e2b48912b9cc8c2cc31b61f8d09eff6c5df8fdf6c710c8dfe1c876d68d9797cf81be3ebf68ffe391fce3b34b10750621b9d8662a99cd951e9427be82e005a1099b09e25168125ce8932cc80a3af4855021fca53cf961d300e334cdd3d4ea7db19b3e44054ec8c097ad498a1a159d49a5b58b02cb170ed7d02c761e55bcbea2b69dc25ae3e9e37864021f2f965895b3f3aca780efa6fd56b63fd44dd062376875bdb8491f7f996aeddefe37d3e17134ae41ccc6a7d8eeda24692c4225e9435bb6402481f81a3ca8b9558048a30f1185631272263aec85e4f008fe46c806ba9b21df5c99890b99b84aa4975c6b7f3351acb862187a1660be6c20a4363a58a9a93af672cdd05ce57d5a247ac9fe84ca34bbcf085ba723edfd6bd866a8e38ba21efd4bd7ea346f60b1f2bc285b9cb2d4b37190e5057cff7628d9cf988bec54b593f3128eace1cff4bf540c0062920e9ce691a39fffcbaf7f9f95c9db00da6a14778e2e278b105a3e123548080987c8f24fd498f050fae644d5fa1294e437dc666bcdfc8aac970e142616bad44458382168cf58230b94e2c24122647fa8a6648a103d74686c5832d7474dd8b6d76c668d557f1d64bff93e98b7c089fb48bc5a8a1b12ffbb91e73190d842fb285f5fdde9733cea06e0ad2360f4234107ec3e6152d6a22fb13353613f9d1a762b4000f6bcd065b22530e83bc76573a75b91d4bb8985b2428d763f511c8606525431e8fd18aa4fa0ed5e22f38c93736356686929733c6e617d0488d5885c896172066e72e534e3013ea2fe6f26dda705af7ef9c43fabdbfe38b5a011772d347ec6860e33932dbfbcf7cc0b671c51fe237f7e9b37e7bfa4ff7049e6ad8b576b54fdb38c0dc8520c731589054f400aba7414a6a5b220cb0d43b40751b2783ed5cdab1d81caac8093ddf5eee90bde46c46e235462f17b6c402cb981066688249682c405ecf2d602f40a859a94c2d65b8b025e14987c44394bc6d57fb843f1a4ee9aed3e7e40d528665a7cfd3cde10ceb23b5218823c6ae63d01914b644a189f77e3e2ee6a5effeeff175ac182151ecd24f868c0751decb6bd7ee977a7b36f3b9fa4c10ee639d663b3ba5636893919ee86b13e6098ac993cd0c4b530e7f6990e8c8b67917a84fc1cad08daa742d58969e138ee0d8f805a090e298b816a5773a4f1626a39644194abac46e1689542da0c0eaac6a995cc8cc5ed67dff4dbeae6e03056c4e3134d77cf2f4cc85fbf5dbbe80fad64f508ef8536e81638dea17673a61882b56701df5d06f75bdce0e2ddb73e2115bb84e2ebc035bcfe03116e84a1eb7030cdd60de087d654fd1884d7d6518b9705f1ce5d3d155ffc51c57ec062bcc9b75ba1b99378072e54787760f353b1eaee7c45764a6d5d59c4b5dc56973905f398b9a80dd999fe5731b4d7ba67fc8ab80149aa0e8589bf3dad9e50029b87413b946d0c88fb93e5e9e457f2ed7c7d95a79cf7feb7acdd0dfa4db5cd76fa307bb5c18fa4a51f6ed7fde5fcb32248d9972807319cd2e9f20501534d1ef7cdbd85bb63ec11680201ab2962d8fb415aecd986abe7dbfd6b85cf495e5008e8dbd313162a290b1bdd2936062449604f480ea036da51a48093786a23f92d4ae882527207d41a7df91af3eb0afbb6fec7de77526807b8a4ffe06cf6d44a7365ffa66f46b12ff5d5f22162771335feffa11e9cf7584dfe3e39567367a7b2b6bf7bf19e6f371e30c8fe312044e5c6bacb40fa026cc27a2a1d986e8db7b86b0cbbd36a68ace1a2aa2a400b58c90723f00dc6eefc1786f7360ea4140bdb1383515b440f6ae4231eb9a35bad326da00417d866b9ae058672d29e7fcc4187d326efcacd6d79136ecdfe7c56a71ccdf05f761f0be5df16becf22ffaede6c73fe6f46d68fdf2f5bdfb5ace561b55502ab60b88227dacc69821031fe48ac6915f1adc8b7a4a79f235395b9fd7713daf73f18e8d10301edc958d4e8313b0723f5a87feef9f31f53ecd06c51395ba9cccf43ae88bf1f46720d527e27d4cdb92e701443b52eb1b0b0a88a4c8d2ec72662604189c2c59d6f25abc354b208ddff9fe419b7fe02bbe1fd2360e9238204723a66ff75374606d515a6b54a61620c223431c231ecabe45077e32e04c4997f0582c74561e196352fae3f0ce9241694685a0b1126bc5eece4a862bc35137842b6d8f0da1110b391c6b5b948a633d9113bb0e254f996e119ff1f68ad057f2b076dff2b19c805f9577fda2cf131e0f7bf6b379d75b9df70929ac1b48d200c7466d5b046149806e5c5a6652ce036af05a1cafed1a389853754311c644a28ecdcaa1cfebf305d41d2221d63487c8ac65db4b73605a68e32665ea39b21cc0e500b1648338b422ab50c4dc427825b728ef2974e58dd8c8e7c346263cb7f1bd1f13fe253eaf24f3a09ecd602b8b3778ae3cc8e644a15cb74fdf7aceec3fef13cb4684cd63b2124593d9efb0b257a0a5ce20555d9d1a5ce080b9ce0d7f79e994f727648d6a54fa63b1f2192acc01a504e895cee49656e30ac3fd1cd4d2000019050941664def3c9bac90a33a18e44fbe0d3673805ee642f91b766537a1a977f275bd62fb3dc8faead6e7f6d48583f2906f68fa665dcfe61d81f5a14a71c41e7c9d2eebee5d91f90f3681f3f1bcf463a3271be7e8dc16aebdcda7391ab73a02dce7febbebf14a2cd7efadc71cb5fed66cd1c6b336fbfd721c7d3ec4cfe56bb352bdf4d930f427ba0362433778b00be48cb5570f038f930494ec3d2fc9736b82a620961d680f6744a133cb0a592f353cc04f0597551394c8eb471e5886b5183c32c3682eb53a9c8b27444000e4816d483a9515c47d593ec467f938be4a576a636e0f67e41f890f635f8945fa2d59cc8542ed1d72f1b67e7c17e3293b3f80dfc993a8223d41bf740b3d0120ed3cd9de9b5cae58b161103b579093ef4dcea8160e559044298965c973e40a30216f73fbc8b7d5b965873b1dca6b2d71194d16cbb994db464a752d61f781524ef444483d267cd22c399971fbbf1bef427d38fc75c2c5476cc9cb57e2af7e8bbf3eebbf990b50fa5c7e8c7b9e59cb57ec8defd27adde6721424ba63c543515300bfb0c35db012f560222223453caa91e0a5f1de8a711d4c0ceaf3f29dbe5a3020d6b733565d204ea834733831f8c5da835aedd9b91d50696038760d1443d72cc3721db20114940663731fb12d5fd881cd973415a5a0f027244713239bb5713e76899561fe321ef9ea3eb96ea3facd7df2ce78b63373f84e2e1ba67e25a7f5bb34334869e95bf69a9865bde0750bf0549a3bf2dc85e01758e99291a26cc1942b5f2a63cfc9916be780d8a1381feba6a5e491ce0916b1c90629c6d89408a729e1fa912991cea8fa02ee6bc081992e038a6a24831572ed173964afe84a6fc7f1bda495efeea5c5cb7a15bfbf979ee771bac85775981fbdd1717e27960f842333516d8d19306612420259d7b044ea337b30b78db197e8a1b18a2b93d9cf31304a23d637462defd02a8c09000323263c911fb885bde0fca4fc456a1a6a0c8d3da032d65897b514d7666ce486391c786dbda817394fde919f3ec0cf5ea379233598bfacc5f2897dd9c793bf1e97fa2cbf4503ef3ed39b7b9af0fe1a7b254fc6557ac07d253d38e46ee8f8e73126f1309eb2cf73fd1b71a2324be2d2c6d4486c5b40564c5744514dcd2eb6d026b6bd9278dd429300ea0bcc61de5dd108c9ae604cc09e385306f12ee7dae5de94c3d01bbb3c5c85aa0f341e30e04e0732749921e32bc8d152d5331c909231fa487ee1bf6177bcc8d9c13ef771bb90797bbefca62cccab219e881faa3ff20536031e27f20e77f9ee0ebf3f5fabc9312cdba2bf8215196198bb8124aca18db885251a560a74933776f3f1a77ca0f8a60f64b28907f7740665c6e7d8dc7dafbe77f5222efdf7ec77cdba6dfddc68814cf690b3b2c7d1b571f5bcef73be0d2289c3550032d64c040ba552c32bac00e6d52229a773873abac2f00b87aee7a37bc172e2ad212d049f1366c8b1b773cb4808afea3ea753dfbeaf6c5b7e3462b9f01341b2a2d233646d0d935cb45780752d696bcbeef6cbfc9e20cbe2a4f91786f858f3b4d14fafeb8e6ff9483d3fdbb9cc3f7b3cdbd95d89237bdb4fee782664bfa97b068a91cea01a620ec4debbf9acbf2a1f5118a38a8d5c47a748a16d1cfeb37194fae7ea79b572942deb734f028f86027e414aa1ce2d594d52b79eb4dbcd6d50cd010a4d0812bc5235cb96138d19cabe238e3d2e7ff22c8d41800a36a0229481edc5c02072fe08a47265ac4459a3600694e5dae775c99ae8a995d0720ede3e9f7d691b3ee55b79fb3cfc4b685b5fd3bbe15d5dbf7d9ea70fdb7d3b7eb59f4160ef3d5b764d1a02c4c8aebfa2c04ef29c98a50eb85000209c621e25784c4a9707c8b7686cb36066d60fdb0597339802de88e581315e56338e1d034e65ac893ef162a4ba70b1230cad7d6ec104a96a2f6c605c8f35a0a1afecf30fc6a87fc11a3df6d7d03dc185fbc26b7d6e3f972bab3b6bd47924911cc9b9802db058ac1e06ba1c6a06d05830119f6c5615359efc82925c9880e8de04945a529a2eef6ef5b16cf92b95fa40daa1095dd9003304e4aea5805f8429b946a6c73c8a90b287d6a854a00d56644c2ee25e9abf3f17f970b4fc3fffe7e6c74deead83b4bcf9ebffde3cc5cb9bbf6e6e7edce85e1234bffefdef1f3771ea95d136f88304dbdb38fd474e37cb28fdc7cf4d8affba2d8324a75e1914b76946825b4cb30d09b6415a16b7b987636f19fcb12ab2b4693b4a7f66cd5f12945e448be667daf57201f9e3a688eae0e62fe19ef971936424b8f96bc0753fff55462d3cc770ec3f58ee1fccbdc50effe2077f0d067fdc73fc1dc70eeeeeffc1087f31cccd8f9ba8f81789d6377ffdf46811fcb829aab6cb71b0bdf9eb6e20b0c28f9b699addfc753f1058e6cf01f7e346a7511adffcc5feb8d1da6e799ebdbfff716347e4e62f9661d81f37cae9a7f3af7fe51e616efe627edc18a46994f971639e462ed2b8fb8e0133bc6b2e331c17377fddffb87928a3a4198919e09bbfd83b7ec8b00c3be07fdce8457347b867990123fcc9fdfbc78d760594b91f1c408fdffcef1f37a38f833afffad726dd1401b9f9eb9fcc0fe607f33fff6ea6390cd62d821a9cdddc865912dcae82348ed2e27697ade322f770708ba3db7e39fc238d966149ab7fe0e81f97abe208517829f1b3fdb345734b325cdcfcb8992679b62e9fbc32bc5872fdd37186bbdb96b75e0665f7dbc8b2fe97e69538bcf92bdd50fae3c62c3d1a1c27babd3202af5d760dac92c9110d8a0374d7eff1721ce4c7df565094cfa09b5bcfded032b269fafbbf37fde05fdf20ed48a3f4e6af72bd097efce771db7ead9691fff00c2eb33f928cb49d81605d442da6d93fd8bb965ee42d560ec4e44de4f473fe6132f2ef1f37c42bbd9bbf6e3a76a96e5cc8766e4709e0da9471300cfdc4289073108fae94c93c99cb1bb1bb767935c713e328365bc93046a6f00b57e2d857862c92bab6a7d28bb60b0fead4ef8fe4a6b1bceb4a1f316729331a562d6e3147199f572fd5982e7ca4ed1371f44c5454599c746e44ad8a7c10cf527dd5a89c9d6bf591e5455d9a94560cd8f89c41a7933675cb96402127a3e63b1e1235122f9e1dc470d769bf7be3a5676a427a4a513a4d50e83a5ac3064b9c820d516889cc87cd8ca31ba480c12cc9cfdca4cfdc72fbb1f80dde47cc59e878f3aeb0450af8e9c3614c5a179561e242b99e35a28aa3b27e1bde6a6fdd846e669c5e78ed5c3cebf31c2f8dd81e1b142bad7bf5c6e5e83331fd6c2c67ae6267690c5a1718e4a8ad6bd6456ae9134b3fa5e3e8dd695af7ae67e378630cab762d29dd5ac2176940ce707f15df4737357eb692a2ff0afb2e83a27c9b6db7100776dd30b08e5b73ece0cfc1fd801db07f836977f4f2359e3de407fcf04f4e38f26ceec0b3d9bbfb3ffffc0d9edd0cff1596cdbcc2b259f6c8b2071c2ffcc9b37ffeff95653fe7d61fa1e9cd5519b502dd5bbcfc3f3bea5e4cf8e7cd1f37ff739413bab575292614cdd5ff22411ea4244871f5d7ff5a4665b8f1ffc05972bbccfeb18ccae68f1f515add6e8573a9e29f379846415afeb1cc6e7edce02cfd192dbbdf3f1b80aa2883a4bfee517279f5af20dd16cf6e51cf0fe8f39b49b45c7bcdafe70fb2fcdadd6d463749d0dfcde36540ba9feb20cf8aa8ccd6d1e1e1f14ed55d17d9ba0c4811f49f7420129757edbbff73264efdb3f9f632d837342158afb37523c6fd4c9acb335ce26c1d644583cb2248b6c1fab6fb73097415e16f3ebf4d82e467f11a54f3e7f536baa7b74599adbd65d0b494adab4be0c45bc77e4b271b44aedf7cd8fc1fa5cba69d67705189c380d2b0e9b459f60da5fb71b3ccf278f94794de565e42ffd8720d15ccdaff6ea36c5346f4e6c74d7c5ffc1165b75e1e251e0ea33458574d37cd8ddb7550649b350e6ede22f5b74d430d7ed2a0bcddac9b36b3e2a693d56e9b75da0a6dcd525806fbbcf9b1495bc27dfc754b027fb3ec5747f3a75c47e9b269a3a8dabdd682ffcf41a0fee78dbff9d97e875f9541d1ee8c245f074571ebd751ce9ddff8d9aca7f31bcb3acacfaf6b1af9ddde2abde6e36f69d4b29ed382c3eb2a2fb3e38f5bafebb2bbc0511eb693d65f93f387a4f04e1701bebc249c20b0c317376ea3b40cd6a9476f03b2f3d6a4780e46699497113edd0913efeceaf8fada4b493fc5cf1f151bbfa4c1e9414284d345f3ded9151e9c5d9c7f40117aecc51527dc5d5c0b2c7776fdaccb929ee1692f30c3cbabdb3c8ef6cd664f7146a27479f6f3d62b52f6fcdaf78ae06e7071274abd769b1def2c33fffc320cce1bbfed8d03c7ebbcdd5eaf139aa7755666a9e645b4d96efdb0fda8c49bf536283e02bbf6a234cf32fa01d8c0db7f00ea38b7cd96e8a7fdbd7732ec7f042a0fd27c997f1cb2d920b77150edd6dea7de5a27d9fa13f00126e167c0e9d24bbc0fa1e5f0c661fe3ffac2710e3cbaccd6511926bff37280f16fbd76da291f7db7517f838f2cedc30b0517ff06c70d92689d7b45d4e8f6a4b83d52dae24db0860c7f00e2d65bafbdaaa7d9afc396ebe0f9c6bc06d1538e3078be729f011f38de159e8f7f2e5f7d705b602f4d5f93481a80328b83f48dc755fefc337e439e09039a07eb5b1cae1b39f983d07946ab9f11a57f4f5a3a4265c507805ed2b14fca5d9dc4fc0ed0896306dba8e8d48a0fc177b2ce5ba039dd24fe8b4df92ad82df670187c1838a3cf09e6ebc08d1cd6ead01f85cfd689577e0c81cf5f22d1cf9f9f7c651995d132cdd69f1d5f44f6cd977df6ad9404fb4fbe93f9abdfe8a921b1bff35a5cd228fdf05b99bf0af0ab3bf93974de90789cd17670f9efbd758bbddcf3231a95d56f36504424f03b51f343afaf83ed4b2aff3a78a371bdaefa3d872ed75e5ae49df2f1b9176e3b05fdf3ef7d66559cde5a46bfd15558961f9ee6d35b473287b3247997285e69a008d66f68df6fbc57841f53a73fa8749f4c259f7ee19664e5fb287f4bbb7f01dc8a0e270de57dd00f50d30ef0a8d1bf0f9a04eb9806e53a7a0f87cfc13f8ecc176f7e84e85e79a95f843fd75ef2e9c1a61979b900fdcdcf9f1ecd6ec3e025b759661d99f2373fbb1f97005142bc7594355d2c9f3d5af9411ab483e90d07b7d1338838d846a9bf59c741b3c2ff758db37eca14f472fccf218ec84bbcbcf8885de943b6a720f103f29b56aaeb704549b2e7e37bc59e75822882f5326a9e36fba3dd248957e2306fadb217907b2fadab06e7fff0963da9cea8972effc8d6cbdbfded4125a7d9ee67d4919e2b8fb15794c26bcf420f871ec7bcf678b3de06072bcedb0067eb3d0a287905fe643abaf6f4a595e71a5423ceb33cf3da2715af22a228c2dbb7f0d83c3f1923da9bffcafd98fc7c033e4eb35d1a66bdc2770ed4eca99325eec5a3d3b7b6e7295720f275b6af9e3f28aae236d807d8f35fbcd33c3a09f869e1fd0cc2c0ebc9c873c04dda1aa98e56d628fdf9c79639bfb3f3d669942e8b67b74fe6d8d06b31ddfcb9f5080dd6fce1ee2d5ee3eea24c1aaa1e251dcb6bff1e85ffeeea38e2f6b26703dda3551e34fbfac23ee4d18b5b38df9c5ffe4ccade0e7bbc950665b9f65a3bf0f15e56b40692f35b79d6ea876726c8cb57d6c14f1ae09246e5c5ed224a9734f849a36578d16b5115d8a3b49daa20dd5e7bd4cfc0f17e191425cd2ebeeed9241eecdfadfaf93b76f057c09a564e26a337a18aa07c1766ebd18878fd21d707218f44e303b6fa0e494967996ffedcfad1f2f4b31d60fbbb3707279dc1bef9739b6c6819e55ebb44da1bbf365919907c1da5a5e7b724276ded4acd06ec85cfc3cff6bfc35a3ade3c4c567fafd9ee07f6fbec5021eb766ef76b53b453da9f2fbc3c6f6857dbc5c943fbe3b6a8d2b2b5aabe3c89c0dda9d5b37389c3f5c9c25766496b837ff1a447e98bfb45555c1c70e0ac5dd12f8e3a9a3fa7e6fb757e3802f971b34923dca9f1fdafdb4df993bdbbbcbe6f2f9b657ff3e3661ba4245bdfbec3b83e0075c632de826eff3454e6a3700783fe5bc0e72cf40db8b0e3336f40bce48e6f00bff3c5cdd22469d1fc4b82a2e8c8f36b80c7c5bfdcb49beb5db803e77a0b90bb0d1b6dfa0da888a4de2b8f1b0ed691fe6b4f5b19b608f0661ddcfa1189d69b57b1d582b6fadbcf6c9dbc057458a34d831f814b9bf6fee799f3dc3f2f8fb7ffb549a3f25f0de1bf7ad0fdeae3d391f7ab20fde1f7abcf5fbbdf1f8f5f3eff9f670e7ffffc9821fd0d5adeb4dc49ede7400d63c8cbf581609e800e87a8df3e86ff4d1fc3d693e9e85bd87979fee7bcaa5afad6afeb3f56c5db4e56cf600fee562c7377ff5f718fee5dadeebece3dba1bfab77ff4b77ff437edfa22daf59ca29cdca4551ed4c814db4868975fa4f35dbef239a12623f1cfe9a477f39d30cb27533c46b83d8ec83577dcf4d12a1e5d6eb8c1fc62d94583829a8c1e86d3c92173969da917951b713edf65c777500a366ef50cbe1a6cd42ade788abc41ca9e9e8daf73c51d33cb63e4a9b94c3b17dccb766d5ea45dbbc5e374241eddbde7d143ea7276899be7fc3132326d5d6d27adebf5dd744456c864dbc839b5da35efe7689c2d554ea73348e3fe5eedf3a072b923fce13a1da5cc9fa3e571ccb1eb186133e6d6c55b11421fb6ef301e241447b87513767950136558224755dbbeea87bdb6d21875970fcfdaa23855a72e14625f0155d36683eba7a8b93f5d3e5983ae8fc962831cb5f2f969d6fc6de6683a129959023668b4cce7bb7cd8e0aa9b8f656a5eba7ddf4d95834bbbb6744d9173e13e47239192046cc80817d3c9e2acaf6ebd3c2a88f5132d9fa54686e020c31ca848d28ef17f1fdd9d278b0d56f6a11f2dd96e4ccdbd76de29e617c7771e4f11df1bac0cdb31ce2a9c9fa2a8841a41217e6c33b64a97f79d45d6cdbd90a3d1ee84c72a3e467acd529d9251686105ac66a9be258eba42e66ea956c3767dbd0edbae8fa2996f9f6336c80943df110b640acfdcb88577da39aebb623ac2fbd9ea213dff66e4846de5b4c7f174a78dceda48c0a073975fa60b6eb8214a331facddafd3e58ccb6b9f1b6c2fda6af0340a9bf551b4b8e6414146f169fe8ed1d7976b66367a48ade47ed9df4b8ff3d5456733b364b87e3cb57711f94d46428c20d8198eccba7097e104d404ee9959a26ed124de7455e277cbeeef8b77fb6a8b61851c9df5278b8da7801029a0c26cd1eeddaeba0521cd1811d433bf6af7feb36f79de77485d683478f7db7dec1ce6bd6fc741d44f17479a83a32b6db6b8bc1cef61cdce12bdf0799d5e3c9f305d1b13a69836e38f8fa1221919c5ed3e6cf0fa1f75d76f54b2f25d89f200741425d9e19fff4d51f2cf2f1425dba17f8b92dfa2e4b728f955a2e4813cbc2543fea764ba33d9546a682c888d8e562f7f9acffae0bae71d2d376ab58aff1c2db3edac12653fd5599cd84ba28461d3a7a7d8dd38f956e659badcb0c4ca9e3632d154d10b04e58d3f8997840ba91f893bd7d16b041757e4a1c1518e0250c8c9385b1e79482586d3090a7d85c6d35e3668f8742fb3b57c828c849dafc89bc7f1a2e3158abef5539d9976b24d2383f7fc446cc31a1bf995283445ce343d8487bd2e3b66876c0e0d0ec4e763992a74e372fb466ea9a70a8d6723b19579a7cdf84ff2edd275daef2e3d28e4be03cad9f27c9ce7385f34e3dd20072f17dc7e4ba02177380a0fdf905f8cafea4304cfe4ee8fc95587f77a1e6e6567b25bffacc35f23f7b63cb695b1fbf5e9c3e1ca639af11b34989cc66c5ddecfdcee1bfa796ed7d2723abadf4e25ba21c9708dcc97eb887094f1faf54512b9f0e062d9e3a6984ebaec9dd3899ef93c28d0485cf91cbbf315c02053e43dc768ee33adac900cab0b3c1f65ad87e17424b6559f1f1576eb72e5d8e71abc84ccacd7354ef2fe4b19ed9a7ce526c33830774b93ea4f5624f419b2488ed238eb65b45e8ef9885cd5ce65ea34f23407569e729f9ee91f7b02e5e234262143508e1bdd0c56973a54ff7e17be9b1ce5a6f49a2ed3ce6fa217cd1e9d4a9738e9f5bf8b75d4d0aaf61ed77e2bebf2c61647e105cce369df319e42eb4ebebb58e7cfdbece45725cc7125143e87dbbddbec3194dcdff5f3b8f5157be32bc3b499ab362cb6ceba75c90d9bf5de87ca1eb23164a7b1f7e1c676026aac34f0f6616e8e723c4e00431c753355044a9e85293f9e65a7e9e5efe3752b4f5bad7ebbf54d81068adcd2c2cb6f36ea59da86096ff0690ce929dbccb93edc56226e74fde5f4e190b5286ef7e22865be56de6d8f29df946dfb83cc4e1c6c84c1df08491d34d29bf0d9905496e17886b93f936ef9bf1b93da09b3bf19937ac7fcc90b77777f0e3e22dbf69ffc11d9f604fa1d93fa1d93fa1d93fa1d93fa1d93fa1d93fa1d93fa1d93fa1d93fa1d93fa1d93fa1d93fa1d93fa1d93fa1d93fa1d93fa1d93fa1d93fa1d93fa1d93fa1d93fa1d93fa1d93fa1d93fa1d93fa1d93fa1d93fa1d93fa1d93fa1d93fa1d93fa1d93fa1d93fa1d93faed8cfbd2c1e93f1687da5208437a186bd21f0979db91ea0476f0a6e298933fd57f344ce0e04975ff7571021cf3862fd5779cc0779cc03769fa08693a231ea7e8806925ce7dcea06d511629b481fcb0344e5ed28f234aa8afe85b1fda4ba2dc2f03386471d47b619f0aedb45ece44a15b3f127738197675fb4dd1f6147be926c3dc574085957d485e7af3c7c814572e1c2cddc45ea264c8fac962e9c1c1127262ee27060d46c22fcc89e47134d87a508891b3dc78a996cfa2a67d5a4fdb88469d698b044d48ee2bbbe5c1f3158d44c6af9a769a6fa01b548953201b8ba944643012c3a62f5b1a5a60d445d022476770355882d63b583c7ad85ef4d1f439696b6032080e9698a71b970b2b9f13b6c4d18bc0dc1d3d7c3d28a453455ae244e65baffe09a0b3485451240a3e0faacbb18b1427688b13b69e2af22630c5f0b26d6d899c90ba3c68e167a3a60d7be972f2663ad1439480a27907298b2551423a550eef3f2c3d0e08841b563d3e9e7bc3177d2441851c83c5c960e99ae2d29ea80dce6a041f36a365b69a56a2e6737ae88f1abc801571fa3512cb09519a6f0103047596282d9e977e2a9653856e306f84beb25f5e8e5765fda8f3d8bec4ed7eeb7272e14fe2a59bc667dfdbe051dc608559e2141ce1dc51b3468d0c996245a0c07890a58735809c70e7f33a9d4e8c0c27804e15b04113b12d9e84ab411b69f01889cb19f7d0ccf7c5f3a982b6f8ca1cb59efea36ce98e861982724194e516272044cd373b7aed8eba358fa010f735969b355d756be004375542eac23de38dc495a78095b77bd9aeaf500e4181625e5f4ee5f61ba99f187d7d7231f1f969334f85e720ea37ebbd120fef2e5d2ea42e571c70b3731d35f4216090335de289ba25098d115cb47bba5b2be773708e07b98d3e21c970d5471d2fbd2eda78d947b60e88f2b0f439b5dbf3adf7bc11b61128095e9ab261db677babf3b21f563e940ff87c741571e9a5dae3395d3844e6d8c748f5707588143878fc1fa34494613a1d33ed753b9e51ebd5dfc2b41efc49ebd99f9d3d6feb6d82639dcef82dd8123946e6738b7c5eb5d139edde79f95d2c254ab845a387cce784661f4e0cb0583673d4d3979a38e2cee75506c145fe467fcdf7568119ffd946b02834994e9a3e54613a11439cc8cd78284eb5a5eba8743a112b9f47395240dce0b659670603ecb368edc7e9486cf0d1d0a2c4af4e78eca37c0fdfd5de7721dde0fe1b4f5902c4c8e70ca1df13e154169f6cf62c8bc043b66cf623aa9a3947db47e51899738a08ae0edf2317fea8a7c1ca2122455b620e346bba8dac69f66bb3d6db689e877c384ac4a5fb903d767bf4d9bee1b58e9e282a9d2af2cae5408db91e1713ba25ce74e9a6ea96f03a6dc64e46a2dfd64c1e67db19d7d1104f19d6649c0db4f17237e30eed0f2b04e5d8ebf61f791cc54b170af1542edbb5338feeb7be325cb9709ff9bccecc57cbdd7cfcb06dbed79f18d98cdbe7cdf89bbdee98cb8657a113ed6b23f2962e0f2a5f7968f7a0dbe2d4583674f818f53531b63d2ecef9eb89068cb3c71637a78895c7b6cdd1430947e2c262757b3a62e3e988fc394d42ea2bfb6d57b3996c71b28fa729934ee536baa43447a48bc48102d34706dd4d157987957dee72fd5eeda2d6fb77c4b7f0d0eee9d132b7fb757446f75a3e734eb34edf33d196c4d1e9542eb7246970330cd1886de409a6a12dcd181c333cab954b78521d6b5daf7c8ed962455e799c9c2273f86a1b8f66c7f709479bb5582147dff99c10377ca3a59dbd1ca45b0ff554d6294e51ee72f612402124899cfb8a1cf90a581ee15b5ab8cf5bdc019592892ab823b18f989a2e3de81ee4a6f3796ce48bb8ddcb099bfb0988dbf96ed7f190438e5af89cdcd0e862aa747594a74a2323b4eba14490dde2346ef01522ceeed6e6315a70bff5f987255240e13af18177db0d9d6af868372fcfe526b1f2b99cba7c237b092b7f02e23eab84df1522eca23f1d73b999f1cf0b14f67ba359bb7279a89b1bf6dff9e2bd2bc50b9bfd21363cdb6d65bd87655babdcd15a39b0e54f5de1c3255268d5cc635b8c5191ab8eef0f36a365be74952e52cce7f67494083bdfecfaeee9c7d716dbeb0dd824d87f2009540f758cd9e785e17f55191f7e61d07e3bf66f65fc5b19ff56c6ff8e327e240a275d7c5665bf46d1c3afa9dcc92dbd8c997559845a9dea8c7fec1a3acdf95c49d1416e5240e872cb33b9eda8c736ffc2467638e8b36d3f17f4dfc85c67b16cb3b4706d9439d3bce7a7224bce74c65637534035eb75e7839e7b681fa76a2323e6689935ba55fb4ecb4f38b6d507ce64ca664cb5cfb57273fbcce78dace19744099bb69a7f9d9cd8cb9b8d2cddc8b68d0ef6d8b5ff8015b97221b30c8ed1e0c6707a923f1bfe759477a7ca30f212b022a3c163a36b2d7a797a3a29b76ed2f0be8b77fb68ebd764619ab43afae2d938b8be8fc9853ed2cbf47d5b8d5c9ec64bcc1b55a7d71a1473a0f2a05c048d1ca0c87527071ec6bb6b6508170a423b6f52afcf99e29f07bdebe7d977ce9246166f647e9276ed1fda39ac935e5799689d6e3a22addcae56bba5ca93102783b4cbb4d365149a8d444a146df3b1be4f327dcbb77b59ea0c7fc748f2e7ed1df071d9de41af7a47ef7a78360fbccee046b7e22fe6e199de77d1662b23fa9cbef5cfb29075fb51a7c8ca96adde30d1ee66d5306df048e074e372c372c6959b469621895d62aed15bd56d301aaefd88ddf913907a70507699368691af0ca319c7861e1c6c91325ce16a9812481b596beb27c318c1bc9e256c3c6df682c99ef000fb396cbff3feaaae7ca677e5c768fa8b35d1eb67526e59cc6073c0b7079170f66e315504d65776c5743ccd0f191966d5fdd2846e2f8b1d75cbce160007071cb63ac76c74a01507bc8bbc07f7c5c9363078d14ebbd7168d1e4993e928bc32ff0fc3278b59aa6c4b0bd2b3a8ffa3cdea9425abdba3f3487caeebf6c5a0bba8fd0f7e53a3c717bddc7da225bd8de9282b9b6278d2d3fbb55775fbd66be8aa13e69837ea365b8029527fa2d377bf95213218e1fc9495add12d40e59f8a872f0f7d5e7c6bdadd3b44fcff5cb4d9459608ee1bbdf325de2ab1268acc10471ffb9c41e7d103a38deda2cb1867b098611b1db8d133eea623a2f7f690a59f0c99569f57863c828b743a61fe3c15b7eeb2b90413718bd3c50b1bd32861b768020a640ab48331ea36f35e75e077f6f2e75767dc6a196f5f91fe1f8dc8da95a57f53787f097e3a521304e6bf7aa8c6335f79a8d68dfe15497ec07ccbf2dfb2fcb72cff2159fe258d3809f51d5352db9450adf12d09193279284fe90ba71d533aa59a8ce6d143a48d06fbd9ea21ea88b85af89cbe6e8d22e002aeea9f1fd3bfe26a7a379d18158176dfae18ba5c19a246a85f65272619357067a9229336dd69db772be88cd8ec98be343aa5a0797b9c2d4ce42b7485a05023737a371da9626b9453ec528b06bb8bb6128362056c9002362e47fbb19fa7af7c88502287b8627fe18a3d1df03478a483dd6c85379a393dc2ff342fdb26f1fbed774217bbf5a376ac4133c6d96a71fe3d0d7e6be234ca4d6b846abfdb592d36da6870899bd143d4a543ebdad2cda62d293a4b33d93372a61744fafec1b0f43983f51550cf1831715b431d12669cfc8b446c9b7aca83ed5ab91cfff3b9305fce054e40ed737b0ec1c5696e3b21b6429034424915984723ea162778bb50508879234769bc7561cecda0bef51db13dc49d55cccb7b96b4d19a6f4d8d3438ace70e6f0763604e2671db3fe6c250b7a46a0609b76086c04a4517b3a43281542f2c238492ae99d0887c69b72392b1d7c7eac8a8ee2b38c1bccf87910777823796f6040e79cd12ef88ac55060f14d7c9e78b04fd7253b5862bb0f147e5c65676ac171b9697642c90f5f4c9622e708314b04350881114561e7cb63fbaf1875eeaf6f3ed6e346bbad1a3b3f5b6c89ead3b75d308500ed70b378e7681cb46d9229c5cb58735977d45e4a894346b67dacce3461b5de0b2428ebef52788a251bbbece0ce12a451cadc944156689b0f35b256258a16af88012b9260a4d027398f8bccabb8e1a23b8d8ce2eafcb76fe560f1ba290bbcb3d4a1b213ec50965826e5dd79e22b19a352d41327c7aac91638cc5d04eb3819b92d4a4d9002be53a50f2bdcedd6ff57a59b9acb4f75631a3dba1836a71ebd25c470c0d914c1d8d1529a91fd62e1cacbd5a36ac31516d399f5a961ebb2be0182bf4648fd1409fd0d2b2a5e193798113ea278df27a75eedab96869c56a309c8ea5dd74795410860745e0b81e12618b14f0d387c398347bed12778d7238084c36448a51bd3377f57f60ee2efa6ff6209ea8db6012972e34621c317d9f0283f8ec628d1f8ced9e6308dde18f9eb996bdd72296092cc2fb14c43386509b976740d22a3319de616ec7061289fc34047e0c94452d3ef9abe936a02237abc33c9850de7344c307c8233c70482c4cfc58dd7a8ef1a8a5240f260462384c081bce099406de0a217da516b6c50c3f4bffdfda3f533ab8b24fda35bbebf022fc6adb3cd2f587cfd2e2da8342dcd2505ecd88a36d3d478be6e70ad8483d1a0bbab5f6b0d1acc597cc3fe6e806358a2937acbc09a8671cad9bb9f71cad6cf8ae3efa24cdb5e8dc000b41b344c94a64d55684144241b36491a2aa7c427cbec75c2c109b617ca0473e6bb38185767359638d49ae0319c998c93d9cc8bc6796239f31e600a0916ba99227e57b1b5060a44837149402eb81d3e2bd7185e6720d9ec84465d105bf061bd47cef0bfc1ef666279b3cad18eeb3fb18f379e93aea2a48e4f58cebe42fa2d01239d377e6b2e56bcfe49f763e0a92f46bb095e7c47a1edd6f710252cfd1199cc61b3f154b2fd5363eafa6cd3a0a1236c4897ee7c262dbcb57ad2c83a3fbf2d998ca8e8f4f3f458ba144471a0da3200e6d6b857264d35f28a63a58d1cc97d10a5111682b546b290a11a58e0d75cf94896b4ac381076513522a1b522913ce28346b2ac094a6baf5b046c9108195fa6bc11106a7b2b5b0d0de4ac1dc665ed0e218390daf14199c02fa493e1b2388288e58c6af5aa3d7a6752639dfe3afca79ffb17513ba49b36fdd8fac91fddf5e239c1cb9a94a49bb1e0ebf99fdac6dff53747de327b63063686e9bc32c8869062db44392b1716395095644f2a8689bbc8ab4b1b898f13967cb7aa93be2939194859e86acc1ab139f869b198b18200973140bcc02226f6edeefedd4a09e52d601b5050c75db83f1ee1a5d27d1510f799fce7272d4c8a12ed49919dc6f11d7f074fc0edea78dfcfd2578bfd277231f856eaa3338915764c41e8de933abebf77374571d7954b5611adaf60465c81e7206a78e30b7576c963e0158568facfecb9e184f7eaa6af658ab51544213102d48c09ded889ecbcb10d5e4976be99aae1823a8b077414278302a436d3c153caa0e74208e3d4b7f24908a0dddfdc81aefe4dbb7f07c947bff2e3f6bfa6af1eaa56ea94783bd160db8cfe90c598d28d2108f6cbfb62b9d933701a082190f2740a68f6e8cd724113636a09c6189a50ed9d2e3b43d908ab59f86229e88eb05b3d74d7bb77341c620452d40accf7d86589e12968f5c79675886071cba5e24431dd5c6efe80cadfe36830645ce43d9a7e1ed7508ed25ade874dc9a8cd85f981b6e668eceb8502d90c99ea7f7eddf6fd7deeef9fb5eaa6ffd88ad5d2ea43e944a3251c34e26b5fbf71e36faf3bdd2c8ad8e9acf605ef7749669788e16bd466711eb27c6957dd9ecbbd661a8ed0b7194f12620bad257f17c4f1e606789bef5cd619faa7658e16a48b1328c90a3d2202973ff933a970b85da33d9d05768eabfa733579d5cf87775e6cb3e5b1abec15c239fef73c40dcabe9fcff1f4541cfb329a6110ce35569d2c1276e641354694dc615b47bab2df7831607d46b80316b03565281ba998a0d1f04e77e4475346214ec11a273436c6c62f62ef9fb418b916a43c00f200afa88381ccb88086733934a183bf92a7f7eb179784a3315196a73dd0ace14ff2623fd5f319940b0f92cd8c7be5b9d3d01e3078473f635a9efaf7e5f38b3e3bbb48bb069a35428311d3f7f319decdec5d47a4b6825ccb9281c5ea7b528bdbb94d732396b784a2bbb9cdb0762d4ba82a18305125c2211d39c4d0d3872d4e589d4010e9bce1c02437fe1ff6dead3b51a65b1bfe41ebe0a3407ab487512914a50c456da0ce807205a140128902bffe1ba2d9db494c7bdfcff38eb18ebab569aba8cddc5ef39a6ee00c90d5ec56048e92dc29853e6cb0312a9200e63ec16dac9bb9e83ed5dd3ff2b52f8d91bcbd3bc30ffffe94a85c04b21253bcf9daffbecafebe3fbf07ddf5febbc3bd6e2ebdd7b280456884baaf579ce73511c6668f8a215a68773ad6f038c9a1b6ca525dd8290e793d8d72e1c8dc6c7dcbd25704cd3c2d6c3c4d3d9269fe4069d32c6d4c7d35c22e9f3df81a6609c57668e007019d004db072af7baf55cc87f72fe7fc14eb6c8fb1ce7771d32a69412179b37d5aaf63c1073881d8dffae61f62ae53a74ac6a0bf67271d054e7bfbaffb025fc89f0f73fde47c825ecf5ee97c3e8dd9c7840ef724b8a98ff7493b8d7391ef6049e6742e978b30779a44030b9f55dba41085d41b20ba14f9769dc5e5e83ee918a736705d361a45e3baf688bb676464317ba8891c47aeedb58cb18e4f475ecc4635a1608e5462a00ea1905a9dbfaeb761a102ef73dfe1dd99edc1c22a2e50757e8f8f3af760eb8be0ee254eefbfd5376fce7b0f8030ff9c1be8efeeec7f6e497859ec487f3f97cf6c6cf7a35df7335fe6f598bdadfd464791e338dfb5b95d5f332805a134948381d7c5965c7bb40e4292b76eeea449e7b6bc48deeddfb7efa0f6a33b18206dd57ffedcae43e3417745bbae93d31e90fc6a4d9fe671d0f3eea5f7ec5798cfcc2447738f794d5238f711135698399b84d6b66f99824cd352dadb0151cc5fc14de7b3cac01364a3dcd456b61372052771619288403732ee1e7c8a77918dbdd8127b379bb5128811b1d446b06a4e1982e7f4fc57b1d7501f6e636356f7409e82b56fe5f59bbcd68fec84e51fe5f867be066be3f732529795b45310ae8f4500a19ea6b1bd7dbf77ff5f628cfa428924d39acbcf9eaac30067d1f84b7fa25964b36b9c3b33e6500bf5a77bfc34be76b46fd6179d370f4dd0c1aebcf5a802895d9792a66cc5511b76b8f133f5b0cad2280ad82de3ea3ea48c4a7067302bd55c98efb0662e9011ee436e0d12950f5c22064caf22643873615980db1885c68863851724b01e6829820becca6fc8f5c39af4f6e1af83ed1006471b70a60667722d7dcebb0af5e1cb7ebdcaebfeed999d4dee2ed5036da8a7e6bf94ef4b93026d567eef7ff6e3f6b9d9cb64fe43a8576392c182d03417245da2c09989400da26094f99abcc7d41a3edd9f4fedfa009971811ea2c0fb326782aea3ffbad5c16ed595d6fb632fe3d7ee78a05d60a7378be00e2050156e77b75f116f9014c3f58aa50f645a59bca87302dd2eeabe176393f6b08eb85b277aa34470f3753cf93a6ba1c53aa8c21674b1cd5432eecfc4bbefb4e60779c307920feff1148ea289dcaf26a39069a633ef300ecb6a17b1d92e56f8c1b760404a96bb25d3e3bc6a24f59a8571074222216515f295b7f738fa95d0ed9ef2818ef4a158004c29816ea8d822e455944c6f3a9f28ed637cf9db36c6e074af2ef34703a6f585ce85b9fb2a7e84c603fd2a76c69b31fbbd02b22fac331f637d509fc6b9c8cf4ca09c61eacca3895a47002a0c531165704926ced8534a71885362d76b5a28d3d5cc0819624933b84e88d49991cee824f5e7ba9ac4149b5e8e34c9ef5a6a8179c4e416eb4d15813475839b3d818c7182a8989ef333bf92ed6813f2e6e153795ea06de483635c94b82f31cd33b1d4506f7671415fe2a5eff377afec9ac460fbc41ebed8357ddeed830f9b25c5b04b5a902685d43fcf3b8b5d5268f5b16dd7b3de01677e7313066e7d944f6e1dd9c35d643cbdd799fb7fb88f366e17bc0711ef84e1a4b10f5e72dbfdbc3f609636623aab235b75d21e964901eb453052498154df12fca09bf8701dad3ff5c17b9db3084669522295ac5f8d393ebcd7ecc3f3ab7e0cf5949f6ffb756adfaf1348e30296ef74797b7e4d411517aa3ec8b897b57fef3f1f9e1b3e2eb8a9e4186c0fcf0a3e7859cf33e724e9c1d4d85c70c7ec5b493ec717dc73f6441bebb2ed0b583f7bafd251bddc0c1cfd25e67fc4467d18bf60a7fcefa7eb7f7ce6a950e438b6fe41a6bdb19d9dea83cc3a9cf9f7326deca432c0bb50878ff161ed8aaabbd4267ef3ff3fc644b2c886dbe80b3fed6af1f793cdbff09fc6fd092646d3f0048d9192059ac00501cac705ee5605b0120a26d8b00053e14e5230f2b299e16a95436c703befd0bdc79bcd12de6909c59a98e2d203b34e94a916e60d2441455693594b39dec439cefc5200b7a48d50c2f8915ff6d6af791be7787fce9e64dcd4ad4f72eff47c72a5b8c8c5f6b01e72b53de5b8fa36a6620cd2a474d2d597d89a5e366a57b08d3e9b43ef6fbd147a9fda9873af0e03a70d03d59d6c6aeda2dc254323c441e82bd9fadc6b980d7154880163aa8c6ca7a1fe70c3b9daf93a70fd52787ea92cc9942f611a0a6eda2407f75186371420cda5a87083b4932c257cea68aba9c3bd8eddca09568c888c18788c6d3cfa07b03777fdfaffe9cc948773ab1ec599337361fe6f1b15699a14b38bcf962cd4ee0b5fcb38e539ffdad792a5a8e2b6b7d5fa7117247974d783f6b27391066e8e90a78328a4a8f634d4f91cce43da2c5616fc45a7d2763b59703b6f7c4d0e483ed405c7b789cdaa446bf23848a3b870b65877bb683a9a31a01e6378f3e06b43b682551706d5064d50c02d732640ba0f4b68fc04077bf42b9fed8d73baead412f5940f189f7da6cf8d272fbfa39fb18d1ac919103ea8238edad8c069a26f5febd2f6423db50e7993c6053adcf1efc570faf7bb420ca780db909bd94176bc8ae59c99cfc90fbb28a6a37531408ad1df7b66018e32b921191cc5dc09136dabad386c18915a54a8596c3b039ae38818a3996bd5c1d2af2782dd69a1724621bbdb7bdc1cc8c9485b4d1c9494233f81d2a01c7a52535b9f21e817a9608479f2f398ce37eea793263ad5d1f864477ebe07efede69fee412748a82d0ef7b6d5de7e2656ef435c745f295c243614b1953e2ea79e468158132d9dacfc7a8dfc7ae1eb52a719d6931259cba958cbd259470cce93a96b88bcb6985ddf471a6e5744dc4764d4325add7bdde86155384bc146ae34aa4142d26a158c7668021bc1e44739fe5acec2d772f69dec3ec8be83ee3adeb7a7a2d577f7ed7b31d5e7d869e9ee44c1dad840afecc5f7f1b49b77f2e32d4624b1a19614ec208fb71fe67b464f48431a8b7294caa9a3627d702aba15eae897cd5ebffff0cdbbbdd541bd3dddb74def7fbf27cd01f1f41867fede9a3c8d793c5baffcc73773787e27f81d9de5547101db950fd46a8a55dcdf01f3bd0c7eafc3da2be5100ff2254dcabc1641aa89835dc9878f49afd3cecfabc7bfad2fadf5a8acd0c0f385a638e54e146b9519e943e5dbce864f47b7b1658e132a97a121433fafe7b19e686e4e816f618f05123388f228473361ab4d546cf6d86e1e239b61a43bdb5079bab0d2db908ba5c71559dac31da5f53f61fb0c2ed53bb191aa6fc48fdaabf83fc57020f8a0d72fc77135ed07f95fe56518b089f2b151956e31cc138bf92873d65e2909990a26a89ccc815cd3a2ba5f05ca8e2cd9f9ba992da772bfd0b5fd5c4f71a201261553ae76d7b26c64a14018ae6d8e85f5bb892c348f41b5431c2c44c09c2fb0a33fcaff9e30576ff1461f6240b016bcc9c200a937bebfff21f6f4ddf854bfeeafea0ddeefeb2798a8f3be9bb4591bfba08b824abdc41dde635b9e656b2d0ad63dc7b2c683c119dbca88785fc356f784224f76d811c3f25f9bcf7bad7bded744fcec4e7ec418bdc56e7d71673fdabf7f935b3e8df982193ce5ef6bf4839aac50e5ba283600e54346c968c3085c44b9586208819f0bb52ae1424c9dd18a8adce74cf728ae92c009fca924b1edd45e6e227f7a0342be6d45e6eda9ad0d7c85ed15d5da388083484bf4b8900fbef5bb7179b88bed0bb045ff584cc1d9ad6cf67f31a82bc6a0fe1a836360337e89ab9ec15c1ef60181e444fed0d793dac3f6f4bc71259cd70f75f647f92038d845c577f13c7757cae1b13ad6ab3718d377f3a897e3cb650461e89e0755c634f3d623232535384ba69b3d09d23da742977aa2af7865bad49cbac6c12e1c36ab2cd4101493b81dfad4968f4966edb026b5b9ae3257577336adf0d262c0053827c4d2a80e8d580916530951fe79add0dfec4b14b8b528d9369e1eb1a18773246c5a9fc877ff25dc95ea165c80d86e0efa558bc620eb49b5832389ee53cdde27f3fc113e7c55aa3a26f441fa75e71988304359cb002e43ceee59862c5c8a8da7d5596cd579145422a41593341d2d27c82776b546ba4924958fc2c613df92ba6ba70f73ad16487390c79b8ee96c812053a213906522a4fcbf5ad69fb1ad3edb7baf8fd5fdf5de3f114db5e0b4f7bfeb8fdf9d6cf1cb303ba197576b36414b64551b56b29a5b742ff8d06544599e5e65210d4d37af5d52421a533189f3a449ec7020a68cad2c319506f6500e2d54980f51999821418eb0952fad7d878973d01d5644e96e65e79dcc87eaba58ccb7b2eb24d7077fa8d7fdf4fe7c8ef5e9d77abfe0bdde79a9d51fff27721b9f9fcd6fe283f52b6181bec207eb3fc07e8c6420166cea50a1e09253d3090dbca6195c2c809a32386b5047756ca88c4e5189f4991916982f290649c05a644b1d157091d0340cf99d8ec066e073401090709531cc0a742beda6609dd3f29c016178fa1731c72be083e97feaacb421476ac1d920b10ff3525f624d4ef8842bd43c9e1bbb8ff99cf9fe54834aac8b74534411a0566ae142b63ebc33fc89a3639aef5090ee57d98db15268e665377b361d0161c04dcc94c60a8048170297a4b567309ff0e12da7622b2c368e27a3d2257786e462b72a70eadb32f075247031d3dd004ea38fdc107f53e3703e67f0e7dc4716eb6616067d9c7fffcc03301e5c8a335d2705cc3e9eddb376cbdfebaed37e9fe27da7bf9f7c96cb74d57a3965f55cdb37b4ac900ba4458d4a8f6c4d179afae506aa60b63396132198dd6498d62359a23aa128e2b930d044fc42d94c8fa1b85ff24db3a2cc639ddbf913369bebcd9806a388b09b26ead2edbc4b06be6dedafabab4415dbfb3a29e0a378ae994c3eecdfbf231750da376f38e6a65f882ebfd41957a979ca428e36821ff3de2fa49d87f3717e5e0b125ecefd4387f7ae8e46188c26091d467c22fd837fc1b869bab9141eab96b1ad3035601116cc4b0a39a2041abe06ab08aada03ec3129e0585a95e6eb684a333c5865d2c0ebda8db56a3237508755a5cb8c8d85169a3e97e7ea78ff100ffe0e2ebec798d54f4d665eea6cadb39c504267dae270ff0a96c62fdc50efb99a5ef056fcb8d68b00a998c34769ab2cf93caffa2002a57f1ea36c7652676da8c34ef8e0f07cf739eeea0de61a24c5fe739cc9f35ab06dc46bf50627f7c79ae27fcc8fffc3393ee3d7bfdf9bcfe37e5789d5bf1df370b7a492e3bede5b855cab4fe35ca46fe3dcb1e75ad824398c588ec0c2b83192a2fa2534eb81f39916db42f0a9b38f2732454ad47ee9b0e554da4b9a379e56eb743cc4128c963c4f1f89de18a1c20f9c885c96d8f683ca260c9994a56b620f2965233fb1aeaa6ff79283fdbbf37bd533f30fe154def3035d45d69ff11fb6b1215552a034d1691de9ccfc327ffe114ff8a3b3da93bb064e9f2759f05a9df05167e6a3b53fe1a04aa81926ca3596f610118d1aae66a295b5d530052e0d108e0d19882cbdf7f5e1ce9fa81219a91706c26793648fd44c0f8b1afb99b03871a820124b5ea7bccfeba6a9db8d0c4ae43aea46fb98e030a2697d81ddf0b3bcc777f0e53adcc663705897eff1c0fd3d56290b79b35d70a78a8b9efbedf5e713f7db657c4348fbfd800b6712f1b4f5321660ddb139675d68602366781172aa27f9b0f283aa5e65b00a0d47316df3e0da7084b4662e4ad64416ebe2cea14b6e66898d6c39ad100df02f6e872da5722a390bfc5c521ea026391b43fcd2ae7b69dc757cd74f31c1bd5ce6eab18f2395a80adbd736ffec4ff9b14272337fc2e7be3b27cf7af38fe4e146df7ce6203fba85dedc47366cc34bebe7dfe5323faf3d7e9fe3fce979022ab6fbfb7f3a4fcf9f0ffaabaf51bb28263d990d28c0639724fbb89401edc28ef14a8b2d768b09ca631b632f18a5be4aa3481b3a6ec0102ec42f91a19696cc135cce429aaac4504af8b55841eb81758248e55894853a0b9c9ce8d88fd8ac4104197ef14fc4322fad117ec92d7fc95771853d3be6a47a5bbe1f77417a5bee32fc13c7953fad726cd58310d08730871de3ceceb71a0f538ca320d9279429770a730490607cd0f9b6cc70d1044277ac50172e369041b454082a5bdfaa7fe14efd428a0991dd3462a238ce41c1cbd423040eb8fa196fe7875ae1a3ed7ccee67e6ecc96f4dc63cdee09938fae941777c91f7fe3ef64c7d33e9efebc7d9625b3e11bbeb46fc9907417e92a0fbfe4c4733fd6ddfc28f68036b15e57c286474ed997f16bb73df23c5c223f967eddcdb5613e07c99ee5d57c554003db205de852f7721327bca651000583d295acdaad28eca240743ec1a39049ea19d50c7737fa02601495a870391282a84998e506a3084676f50b69a91eabd1835bdeece4d95aa71fdbbf6feb8bc7ceff1c31191ff01bafe24337ebff3d1707eaf558b30bd7601f068e3ae6c00ecfd2b37e5b14b87558a8c73070cc45304a9f3029ff7bac9d3afbfcf1f78ff33cfaa31fe679d8e31e87b33af8c936d45ebdd739ffb56fb6276cd5262fcf816bdcbdd9e4eed1259ff913c37ddf50a7805bfc0d6eaf443f36593bc994ff71d7bdaebb54ee57073b4314bfbfc3717785fce4f378476c820ffa4620272ebb0b394499e67712caa913b9d6e081688d4d0e32690a6fa30c173e71e682cf064bcbd53c0d46744a5b441b8b2956726bb3f7089a271df608954d520cf6bea20deb46289a583b9ea5062f2b41a769c3022714d459c71afa9c43f45bb2ada916bccfcd7c0f5779055d1bdb79dd63f28efed2ebcff5111b76997c5b119cc51ac856bc29a9867256a8c7a8509657327f094713af73d6c4ae4c0cb08139f0c24c2d7d38db510e978c08c8e8300c01160bc3d559514d09f5744c4d82395494a99907f23dd6cc29edd8bdc881412f916f3fb38ffe191bda40555ce07ecf922205aff1c1dfd3834db508701a168d72bff2b1c757c2a8bf19b3b7cf5ed7bbd6a7712ef3cf002cddbc6a4570d3d0f6f7032508863aab788971a8618f19e9c60bc458b635a445d8b8246c6586bb88d7f3a414bb2807335cc2504e52ec33b10949ca62ebce4c0ac95ccb510c8c4c0937e602e05f3c805b769663ea2bffeca93115481303bdc26cfea996ed230fd83326f2cafcb06ffa1918a3de870c79637da39eb9c731bdadcdbdb48e096d63ddfcca973bbef7156203b13d7c14fef1dc1dc6edf582fffd3a26d70753b7536e9cc10791a7bbb9862309e09853b8c4c57012d114bbe4eea735fcfb4576710ee5f81e81a34ed8d1afd6f26a7196e35a82a7a6b2dd9b757d359f530de1056bacedc5548504a0d10ae282af877a5234139f482aa9897d427566b857cc89812ae62a7bbf86af6adf2f95ab3bc9f1b1a9f3f4abfce699de1a3fb37bb6b1c17211081597f858fff3761ef5d17ebd2cf6252d550adb89bc60e431e50d5c361a113dad1947cdd252cbc818ed6326951720e4f16aefe6cc8e29d871ee1a8cb35f2e9de96ea1e91ec7f9ca4acc180887b1d4f46813080b5239ada0e090109e4e9613942df49fc856782f9f6cf423d76ef791939555a7b3fd3fcb135fd685f7ac97753d76b3d78d5fe1edaec5d9fc61dca38dd5fbee3d7ff8615ced475ccdccf131455ea26f8c28a0bb953d03b1568bd040b60fd13eb1c4322ed1fda2a32d0182d2bc5ea369e5213e7ce453c971867eb102d4cc1e2e436d5860cd7df0806325b6582c0005cb092e084fba25ac669e0e616cd5e7ecdbaffc90a7777de92b54f6fee223fafbbc89f1b3fb7de4d4880b588b2ff26867f82a7e6837bd1eb397b3a773d1f7323af1e87b17dd6d610dcd79874692255d481c83144ee45b0a1056ed998dca28978040ba93d47117065b87a0b29707db3ac7bba52d0a64fd1eac98d823ea14aecd0adaa500f3a1883bd6204b0c908ec5920e4b4a652834d8d1236ee5fb772d78c24c7f75d7fa187777b5bbf632eeebbbf61c3b3bf500ea2eba6b01acbca27a486c0711ebf7ceb7f6fa729a3fc4f69d96909b1de920e2b9b87795132275b7f3758042e23e08adb25c63f3c00ce9b8acfa85add44c0cd1f89624ae0e3c54805fb11a6591310ae32069e23c3743adba5f31e7432c312cd4e327f7ebf9fd8eebe554f1b1a7c80fee86f395efd99fd56b6038fab997eecb3e95eee12e5cc27f75ac25f16b9630bc41765df222d951bd99ca42ac57399e25b6f42591238fc1db988386e6e93c2ed30d5595e369b5cd9867badc6959912e49e981a5851003d4a453340ecbb0a3169e70c566a112034971e54f9c5a7ecc29ef9229ae62dd4cfb1aa1bfc8d11dfb94e597f24e67b1dee7e99478c9cf7f87a36270957bd7e7ac58fe162b70eefb63fdf8f2b2dcab4de94023cc2924ad946f8746a8396b2f0773acd28d0f9095f8db36d27aeee86dcc9cb12c908e730abc7cd6f8b05af02926388704db691e4f37e62a1f0a69a49ba5dd58c236f598825be1ff7e401ce5b1c6ce724d7fd9ffcd66db3050efd6ff66fdbf4f3c497f8bcff26f7ee25fec620ed283fdf5554f36748cf55c43d7d5318787b53ac5cb5f7d26e1a3bbbed4cea1062b70ebe7e2d12fe40e4dd3fb244ff76c5a0177aa5a1f8ea63e0779a2036b495814db52508da5510e1fddbc5aac72bcc1107bb8530f9ec24a14e036ccf7ad6c878f4267515ca86dd4d6b72c5313dca11c01f6b126f7fb7b74295f73df33efe073c5a5570b0e2a39fd7aaf7afd75953ab0619d1cfc406e6a0bceea28c09a086627797c6e5e87fb7b3187ac2f26a81344606f5d77a483541a308a4a94d1c001493982d45205e96e762ba61ea9ae1e91b27649ee75311d0269a53a0b9c89c7d3b9e4b32ec9f2bda4e67a0e10a49a03301961ce87e3251909618b544e91ff459dd8f7ee4d8152d9636abfe241bcb99eaff032e6690f5eb0ba0b7273918fe0fa5aebeb4deb1277c7f4aa1013761be7c00a79054407995760dffddc0fffe63a894a18488b0de71b39fd9bebc4ac75b388b8eca43d6c9fede957f358107ab93fc521f28d512bf42de03c1d9352cddc8c6da22c35b0e1b573cd03ae42864bb14f73f52ba18e41a6372de79619535173922ee854e8722aeab8b006d44839cdd49cb08d161915c2937040b2592b8b26a5e5e841507141edff77f4cf505b04a336366e5eea05def7313d3c673869a8b342f27d2dca379c5c1ff27331870fc2077914cc3ead5197dcac9280a9a39e3fe1d5fecc15671c6c38e18322e28d5af027aecfe71aef73ff6720eca4ee395138ae9ef3dee30fbdf2fe255cd47017e9eaabf3beefede4ab9cf7e143c4e94926f47f3ff1c45e166be7a56c71514ffd32653443d0e7c3505abf1f564c40942918667211db6a101650794c169e82e3652078a2998f0bfdf7030f127dc9e5980144b0b51d1cee07a5664ed6b581b3f417a64de1ead826c57e1719e903fbab3e983717f7307dda97a8805ff5bebc5e4cbadf0f761f3eebcde7cf756feb5c18b32341f210729c89b2f25636f204cd1f5c28b752396db2feddc596e4a41badf12401d4484394dd352e4703aadf354c7706ab891cf0dc99fa1d54acc496c8441791b4159db38d6c934525e2c40236e1624d7305e417fdf1be65c31c646ec0b488efebaffb4e9ec19eff505f2605ad6580ab780caa636dc8fbef2ee5abb26a69870da3aa4cb8d27169352280da0a42145b30678c595287d9dfaed77b9ed67f816ffbcd98bd5d6e38bbc470eb3070ca63ffbe8b31b1c063422d74a72479baa536f6dc831c81e8c19da460198c467e26776e70b793506009ef0c043cb02a9a0de72990da3090503c50cb81d24a73998720342c6d09c52f41d114f1bc59e5034d40982da7238340d5f63576dfe1f3361c3399e2dd22700ebecf2e7eee51f6ad5e7dd7c031b4ab60a4c52d68fbdee4ba563fe7048f6bffa7f9d5279d79599c3f83fbd852966be466b21e6ea99dea11dd34d270c2c46ad48a31076b3072159a11a528e6701f9364b7b42c33ce1b2f3694ceca9b8ee6db1d66233be1031069ec575caa4000159112f9122ae133b9963419f897f4d4fcc7ea8fb07ae2e4fdfcfe5ca5de28171c1e6ba64fe35eda4bdcf5c1280c6046e9cc1076fdc8a8b03147aed08140144fc35c662b3bf9d6f916365b4bfed559f61eddf61a7e095661c9fa737b1ab73ef62cb9ccf610f6104a1deb31c19ea7b305b2b61d5570e9aa6ae2e68e60d4495753e97acc9924acaa09af349c1d6c73387795b376a7e99e15cd0e2be7d1d3869634e07d32958f1e1fa67187f78237cba5bdef685ee5324325553fc16183ee590ebce36ffc218ee4cf78ae72a444e0bccbd32324029c9eb18dce633f3ff2c69d8b43be7ae615e7db77ef983eac93a9a30ebae26d1dd917759fed35e4e81fc73fd85ab938f6f6eff9aedfe6ac8fe35f70374b1fe09cf02af7e910ca4ccc7d8a2cce552b27722e0cab5b68d7ace3bc2067fdb3dcd8a53d8b72c1d97ec1592339dc7e6d3bdf3ca2bff76bde8c79922f2a190395042c8dc7da699ccb7a0a535bf942076b2fc0b5cbadce2fd123b15081d643426c11867a65928ce94b6bdf3098fe1216aafda913fa19deacc675c9daa1e1323509f581b1cad2d22f3189281e25aa9a08a0b4b0803b17c086d8da8e64905cb7ee1fa5b1bdef71aee2f33a6e95b4a01481574701564901b517beec9fd48c9ced8777b01541cc9f7010cf75a3da59acad0d0f3efd2e2c2a151adea775a687e7df721b9c9f7314a023d7b5ff3a9e40dfcff569cc93eff1fc7b1fe619ebcebde8fb27f7f5619f8efdfc6c01bb443ff5677dc6e67fe82770e4469bde3c26536727ed61cfdfb928c436e4b27bb9dbe738fb51256c5af79c5c85a9e237fbee7ee4c5b355168d8f1c7e620cf649df730057b27853dbfbb187ae9e56a17e77e456b759d66389d79f9e81a7b1def28efb7fc48bfd57d51abd9525e7f8985e9dad2feb13e95fc7da5fc63bd890aa3b72b4e7277b9f5e86b1b5d2fbc8c2adaba3a5976ff75e59e58c5684c2348a4b8c5970b78b038968c77cd9e111d21bcfcff23db7e48874c2a1e06627d8c82225dbb953b149e830627ecdf084cd637d984b0d8d3c3e8c28f73a5cb0916f7c8eb1bd40bf0ca4cd8eb2ed73bcea557ad53c9d819e17f6584ff86e1eda7ed173f05ca4635ca2a5039f0e530a55eedbcd9c967842b9b07c2622690b6361b08290bb8744897b947926cdd56c55a07a6188a904d0e796d0503ef412aa6c66a0da55292481b3f429d31898e9688a844b1be86b5e2b7378fb4fd4829e899d7ecb1e14c1a81681537e859d39f2c5fe3d3779bf8736504921d5b38df0f4997897f3d8533177012b7d824b9fef1fa8954631a15da49b9d64c84e2cfa10e78c9060661082f5258399d06606edc2ced7373ba46443b8b229adf65eee8855063d39deeaa870a204de74944877c5e99ee8bf4dc2460bcccff466ffb6ff70f3b126e47bb2af10c1ac96f6efbe2762dc6397bf837572afb15f67c63efacda260ed22c0bb1e0f5798bdce3e8d7b91fc732d458465ee6480665255d4cd59858b2612ac1af996c3a4428398d69d0462827938886062f84096b8c3e9d2021c0774e702b146250b381ffe8af4ca8ca76ab2b2e9decf1d2762ced8e51547134650370ad8595ff252f927aa9e8b63eaec129bb5d23e93c7f907f7e470de8ef9a1914a4a5c9dea3dfe30af1397527b19cf3f0960c1697def168dbb2a30a27a38e0b98ab03fe4735081955f8f85e6e922b37464d381df3906d2711997a3851738636cb31603b527c4d37da644a8578f918e3d92837b6a6f4d8f088ef3d960de21e2eb4d785d4ee6678cff6bce91a33f46fe68e75c96cff8c13d3e627abed307e22afaf234ded37d558f823fd5dd5fd2935009b7707ec90207c2722aa2311c4f4736cd658426ac13e5684ffeb256ea3cdee6dfe85788556c43f3b02e8735141cd627bdf47e3e97af1b41bf9222adc34069f3ce6d30454d52c82e99e02a349c3931d24dd4fd5c97a07738a4efc8add8f08eb2e16baee9ab60525ee5b17bf9f432be067e803dc184a48d6b54962074104d214b78d5860cdec64115b9b471fc89220cc039b30ff6169a21bb9ebbc510cbbc89a24efaa182a12cb1458813e2c0ea44291f58a6269e21747f825d8f8c466c5def84263a2fd7daebca2475b6f7ddbf9def3eec49c4e5e337301efb2be555f3d8c095d00f67829ecec1f3e7fa8891bc2cafcaa89c62200baa43200394b2bc9accbbb410207c204ae89e4a1f3c806b568646a26ff5b818de635845b264b78c9a5316e47b5e6c35168c66b4af49c4f7b41bdd279663841a9cc8fc4e137c58c852fdf20ae4e3ebd65dd71137ab536f9ed7588c3ff6b8fa035ef8b4864ff2cea9e2f5f0e5bb0b65830c465b11a42ac9becaf9de7c8cc7fc4cf682c46ed4ca66edb1fef0f5676d7fac2bf87eae17e97226ac7421b5dffbe554cc16fa4c8f0a9179faef41d8e111b186ce5fda7d2ae6c3fb6ff3f5b71f623e3f93a16fb9b70ff7e7dd3c4eb51317d977602235c7a539730e3e8e54caf6b251b0628e2ef5b44174001236da849df008af2c543842e8d28ead1cf0405942df3fb853314808e3beed20a28986d88911d9225815002ca107780671ac8b4dccb013594afbc2effd86bf7af0f1c14eacbf6f23a0abf4edfb30ee710f0aaf8ef5f0c56e20c7f12ef25ffd1ac80e5671ae664c8d70ac432e69fa8b962a149359137184e63a7a94133c59e51e4854f24072b7917a75cb18a2c4701f984d0d9c0f75a4c10dc9a44e3b3558e84367c553974e984733389b1ba30da5702609fbbcaefd429c5aac9b997889216a97c72058b7e0b0afb10df9977c93073f667015bb2470eb90f77d51d2d0e863492a69411af6bcce30937d6fb47eaccbf03e56f5cbef244a144c971013d7ae52b74c3a4e4d77a558e9e7684a6dec1110362b26741154f7a430c972a2ac3910be3bb97ba046a5b905f8e5023576739c45edef07d9314de4aa590067c728b4135acdb1a6b5abb3f5cf3fd64baff9b93ee7960cdc3e26904c9d2ae64a8b02f12ae7f59ecbe0aa9c58e7f8493661f026a7f1a1e630b261b7089019736717bfcd7f9ccd67f45c69c73e9c2fcf9ea9653c3c1b17ac0c8f31fb7a55b0367e83973c9b8b79d11faf62ef679e7b8573799e2ff8731e443d26c6e84dbe6679a69efd1fcc9b3ccdf76ddea4c46dc4817a77a63ee4739e3135e5c15fc0bb630f39534b0a7590b169527efeff2537d7b171f7873379953cec7f791fd2832ced393d2b69b3360cf0475cc1d998d415e2ba3d3f4f7f67351138a9b4877dbdc8d9ef8f589bcbe2bc7e6d31ebf700036584399848dd31a55e5571202342d3fdd28280b3f49676ce9ce72288f5bcf578e311e076823b8f3ecd4dd90e97643a5af2128f9066ed396d52966363aefd367c4d4c041f3a2c93b7742a10d2d3abeac9f7dc8baf386adfc9c9e3fec5fd9d31bb88bb9ff6f3fe44ae9dc9bf9ef08187bb58e25731b1333d727a5f15a4c9f8b52c3b2fa344e0bdf4bdff537ef86d2ff1e623e6e038e6298ff6faf7c0ff5bf7edff7293ffe1dce4c18ed3e2f67d2efd8b58e2fa1ad83ad6f5f9906074d07795b4957eac6739f7bd76b2932e8b7f79da701bdb32f24b9c32fedb8cb9125e815c4f4f29e370468a6a8e33e4f1c06d58a1723c9123a92b1865f08107e94230484303bb1e67bf3c3a9c21562d687eb7179de308307a44796d781976d824ad6839d2afcb777f9029288deda6e71c7a2d7fd059f9835369d3fac906792337cfc88e673938fe167feacf63fdff508fc1d8ae3661e0ac2f8cdba8444769df87511fa65fe605d71fece71fea7b948507db8ecb5d189cfca737f3d04efc4817e59c060b833991ed4c5de24c12bd32ddbc82ac93d63218cdc2d2512113296d87b78935e8561c3dae0201638873a96920cec4941311a082b63e1ba9980b1d834a310a1a9ea9d1a243d384aa8870b9887367e305c9ee82f8ee3f178f3df6c0fd8a93b9bb1257d06bfcc4d3df4f7dc02e8bc18aa26a2475c192230b69c8649d00496e867e37b2bd921511a8b2585753dcdded25c0804ed93d9f50d3b5d11831acc5f6a0752dda323ad3683b0c3ce6f084a7a12844144f1c971492cc7589051c393e57f5793e9a8b74431172d8f53db80307c425ae62fe956eb8794457c15d8b340cdcc3e73a29d9a3b4d5893be4dcf7da7e912597ea8671922b0f41a6090bdd121d4c4276b78b35b6c7f9d07333ecfbdca9221d4e3c650d7cae52918928cea8366febc708604796b9ee4f55b82ae983dbb16e35c11de5788ca6c9007718504b8c56f9701f4186a3c2999fd30d5fdbc17dafca4ff9d63e72369d9e3d635bbeae473fe987333d498e737baa2ff8b3cd2bd2c4c09528f39798fc7bdc73cfcb26545234bb901f7359f223feee1cdf6ff3cc07bc1e989fe47dd6111f9ce3143f734efadf3b3c7fe4f22baa4bfbd2166180b405ef71d9f9b1df465ebfae23ff563dd3df6387bf9c47ef4b16b09363d0e3c4854d6b1938d5e28819dfc587b3323ed53d5d766f025f970ba62740303690ca89b02183a525745138a93f91230ed1c62d903befd03de20261a36284a201d39cb9ab63eeea96c18ccd60459c626130ecdab4f332111cd6194fd08e76548b14c64b9a726629477cb3eee9e57dbf8de5ee8e388febed87086e6a114010f2fd415f9cfbbe3e72065f86f911196a28513b1ae4669439a3c872d442bb3359ee9a6e20dd98d6634f436ca14b8be8e682e450e08e6d1243de22cd717d7db35fd234433415a4dc98a1269d795b0fe2e9c8f23455621b56128ace9da01183b30182dfe53b3ac800af8e4ab48bd7a093f6a997cbc97f8db830bf558bfaf7354aa7b5aeba581ff4f1af83cdfc5c93adab6275d21f5fcdf7c4ab7861effc6623c6c3beb751d4e5031f563b66212d86a20d69aa89e20e70a8aa2857f7216fc250df1a890e999cb23456c85ad106ad6c73164114628ae7094d077822eb04cc067832029e0e9ad8ae8d28477c394d75a9a5c62dd1d6df9759cfeb72c1be24d7a873f8e3f8af64d47da20f1fdfee95761aff22d9c43dbd11a4a8bdb893da8a55ad6b3928514e9014d0220ccfa55ecd50819d90a6d9429fedbc428d10dcb424180d12ab8ebc926a88c307cec4dab5f12d2b250ef3b075cb8a110e36c24e1aa6572de3d52f8f0eda9f70e584bcd25fe9de73baaf97613167ed4b9fb3337d507b5f44e4af62fd9ff6b24f745547bc495fc997d5132ff8dffb7cd6fe277c74a7fd6f05c7e9310eff653fbdabd896071990142c0f397aad2b9fe671b2ef2feca508d43eceb05818228d2dd7241cb73e43259a488de7c33da7ce320638f4754997540a6e89bd6f0d76915276d2d65b7c38b7baeab85fbba1e6dc621b2f580ec49288119b56faaa44815cd790b6bf355f0740941fecfbefe39f2fad2738ae4f1772f14ea67e274697fcbdfffcc7f15f647aa2c3423cd712cb835d7a8ae125976165025ca31ce52be53da032edb0bd6d63921254327709c56c6599864fc45cf2d983206ac919ce3c0e3a374be97282f7ccb65a44e59cb2d08cb2d18493d1d20d1cb4b4d3059adee9c270f63873c694870f6e090d965fa26b9feced2fee49dfefef3ab2fb8dacb67bd97cb09bf48b6b6035b40d59ea7920792013514b864cac391163ced4d3b1f22d30420606386fd684a05f1ea81e45ae14cf878f912e2611ad9a58496f15b0c65bffdef91c4e702767b155eb5277109bb28528711912742ff9be3dd93097c5dcf2d1cb3bebf05ef63ca5601f1d74e9fad39ab49b97f519ee93623858f92015367ef2b3fed0efef2597bfe0cd4ee8f255fef24c3dfe417f04428ff8ef97fe9767b86bfeac579ff313e04c7ee2e5dd396b93e2b9cffffe6cedd68bff574b1db6f16bee9bf1595d5444dccc171c988b40a66f75d0c767631b6a87b5798f457ef7dc36e27223c7a05ebdebc3395383633fef0f3567a32a2e7ebff4a07e1fcb3ecaa854bcb20d0587f5cb3ebee77fecf55021eccfebef129d653270d4b32d64c3f6a527e5f9bd4e74561fecb2d3d846bf0fef736025aee232afe3a9035e9ebb4afeb639e85bb4be18377bf61c7d8e9bbc4abfab0fe3be955b4025a5b34bd6da69bc8b6ccb9da78b7d68202b2e7019e7980b5d3948770c9cd723c907adb07e3f20fb6e80a6621cdb759000f9b85a0f6f19dd9ab46085c818c3c5d08e2733cd0d521ad146f950860b43b065503d6028c28429b6b2ab5ba9a5591f6bfdaedf7b7c3f230c9cc733758767d6fbfdbdf8cbf50e649a14e641763dfbbdefbeaf4f32e1229d917410522e815726bb6500b5b083fb05909413ac12a202c21cc7a3e8215ad73366a35b9f6e9b880f34c24210529152ea9a3c478e9c8c723f93fb24636b9f875a0c477b7f2a4612deb4ab40ee996596492737c9111ff45d5ddc7c037ff5debeffb9fd33b59ed736e9f361fd6f5fd80f9065abd21d084d7978eaf0838d8379dd71ea64321835245003aaa5219f3a33a2353e2d53e6ae8756c4115f4e92c19202df538ebf1cd7b3b07300332a2683d16dd261413b3c5fe54eed95e9fdc14ff5cad4fa11277ae92819a0577145eb03d6f73b3228e2cdf6c83123bfc26d1bd78acbbd1ef3287bd4361ef73c38a5f04fb8d3cbe44e43f4df265ed73961acf63ac70df599e6150e9785b9f0cb9452bb9ac47eedd372a4902d2d4965bb2a6a17e900b262bf137625a8415ba263ecaa51ea76372dc9f02ee135119daa924cdc87b409fccc611488fd5531fc65cff3a384ce06aff762a6064f7c887faba32eed39fcd106f9bc8ef34af7573d8aa38d628441dedfe3b7f3d08efd032fabef605eee99c80239e944e615b98e496e70cbda8bdc192db9692441f2b0b212b09a40caa9f2fc834dd5b99dd058b5d0eb6512e486a7e4cc6372b08470e60188a9420c313c08bbd13ca2de202eab75485c5318029d3b1b5f72337e1987feb40eff5c0cf525dff09e3bbdb7997a3ff088199cccbe655f1d6ce4a7fa8e57f6ee15eca74bfdec269553a47d03877658ab2bf0c8896d18e04e4e7bfebe679bfbd4f7a4f93e775c9f8fd6566a34c053b5f10c5591cc317c0a35aa350e2a64b69ccc7698570d2fdc26d64d0759e0d742dfef13285b8f371dd585f0c7bf5b9eab8cf9b572f5e1c82da52575e797cfe4d23764ea66c85e4e9d0d5ad71655f2e1bb9c68e2600b72961eeb47bea8d568afc1c72f76c91aa890a3cd510f3c8f7fb083ba4be3ff510985c89b3dd2c16e190867c560b19caa07d6393ad2ac07371f689457cad39983fcda5a652a4c0a58910e56421f0cdc40de47f4cec0c5cc940add324360919b5acc508aacbb961643cca64ecb6da50bc8a2f8ba38e92a69418f953ef6d07e9df7bbb417b738acf937f671f611fbfbd37d3c8e77bc1f8673dcd363cf127001c7d264dee111a34e25035463087728bbd3116fee85056958a229e2dbbfacf738cc55ebb968c2afe37257e9897638d7b10ff230c0e9d3397ffe4c667d0fd2cbf2285aebd241c7b4618d2963b4900f289f99586b6e31c1be64f2161761bbb49a4d34510d064a91a2992604730c53165b95e99678e39668ebe5265b5a72bfb4d8afd81e0a9e0fab50557364784070e424b920913acb43fc651fd0c4508fa15e57cfba6b7cace578a7bbfed097e0d9a6d53f720eab5af847ce99e40517dff4b2fe2a1cfa6f7fe73bf6526c3875c4f13306ed737f67760dcccd9b319fcf1557f9517e9cb08017e926c097b674637fabb934df2dedba94ccd216faef064f90efd3d48f792a709e68896d2e577cf8284b96ce3b6f9f9430c31c5034ae39eaa019b24de7651e4046ba0e0b39493454440a79110981f487012ac5c265145c60475fca17f410b7a088fc23264e4ed9635ca08758ebf95f4f3d0754d7ef4b79b17ced16e5e19c36fbeff14b5e859fb5485ab3151c6e8f3d68fb98fe9b799cec914b38ed6cca90e62b8458512d12cb6a5d7bf8184dd2ce53d08f19d5a3ee7dafbb8be56df7d4b3eceb5ceafbb8dd0fd7e9b9afed718d9e7ba61df4517b618d4090560905986678e071366353365e062c88fdbac0cac97c3a2c7dcd41111d8ee9b856dc56269bc8fb4497dc33ac262c6abee2527327a39dc7d04e6a330373ac25d6701672e809add69613aba5139586ebdac2567d01e77b9a269a7a4c0c9cc6764342c3a992a977d6fe78e9fbb8ffc3bff7767afc0edf9426a5ace25779b0e007367e90dd1d732de3d1efff1d8f562eb979ece3a5d3e6f76c3218bae463ff93efc85cc9cd1346eaa506e24b9ed72bc42fde8fdbcbde923d86063ed80e276ebe133fca65710cd3e743dd0b2ac4279e9968e180f33d58da827840ce518074aa3520e46a4da769486965131b8c89ee504951eb5aa070695d517bb8c79a669242d951a18497a3837f99bab9d8a0c26905b3748f9a9c59f9defb6efcf45ceddc97354057b09d3e8c7bb8d31fea594e1c4197e6a26594142627c46b294515a656ebf3a409f364b02aaa9d4fc1ad30d2400235c19c2dc5540aa4b0bed0d12dd5d934b1d18e4ff09e5b69e103362079cd630db671e9c02473d432406d9cc3c1ca924e5240b2643fe19bbdacc631b2e15b5e9af67d3e2a4d9316742b0ed6b1de74eff0efffad78f49ec7f2758ee9937bae5d092bf566ccfe8e1fcee24b9faa9fc4a2a684430d596c8e88a5bbbc7656c4998940b8f174a6c553b68c72a79405b84713abf375883d22efe504f3a535d3688e3b518e665127034ad49495b0e081325793f496b643176562111b770f495ef9a4a8b7c4da1a57e51e2d47200e6edef6f9f87bfee30b6d2fb98df5d9177e6d9fef35fedeafedc73af8b4656c0fd70b72fcddcbb8e4863a9e2848caca23b6a384c696b1521e628c89bc72a2c0a1a2f31ef85422a6c994728119ccf77ec11e5796a9cb5c2de80431b71d6a1e83845a0a2cf466b682a9a0a0aa13986e194d5542a123acfa97973757ad3114a5fbd89ff7e92895f6dd6bbfec63dd20378bd8566534fdbca636e2e6460487b5724f7ef67b1905aab8507518e02c1abfeef9e27de0758d8bd7bcc8e7b853fb79d7d1a9363fd61b206dfaf63dfeee0cdfff0bb58455a2c334342ef553faf3dbe7d0bf81bb0657e2e539de956094267ddcbad7d76fe6d1f75ebab45697c25b9f4b42295289ade63c909eab413fcee560de311e2b0cdc3c1d738e7f85b9f4d08429324d1a59ceba553eeba4aa5c11282526b0f33ab5890b2723ba6b2e006a497070801c8f06ce0336365ac85c931743e39af7a8e73fd69b5db8be36a6f027f2d349e331c8a3e0cb3e9ed7c21df76722e4fb5ad8aa3dfa656fe7f1233c31055354d439016cb330d2715caadd92a3392e98e3ebb58bb9db7881b293837dc7304330adf8843611719698e30199a62e03a913e5ec3e0ee04230047c3033120b4691c20d6362c726ceda2d52b082c215405d55b646dcac9e6b45db81f1f7baf4ee9fe75a36501517b83f034991824bfbc70a7df8951c328f7cbb573873470e96c39ff5d2eff9822ff20f68261533461a9fb2290f5223e255e7da8ccf8db08bbbf0815b778d1f40ee7769eee7432838c242e13ad2cd4c766ac4329c8746b2c3763a88488a84dd34748a37ab69bae7a5aa5639f8b5e2c9802a5ce3004de7e0829e295fc75f6f92836f3eeded9e369a1eeefe3367e541f69c8bc5de244655878193ad0af8b0d00fbae9a6eeeb828237dcf1676aa66016d9ec544fe0a824602a79e60c09cfda0bc2663d6eb0efd9d082c31ef7e7ec39f7d17ee00becd7e42da7d8e1f7cf70873df1bd3cdbebaf39463efce63636a44a0a94263aad239d99c9e7dcf775c441159e9bf3f9e7f77d8d7281d407fe9773bdf2ecdff527d8ba33f1c4273f0cecc3c0e9840fb6617077653bfdeee25e6b1ffb087ed18b66fd2ed6ff339bbd0d3952a264db05175defb7bd9d477de49d0e2f9205b1c28f7e46dbe574b44e825484dcdc241616899e6bb4f006844215526784b2e481aa4de35a08b95ceb4285472c1710db284714028fe014a904705e4f79062ba2d2d94a55bf96d0d399e52c88cdc6929a6d74365670515dea89bfe84bbed32be471d3f4a8d30f7f9eeae52ee38d2bdc02eba41b7146c4ade01b831675e0e7b2153cbd0fcb0a79bcb29309ddb1bcf69209d3d87414f82cd4fc3c9df17cdb2c346710e6c29776b84b743572150a984df74b8e526c032ea1122b25a1cf9d31edf0af737ef1d7bed0fb18df5bfea8eb70025c1c073dec731d06c88c0bb78eece12e32beb5ef57e0b9ed6349c73c5f0b36b13e7c783907efbfff51ff3881b311a796bc8f8cb4451a34570c6252aa073e497ff91df66489219e22e6e7d04b0209dc8960b8dc34b13dd371201c445047ed3be04fe00333d2726999a14f989be8c2f7c06620d99d498a5a60588dc3f5b0fe2e56a2e7c8e14e257475aa27fe72bdaf5093d3afeb3ae2b2eaf319adf67e1e273ee1cbe2a004a231ed1c372a9ca5a77081b2d90069150c73f64be655294afc8033d6e0a2ae3dfdb71959d84f2cf8cbd75346f4663ed7d3c1d2c639828c24ddcd9eeab263d434c2ced35d22e74b5e5788290d53b425c429447e819df31fe7e3e9d7bc886df8155e58bb529eafbfcfa26852f17297faf1fb5e0617e4f78e3e123323ada20b6035be5e51a6232d998e4a9fc2522874eb4ef182952c62bcda080db42e910f09c320a6608b7258c80c419fa1ad60d44858c556c530c496a01e4d29b65c8de4c31d6e87d10ad20e07624bd8e8a38ff48ff5f7fb18cbfe320ffbf7f18d7e7f1243d56131dcbe9277cff338e5612f8b6f70b4e1b6652c03c75d003671f37acb27961115bf3ba99ce92a1ba5ab020638b803d2920d2f129058bf3ba2988969c5bdcc3284055ac9e07695a309d1059339db0a3d5d84ba065c926b73cd99d05254ae72f485263fc6372ec24878ffb57d7d8efc652a4d8af79c0767f04fefb9227e2e97cd30701e9f65f271fc537fdfcbfc4e16c0312d6185ec0a20e03db0299c9202371efdbda736242c971db6e49c5107cb626b0ac602924b9f1338c1b9b4564a6d08943b42e49c52a6626e6ea512995c0f05e620734bb9645d3af6ba9986b9c9922ff8b1fea5bb9c276bb039ac6fdcdbf0da617dbfc3b1758dfd3b37f66ee10f37623aab235b75d21e964901eb9ee7851cc7bdec7edfed39c33b3f434a1ab00bd9a68b7341996de9c26a6ef144764970f780b9ccbdce7b203a9a2fe91020a38ab0dd50778a420a46337f3aeb4243a958c18e4e61132a31c3fa60176b42a0b2ba17395b704beaab029c8b557d15335887015228f34e6bffcc51fa11136cc387b87ddb87ec6ff73bb1591bea3d0fc9e11ef71c5d5fc727af5293f0719f83914a0efe7a89ab7ebe3dc77e2febbf35ef13f6f1325c1f836359387405475b6cc85994b9bacf1cdb252224f6e1ee3a4c664ce040ddbadd1d8874455c4b11b7bbeb5c2e320af09243eca3ee0eb012db586dda90a702756eb7ca460f2b92ce65867394abc73940dddc903f392367efc41f3951bf23af0fba600cb290a38df0412738480feb1e7ee9c79ce1faf9d9fdefe35cc71816ad139dd52137b588a3a38dfde7f9d5a778d245f23dd4614bed7a1b02b641c0b965c059200de96e267d3ac57904d5860548c5b6b5939c82855e2d5645a504103ab7704388e3108b9a943863ac0f4c5f55f36802cbe54466c984ea894177b890981a55c6803b08bf882b7ec7c73cdca13ea7532295acc1fd977d89c603700d9efad3da1fe35ac1ec592e7f9c8fd6f3505e1877d0909edecb82158b8ecd30dd1a54492a20fbc514dbc493f457a43130d79a6d48e9de67ea97b000908543b0adf62bcbf1136bf88820dbc82e8d56944d30b706ee24ad98f206dc42f7abe2b7beb28190133c8968137d97a7279aaabd089ceacbbe3eebebd4debc8cd7cb38f320d322eefdc87e09014a233d1d848a75215520e155214b91b180e9f17868c7135773f38d8e82b424562312a50614a07619c0da5f0fa19f6f1f6897668972f598aa2de5de2e24b29a83914296b7275c92a4c411b59a5fc2af53efacfdf215968181887bcf3152742e0e1bb04a3cc754dff2705da8eb9ed673f7e1df8ca7797cce55f0617e3f9173c7b10ef70748aef20539feee65fe647a4f35eccb4e943ca7c0cf412974a4f99693454aa4517733986b3564454a7caeac552e1ed9449125874ae860bf9c30b2d01d5f5087337ba65186ed9039cb648ae74b5e03cee132b2cd35c9d96da43b8b703d3c8b3d4f0a9685017ed2f15e6cb334d1e99d0c46079d940bffe64edabfef5eec851b63660fdb999d56424f55b21edccdace1b6e7789b3edd29b39bd9205df92370f82dd2f773379ffaf36fe6fea88ad7a34c048e1672f538b351951408c401d2426e662270b7b3a9dc441c6d66b6ea6676fd181bf27136c5bb99eda8d974d4c6bab33de80f69ab6cb1feffd9fbb62e4575aedd1fb46f48d01eed65a304a424162107c81d1077a104a42d54e0d7efe1a1aaebb4bab4dab5deb5dfefbbe8315acbaa443233cff3797e3c30c8f5d4f975766af5b0950e8733e83da630dba5c73d80a73d3cc8f2f01d88560eaa53d7dfbebe935e9dbee7fc3ecbf12f5cb7f3ebeb6cf499db6726bce171ceac4420753f93db5be5bd74951efcb4102c172128a490b912ed1193e62ff6756d1eac9d718c3397ac54e9b9691f0f8208e53e7b0429241d9e905ab2c67cc7ab75251f5922c0919f7d26da7cf1293ec9ad6253dd64cea85363f01847f5f0f4cc5eede35a1ddfce9817a56c14709e7b49f9bdbd83c384daed5870b295957a54dadafc96bbed9fe12bafd38877877f87783cf99c4fb67dd35ff4353b2a00c8cac3bf3ccf4ef3506ff6713d075102f31a47b84be06897947ac01ccc30b43b9fe7cb05039c87cdeef6f1fb8fed7c3c68e7e1b57ae2650fd8a7bae106f53ebd95657bd0e9677df0bcfe59075c5ce73be880a52f6a2c1d4928426658c93bc21a14a20c4aa0225f78e56f75c09ff1dc7c54eb36b312edb3b30df6af3f8b177d769fce01de80d3486f93839f139d6b13bfd63f634c05d7f567772348208af1782453c7eeb9590f29c39023742f90d621cb61c64633e50cdba02460a1c93473eb3de3f5b720c29bd0006bb1f2667706df06a5a694ea6f04e05dc8a4a6911587669e638748c96b8f45482b7029c694de269fcd0e1ecff3cf31bd1231accfcfb23ee69dba2bfb4f859e65c8db0bf46313985ee097f530ab72287bb4a19cef854d864c73872005b22a5fa65a323f9284b90f1b6eae878a619919c0cbb806ccf07cbe6c8240a08474a302c326a4761392d21fa606c199f1b04999fc7d8fd425721b59474ca823f6ec25f99f3fafb9d499830ae94eb7e7f8f2e5ebb3ec5ed93bd433239ce82614eb7d567a0356e86156104c220e089f0e70d116a9a3b8ecb5c3204fe60e014c4c6100b8eb973acc0abbc705905ca33133ad8edbf14e94dc52a61c32ca1b622b402be931dbd807857ef4dfc74057e1125e6b5b8ff5dd528154f0cbea9fb7f165fa99409d3479f36bbeebed7be7b99babeacc461b8ab591da23cc9cfd6e614f41627876ba52de1d9c76ca2501654d3e77f1b7c4e65ea6735bf19c90f16827299e8645cba893b789a3dcccb44c696a574e24a6a63603cd5b5e499908ece0de7b4ca0b2d3424f3fc2c4fc3a0702ce5367ffb627e1263ca0ff729e82fa573dfc227fe3065810fa57bd7dfc247f4fafcf3d0ed7e141ec431d833b80ef038036a120df92c29bcd850702eeadf8ea618f6d5228aa2c1f21ad26b20f9da227a56e08d55b4965836dcf65bc2e5939d8505dd7c2f1c6494f1c8cf22674a42d0a5d6776fb731e59f1dc21f40afe8dff7c2d2ff28f721d47de70163dcd20fc2371537f9ab742dd2204a7f9da831d7ebf9f2fe5c8440110d35a67bddc1357178b88bb8920bda4ea3e33f281723c0f032524e72835eb8a2d471536bdc277739e082069d942a13d34331e3b2a54c29d3a5ad0acc34c9752b4bee472459831c410340a79aeb82dd7ec419ef3ac2a9a33cfc4f1f967dd7f9683f87436a35deaf03c5d825d5cd6fa73bcdc0fe6e8be2e2fbb14b63a1683677e995f32f36e5f5f9a598c755e30ae3684e13167da8a0dbc91eca15562688645eb65a896b1b001af2458084517dcdfc5bdf72857593b178085a0b639e55cda244c5dabf027882705b22504d11c796526507007411873194877baa3e53fc4057913dc867f714fc23bfec74febda37e8cb7ccd8df42c8bbff6d19cf0b0afc3d90957c88e0da0e7884b6e7b342b1abda8b8c739e10ad67106f39dbf2ae09c6290ea1cfb5aaf43cd195b79c6c27edc499619187a9096f64e41bd67b66c4421ab6c399ae3326e8961435c12e83b002d38f1169ff4c2fef7cacb0539c29bf4711ee5a4fe251fc597621e21e41d9fa82e312d12ac2c9039a49776ee13a03a55e6e3b0942b59d5735a225330320f234d845d7ff36d2d12a64adcf3fbb9cdc7cc6ea874a5e9579e7367b46e60e218db3299bb6495adf0d2a7da8f41dde2dbdab45512823a2de5ee5ccbee7e8f0ffb71aefdd7b99df8d5bfc09f72c4813ae5b4cff2f0394ed1db598e2f72fc1df67eccb39f731dec140bbfdb8fd19df07daff2736140bd3281b2f523af941c25499577a2a85d19797b6a6316226f4e985733a8b68afed8a4d0d361652186ea908bd12e74549f44355c54f15e94f59d3246df7ca8a390e5455811c18df54e3920c856d8f657f6eeb63c73799efd75bfcbbf4e7748071932bcc207ba4dfeef1dbfde934e79b39f736ef6ba7ce00c4e0da1654f7a95609e0b65eb41d68dd6739e0dd24a96d4513488f44c086210a00875bc7641e5cf80a23a86a04aca78c00dbce3765349ee1bca2c80423a670e0f52937f2305b068e96d935561c4bd97dc19ff33edced1a77f9a55fd0778ff5eaff91453f381724e73c3e7752ecfe347c85306e6bee0e1dcf64deec8692c72202314c77d5e2d960d0e6f5f9fdacf56f6dbb8e7925c723f1312a44e6b268218c918ac0e67328bac5df2f9ccf6edf29f1d2895681f15d4c521a63d7366edd357798ebfdee7b9dfed1aeca91d36c04cd86c20ca4652ae7416d980768f265e0543bf5709a76fb1a7febe5a61d681e38cf2453dfe7fde6ff8bcdeb37e3ccabe615c8f7d6c00d25b46689231b7a597b2514b9ca11facbc35e9e5389b786d6c34889404a43d3144c5869407bb7022e72c8a7712e6eb05f5f769cf80123297557e3733da229c64436ab7bd5f3465560e0698133f34b5850d8fdf3677f9eaaeffc2a13dc4e47f3cb3f863ebd32ff423467e938861af9c439cc48b9938cfaa3bed677c50fb1b61981de4a34e2b6c1ce2652982937c94e831758b279fecaf7e7ec64ebd8e775381f56031413fb35e7931b53652e06066e0290dbff701f336810020d10f26071664e211aa88f5a46c8733036cf084ec171c8314a17d5ae42e9ec87b2aea2901b995d97a9eead86022973ec0515af009edbd6f58dcd4777f832ff0320ff56e16f7f0ec4ef93ca1b719d4c58b79e39b6032ccff817cf9dbd9ee2fe8bb263e62f97c1a5fde28670ef2ecd98e1cfe6f74d7e7cac18a82da611ced169aac638a4a6c8301b5e5b7d45133c12db610eb0e57561d439270f761e097f932ee46b15c91d9cc240935463133f086469263d79a2562140a5bd9d4aec37465b9942a9e39cc4cc0d4f457687885aefb57f86e69c9abf8c44fde2c4adea59ff5e9bebf235ff6e1deaffd74de432d21329248ea5954ebacfc7ece2f5c97fbf4ab350cab9a285d8731d596af0b7361fb502244524a1c0608e5f6304a8ac6135c3335093a3c919a72729732bdf391bd1195becf0083583f0c52379ff90c2d8355d1495b6a09db80bade5a99966645738fdf7387fd8ff0ff0f77f71f9a753ce8a16de6184f36edf0ffe6cc7574956ccca94481a1cb64a207ca26768aac616a0f03e1e4df920a0f1323ef29ab139fe61633ad9c9b355930afc34887dcc122d11c2e4a348d236d078c53bf1cf1598f6799d3fe4cec9c2715a1ac18d6c455b56fc7fbe41afbf5b7cd4c1def164885a73fc3c2c7dd3bfea8afdff38a3771c9bb27dff5f935cdae9f4fa5411b405d26308392e66c215a9a39c4e0aea52992388b240d0a2e169a18cace21e19e8dfba0bd33adad58e516ade2bd3ff96150eef9788249082c3bb51f87b1a120ad7e40aaeb48683e4e1dcf15480f16ceb0ba1cc3e7aad8affb5aecf7747e57e56a6e80d9fee1dacff75009b094d1f4571ee734d37a3196fb699ec9e3bed37a333818e2c8c229e0334535f49997b009c74189137508478a7a43456391de2bc20a4db0bbee086c3704f0b9640f708e30085d3e0e0dcf9e81dc9161e38768bd912b3d3ee23cf100faf6b096825c81d975f1d93ebce5d5f977cda7ebf36cda2576fe46f71f7a3f9feffeaf59b72be721499731e2fa102f63b31e2c6c7ec7cad1bd70f07d5291229ba0bb196c87d90435b41cec170efa966aaf9f8f9b46316f2d015a65e57079f08917131e6321ef556f4dd3026ce352da8b4a6e090348b9c826ac46699fff1db2712dafcec7b1c7efcead3be59a6f716e27dcf063dc58cb5fb9fd37fb31fa2fe0b7387242aa8079cb3b53af88819a108ec0dce1585664a2228b26d114a4c81b6422366216ec5419ec6323e832e11ba1bddf6363f433801c8436e8e6c8db611befa8403a301a3b58fdd81186c714c828d1c4e4910caec08dff5bfb0d0efa55469ff5a4d8ef3978beaab39f78a2cef7efbcfeb997e0ba3a6ec6b110b6fce6aff229a56a7867e8484c24a436ee659417a92bbff1090ac262e830c30331473ea37ce7db1aa93ee704e9082fbf7777904f2897c330c24b4af3092ddad82fed1de3aa61a6355c208d425498c16df1cdfeba97e0034ce4598487a9f076a9ebff8feb3bc820bf2c8f7c9bbc552fa3673fe2f0ff73ac775d3eeaaef756a92648945ce268bd4b78eec645bb66ae771f08349b192057946fb0e07146f54f9f9249863c262bd2faae658515eb68a404d338495c9d70c3fbb698e01dd60fe69c727fb192e3cc9942b6b2dc10c63dfe9083efdf8a4973d00367bedacf71d8f7b3557c1bfb71e6a57fd63d4faf4fbe21bcceeff72ae9d6cb1070904584f8b095b4f2384748a6067e644ede6038228a122e5d8b8a02ecfd706413a836a1edb1b9cd3ab1428fbeabb174a6904cc8375aa08132484da378400501a9dd84d4a85d5aeef78c5aff337dc327bdf7d9fc53f80e5ff90fe4e4848df34b4eceaf4f72625c376feaef02608d33d64469258bd8ccdb90a170e1eafb6442a0cf39276c34095dab228ebde7405799ddd8a400fda2c41d737029cb0c28919b0caa20305adbd72a5a38a0c5a5ee93087f9b4f94b1d0c1de8f082030bf223ebc00e3f57fb8ed51aede4b113471e47571f4593fd3d14fba4d6c1b916176acdda02e2bd1f04916dfece7ec37b1eb663bbac66505a9c2b20d7d600d89f07a311e3929f48ab9c06d86eab18a2467dde3208e7098716d53d64ee295d7d2a8367c31fa8685015233278199df4bc0ed85a3a3cc18095a16c64220e7ae1b015592c7d069a5ba6dad245725aa9ffaff5e3f0ffd1ac7e31d2efb5fcd19bce31bd75907f2b83ad828b47ac15dd9ce0f71a218ea851b7cf0f75ff2d63df351822bfcb93faf19fe7f73a7489e55dea7dcac1ff0f07f59afbf5ef79cdb3fdfb317f7e99adc6d3ba37c9a167a42caba24b6d7b3152e32d722cc692b22e4b798e37dfaa773d787bd439e2710e4d9e7781a37ab87fc5af3e959291d8ba689a31f5faa7f508dc76c4536e184ef78b96e79a4a05a15a6ef7a808b66c257eade17e09b04d2a17d70b84bd02fb1cf4a92cf3969e62cefe824db0b6d0135211d35f24a50cb39f85d8aea7100bd38a05e2f91bd594cac5562ffff84d3f8fc7c0f31c72575cddbf4fcff5af329e631a5409b43ccf5250ca8c8aab12bd771998bd056fec219ad799499ccc9ddcce49a4f086485725290afd924dbb042cd7da79e85513cbcebf380033d619cb4ca46765aaa6e618f1abfcc0c5ce6bb70f26323fb1c085d8f1705e894962e71c0157ef1bf62deeb84b3f7d493f1f95cffdbb9ea2fdfe785405dba044fbd064fe7fd663fc69917f93adec544631d2f478fa10336a9a98bb9eb0d19925e68cafb000e0c32419bd400ad081b9845fa67a27919f778b0608dc126a4106c34a03430325077698508336b2a5dbf3ff8c999e68c223299b356044056d419569ff0025d74df2ef6e96ed4a37e5eeff4dce1d9afbb9ef31060362c9821abcce4eb9881716a0ceff84a8a1058550c305bd8ec0f9f4ddd1f31a22b5eca92779fe45efa1bd5527f66f0c8110664297576eca37cbd8f19f5af7d56d162f2006424073e455b490b48ddf580384d998c9b9ca1ba0dcbec26cf2a83782d05c86711e9e2e878873fe3513df60fdfa017eff4dc22bc4a1cdec42138f8ac471996e1af67f8d1fe66f488d77da57ecf977181a7589089e00cf049eec7065f272e5f6323bf9b4ff2a97079e49ba80f2996be5bdf8b42cea4ae51e8e03d877acac3d1ddc2ad3778351d0695d7c762ba4b19a843848c846a93f21f9bf924004c5bda07f218cf5ea05b3732d2f07359bd091fcc71ad634c06f9502d8dfe0b33dbc38568ee667d009931d8cd5913d070d42702af17da36a929e30553b6608dcb1d64a776838981add4c93ace1e0721f086d8a997be130c3243aeee7a8ba989258518b2c4b50762e285a25413d96706d3d640422c6e3b4ff05e474c3fe06ab8e0dc1ee388e8cc0c9a5767f5bb5e80f0369871a9830c196163163dfffd836efe603f06f802579e2979b0c956d6863b4dc8049948a427b4221b1aa94820c428e3bd329a8e14de26a5649500744fb95c272e5a870c783ee7cc2f739c2c1fdb44e82a1479c540dd60a1581a79a1b0bd796a282e216282a2c14dcfb7b2f21836b984ac492a7cbe3fde022f4ffec83f3d1bfb84899346459395bc5582f7ea13df091ff9baff3c16fa78ed836e3de3f608307cc119d39cd7bd2a36220599b322ee52ae7f2a27f79856081bdf07723c8ab181be11f7c1484d4242676fcc008ae38af52c1c39ac526352e22a5e36496a909c8b0084ae9a638a01e3b91f086de25eee3263b0e1a5bda705cf29c860a6bfc2e5897eaa5f72d0facb8f787446bb04ea274ebb938d7bcbf552ca3c33492daba2511075e9531de0c4b1de7d8023d44981cebce06f39d6fd1317ef5b7cdf23ef2adea5b0a965f88cbff99c97c16f722d97e8a9148ef671c9b7a7fcce3f81ebdcee52d35a1e736127797bf1facc8f7e050e977494eb831f6d6cd465887eecc30a8d6514f71222e3ceb4eec8f2fbe07a1ccae3fc7c713e6fe31d0feb45777b64cac85bc511d633d1e8c565bc2f37887fdb9d82bc8b21ea65080e36fd88fbf4c17ebec44b417acf4f5671ab506ea75a3aa418d5732413e9fa1b064724a908097a5c4838da8490d8a4f71aee18ad3adc75caf654f369508c12667826e368ba888a3d5fd95d40ad3b6e6746227029349ade9979b0100f037e0d2fc5df3c8390ba1e98099cc730ffcc0f86378a1f1eb38a3d61201fedf88bd70dfec23c70587e87d25eefb18d1b066bb0288766a831f54d8b4bae1a391e4d7d4796dc693702e59502757d0779eb733e4923449481d77790fb19d0f7826153d062e88ba223255a63e7a10d0a8e03f3c1c8385913e8f509fb824eae749e3a6dfd8bab2cb8115fd6d5984a4d2c1a3d13a4feac97d3ef6ee4bf09b491212892e8c871fb62fdaff8e3a0f20da9d964baa7f6d04c6ce4c7cbef3030d79038814156de569ab5f69dfa1b36c9725179b65f298b2f9bdd9c494d8b5c63d7f3ef4c3df34b50f8f67a274b4de50af531451671f2381305b88323a18c119e41eede96db18ebf4e0c7feb2cfb7c730f977ce82bc38f7d13b3d94417ef4e33fd7416fb977bfa4837a29009427797cfa7f73f699afc34959f9436e7b3947b8e42b798893f30cb1c13cfa0164d1e8c4605d1a8ee60a0eed14e27b5e79803149fd7004250395746bc01cbca586d163db8081a906bccf7f86e3d1e3c2e6398ebc716a10cd230530cba7fc0a2c82b8d4db0fe4e6e9fbfec20e309f6472f8f35a9ecd54a06d2c94be1833e926393a90a725aae40bbca437fbb81657a29d518def0c2e306c1a6c3223139949aa9a071a7155e4cbac6c93b8bf28bfd1c888ac53482ee009ba090ff2f37aa7e7c08dc41915cff87417cf3dd90dd7b8497ab4159a237fa2560b849394cb1d2d3d1b239ecf8cefc6df33a7722db730a853f139b6cdbb78e36bb27658eb68b71201f48c9efeee75b9b8873d2f0783ccb4bc3b53817085eeb1f64d0987cb98a36a8eac413221735ae44b6c343464c38670354bb88530f266d4b41e55a97fa6cb669e4020530142097ec0b90356b8b77efa055f4a4e1c56e12e3355ce04bfa2b7e4637c9154e8e63cafb84a9d629b547f894371b18dc2d7faa6c73d80e2537c807060e0ee6667dd4867faebbc05591ecf7c925deba790a004d6ccc8ba45d878b2e4143ba38d72b8e19b2814cb26c0a209121bcf98ce07c2191212f1424488c78cd7a981b81f8efc8c7a20ebb13d3383362ce50e3b399a730f316e75713135c39ef714e26fa196de7b3fe5aafe3278ad3d3f3e9f535dfe327eeffe16bee451268c4564e9132ee7e9cc8e3d03917fc670f0af9c11c05d2a6a0b3b9eafd0749052dd52d79aaa520d9881d77cdcc429c08fa22c06e18a6c671079d219f48b55d1c970c4f144253e8a770bb1df70f830e4fd0f0317eab09a958ad19c2d47652ac85268bd62007bfce3fbf9593fcdb33c3eebb7a34cfe95dff7b79ffd7b5ee24ffb436e90e313ba49c4b11ffd5ccb7fd6cd6ff673c6c8bc0ae300fcc48caf9433dc841395a7428a996983d0514d0ad1a32fb28eb1dc09b5d7c56c64a4d1c33eac2c2f13cd20b1bd75188e1e438d1f7d31c419b20d2c7211479e490bce281c4544e8262d4982119af9c89b2e5c3ef83be60bbea067b7c9912b02af2fa921e23ff7bf9b440ceb5420233e61d7bf7cdd9c6651aec3ec59b07aca354289ab5b66b79c3bca98b3e9c00756aca88c7cd31b601b4055e490010eb933da49d3325343d9147072676a3bd3d37d88bc9d1a37436ae02230be9b8a92b598e03d87d2c065130585b7cac4c39e7f9803f83ace6556a2950c815eb8569ebeb837671ef43fe5ecff79fdfd3e9c87fe34777fc2f563b7b8d70719acb3d36ce08bf54ff9537cdd3d7628d55baab9ccb4370e18f78546cc37732db46dca12606a78152e87112dc15d08c84a9af84e0ae46726096680df1324f7c4c41d66a3b570f2b5703228974dabecf540099ddc018b2f9cc6e6105721cffd4bf97cd34f73a6d3f7bcf75ff3654ef1c0b34dbc6e2e2233d4e688cd5ed65839c0c20588fd95da059438412111b5e544e8b5c17a126782bb14e413b58a070a059ba49cf6aa7cdcb14ae72150818f2c169a3a520ef09961ece365934bc41989e432eb5140049afaa719f80b7cffa3ac3627f9fb34d634fffc393eaf7790cbe379a662b43df75c5d8791cff3e9a2788473860ebebf8e7bcd1745def9a259cd6dbe4b395a6317ffe4c81ea4c02be788f4c4f468ca727b3129765c809a18d99084a386523c569c94b4e48e82641e54b2cb386a67c09bd2893508051f92e2434ea3bf8803f23c33f43633499e3a2d8d4dafce4edc1a5fc33874469b4490fc29cfe577073df1ae7fb790c203cf35a5e367e277382a121e74046be2aa68a4c3cb38e28fea555ff03bec9597f6e4b9fef40e7beea0ab5c6c6425d7b3cad36954bcd6b9ef6b55cf39aaa91e80d92a7bd31772ccef81ccb5765945fa635dcb19bdf83c7b5f63abc84e8993dd9deac1077d0fc73cddf6f0bd3388ca670c99e5bb79cd536fb073c6c52b47462264fdab9676e630fc0b3bf217b9a267793fdd9743acf8e20ebcc19cfc2216c1fbbac5c5f9cb43ec71f26353d3d2697978dead8ecd2336c8fb67f3be6f7a971d672a468fa973f0fb3494e129ef79dca30007bfe73a5feaf9f7dee738a5c3974abcfd1eef39d8fce52df416d171c58f3354e7759bd3fdcaaeb20381217f2eb49681280ceee465c2114ca2ba231a69a50913766ea4056e39941a9b0f6d20f28a4478c5dd3514a5e7c7a5dc51e4f9cce51547681854648dcb78200a1e72cde982ab2929821d060a60376805baa95fd5bcc0686adf602e5d636bdef3e95dced77eabbebbdff0b55fdd6f6748e471dfc0aea8bc3ad4aa91c5d09565bb0b270f668a2450ab1ffff9b8e43777e9c27ac1073afa86f58270605e5b6bce20023123e50c588944b2ca8a9651ada7ac227be1d86dc2bd3a843897c2ab4360b741511719428fdc78e8521b4319e544a2078023bc65b61c86bd228bca02d245cbc028f619cf1d598cf2ccc88b051bdae48a59e8ebeb05373c4f93ef8ffc71ee111bf83135a79fe849b6c5b7e05f30dfdbeb83cefc603f87f30657f3f3885a24952a84ad0d3cf931a04cd74184266242769c35bd04ac2311b28859f7beb6f609348c982319977573076ac40dbee23da1b29073ee4e0dc5c05c9420f71d3ec44e0c5247f959d98c7d07c53e4238bd8663fd020ee65f3ae72576dd9fd72bbfa00bf617c4a2476cd45bf8fc991b9cfc7dd37ac2a469afe9e189cb609fb892a6664e84cb690c073d2ff33211c6c007dac3cbc7cb6b2917ccdac5e541afc5eff9db2ec9f53f3ddb336fe7e9f59b5ae017728b77d7eb872e15e83189ea0beb89fe8dea8987f802e4a9a3bfbdaa29bedfcf3937759d0ec0254fb29efb598f2365e33a33f2289b68ea178a2f685e64a2d9135818819674b1c26e1ca19a50a917155ffa13d6fa05a78b8ac43c523c58c9092ef42cd66823a817a4e57497b2c0e040ef9202870a62935e334ff577f717bd7a86e77e83dff782829be489dfad7bf0995e9df3211e68ceeb5d8701c7791218320c112a68e595dcb55cd93f6c7ca6e7a1c886be31858b82ed639e635ec88dea51442a05694f688aeaa1020cc6acad301b95be8df633605531f4a8ea894fab1c52ae622a3890a6c20178d807d7e41aff360cb8d13229f94a8d419e99b8969fe65f821bf1ddbc5bf7a0979ff1dde308f78950db193dad77850fec31018cc58427423c0c66068aa92b398b701746b199f5de84185faea77d11a3fbf9bbd66985f752e0cff054dad33a7f8edbf48cbf26f43633ad278cb6e7e79c88619f1d62e4633ef6b8e655774652de0446fdc88c07337346162de564eeae07acd7fd9cfb5dc80660d693245ee15cacfc5eae783f47ba4d21fa1618f21b2ddac7d468f9dc9d025e60f7cec84c0e472d75a515f07ac70bb05a506c64e3efbd985841fabe4fe63f3e53fde2195fd41b82ff3c6ef9757e91fffa3c4fbdb2576312f8100f898b87a1a38c54146648952d35a621f57ce2fe80cc78ec525741e57895effed8b315d23ef22077918305d6c47cd884bd57488d7fa6142d4383605e60873062b1480eefe0f741dccb1c0309926254c81b73af5c8ae5241d5e1ef4e82cb2bad4b4745691733fdf737ef0cf735fff720c805ff27a61aff76df5fdaf3eefd7fbf8129f19adb84538e614709c95ad27ec5119dacd373291cb0c59c0378954133c50653d97c8f358d8389207fbd41e2eb1fd38e0606afa36ce899baf151b568afb9db0b30d81f566c18049cdbaa72b9e2426f15221d77f8b0ff65e5eaeb029c36becf60dea4fefd67da97fb66fec767725d7f0804f3c1f7332152eb63257d79c5b328420baeb3d14ba562c1c064251f4346c4aecb04dcc6a2760799ef63c4f990c792fef7c7b748f4b7f47111b042533b0c98dc07ce888b11fcc453e20c6140a849bd0e4bfe71abe12abe7c88b360687d8b1788583f26efe866859eaed2126c9cad15e469ef1a4d74ebf636ffdeeedef1cf382fd4280650adbd7382b6f6b15e5ebbbf6eaeffe650cf9df825935dacec450ab31783cc8af149fdd0bfb56f7e2edbac77b912ec1564641933aba570edf1e730ed7de8ba86843e4c905cdfb19f01e63c38304713304394d45734f6c502c2664c64ceea9b2dd057048045b77d421e3a0f0db38c212dbb921cb3c5690f59cab4d5ab4796220260ab28dab7aad269e9754594f29421993effb982e8e3f8a2d3ec4ee6efb7d8a0683d9aad85e9d137ae2b5ffa437f026330cc7b50e31e4681bc3239fa171557f31577606d1de072a0a11ef5931eac94a6f49e143dcb35e38f690dc50c728d3cb33d71a9e65f7dabb7190fdc714a2e2e4ff90634dedf39afb719eee163ec05fad7fbc2b075f397546b91c1ff5a271f00d92634dfeb4fe75b6047914aa1683bc4a1db2098afd30367f80a46cac1904252d1048c4e39eea1af2128d53d7ba4b10667750eaccb57b05b4958a116195759794d2c5059238522677466e0a7890f552336499b2946b3fb28d74d97c5493ff1c4b2b22bb18a26d5a9e9ff57186ef2d2ec141365ece1e3ed7c8afc70c377f3487f562c81f4ff39c9fdeb39bcc0a6563b08ac57025c52f2ed177ef9d74e3953dd8bee9837c40c1da585496e10b5e08ad934525d7199339ae3864c26f55a5784cad996f7b85b2752201c201ab7fce995e4ae14def8c7a238d26897bbdbe33a67bccad5968b7f7dcd91bb1a85d9f790dad3c21caf6efc081bcb64f731f0bbc39ce4588230ec027f737be514de5ed4cfaf7e6fd7b063cf5435cd5d7b5f1a157a4d4dbfa2b6e24a61ec4b0a6a1598f71f43048a0140ba7c5d2517dacadceb7d54694d80c5dec678e97e3128f930a4dd404cd52074f12bb41aacaa7a1c02c58218717002838aa13bdee7095ebc584e32bfa332f98cb56bba7be957938801fcf4f3fdd0b70b8f3eb59447609e4db5773bbeffa435ec4ffd1f34cd702bfc7647b57cf8b56f16906facffb38aed42f6fe5e17f67c2fe5b66c232076d3ee5033ad5eafedc5730ad3c81df0f67b68f45b37baed55dc76d6724763b9e236b88dd3a892103594f8672a2e34539da6791126a391a1263b8e62b344e27f99c3b609251dbc42b3c95ecb1bb33b8c9358177b0d50472dfa7d84ecb874e41b9ccc4c8e4da8a0343dffbeeda500e9297f68b3e61e99f712e77a9cb8d7faad7fee3b54fba5c390fc71c622cbcc3df05eac4f17dcdec7d3b63f15e719c87f65050fd633377788fa3e990bb569e96b9118387763ef997f0679ebf73e6a02e8317f0aadfa2f7f4f59a27193fda042b3fe142d9d7f7a0b2d60eab3ae00547845be19d591873773df40d7b4f44b05ff07c39772d2ba8b4cbe1f75dd273290491d2b4a4bffcde9108df67b0e9c3ca6b316cef4337ef169127281cb452d42e2e475636c9f3c495f72147f6dcc5bff7832ed2277a95c28be613ba1bd9827d22f0eec57cc2cbd78dff059b90a2a265e1284858ed06bdf78d9af16eb1f2873e57f7dc0e3662f5a38b0b5c65862c5595ef04ca4b5c3e9889190fd3ae89d208370baddbac40a6a0719f19c38a9a39c26e8ea46befb9a979aaf332847c9c690c45f4b7f0466df1f2ef9f334fcad13683789d3a7a9b40dea92bf30299a3b79fd99f232ece2db8324cab4ecbef671919ee6634defa877b791daf499169cbc844b36130de2b21077ea97229ec9ebbde90947a1c3a641e0a12873006d41eec1344f07ce2516117c602494f95ac53466bd2321bfa256b290f604af1cf80635f512968af340105bc83a021900f3fc234f82ca7204bd4ab31e8a42079fc8c63f1410fc6afcff6b190fa994300ea72f1aa7f397beb9b96a9838c832d7a95b7a4effac64fcf3ac2861c835e465e1d8bb65e1c74c1af3ea5b7f1e8e1f75a25f42ae940999a5e134741a30e720f719e39fc3536cedbbceac1fe957a3513de2e85c645f8ea7fe16b1df7feab9ffa2bfed541be41af9ca0c920ef92739f43567d56a3f16f83777492f9263349318bb0ce4a7deaa988bc63bde637fb3bf7205fa73b498462ec5a264156a726182b36b202cec794b33d771e4102a63b21f084525e526da145a98edcafe18a4fa57ed8abd2abc3899ec6455da5ce702839eae9aa80a1596f63c120e5cac613b517c514c491645979e12c8a6975a7982f688efed44598cf37c891b8dee9ae8ec1519f1e9ff9dbf7aee6c9362003f65ead649c897a9caeac295d8e7820481194df0712acbbb0f4ffe33dc187efa95c329c096fa83e9f3b06b3437c7b037f202bb9a1dca2892b6dc8532dfded7b0d3ec5f457e2c949d39ff843ee802ea89013f6791387df4d6aecfbcc20df66400e95438cb09aeef124d831ceef94fdb057c6e33075a6c3a468db7944ee164c0f78a40cc6eaa982a8f30baf558eb6b0a3271c6033edf51d759a6fa47ce7175c7e56ff80edff438c997d568e5632c2fd09fb9fd4317c6ce2c8abded9b3bf098f3d73bd5d0c799f75602ba3dc4804decc04eaa4f924337fb5bf334ff175716b9f9a9c53d322894baaacf4ee636a9be12adba828bfe7aee571a4a398a90077232b7146a1df35d65df7bd9554f789e97d93a27593705408b74622d230ae721017dcc15a6dfd4aef33885908f52c2ca493ae50fe094ff1453a3385ea70072fc00c786b87bf7a7747d5715ebc3bc6aecfeb9f75647f1d9f900a12961bd4691f316b8bb4683c1a65ad3fb1bcbb3e1f843a0fb15091af91c981def089acc34ae6bee3c549449210da3b61838e41af4845d6672b2f4e4b544b773d64116fe4c412cc4138d3f5235969318ff0fb7ac1153d9bf87a9cd7fd41aea560dbace4cd05bc0fed6cf570837bf36a0eef74575eede3846733bf0ebbd7c4064994999334ca6769c5fa984f019e78fc0e3c0c48a5f7b4aa97b2586f829ec78c918d6ff228d16a90aee2165394870cb8cac923c1bd98bb88f98c81d4a8a1ec9ac7a444b95f8cee92b011b292130aecc11fe39d9b16483fe54bbf51dff369ade3b35602ecaf9d233ae7134c51159b6c8229a9fc96b9da90e3d14f21b0815db557ab60183a5a06262ae6dc7b8c7b9ef0926c7c146fe6487f532bf993adf838751e7b8ebc86d9fb5656019c73326013cba3bc76c36513315b72bff09cc45557d4552e8869c4b0988951798a51789e86bf38643e881f766989f5afd8c4bf1a433373f97621f0391ff5e91cf82df2a320adf4eab08f939ff8bcfe792efcba3e2a81bc9e95752197cd4f2cc0e39d59ec70a16621b292b8f29c599fef7dadab985a77cc2545c68927a8174bca77895d0764a2fb9891bbb0680355fd18de19431a5456c72ba955496251e9655aaebbd88c07d4e085ffbe8fea6bfeca6567b38f3fd377e739c23fd77787b58ef608648efda5b34827e8272d509fd97acc0cd9c63ad82cc24740ca519fc27a9e21b927abc248cbd6bb3395cd23ab6513add34add73474e17135dfa8e5a63311ccfa984e9f8112e38d96746dd2f224bd3ca3365550759d180d09e1afe6d312fce71376b241ce5cff3dc7f071ee22567ff697f637c9a7ff8f39edcf6e487a0fe942bba1aa306633a1d84aeb5c695ea1990f741a9251743572e9bd9ac57a6efe4f30ce6fd0c12404c3c17c8e281d14e31cfad4cd448393a20a69a5363e8f3956504c5c3809623375e598d2a0210567c996aceb28aff0c0dc23ef2f93ed3ab278e5fb04a1cb44d4bfef8329f83ff1cb3e82d66dcbfaa6f368bb8568235a9d0abac1c197184379ff77b4f6fe1ebb64a702043d0240277a949f20c3e1eecfb47ef37a7be90ebfaf869c573aa718e4bf91882008425a282a36f6139daf81372b7d0c4f719b67089dcc48d41564a9ff7389026b2ee0ca30b60be171a6d03e60f92495e63543b89e1d1397a00ac421b627bd380aa0e3bb94e5678367faf735e9daf7879beaf65f0f0d9234ed8c9563ec59c6ff27ad7f71b9632f27699f9020fefad1c8fdfc8ee610d57efcfd80dfb383af8b5a3ed9b9ce95fc9a7a9cc6c9b39e8e09fecd273cc2c4bdea5267e111fbfbd073fdec8fe6bbc84188eb699c91fd5a907f3b267725ef3a95eae226b9f9a9ef1660fcfdf29baecae1c6360799ad7326611dfca08afe2c83ac9fdef67c56e32fbf2fb3d1c753538c5f1f2383fa6c6001c6c500cd191d3f0bc8febee9140fe0c8eda64f2a34b458ed29e3798adbbac523d2ff69d6f68d3d7168a9912a1a3985f49474d722b8870e73b6da934b2b0207be17c1f726401dff5be6193d0a0249c396a1397a8f19df54e966b200a63b01097e634bdd525ba6afee739b52e3eda416f75eedb1b5cd9ebdac785aa32d6fcf4011a4b37f7e3a2dda4103ca630dfa80a5b73471581d09c89960645bd0dcabc4c97cd98b979851d6f85575e31476415e8acc591ca55414a09f920806a1543bc491c9ca84a9b0b8e24b347b78d3b1caeb331d00b97e85fb3283f3ee44848c4b03ef900e798e35d9f38a8d3523707ffff979d9d7ed02774acc3eccfbd60cdc1dea5826fd599dbf2ff3ef1d55d57cfe8e2ee2f71422f91371d0b72eaeb7b1983fd1e97fc6defd4d7ee7dc97379e6273de51a50738c913e7a9ffad7e3be324f242c1f62a39d494ebe6167344fcb6645edf5264592d2898499a31dc91fe00c067d0af074eed613de2bbe403fba140e5789f3b8519ab8c1ca367c3307a4aca7acc785e4a44a8c6627503e4c79de2e04a84341bed25b5aa765ae0f3aea0556ca47d842873b5ca7a5fabfd2e1c778f219db297c17131d6d9972f4e34c109db99e8e213264f81ab3e94f7dfce9e44adce093ac1549e4ed3fc76c798bd5f4351d27052aa4a3bb2337e78bf58ff2746d0fabc03871991977df075949d68991c7dcc4f20e8efa836e6366b10f4bbd51a6350dbbefe00eea26ed1a3f73789e01e2cc9d11209137cdca5626a662fef871939675bd88b8ad4adfa486949807bd120d14abbc4d99bce9dccbdb3e8ea93e6282dd62d664f0b59e9ec3b9f141361e1efbc853f3e81f6d8f7817e605f36edd2df233bfddc3c1773fe82fbd707f6c33d7db296774f46967a57c8c85ea8fb6b3bbb2e79dd575509230a8eca1cfd5a3a00ab062bd97ae6fb2655370faa34ba8f443580cb2151e2b8ed654e7db3bd83492b5f33b8397a193974985302b75ef47f5ddc2193e2afa30485c7b871d32f0d18f8e821f7dc0ad90dbd7e0d0fdc1fcd43b9ee78be6a7febbe79c5eea268180721e1ae58c369fcf3b05b799e5f8ebf59f64fbc37ee7e35ce0b5b31c545609c04b8c188cb9ba0b5684929597a8a25de25e0e03c3fb199b12489d8fb34842123db4a1e33521b0362a22bd8275e447f99c6b4ffae3a68845fb33e43a8ccb514557eade77b821387e8c4b9d138e8634d237f509b3f2c57cf17230f8f39eecf82b3c7f2fcfe41c8ffe1e87c9bfc9ccc0db1ef693bd7cfdde57f8fd8c412cb014286721b5ac042088b567515823df94f731d3b1281b368fd40edbed3d29bd710834218c6fd302cc83ca9a6582f0ac2820ebc99c4fac19b3f56e069450c51a289bedc484fb6439628cf3d277f8e6b67c31a778ecc9a7ff6b9e97cb6de5f5f2708c633b55a2c74b700b6ee337fd5af3ec931fef7d56c93c1d9fb92daec063a2d49b665df373218029586353c3ee59c4002fb20166418b8dd1eac2f8f82cdb17d46fc683fda9ce1fdc22b7f7fc3be7e7718a77c273dfc0f8d46f706d1e82f7b9af04a60b319c71a66d45f53075bd3ca60a482e130cf395ef724b1af5788164cf389e5190df2f44abe78e3df44d14270efe7607724ba0f5202e74eb97014c284189438a742591aa828d3f1e7165341bfc219fe1976b0875d681556a7a7a26ce39a55ffd851ff113beea9f7e9593fe077a5bbec845fe0bd35eb4757259eff99fcf291fe4fcb4779d3a7a73eafb7ffbde1963ff0a8e9904e895ecd537e5d453a2eb892a55ce6c99fbb0dd935efb29e4ab1bcac7636a2a9d9538cf206b12c887cf316ef8aece74d9dd3779739a93f9dd19fcb8517dfe79bd93af1461900adecde88f6b7bfb0652acf7427042800f29e455461f06be815b2a34f3ed3cf1c5e30d6d165967e508c833f6f231afd4bdf6912f93fbe0f3e7fc96dbf48bcf599dfd0d75e4d59f5e21d3a79a9cef4c7bc115c97a15fa603df4a98a9846439fe5d380aa714c953d777228ca0c72c640cada6162d403c625f2cb1af8b68ee3423dc62c0f98d36e44d84474a54ca27f6c14e05838604c0a7b1ff3182aadddf7738917dbff2f9c03a90f727751bfd62d6cff79bdb39d33120174b67cb273579dcb8ca25cce273c4a0cdefa3aeee2a2d18bf1c8a7c6f796973ae6e5a00b0d2525258188741f0822a55337598964c879cfcb265634bfc70e6aeefa870de67c190be4a613d426ce77238e9015706b4ab56d108097f2d2b9ae9283eca91ffed359aee016b9cef37a67398ff091d7f7fcf7aff319a8de869387414c711977239d18d8f1c57e3f033cf099de65508350d443ee3c9889ed4181240e91ae78894b624a633e294ce12890ac3c4e8dd696ac0041917529cd762a52c398b5824f64195764a200192eaaab7a56eb14d6fd538ed0ff7806f6551ef184edf98538a92417d44a6e328f745ceb741f64111fb9ddfc6bef82f0cb7ca74af28d94de7d42337306549e9488529e6ffc62e4a76133a085d64c104c233ec650af92955a26bdfc9650cf99dbca0da2bc96106f892df761912f69a5e73154c3b020351b3f0ed262d409ca57a250dd91e7fc92bb70c4b5074b2564f9b96d6537ca4be05c1e39054ebcf8c767fb7a1f0d3ed6c7afc477ae7ef40c7edf63a35949073421f4dc838f43ab9c30a3ee30f45caeb1487a4ee78cb73e8b37996b2d59f9ddf4c78d9402d90ba7313123c5dc1e0674d9b864229749399429f584e2160840de642e97aa04930ff0d2ffb73efedf541f3fc9e429073cf9ec6edc885ff37c370e3f97d1c3cbbbf1b48f6bf9354f58d80ee2cc903d17684e2b3e53b01927a2de1dec67c01ee10c728cb5acb34a0e19528f62a5c60147436c079bc4c6309990312e5b8f74cd9639641d17b20c8517dc41c588e1adb292f414229ef5967307ea31fd10fbfcd37c8b3ef7a2fd9f278efbeb6204ac63937732043f3338dabe8c357fef3bbde5dfff2a86010659f984a970e6d33fdafc8ff735a3478efdebea50dc0662f97d88e170498d0150e3913f33f1149740fa05cf63287ff242995981570c16804cf05221efde2f543277add2678f2d670353acf414b335c030ffc935eb58540fb2151ad0ae7152e6ada9295162d6132ac01167ea029bfc02c7e077f7243bc423e006f7e48c91707abea7ff1be6c1365fc95715a490bba1d6ebb99dcfb0ed31da8df2392725d6b5eb9b52a7ddc8c2a01619d01d336c18aef2ed82ea6dbcc2639fcb2e731a4097cdb7391b211ca99250bec7c583411dbc16bcee0f7e21136a1916c110a3daf908d7e4b3fcf45baef8a91e3c71c2ff45eee463bcf1573c3a274e99a773bb09cfa84fafbfb3a7b303452264f9796dd8be25a744231d5dca573274dac7b11fff0a4ce3536d4fc5bead073303dfc5463e0c56f90abb7a93d9b91b3204a9abef9531dac515c1b33e2fee002189818af9c4dec505ff298135cd4ab98c69d0f2cad299393513fdb053939c27e326f40d1ecf05b758cf97326c7e32aeafe09abda46ff415c7d213b6cb3f9df37e7336ff8b4df35f834d733eb759848dd4f43eb3cbfb1b9f5f9399649795ecd5399edf6b8eb368579e277770a20a8569540c55392a08933483acf79d364ac470932c9b3b698cc64a5bdbb9abc230227bc63d1a477a1d778f4666623bebfd1e477c933a4da9342261a9fc19503065b9cfcbb52104867ee59b8c61422fee23c45a8dc12a85a34d22d819c3e4921c52708bdec25e464113c3d12e815a3ff93a4f76faa37d9dfda0eb7a10052f58f130489937235ccd79a105658d4e8ae156b17a903abc158ced84c6450c82c1cc18ea9416bb54805d663eb47e65ad94130c7cd7efa859ec7dbb998baaee52a8b0d03e480502613fdd2d04f07de1c1d49517fb4189207a26f03a16c3ad149fd570edf7dc785ff3876ae9b02686799e96437daae1be7dcf38cf005ce51fb598e7c122222d29b8171af986405253a63b41ed7d1a499f5572cbc483e12fbf6f081c8d535b463e9c7614e53ea1de6061d77b51c822a585a120db0725daf1150e95510f89892a1c298a21df2f10813eaae157f0312ec7f555fa84f14fba440cfb44f8bfc522ff009bfff9f3f3df70fafde77b4f702de1304fc7402f1cfd1997417fa379df23ae742cf68d8cf25a3dc9e08b7d9ce71caf9bfbe59287ab60480a7fc029ba5fb82aa16eeec59ab0ac20903ac372d64b461c3510259ecd5d3560abfc5bd6dbfdc2b506d8cc97a48ff76949c6a993cfb342d67ec1b162324c21b753a3bec7a6321284fd8c061d11f5ef7ba62eb275a36d22fc262e47bb4f7b6a8f78b637986b7bb5e6f1d9bfc44d39e3e65e89dd8ebc69321e597397ec79af3a451f86a9eb3d2680194184bf093768a5e3990cd682430588e935a99b236c925c01d910db7b0c290a42d6e204e4d6c2ae9932d15a9a18494ea68b72dde32200010453095043df63245c80ed888c141e39c8fbf4d8dbfdbace7829cecd95f7eb84ab0346853cce747e6a5f6f958ffea017f878d6eff673ee4fbcb2cf35df30fd70b8675152d48e9ce47e66903bbfd26466aa889b799e9a16ca0c34e614c5b26cf0dcb637c9eac7663ee1770153fbcc0d5a5ce2cee76a2d7b390b85b7c4ce68c3a9c499d8c3a018fdbc3339c8c6233384fc2b7dd3276c23e10159caa75ee8ff83bf84b57b7e6e1de81301ead441cf36f0376769dc888bfd7c96599341dd24a2cd4f77f0c579bed9d7b1376f3c30ae3ad370d4cefa9c60db7bc4a89e05dcfa99acf248469e17147514b076964014b05276aacc4bb2ca373363daf9b030d2834f84bc9ffe7254a53d6ae6d4f2d295da92ee7b2f6c42e362b4f3c7cd5e5119aa02334a75480c402ef5959ebebf82baf89c73ec5673d9cfcfd64c043192f1abe77d7ecfe84eb986ab7ca52d35d114535d4886db39c761e8b4838c224bf50f202c87067633189ad20f4d14f1526f7039b2e6bcdea428f769a1ef531755d88ebb45e4319f011173f2338810e4952a64c9136c6666cc300c8bc054427dd8eff699af94447e232bfe98baaa962e59cfce33e99933aad3eac9bff9209f7db04b26e992e847131f7ca773bfcf6906eb9fe7253cee450cab5975c429df9dea18c3c3393697cc51ddf0febeee0f3ffa96c631cefccdcfcf33a0d7d57f13a4264937aa33119ba9fb633f3350c5edd89c4152d01e79dc24946acb62b07e5c14b88e410c92c8b37849907f90d90a6f257becb0d62eae722b30c098083251c5f781d49cf289c51705c1c9f87bc7a26233e737ed19bb2d07d0dbdf3963a22ad7cb5ffae93e7d78d1a337bdc1eccbefe6a8ffe33d6bbf9139709e77fb47e2d1b33e7d3d5b71dc9be05bf94ae7fed567be14af0ee7513e49aaac6593691f446a33b739e4aeb55ab07d470bddf9626d2a63ddcf45bc497af9a8b4b76506f87607c1b739c3ee62a5e7825b3ab5c9064fbc0d35d7f0ce448f7337ff298bc7410af4b7c511dff107609c81e0a638e5384f9d7d131f9ecb2b3ff623fe7e59a7256b0ee79c39bc53ce59df3fcf85fd653eff3f3fa7ff1bdd9d9924cfaa7f819c46d88823cf3871127fbadf2ff5f324e50394b418607b3496951cb09eed9543a45f0e43510e7741cf76296b9dd0188584a352f5b981233d544eb3e311be63c570a08a6247a83fcc22d66646b0a72689428aef83de8aa5d1d054e0489975ad8006e27d3fcfbf479fff7b7329e7d95db4cd60f1f9ecce6dfa005eaef9ec4b646390a715aecf71c035bcf32d119c8411efe328eb12315a71472f0545774974e4499ea7fdc3f579b7a31f78ee4d18ff6779aa9f7cd373fd7d9542d0483134fe31fcc1bf5cffd9d67d34ff7deee7b802bb9d5b0ee53551a2f114048f739bf4b4e06b11a95d5ce443695a55daff5bb0db3138d8a658289d7eaad3fded7c7c0b5ce8576b9eee4e64e9ac44d5e13c66f4b4ce95b55d9f45c4a70cef08d333ec705bade43d31c986c211a551d09371b3cba835f421e9173600e238db8be63c92804f724d0a0f5007946c65d582eb6fa1edb792e6ebccad2758d7fdc2f1009b483b14e8913279e3b9cdd121bedb1ebfbfe04d1211e3170f89fd1e9bf8f43bc71a4e52a2eed7ccf0db19a3d3fa71c5abf367fa8f3fc307ea8891fb5a47bccbcd995e331324578efd2b0e7d3beb7bc4b81e75a9d0c5333fd20baea5377fb3911159a790bce5d87b8fe320d8f3f3c0e3f76b66cff6eac8d5f3fee71f6017fc7a6efe16df80d7ef0b9892af651fbefb79218507ded9d6f7b80fdd1bccf02fe948e9f0a512d9e14e9ed735fa632c7e1d66fb8494f537c1b59550c21247d62c92f5a2f21c2638e488c4a14bb6818922593273314156e2289441cc162b99c4457b901f9f156da084622cd263e53c40b9ca13c23dc1391e722377c8f8bbc94d66a8098a6fcb4504fa57f7e95a1c4393ef65e4e512f2ad1a7fd01ff11772f8197703bec59c9c40e73b090e3fd7f1290ff2d1fb672e87ec3acc66e1add33e9f61a7f6e222b716ce102c9cc24cfba0fb7fec7d5b77a23cfff6077a4e1290aef170ac0444892564033903e27f1002a5952af2e9dfe5a69db6da8d33def7f31cbc07b356e95013b3fd6daedf7551d34b2488d74293796ce22429e4132b5b8b0bf898d89d93d17c1cda1a64b7c36a41e53de30d14150c66c6a05ff07b8b971e8feb9f6051dfaf53fe6b903850b22b6b20efebe5220e12b16993e899fbc53e1b6b4b84752fa3dd5df48623e624ee914438cf6a2f3f8ed57f3ec87b7ccecfbcfbbb538ef4cf62ede778473ee229f9cf853c25ff39c35372a9adb13ef3ff6f70e75fec8943bdf3f2ef63846fc76f6f0bbec5bf5376b9de2853a5af7912948d9dc07c25a872e3b219c81aa3f9edf04995ed23679cfb2cebe78edf65869e638d025cd916438145059c0445eea6f5a88f216e296b680ae201b5875e5607032582b58223901a8d95f5c4c5cbf673acd935ceada38f1d1944c7c6b0fc1a4b7a25ddeb73b9b3573effabfefc91fe75ba1cd2c4b10ce2940629f365ac65a52abddd6bcb184d43eac6989afe80f2110e6daf5868a999237966932975d59aa26093b841978e8954c01bc75539c8ec66a42a8e88204f09c82de66ac66e87ed427b9532ae7a667db2ffffcc17500eefd5b7f8e52657f0c9f66b0ec8081fe338af9e0f3ef465fb8ea2db407846560e930ca8910f350ba0eae20adefb94f83ed228a32344801e8bdbe15350595562481156039399de80f1b80b29de50ae1f98d9b8f3a85c63d8705fc79644aa5b44e8d1d7a33b65e6abb8f86949f7bafad7a9e0207186e5db38e1496cf18dcdf8dbaeff750dce9653dcf237cf8ecc196e77fe726c0c57a9f90d9cf955f45630ccdcd13aab493f13789d3ac3edf33a7ad79f16ff81be4a168dc64124c374bcbb3bf85de84a1d9af80983fc29064da8ea18fa63d4850215a1d990d4feb19e82ce5c38be35ed479d5f2b7f11c58038d250e35f9b1920415a789b8c0d6f33d094c4d16b09739715e52335a5c9cec6ffbeb257f7bae655eaa0671f0f7c8e3dffc7b0c1203ed64c7d7e6f4fae716fefdbdacdb572d0468600fe416d729de97cbbd0a3b12f3acbaf5a8bdb70265d3448c6dc4d58b7898bd16d665b85b231947b2dd4d12603798c6d057dc72aa6261f7038010bbb7de0ceaf35b671c54437c16e73af34c1fe7288840327c2fd69a8e5f0bf988be09b99e09d1268f5dbb7f9b9f379cff3428937f1e2530d2b670812a19e9e71c2137d88919df24cc975b6843a162fbc6607dcf08936bf5aa5c673bc23dbd90dc6891deda0b79afd279fa19f1287efe6b97ff31d4f621dba9f45076eb137318793be9fe78e3c1db3e132a97871c02de28d14afdf2fcfc45a7ebffff69c67279cfa71d5e8d80c9ee208efb17bbff7f799fed6aff9577e6304cef3ac1cdf7fe16c38706c7e8829f8248fff322e279c9a6fb90e8eb1a20fb99b3ec0b8bf9c29c77a98c3f385e7928cbc7616e166f11d6e9aabd4d0129d55a0cd0c7d73a8317bfd0c8edc7e179d5566d88fc284928a02f5a096c398b9e580016f224a7c9f8ef331a50a52e1435e421f43dc25dcde2ccacc9c827bc8ebc9232b2121ce7012536f4c75608420e7a9266ec8f389df134e6cf8c8dc66c4239d67b6977ca167f3f7dcf3ff9b3a492071bdb512ea5b7a9a57c0e3bfb477b8cbf26d6af2fa806ff22fd074b15be210162e7f1819cde7c2e9eaccf08a0470e187ad9d1aa8c18ee49ff91ddf1a1b01f5f379f0757dcf55382fdeb4791823ddca67ddc4edb3bd7ad95ea202834c2bdb2ff344941d0c4557244ef748a8574a9d4f93b19afa656b8754dbcad83cfa155a32a46bdf81bd826822cbe168c151e41bcd54f668232817b22680013d17359fc5305f07057688a937bc6a57a7f7fe3f678325c2b266a2dbaa2f70cd781fe38fffda87538e7e5a847095d5fbda9d57ed03f3c01f75d1dcdc50adef7cbb35a4318099ce6fb839f27db7ec99f637f308e3b08f4dc954cec4bd351fff8449d5cde62c33328473e9c86dc249b1a81b3fb4651c87c3410c3390321dca0aae82424f16dc5e4f21aee97824fc88af4f317adff7952e9d9b740bcfc55abf83a5b882af44d63bbbe794537a7f3f7df07f471eabcbf69797d10914b60770ddd858581be6e42b8a644c809cfbdb61bde093edcc4477c4c1335a5a3bbbbbc4ae5ca6d4b742c4736ae811a524a091bd910c8a603b648999df4c61f3205d5c60caeb79a4adc5b29519fdb9b920feff8f69e428e7c7332f409b55e8497ec947c60e9ce2579ad79d3d3b8bbc3cadd4d12f3ae94f8b2fd321dffbc0b8e00136f40dd6bfe082f1ad2fb0191bca6051be8c4b6d62c81f7d43dd2d282f43418028c896b8525317dd671599b2dbd64fc2e164319660c1561b5af2e5b4f7dcc0d44f92611c56dacd226f446c4c69b51a6467b909fe8a07ef4909b8fc6de76627dc9f7faaf97c699c443943181b5fe1a8fd2bf18692b512f86857ecdb6d8fdabf97d551026f3047dcc29cf8ca1e5256132f0b5bec8ffd75065a3bd3f998daf94001526411a76cec15788c7d497ff6b35ef732f21e18f3bc454d1e587d6f90aa9dcae8de22b7c3fbd4e156c0731694ca57a64a789459e9a9aed5dfccff536a8e0efe58fd5c4bf221f665999c70ffbe9ce3203579911cec96dd7b87fc45741ce3aab9d8cedce33e85d499f93597dbfc3ae784b5d794aa787fa8fd7afd0c36fbf8e1651a9b403ade4d18359daa1a200d8d71e499be58c1ace413657b235ab6ad747999d8ca0a4a9e27e560e30b891622cf03a6ef336338a375692c68f618b281e5035d65b6040a965612a1061bad3d357333347292016b7a41fce41fd3c3dafbbf821c737a7077a77f939f69bfafafc0adb19b375ec691b78da3b2dd9df3afb99a3ee9df71ffb38bf6ffa222708e724c4b6ecb68340be1e451207d276c24984b2225ca4dea961b5a937582781f9bd92317300f1d3de2301824ae27fcc8dbceb6c309d6f1a36f13232cf01da3b6c5fad29c33b0491de44bfd6b905560e05f9f0775bfd7a483b65985ac77f5a797cdbdb096a9f9abcdf618680d92487e15ef3cb4f3f79c1830adbcf5e2166eb27d4c8a34ea502b7feef747aceb65f7bc420d9ff5789eb1552f6d1b4a73847cd68285d0531e79282846ab8563b909804ee88e4058a80e57dc94e87e90f5f69645de1d71d53cae722fd418a4ac7994634408ca739f596140f39c14dec88f9ac719d49b4574d53c58a58455286737eeefeb8ccfe189f631f365225493d6e46d5cf1fcbbfd42c0656a746fdf3d89c1a9fb64771f086fbd7078398b46db44c04639da78abf1f1619dc37f1dfbadf6e32cf779c5af632057a94b866945b4acf779f7e39a7e793ee22f2fe36e4e6b2f16b53285ebd93318ac439deb8550d34c9031ede55ce8fb8e8e632374bd010d870936763e8bb7660e7a4ac160430af444dd5f7deaaa298d9811446a2a686c250e69160e72181bc214ea9e8a06e17038f6cbab9e59bf315faff89a2fcbe5eef38cd5819bec34977fc4797d190bc5cb81f5d7f79571c01feeeea663bbbb3935664579193f4be99b44745b6937795859415ca260da23949a44aa1a259931e9a5c02b1ca906975e9550791b6ac26360ad95f9d3884dd9674eb649747e936a8f85803ca4e11061804a09e42daff8882189698567c4c4137a5d4dcff610eb7fe182fde33d790623d87e0f43fdf7ba50e941dfbf7dd164bf203ec92bd5a8c8ab1440461aa94d20024b56d0250579908c88749cd77f199f8469a53b250eb8ba6fc428afc5cb7bd2eede0e13569345fc184bd9c72aff84a717d20ae924f21073e5466845a5d998191cb90ab1ed424bca5def69d6e73e8eec7528f8405470e23b7c82351ee11e8f5386469833404c75c73419308692ac2f21b7514c6dab93ac5b33349ad39ed7a292d10571ffefe428b78b68b48f7bc5c22a5303bc999be71cdd7f21570d3387e4ca616d5a0d412264f3b5fd1e9cd635fe91fdce37d2414086f0293549232b7dc49d9dfb3d38e4fa2ec3dfcad4090c518cc205c3928089111bad9754b2226048a90127c2b9ef24809a5095b37278836de84e618e1303360bdb8bb1d3f0b4525b02f3b988ee4d0547b3a082200501a0c2ba8da9374a6b66328d67891bacaf9bd7dedb4eaf729d67f4fa2a7c1f8beef137f6e51c970c5ea7956ca4f99bcf6aa207f0131bcf8a23efe9732cbd6ef7b8925bb88aa3c6fae2dd7e2670f36e9d9f79473f6526c953a7d3f216d6a9335cc6a25b2d9eedc53df7d50936731fd7ca1c708c699da96b3ad6922f04daa6cbe7cfddfccef56e4fdf4f77eb2fc26016bdbd3fa243acf23437fcac0bfea28d778a397dcb17f7525f700e6f3a904ed6c615eaa520cdb386deb5ead7ffa9dce342f0752ad0d3d9fd5bfcae6fbba397e265cf9d07a7b6dc9e3fca597d1d7bb8460ec138ecbbddfd766cb73dd68a5c1653b6833e2864248ba00bc150b2529699d9b4c4453800aac35c8a99c971c0265bdce369c8ba966e577d52a25532ce63ec225b3904488043df9003e5783e61f08699bfb6be4665e258760c1a43510ffa428a2b632e0f357e11068bfd5df2b24ebb73f8ec67aee3bd1e8bd1ad5fd6f5f604a3f9efc4af22af9989e6fde79ee15009ae12b7c8aa72b77ef67eddf1e716df5ece75844d6fc6236df93d267ea48b39cd378c223b10d057ae8a7dfad3228562a190518ab24e08b29e23b5f2856e7c8e75e8682dc5af4d68e71573b8ef57120b7b652c8a513f7778119abe256b6fac5837559555067fc275548f605aebe2657e7edf0d97ced1ea85875874f9e20b3cee997aad3fcbe59eb4bbb74bb6e9ed335ff2eedefb75e99eef664c6e85bd5a07422ef1d82b33a006296f1cdf500fbee846b8d6a6fa764de437b8525deff0ce2ddcafd12bdb9a97ea849cafa3f852dbe2eff1d52a224d7a0b77eb762b05ded9bbfb7d78da9fcbf58a98b63b5aeb2a73b33e2de19388a4c17a340b415373a6726283c1f7f830394cc45739905f3b7be50a7a36fbb60e63207439a387cfbd8cafa99d8bc8df32c13137cb47029543016fe751fe9416721200b2f19d8dc998676303aee66ee37301a7d3beec19e573528ce6a9815156596602c9a340d2a1958efdedb0ca6cdf8885a4739bdcc7cb61bd2854880d7e52dbf101566eff9d0e63419acc0cd6074ed8c3f85e687becfee6c801fa0d5dadabe42bdfb4f97b8e5ef8d80fed5c5687332c539e0f029a6f898b09867a43b55c86104f1360dd7037db86614b31577d5c423b2d3108b9a24ca07506ac510c152035f76650cf7c4e1e169a7bb8b29689a19a8c712b19e73537ac5a56d898dba897633dfa26b7969938ba486ee13235f39dddff3a7eff2fe9987d16abde9dfb9ffdffa5e7c5de2f5d2ad894aa188d42d06d32a77304f566427b31d6c458447c8e8de143524fccd4558fb2976d3a1e6d53a0ad39d75a71bcc5a0a17e9f6d33d1cd796f0f384772512919f6fa2661aa90911765bcb94b197f9a7339bf6e2c63e7ab79cdee8e50b76ff5bacff866cbd418aee4ce2f10cf78dfd758df133bf1354ea17de6357d9d6b388f637e8e2dbdeecf098eb8f99dbfd8bcc675ff0f737a3caf3dbcdef9c5b1498e77e397fbe20a79f2b36defcea3e73dbbb3e357bbf9d9b5bd3f976e2fe4a2e7d960e170c62395a7ce6090503c9b1958fac27285db94a99649eae832a8702e4d3d2735b995760013337f8a0bc254a966ac508ed4d8633d6e45343239f43bc6f95845a40acdfb41c8cb01ab9a4ad993cdb44757e52b4822bf4d057a6b579dc454f6eb53bfacfbf3f181ddda34a5408fdffb3ca563d1f607fdbb178c7bf73fbf8ea343ce7e267ee7a0bfd28abd02ffddf37a3de4bf6fe11113f0ea6c7fd7afe31d7b197f250d2c424734435ccfe9a848ead13aeed52d058db9e0a309ab110d44d0f995dff908b57e855a69f3242b9b2080e596966410f36ce347cd24e4642b0578cc2a0b7154f6d255dbb8fcd573ceb7bbbd220d39168c5c977b23927922ba23eef1ed78bcd5c43ca9abf9885fe9b45ee65bdc77277ba34a4def75edcc07353b12a6d5f12c7adf97333c18898376fbd24a85b74edd37fcdaa7ef467e7bc09304ed116ff23d4ea8ef62e8c29f7b0dbfffd95cb8a1cb7d3c54744dfaa55d762ddc9e6ae4be0617aef69c5c5bf0be1f7f84e3a3356e5398e7a98b235e124c4cbe59a07bc88a9f83c4b02d59754952350d75e5849728126c38538e9e519ac3a426093727560cbd4a56e8716a724a68309882e1726eefe3d571e62a4b72de2c18b1b1468ebc729df32917edabb8f7df63392f3dd7dfced1694ef61823fc5d67f6794de455f2906fdadcc768dff07f01f807f9c7a5a0b24a0a6650c889efe4dc67ed03292d9b457c4a2a7e93b1b6cc4a64918a78329223e2e82ed36aa2205ec515bca5259c64639e27bd57e1f12848693ee5b6b428f5da2cca1f492f9fa4d14e686f7772395cfde3754797effb53ae0a83b7a9d17c777e07579a5f9d8ae1c3eff9fcd1beefc73e9e71a966198334d1fa26866a4e81bd91911a85eee8c6b7e12043da51b5aa71ad1f1614cd498f07cae1eb2cba37f09888c0f8b1667a54a7f5a49b01e5aadbb6897bdc849adc309a2345319336e830c2b9322cc1057409fd823beb2af3b3f3d5244c9deec8170df731d959345a27c79af92ff516fe7ebe76b66da544b73a9e59ed9ea722849b74ef43eee6eff37e1ef5182e9bcfa8b15201e0d4648f19c03d83ca2263dded71043aee892d8dc4c6b3d8e866d2d13742a0298ff824a0bf7a56760f71a19e98c9ddb4226500725715a3fb64dbce0455b794a15506950e7bc2a5c80cc26343207481ced53f96cfdf8d9fcecca04d77f6fe19ccd30b36233af06a7f9dffb84a9dfafb7beb35eff4f3ef5abcd7539c5c749f0bdb9bc63ae86941a6099230e539f21dbea68859c4c60fb1819c39f566d4b63aee4027302cd78f46d5dc219047b9434c05d8588ec8583e254663ce85dd878234ac26be0fd856f5784a1c8d6666def8a6bc93d7c543bd3bcb0e76f6fcf62cc7d117fbe853ceba37bc9c936f69f3fd97d7e86bfef6cfeaf7ae84e97adbe66b2ecc3db7698bff40cf3488b81142b2e58e2454eb79283088f5a40bb7434920097d9a415c2a2b86a35ef66a39175ec90b6dab08c1ac20b52a641e9a68221c748f0b95cc6dddb25e4524ba878ccb829a642575b6cd74839450005f9737f7c4767bc18dfc17d64c56a14de67ec56b7bb598f0368e469b638ce0f8f3e5b9218530998be60603af4b743ea0552b492d473e4273c5e04cb93f077f89f53377eb4e86b04a44a767e25963e63b7952ffeff36abb7b775f3ba3573284b972866d22f639ee0ffa058e1a4e17d9de2355e6c582dfc3b0b2a8aceddd7cd38568b641d54ee6918eb003cc20d28ff3db1f168dca35b1032b35ac998cd87a4e49a54c0fa706d629fbb1650c4d4989566965d974d92604f98fa26a46ace030a6f69aa1787d5d1e45ddaac8dbfdbb8fa3d7fc1fef635bcfb1bd37752d9fc6533243d769855633c107c94b2cd03fcb6dfd79bdcef1efc201bc705f9e6295bee4cbfafbb37ae1907a26bc3c3378991c342fdff503803ff0f10206ac7bc21a5b8a26113c369331db04d5f09e8e7f5a249a58bc429e1472eb971d0e44dc53c0dbccc68f49396cfc9e68116922188a39270f842320ca868506767c9b6d396b5972dbae3340fccc50f34400eb9fa8d7bdd4c75bb8e41b7a0bc195ced51cecee9c9d4f7e6cb73d72a85d16c3b15bc9296a029e4f05e275c0f3a739e76152693805304a5ccd859df7aa921b6cc04271ddce05a19cb533ff76384e6ab2e591728228b7e7e3c93a65388a6be267403d9052e7723c32c308afe598dc649a8cc8a9bec8f7b5866f0797e224ac5874ab67be9daff49daee09fbdb4b79f178156a9a37b75fb277b08f4ca206e2248b2886cc8ecc9663e2631b539c59c6c28c46140b199e87c94da3aa2228729f51e59858d591f74cc186ca580c47788154314619727c2ee7452ab99aa328344d8882bb2e2e5e691688d623330f798dbe3f8eed7fb73bcead398b7f75356a8578eae16e1304feab83d704febd537f91cff3ebe0946551c61900869cd0cf4a00e5cec9bdd7db9c7419ffc0e1c6ab82e3bd36a55e23bceac8d707194959af8c00631cfc7d4d6655c75beef123ba3c13628b3b5af73131bc3415ce9d55cfcea0ebc10f6665113ea970a920addd0d2ab92cadb66f01ea6d5e631d5a315168dcd8ce60173424fe256bbb18978939ddf2bbbb17fe1abf6e9e4e90bbe81d7f356a5a667c69157ca2f713357e28e783367729dd52acf2aa2f73a316f9eff882f42a4e0c723d6caf61d142e8a7ca90c351545be498c7690d4b6996e7f98f3b157308a1ee634802152b5ef0c97a2847528502978d633879bfe6d9ba7cbf6d1e7c8c74007a2ccb16f9025e6cac1e530c0f52fb01010bfd93be7c7789355c3c12284b974c8575cb4d78a177dd8fe9ed3d0f5d60bb76c6341ca6c79b4272f1b67b0a0ca4c352f67406966a219b7fd6d580d6f32630317b65aa675ced3923b413fba4b8bc97aa147c6accf9b85abcd241a9194cb44993c52a5e5a6a5b74e2232f56bd52c5c253231ac14cce74ad883a4901217deeae49eff7c4f7cb2c63fb60593687418a3aae93fc4f99dd94fef79a26686fe0a13bbb35dc135ecb8c0c54d5a91fd1ac9aa1c66fb58e1311e487f3ef97beed38bee1f8b969ccda9bd21b695877cf424a17ea2761748913d5243dd64116ee611c7d88134ae861c47a5918d738a19b9a19c0812e1a9a8bd5c19e563500d6daab9082a7b4b9c7c9a712439930665a492906d70e1f95fd870273994c0c537a940dbd86cf2643bdcef8759449a547c479bf32a5ccf3f33b369e3c82b16157a9c19bb73ef677be093dadbd26ffa74cc855f860de4b917145e1cd7cd84db032311dc4b2ae9511e5b89d389d89001a71323eb3d23165272880a51e691b0f3bb85a373a61b491899914895e9d8dece7963c99e6da6865c0b1e6f9312d7caf53a066c236316a41a7f3f17fef9de2ba5903a5beefda32235aca7f7f8a32f78f0f3b8dacd49fcef70421b6819d79e56077be1f8f3d14eb8501332ad983503ba61e1f07e51ea7b41e546dae4292e3db028949de8110b4d4ffae35130331b8321dce2687447aa7685eb1c12d373539d3fcda004dcb6e6b2b4402064320f7f74ac263a71da7ea1999509cc12517ec55574b26f5ee106dad419d6fb38d3bfa49973beedc398efde8ff7dadbdd5a1a6a1fcfbe502b67efd3f8a5f7c03449168804aaca3535a51b975e9fda920a36e4893979644613287bf894955de0f7b89a42e971d0ddc8a821196a8a8ccb1a1b4dee830d90b617a75173234dc5a686bdf10bfdc0ea5f90d9b8f1410393431cfbcc3837c617e790312beced3538d3766d1df2b38d31a3cff6df45ebf6c137a4a08e32b8f303fa85cad35acb056bee082432ac3c776acaa75423a94ab649296f53d1163e27b3a9610d8268b44900f629d3beefa0043b64992239a6d5d065467e9f86ede3a26440686e25c05b5391810beddbbdbd381344cbe8672b23047fd79ef9677129fbbbff163e64c6f0691661f08a23add9f99cb22e3fd53e3dea3af5b191eb54d8ed6edd1ee68fbdd4bc9dd38d795d0ff3526ff8b92d7e880f0bb47ae664fd176cc3376dbecaede7a9a3ebf4cfecc124b3f18a976d27ec41cf4a759bb2b6892b5271b3e9025882d4b11e48c4d7b46e38e6c12605dcc91c59cecc7b98b166c22bb455a2dd2682d8d86920b57f6c89ce711229cea27c3be7aa6311c985b0070279f29c1eee07719fed6ecd249177bebee34c2eef551de80731fa3fd04b7bfbff1fd504bf5f8bff147e037ce0077f7dc60ab4917c54091b749c0d6916659bb4d75ec2e42835a558141a63ee77c4c91e31225be2aa8a0a6e322a3733d36b69c4755c28c061f3c028da2ec6c44fcdb20b22ef561a6a9d31b59135eaa45d82ac1a3e49e77d3ee68c6d12bceaff1bdcd7ee6c79aff7fc9db93883bffaf3b9f856def6431cd6577662247359610397ed03d7cd8c19eac61fcb350d87135c2a3ba8bd9172ef07aa22f74ca04762344e18c97956e6235c977d6863c767d84bcbce9a42e467342fb9dd048ca2e514b4368f904d2a0c128384bc0f80a4c87c67277eb1ff5eeeb64e09bd3d1bdf7f8e079ec9e31eb845dfe3199ffdb53fd6b77ebd365ee93d1eeb93c3d738b0b767f7276bec03ddc8b367393c5b8bfe4fe55dc30ff40abe5a5b8c4056fb9d04ed32a8514f59eb89aadbca4a9aa9cbebb90d2789819f32a7e9319741ca361db3d1fdd48023bf1f71df262c354945d0fd468e3dce231c6768d4320762caee0dde67a60f601e503c9d1add32e1eabd0f72adb5752e0f0bded7531ee7f6d5f373acf93c96efd333fe1faaab7cdbe6de7edecff1333fe7c5f5945411ca7373c1b4cbc778450c6f144295cfe9641b54a8f7fb3d7ff7993aa463bb26b152e7c46e3b1367f7af884b7cae977ef5fd8ffdd86bbd6c2fc6392d83426f03d08cf8186de3aa697849967e9577219013aab5bf701448fa7cceb9371005f644ad6c1fc406adc920d679c2187e4a356e7cd63d2e6e5b8f38c37b89462b52ffdcfa8567f212f9a1c8b5281bc2c0691ddea76bb83aea9108bc4ef7ebeae39a8573f3b41030570efe0aa7d45f2936b2f31fda382245725c9fcfedef316817c7417e02dfe0812c87a330e29bc4503044dc8a4dafc02e9ace457b33474da376fe9d6872c28929c68a856eb011e1d0a5e5ca54c5288f69be15f45787eb3c4af4bd99954d19501e4b1b1619920eb75b9c856da8b4fa3e06ed73bfe52935bd36165db3a876771202c9e7f8a24db29b5f8140fc5ae7e0cbdc17dac646fe8d3a90ebf80e5985eff7980ee3d0eeb166e9027d62f0181bcd2d2d5045595e4a9acf71e44d64a40749342a42a01e08b3cfc5d4f3ccd44fb1d1365f694af97b4e802b9cb511b6d20a3f26d1becef755fb60afff7d0967d562cc4c51c5fd7c3cb2f038dfa6866709a7f51725491283f8acc78f6763091159a74217b308afa4e09b7f6b9e8f38943633ba9ddfbdfffeef7e77e486bc0ccf9500eb2e294917885f66e6feda08a4e661b8024c7837a9a1c39961b104e4230e2c28c71e549535cd226efbe17080856d128e12ca1ae6dba858d468e623f4840bb516e190716477d4f17868a007518f363e282d853e88d1441ca406ced3ca3a8cdde7980be33aebe9759bfb3d0495332c62613da5c6a03db67399ae145213c2bc6932d6cb04224d502e9302cde9d8bb0db4d602919c3aed9255daf281956053ce59819619550637f3091be7e1d4d0e394112b283150e2d796d9709a70b52246d72430cffde8e78622ce05c54c9eea647eea5fffe69479c1d59cd11fee9a5974e08bf7b72f5c45f04c1d53913ac327f99b27e89ca6d9911b05bef0a57ccedf89b7a989fb99405b69c69fd75e55c36d1ac2328e48fe3b3fc43ee2803a9c175b789f1ac3c7b7f55f2767ffbd74276de2e85e39c33aab50fb2a8e74a6866fdf46992de17d1261901a6a1b0bd0ee35310dfea4f639787f5ffbfb3967d4216f71a893e7db576d6ef6dfeb44c728b7766d24e28dfd71a2539a0af4140ba567d128ff5d5f733ed6960afd9408d864af6bd9ce6854eff6475af13d4e3f33894e97af6ba04fd6c926ab38506ed9c6b506f245cf999de5aaca5c6f2d4d4f67a6ffe9f7ca2abebfd3b25ae6e9e735d85bf92a1ff5e1f8d7fb779e6301bf73f89fd5217d437b3671d02a39dd8bdfe372faf33be3d8eeee5c3b723b7d5873f0d95d79e00327637c8bb5aaf018cd28d421a948bfa8a09d313826a60db98ed78ac151504c4c1f341e75e0ddb4c70f81e8eee7e817c81801d225750027bdac7310971da2514317e3c99609729f96a4086b09fd9a75524bf32426fdf5d9f6a11ff4cab77cff9d2fe3717aef83be89439cb5058d58e8d531defdb656f7c4af388bef0057c8a77dd687831d51a1263dea56bfad09d5fdd19ebcac6e98e31116300eb5da8622e8b8834852c901e7ba4e1caf63e1f05e08bd0e0de887b50cc25adb8aeb50a13c96c27268091f9282dc338881cf70e54779af784e85eb8185eb89a0e7776a4c34a77bbcf82d71bea81b3e13e757b56cd22f726d075dc9bfe7ea89236924e2c761acf7ed02f30f340d63de7b63ca702b2a344e191e6740e76185fcd0cc470b3d3249e19b52e78dcf5a77615b77bb7542cd914e22ec4b070e44652d535b15be916f42a4645a75c114b4773cca93cc4037c938e839cce7a1a3e2ccf1ba9398fe17b8a7832ff2e9bdfa86fff80c76f625bf94fdfe1ce3cc7dd229c1a10c619b889dbd40f2cc58bdae5fde7eeea37979eaa0a7d8e0e5ec7bbef8194ef03f3a9397b1e8f2b4c2bb3df8ca273fedcf71df5da8918bd7cce09cf62346796c60239ffb0cb5b1cefbb027561c218e4df290b07c15d77948507397d9bf3621ccac29c05a8cc992952817e3d128ad73e0bb64e097709b216fc34d45623e3243d1790cf0698234c77cf43ef6fcd5be5bc611d6b80876e7d397e71fbe0a9ec0cb338319f876b71f0f63fdfb1974077bf132ec7e688e7221ba495ae400232ce2723809ccf2312ed86308da5ae90950b5d793716ec4b5dcc69526613deab121670491c7a46aedac2e8da42a3799e6d3a4f43789d92c69c503eaaa9b856b0f92486fd23ee832c1a30f306dbb3ee6595db632da6390f763f70dbee8ed557ca74a3fc59167cd041f28873fedf7ca810bf0837e1db5112fcb633e1007837039f4b8464b510da70bd1ae25cb9709ca37d4e8e6418d5c5a6153d8cd2cac86351e7b08b3dc66889b8c132a9d661c3aa4499ce6c1b7c92aad72cda85aa68ec7704526d440152d51c3fa7c9d4234fb82eff6d46fad860379a22d732697780d4d64e3c09fbbcf1f1eda3dd6175ee6a34a36018a07162bd58decbdb574478815f1362e3d9381cee082bbc1b68d62ed3d24b5b64895bb19689fe23e37b3db61ebdfb6f72cc29847924b8a27be8e3764cc0dd58f9e828adcf9221f87d530497bde860687e129d6fcc31aaecfe3ae07db2e165d235ff86b3ff261512b4557ecce9bdf755efe397ff33b7cc3ab243cf07965efb8fbcfd5249ee53238cd5f2e95c377fe6b9f44cd7b4ec9f77ec92b3d9f177f7c70e65e7c5787f89a93f7433ed26fd4fbbcc9697c339f76661cffa11c0bfe28eef5d57d293c892bf980a9bce3dcde248875a1d138b42444b1c69151d38506d9069176a4adb52a919d4468cb416e32a35ba6cc9b53966fb0408f7e15031f8ddab9dd30526bec57b05b38ad8b2bab4e407ee75354cd8cee7d2cfbe333e6d4d7fcffbee4757dc98fcea06fd8bac733e6b02e7be5eee33b9fedf5e3679e6ada1ff7bdf99ddce7bbb5709a9fff724dfcbae69af80bce8a2fef7dcc8c462e2a1cd17238f21d6e062cdf2c8a115eb82349eadd9c4a2ba9cb8e9659bfafbb32d10d2e02c04bbc9e412f9086b5f5c3a14bcce031117e9fb0862db43d2011ebb943b04f098d23f5c4356f0960c6c9bd7f668dbcf1fbc3533ea5cfb10f5f9e99e7ef9e3f3c33bfe8cfce4efba2f6fe43dcd997f6c5a2d66d4ad9a30adb3e3031e5a6b6e7119ac7823ff002dba496f701688bd46ecb246a64cc1aae583e9a8f71489d66890d8b2aa69ea443c6a1ad0cdfc91fa7a095187838105dcf0d3ec3886bd94bc40b1933f1dfc024ed6dbaf735a9ff1d2e89afee399edf8695c77c300061950b25604ce848a7a0e37346c64985735294db1074f38c939694f889f468238bbc549c0f48a94c857e1a010b8cb46a1f54af731fe832e11ea0638cfc3aebc39234241c0e128a0d6af07f0a377201b7c477f7e58736e4ebb5f10e93f43e267c3c13ae8b493aa3b3fde7e7c11f73417cb5b61882aa6c59a649c5982569a90be578a1cf566bc11463856d622add85c0416664665ce8a544b1455cdea96802a4191b316bbb10e579328e4d51e45eca7d93037e833912311882d491915f7b098978adc6f29fc2bb7d8b1be2dcbdfc2926a9f6f2d8603b5f78131f7de16fd5c4d02b60fccfb4bdf71dcffdfe5013d35d180b69029307a14d1c697a13315613bf96280c7fc0853bbaf1c7ea8681fcd61f8f58e6f23a13792b22225206ef70c1bab903c78a7b38054349aaae24cc5bf94ed6cdc70aca6a78231d349150cd62a89db888bb8ca9e6023d9acff3a0155ac5c22aa408dab7188ff3b9c6d8183ec506023301f3ecf6b966eccbda996556a1e274cd9db5d5ffbe16ddf0b6b1c0471cd6f3cfc77bfc423ee7b9cbdb29d874ac6eb00f95cdccc6481c6048a06ffc4857dcf16ed5584aee740561ed48d5b8cd184e44294d3c9637b8981829920f7371df2d180f78eff7e1984fa64677cba25142f9cf2ee9f3d5b4cf06a1636fae35afb2d2abf476af49553ffbbfcf98d54ff7a9818ac4e147aed0bdedff0dfddef83a75d306ce6323d7c71ccdfefbc963edfa07fdda9dd797f3441af77d0c90cb6cdc51d8c4187a37b8203cadcb2d817a244a6b957044332197928fb61220e2476a16087d2f041c73616d63e681b026b318a810bbf90d36953305dd3a2cfdc7ccc48ea8a581995793427b97f0447e81b75ba58675f8fee6689dd62f319df35a9d95d2eaf6b506ff2b1cf1fbda92dd397a0b8b58e07b19c25e0a98a7356962d3ff5c7fc9e0965a7e8a1f5ba5a6d25985f3cc60edeefd57b1a373efbfc1a7bd70187f94bbac7f8f45eae8c76f6a907e23d6f37eecfe5decb4343838709ff33cdde3dadef4e7cfb1d3c2ba25cbd6f1236f24b41cab70b8c1a6f7b0a8d4680af5123b5d2578becd9c8d19532952d66c39cdcddd3af6199e29fd73cd221550dd4cd272b85286c712581ad2958094fa8694902e388ae3b25b738402568ffe291b78a304dc7c541773ce3ef9d6bafcd2dff908b7ff47fece993eece6ba5b2b836f6303f532848f729f7f9efc690c0164cc8a33ed9b7367882960a60f2cbcb0578030e8b30893d454912cf287d018aec3b1aeb199077124433ece36584f8cb86a4958485b508f49aa88126d2e6a0c5337cffd7e6432aa96493fdaa494c409cbdb8b63089f6207709e3a9b36def9a55fe12bafa429131b687777ee35968f77cfefe73fca47aabb2990cbc0d0f75939811ca825d15a670606ca802c3490c6b57797307d9346f75d22f05672359df6a33ca0ca0f2b093391a3ccf8b1e563fd149ba382d4e4867204163aaf7c8d5c6272cd41e372a4fb2cf24e70009fdf2b97f16befcf26a19ff67e798d0f9c64e7cfdc73f6c59b7cc4e79cc1eff3147f16b38d05d4a9b3df63eb59f8e679778ef697d6f3d2f164c020b9f569b6496b15b13eeeb968406af33b4271993a8404d1280f759e2460e8f911c7a49237b2c05b56f3400a358959ae33536b19b67281ec47de4baab467331e1b3cf24a6a9030e1930e536c866775ba3ee392fb9dcbf9bcf6e13deef05a31f17decf732bd08419ad06d4a62b78318b2c7b8443d17de3ab4bb8030429228db648c6bdf452586587231e8434715a4ea226978766c489f98d8a4209792a96d68b737a4d7375873298b9f9d1c6b414a58893a0f284503a1f185b50e17e0a92e886f9ff1958ac4193e2682e45f71aef9db132cea1f9e77f93a3174191f38225eb5bff3992ec505006b6afa8fd4081e793f1261d9dcc491b25361afa5296fa9465d02499371cd38e8a0a8865610e146d5d8c336ca3924e34599bbfe385e731b3e6446dcc550eb39c3cb39553c00fc3ea9efcdd0954fcc596db3db21b856cd6d2c2cebb50ffc7f1fd4711fe206c735501f6d8f13db5bf63292fa457bbfded96be7f2ae6a951a933dd6551e799b27f57e5e3fd052dd9dcf68bb08e1268e8e75c1f567faacfbcf3f7e9fe0ac06425a0db7a940ab246ade6063ffef839cf2ce26950e69b2fae7cb7b387c8b0d3d732635bb3b43563fbed464bf928ee7737b87351dc226ade4fa633beab3fb9b83b05748b95ee2db83470a3a8746e45eb9e82e294815526f2ac56430b77d10009430976d31eb6cae792decfb4d40f134eb494099eab26ab00935eb783fc2c9d85e8b223745dd48e6e61d8fbc58326f99024c2ec41315a953b67b2cc4973196c993bfbc069ee83516607ff6bf7a3e625c2e8ba159d8c16b2ab0953a8a06061189b01e12466e159f0c988dc77ee5f949ad5dee2a94f2d172ceac095b0e49cc2c8e4bce29cc0b8eca75d64b91940a93b1445463140b4e04cbc7828e5c5a2a8a4553d148055f9c1b676c9777f5009fd7fa5ce96c7edde6cb381fb823a8df1edbb94c6714a2da2f9bad8c7e766cfbe391518c628337a226240624e0667e1f44f2566d5bc4aab8f369bc5505e913d14eb35aae93124e488d6235ce49c8e57d4c739edabfacac52dcb73dcde1c852e8de9a41722322b4e2d1a5b5193bbfc87b5367707abe3e6b8ec13c33f12b1ccc798cc9077c0adba30df4e97dfc52dbf1399eec7dcdc79fcef73aad0e76eaa15d70e8e305dcc4a4f72dea0cbac4909374dbdaa25624d07a444bb90e0c3d61d43eab5b796cbbddf5fba00bf52fe9f419a771ad83df75d29f636dd7b73945bb191d950b9edf318006dc91c9cc94dbd4c61e8604528d3c4c65947d5797f573dc6f9b08d8c45bb8b3a1f7ba3cf21d06f873bfa85b2b41b4aaf89372bf3ac3afc4d9ba1b779397cf76caf398bfeac71f71b82a5bd7d2f192201a055c07039f8f46d4c85b2e7037b7f53c31479b942b1d441807a2d9f825775206d742f82617fcc66713c3af801108522eeccc4aa1f438cfad807591b411536e83a440948a7c3c1fe362761a5ffdc2ce3bf0204deac191efc87f1f83fcad335a0f06c71af1cfcf88436d57911ad66eaebee2773da3fff667bed7fb760f73b83b3f276d6c0c9f76edaa5b706cefa2fb3864251f33173f6043c399992fb118ce84c03d29739ab9238756569f2c7f40bf1c0a8ebc595c901b36e6eb54e7262fe37ea1659b72b2a615be93a51a4f010e893baac2ed9063fa0bc812d67e9f27a18d7322bad9855c8acfdffd69e7cf1fe7eab926ed3b73f5f277ff824edd9b365fcf515aa1f6a035ba6be7a2f929a9593efa0041dee3dcafd53cd6cd248c3816f588c5867a2026f779388441b9592be115a28c2d0af325717e0c641503dae716af7fc2a08a3752483a77394aa15ee3c806a4fe654a545ad45084c0bc0e224c3ec05f9fad6bfc32afbbbdda98beb4fb7a5c33936f3267b85bfbc7f62e1adb2e61de43628e969475773390fbb8c8ada9d1dd63d7deccc08f8ef2c6490a2f146319cf40db5261f753434dc918df4ca132438a924549268b081b19cb5dd6e3968d65bba8ac2036da8d70a0e90bcb9b0b3c4d6a1deeb1791f8ded776a04aee333ed6315477bfef8f36efc2ee5ea84f914f28e3bbf4062a8446e8734b595212bef86d8f946420f6280468c0ddb34426168374f0b270f45a9c721909c8fcb2eae3d91d8d65c8dd9200030e2540719f096aac001b171c259bee4750e89a3277e05c169de74b8518e5ea7155a7dea3719fbb8ae961fe67aceda3c83ab8cf5de97e7e5db3ccfb9df1f3887e797cd81c3d80050ee558a353a74623306de3228e194e8fc3e84d8cec2d53601689495de2ae5deadaab0414a068372d285a89909975052224a9cbc4cdd7b6b510ea532f3fbb9d3d9d2b18c94c13b19fe78c4029729e0e585fc79a5145dbe10afbfe77eefffe77bf6d2b04d057a92ce97dcaac6c117bdc67903db5858e5914bf5f5738b97075fe2123b895325a4eb4d49654da5f1032c9c661bba23b6a8d966117913662b2f15a44f596061deac24d49408f41088c1362cdb1be2e4364723772eda5beef02a65c3251d7be6ccb06ac99ba744748f53301473865ddf084cfe112fe49e1f7df82485056682b74944c0b7b8d2dfd72cffe93e8846eb74676fde429d0a0d94c3b7c7b3fc5cbf763e407f69ce9f55419f19cc606cf298811f1d775527aaa68f21daaac8db103ef264f9633333b54c356ed2429299e9d9be01ef5444264af36d00d07d58f3a56f4e2cdfe5f378d952c2f1ad626cc3b85e0745b911825471447a7679cc7e9d563857fb7ab89f5f8cfdcfebe8401b6fda3cae69ab88a33d1668b3e769be40f7d90fc13634baad4ffd35379a4a8ef95d5a423b160d943de2414542dff42f8cb90c9f64a5ebcc24ebec4b7d5276c571918d3431484defd95e7bdd8f63adc565fb3d667096b95e9df45c26b6375fb05f5b2cf287b9ab5c359e3c9231db3233eb08f2c2306abaa0567e36f6644c754b2a28e7761ba85a0255c1a798e674816438670d1605795c94d0c6453ef70bcf481d14664eab4979ad7a23b2567bfdfee1e6371ef00cd6a1527bac95acf96a26e4db1cc949fc06e689c15ae9e8eda73547357f4a22047ff3a4669ff2367ca05bf4698dd43bcd990f7557cfee59a36dbe8c0ded797fae110b1cae13433fafc7c3cff4c0f97a595d7a6366a57c24a019703ee909d36be192bba9a905a1b145c4c40c8dae59385e2e198a64e991a0d006aff13c5d0ed753a84d5ce83ad08a324066f3f1042608cda53d7854201e2c4aeecb0297a4b45633a31d24f08083fe70fc44f375aeeb6af1b5c3b82515dabe1ec7fd339d5cce03c6a0393550191bf286b979c11cee4dfb5194ba32cceac9da373a97973f3671199898e38118c7039fa26281f0bdcfd572e1fe3217a8b92560d5492e0171622333ca415665dbd4c99fb8687a5e769894b08ab5e7a9e8848bf0ebdcc0ee0c8b3848c4a64dbec7b7708dd8d2fe9c541169d25bd83cfb146f7ff707ba6b4edc71a6eb4c6883d4762723041608e1d44625e7dc56062a2ebc77dff1ecfc0b5a23c69b36f7f76e560dfb3d374fa58c4bb9cb0e5c817cc42bb68e2b350f9d2e90e867c74b0698b1dacc5d6665369a62e347b7b81d02ae1110e3cce4637e933ab94c5c6e52a800afda202839081d62908217190d06bc6e740032985074430b5232e10f3257f922f2cc0ff6f476118d40badd634fcbd400ed73ecfd5b31b12bc45ab25a6f94f3a3cdaa9d7f306c0ffec533affbc7fdfba3dc60147799d379648cad793459a76874af2a3df523b515eec89791e6215323517834b42dc96d9e670e30677d3e9a0bcb67ced0525a6e7ce8cd668007a4464f58b468515916379414a5d5b39a48c17414d7dc9ddbeda5fbbf94029dd6f29c62a7def305fd196ed1e1f9b16ee7d8eea5da46761b08d4c510dd62833ca69a3ba4e40575542b28b789e1b9b199d7e7fc18e9f0a512d9d7b1f3ed356c44a2e39ad7bb3be4d86e8b6f2fc71249678894418c94922030f80cdbab9e6934f77533f64b4f72e6e50b57f901f7c6196f5a2a1a408addda43535f7b4bdfcd37bcead6447b4f0118daca440f99ab9e0231ccd39e6ca4e8e67367d3b3b22955816ba64f6cc24f63e5e9b19ef3f9fefdcc27970edf6b5aedf335eff3209fe358fa2badbd0fdadfed7ba2f7fea4bbe7d37a9b53da5ee44f7633a166dc2138a98847013770d978012032893c80415367d45fd3eb7075fe554e493a5c67b770f7f9075eb02ff534d835e6e0559b87717fa58f70d4cf6017ed91548f1a56a9362e114829ca7dd0f469d98d6511af19e82ae1e087051b4055e4becf49bca8c83865f956d8f720717f3d4a98ad558f6460e0276cde0f24680033b41d445e12184a2ac7cbd31e938c75ed0c0c3a665e0dafff16bbfa311f90ceb6b09651d02611d15985406a4efe028379c287d01c6d0b988ae7fce24b8d0f38d59bf25be9202043b88eab46c7e61b7daa13fdd1ddfbbf39113eee7312e1a346e96bfc3f7bdfd7e7368fb6eacbe79df43335bc07b9d76769f5e2edbba718a7e7772bd4efb555972fdc4be7b81a0f7595eecfa7ccf5d6ca19eef9c266955cc542bdc225bce78ede63ff1ae9b076cf2f59593a7d33ef27794633717491dc1e703372ef63ebdd1a6854c55e8ff9a9a6879137b1b1af555ea50e2ff6b1eee5a76be0b9adb7dc67e16bbec0bfa997d0fd6f5ddb2f6b25f6b61e3e53abfc6735decfebeaa02f76ecc7c767cd97365d3e49aadcce0a5cd0d29bf9b67723119f32388a456501c6f960664093721fb23a0301552b66df5b3ecadd80fd30428e8399c103625b30ed4746e2a23ba1d92367010cabe15aba6a1c30b4161a953e903a60ed776a39bf5d6bf97c067f4ffff5e713be0a27cff339ff5b07f65d3f5aff0f7864a93d9c2c6c7d17f3919476be0ab50702882a626b216a52a9ed10ca120ca6a62792220673ee79a1db1469383488a908d3b9a3c6f28eb9c8235af529f562c2e096961a29a4425c905e50e413d6da7e2d47147c1e333bf57776df7bd4cac8abbfb2738e75ebd7b9631da8b34ae997717e7ea6877afccb621872ea435e8794d4a1d83c323b4f52cafac4b07ac5b193d9ec312d39a5d1c4a49418738e0a092626ebe33e34eed758ab8e0aed30d66c82d2938b0205ea7665e0ca4b32f4b36754f90bc136d4f861513e9a1141eaf3be23d1b2e2db5944d67bdc74651def9e2ff5d6faabacdfd3b68f7ecca96edcb14eb8bf0c473af29841e6a9c9fbd095091f7b286172252a9e042cbfe591a40b07ce32538900f06aeee411066d244106629a635e7238ebb1880b0939d4eb45d53e2c44670566ae7dbbb90d850e83023df02280accf361cca4b71a4bbefdaec3157aeb7ce1cbe55ce191da1b3bee3df6bce4b875789b0f42c1a6d5373a4b39aecee9ae73938d3af3fc9ed839e46a812ac7df0abce5f540433231e885227241c8a296ce0226c6f25080c59d80676d820ec3d131ba44eebd12c88bc5be2f02d817a436960845ccbd8689e128304b4840fcc59590195829493c1b4c73434baf8022df0cf7db18fec9ddb41f7859ed771fc0efbe15fe0697f69ef783e55871cfba5dab976bbe0e536ae1b4322550695be231cad325b8604de031ce12a7347f8d2f33a75902545b08ffb4881da7f6f4cdee7bb0ffed1fbfefc817641bfa8bdfb54204bddae7a9ff17116797566fe0489c0dbb01c0e1267750e5f52a66670d8535ff887873aa96bf8e84370d8dffb7ce3abf6c1a1deeb328c03a134ef7cb3b1256583c4453c13cd36e6e82e8d9ac4679d178e35e5104db9d3a110e00976daa95f0d892abb24e955186b14ab9ad874671744762f6bf5c80b3d0e4c698463e2077434e2cb762d81ec83126cafb59793f33ce89feee1d4248d34ac6fe4417f1eb85ffffe4e5c2b47d7e96efd1ed6eaab67b0b90c97bc9f2f4e8072b921691c7198194884a5ff387764cd97ed9cd7f25638ed983b50a842f5492f9f52a3b1856e0cc5869c968a2fe828497ac2333b27642c11711aea3bcd26a8551130bc9b339d1ad25844cd6d0c3dfb5ab541473ef8178edce77ce51758c35245a3958c729d155fe55d7e9efab87f366730733abd70f8f6502ff0faf93067dfc719da2d36d444daf94c811f9bb92b2733636224952c02e3c720eec988da43efb2f3f72d37da1767afb9df177f8f15fc06475bb6e7d6bfcc6ec666507621619a60d01982c95b1f298bd5d24c5c1bd28277ccc90bac4738290323d6ba9640ae42cae582913abd5d6d549d7798cb495cc23b52235ff6ea5e6a7593466cc0c73cf1395acb2a6fb9adefc3e8627eefbddf951af105775d700dbceb49bb7b3b60e7178a61f516d7165c887b058f2acaba44585e8864c0c430e7359f2cb4670927d8fa4217346c8bb40e406036368ebc680aacb11fa9070a39e5f6b09f42a2319077aa50a3c41e984afbd6e276b80e237d4fd14fc8d0a40b6fdb4d82d0287419bc9efd6615afe2b7e0cbf86de4b7aff489bff683f63c837f3f77d916e6f19ea70b15eab057fa9978a5874c9fdbbae8ecf7c3ba996100b74cd8038efc4d52d95bd56349cbee860b350d800a241addf10259bc967a5135f354fb83390b1eb99e6ce6b72d5dd4c1368dee7bc1265be2e0c7d9b6357144aa30b2d7ac1af280c92e2c1b9752cfba5a5de8abfaffcff95678bff71fa3d13611b0518e365ecdf7f64c4cae52c23ac6eede7ffe394d983d07c8ee3cda267bbeaacf639e8983fa37fddd9ed583e917022e53a3eb3fff6eba9f099ca74eb7af45fbfdeee4cce7eedeb5b434104822a96751a3b37ddde72b6db8efc590cfc79a5fe5939ffb7b124bfc5d1fd6a435debcd57a2fcf60975ededff36d7c3e0fcfef5ae76acf4efafc925fae77762f59efb525420b64956ee5bb3575a2a7f3c2c9686db26a085273cf817c88fb4718c491073eff7bfe1457c3c1076bf2eb1c52e4b7c75c03909197ab632dfb97f8febfd708389713d9f90ce77edf1ee3d717c516a78030dae7ae88d492326cc6b536934ab70a3638747f0e82884b610fa95f3609d16a9d506f94a2d11debb18e2bcb0ba93667c0f233db4a946d9b011d49ea2041dcec91f66a464aac53a00506c3ffc7debb35a7cafbefc36f2901e92c0f174a402a7111b2819c01714a252055aac8ab7fc64df7b6d6defd7d679e99ffc13df7b2cbd584907cf2d95dd715aa129829faad7ebccfea4a1fea18c7751287bdf6981b7af1665f7fd45dfadc1e7c3803fad4bfc2f77b18bcd2913aa73bd4e4bba7bed6671b70fe6c1b1cbc8989ced9a1e77e8ed7cffea18ed4e406dae515b25eff3e1cfd5c3bfb4dfdea7b3c41f09778829e9f65ef47bdcc039c9ee907dcb44ef1903a641718781696eb6d583725670d65a848b39a101edf6db25861d6f348f5c4c64617468b722b1c65d35efa0cfedd486e3bb4e69bc093cb9c0d531eb59c8cf96d660c4b05b01d8a61ca44d8938adbd1879aeae7feeb1b5b743eaedadb0090edded7cb2ef847bf827b3f77c79f7ca40f3f07dd0f70f02404c375e6aa34aa49c1c51f2b135a86150e42a3605ca009ad9a5bb2c0a188838e57ba2463652b43a3748156222ea692239698240805bf09d97082793365e5dd56f6be2fa1fd88cbd60c17c4e7e3a261b5fd91f3f93fe4340ebed25143e9cbdaed851af379ffc0d46d520dd7effc94aff789818b836680312c2eea73de7fd06cfb598e2bc68b24b6f554a84d72d4e87c378f13a6fb3a5e95c1d4e47eeafa5e40fd716e3456503688f7ca99c5f624a97d9d7059b0ddf05fee0cfab9c08ff358a20c91520100b385f4049531aed82ee2b6ce8434086c3467b0130b6d4f7bece54ca754a86956facb30ce3717e29e33bec2b1f677c13f38c397f233ffe054573cacef738d71773d5e59564da7580067023b18608bf712e6a59544bded8635af52d82c32437ba4bfdb2a4820f3f88318332b70f10873023277b00b1cb6e36c02d86e1887dc17b9281259c9341bfb01ad14bd351491c8f623a1db3378e50b3913592471b0b7416d5e1f7414db6ff49c9bbfb2972bb4f7091ef21ddc296181f4845f3dfb73faf7f1a01577550ec5df45fc2fe031294330fc97315c88d1704362dba5f0ef0e23df4f2abd4a181e315af8a94015d6cd23a6e1ead6b056dcd1c69ccac99c17372a5af738c603ec61229d09507de1618f87a44437d4b4979ca387a46caee4467ba38b729eefa97a8ba37ff9ee39ff056f32018b6cef6f3cf5a0dc9ff5995efa363ff7ab0e1a61a990d64b4ef24c4f4a35dcdf85ebcc40e531f74e746292e7bd72b2d11f39339e6b4cc9e3ec22bf8f2c72336c8f3d78444f63be4b2378e8c7cb0c4b7fe4fe3fdb5bfd0bf7f3c579ecedc561dda6e2d01358ca08c2bc2adb3778b3630de64a5c859a4ad0c6b2e79ac785c174e329980f482daba442130c50c28cbb5d02b6abc0584259426fae390ecd220ecb652f51d22754c5f345610555b251dcd94a7ad008693383388131a49892078e1c2b4292454c7f52477f5e83eff7ffed7ea9865ba15e8d602905df4ec5fe5ca1f5c95e7cfcf95177fdba9cab48fa9c3b5606913513cb5d288a918c86931997e319452675e1342cf19847c39a38c3c70858b660394c3d6cd25e8da8d33e04633d497a3e11ccba9909ec45d17a3577bb2d71b02f0129d29888bcffdb879c44b331215fad715ae34d760f7b75d28d7c8af59fcee4d7fdeeef6dc98feec1d35e6efacc18ecc73f71249f62244357c7bea8cbf33de15faeeb7f17dd528e8626b96f83b42f07116a36dcc120437297b002c8ea0e0aa49bb4d40f89e892c4589bb981b8f2789169eccc5987e7ae3549114e0823b7392b0664acda1c4e06646cc3d0805de6b6665a6231f30a4381e213dcc1bbe73b60c55423ebf7fd681fe334bc7b17a7fd07bb7366fc57f6e6f91dbd59f3fdf8d7d91939ce909ea5d0de609358a29e6cc312ee9856bb8411cc9dc64ccb3b433aba88dc6093dc0f4729738058f838f78a6d049b91a2214c442b7935d94a67281444f76431d9eded51268a52f6284e6b9fa77563d3857f2d57e2837a75b79dbb5b5ef72cbddc97938ff765ed57d20dbed4607ee176c24d26f43a895fd62c7ee2bcfbc6dd9557bc4c4e79c28bfeeb7fc7931ff744ec6be93ee5d9dfcee3a42d75258f662b73770044343412d18d670c9679a9a9ec4353a1e65f8ef4885643269cb6e663ed095eb8b953cca64623491dac3247ae983b6c7258aea88b4714903282120b5a1a212737aa6e7a6e262bc2830d76da5609f9e579cc0d54bd6037bf771ef7beeb6f9dc733e3bf9cc71817b23a6303f7bef355e791838ccab1f41a76dbcb410ec82aa8c080f512d2712122af9829501a51cdef6f0d6651ad5902509bf793011fdf811c912258702fd248ccc4721bc2724b17684769b18c7a32c095dae54eb20b35aa6e7bbf53507e82a7dc3f33f9c61a078f014d7e6d0f1fd6ede98e77f7f70de8a70bc7b81a0b03f03ae14518c27c45c7b2551c5b04f829e7be171a44470eb4b1492029bb7b4af14d089b47596a2dcae1636ac871ca9a2ed32a9cc7bc0befff6c2281c6a45793cc690d65f8987b7c2a6b5227143f28b1dde18ff9d82ff31ba1fbbcbe9b4434c6a14f30b69bcc7dd6533fd32bf4f76e52da2feb64eefdefc29a0a544a6ff2b576e34bedafcddc612d8d5739cff3dcf92f7acecfbadd1f72c29fde452f79d2731afbcfcfdecad8dfbde013fe9ed5ae7fd90bd04c62fff155bd667b1e3b2e9b43cd382e5b653ce76cc1791d4ab94e62d22b6ff2be07eeddf7ba461a05980a68bdd5b238dd0be7ee12573f3eafdffdd99add4e0a549e342ade692b041f79780e77a52c9337f9f1f0835ea61418e6157bf21fb649ecbf607dcebfeb5e0a68c867bc7abe7f0f1f72eacad58ff308aef39abd7cef22aefddcbbbed0bbf22b98ba0fe33edbeac3d9117c9757c3dd8197e2da3c83188e656d2f72401ea5ab1e099275ca4a33a9951b0104b3855fd2dd1aa4e33ba04a7f9d42d573c3ba9982218f7a1d49212bccb99b01b90e16613747a4a12e9f7078b7519a59f3aa75b82e3ac1f9202d8766e4e22fe286e3332a03edb2a73ac6d7b99c5fd12a3e7726dfdaed573fdfaff1fdb558d8a0231cd58af9e6b4d79d72832e1f0d638e4a2063c7e200461143e3d458ae22441614e86920f42376a0c002b90947e3196fc6511c6ea5b334736f02935257d8edc2dc298c302661506b33476426cdc04c3df485ef41ba6fd4297f07f3ba5f3fcf79deabf991cfed6a5d1a0cf8625e07030974483c5fcc75b822a2ed05f3172ab63b1aeb010345223c7f424117b1bae0c1fdd0490516b3713e98311885da8f66a37692f43ee466c3556cffcb7b22594f6ee7a5df8675f1b08fa5c2ba70aee54dcc2b0ef3433cf9baee167e5d3f7eaf43f4558fe9ee036ee987efe3f59807bfbac9dced110f6eb0f634ce55ef2667c3cd8c252be9409eb160475d7c8f1dff9ed7f23102cd8023fb2134c08a697f2b29a989c7bdbc6e5674ac5ac2e57a6a9007c1310cca61c9a81f2634d806e50064265a3123b7d27862a4150a3858ee38c722ffad5a714d36cf3d6eb15f642ff116fc866e5775d0bc38dc9fea63ddf323bee597ce937e9423d81eedd1d15f7f3b0f00aec3941f7b4fc332b4b0034bdacb45589506a1a5291c672b4bdf9e09cbcce37c357772381f2326980e231781bc0f7a09783335da591e9766a8d524e46a30436812424498c61c7332487afb3665e120ab9bfb8406963425be92cff2624ef2eb7afc2739bf67ddeb0fd8c33e11523fed8de0fe5bbe46fbc2c3f4caf7fbda9778e5ab5dcefffe425da8caf6efcd24bbe3ddd615cac320bf3f610fe875b521ec35e1dc2156ea602b65839d02da560807119575d2dfeda6803fe4bc590462f8185182e7f7c375e0d9715ea2750e7125d8dd26d08d9f40b692146f42ea9bc453f7f352c7b46ccd844e7ab22876e9385911e4c7e9b14e7ec68e0e7753c18ba336c1455fec17f0507293df439d08bc3caee3f3f8eda14f76115cb58e698da42cbb2d36e066164b7fce5135f3f48af7be8181b3dadb42261a1d1adcc751ebcc173ac92bd4d01e35d2180c82583da4ecce24d5c4521affe3a624b2b440c671819dbb1dab86847bfe4eb8da9088a7d947cef11ff6da7cd6f776e030fdd27666a67f58bfeff09ee05f88c59fc67b7a5f52a0453afab447e473fe8ddd1a849c8fd298f7192324eb93015ef0755a119bbb7e4f7abebab27eb9c92b70a8f7279779d47f85377ffffc5904cb2426c5d37a3c7fa693477cb53e0dd8056cd073306c09e39c556a85cb894540f78f501229aefe912ad9cd9c6e998e7547a0d6b4eabc9c124150c133a7b1829a2c831aafc3d2e233476d670ebfc9dca114e5b04974738bcd104a81fdbc9434d5f2ca3a25eae7c25aa486062f717678ae5679865ff4b53f97bcb7fdeda1b61b132b7fd1bd39d62ee8053e9083ae883ec5ca173184bf838d7d33e6c1f7dbe4156ce4a9de711ae73a9ece45515317acf018f9d3be584993133c1a6e0216f6acd41356c1a560d2c39efd486bbdc96a0993680d02cfef12c05b3e0e577c91777381d2004c00a66a90547e1d9a782cab8632b73470cc36bc9746d4238ef9b51864d94febfdd9ef9e3561fe0778b62adf597b1bb3ce5d04d263fefacd3caec7b14197710c228d31af9a69ee38bbc01d3ea6e3a20f358a32ce8cb4bfbbae27a5c6dfe4d49f7ccc9ffcecdeec5ff3e9bf1abf0deef7f7e6757b6feeea8e721461afb0252b9862134b71d5de1ad26515f6a9a1a661091b0afcf0d6e0491a6b868da697508e738aee53282d6986dbc01ddacc189ae14221e9912d05459170bb8ecc7010503f9c09747f0b88135dc0bfbf3e9f99691f34e312b1fd6a6f9ed196bb88e7fe8d5cd2fb710f71c4fb7efb27bde7ebf21cdacf4c69cf4b98e0b1defb6f321bb381d478ccc112e6a6a4d4e3452afc708e0a129532c898ff2fd10486e6644b45d245860e33d3f628d5b394c98794eb5168f855229c1da9ee8ca4f635a3d2a65ab288da9fe4fbcfe101fe176bfb61dcfdda7ee835fed1da8a3616b5ffc84b00028dc629e37650ea3a10be37f39a870c684c0d35e0a69221e09a56c4145432753f5c50883531ed4506ef408e8a892c5b3e77ac29af86765e593b124f7692ea3eaf2c7bee155e14fb05ebf5078cfc6f6a25fe270cc6d7b1f961bdbf89eb3ad3b7f4239bff66cc837d7ba353fba3b8dca30201ecf05b4c1d2310ad3fa7fe44c632c8bc09c83c3e4b4bbf56157cc063a78f0c4442aa1ed49888993301ac24bdaced49daab9851edf11a5522d6d67c5cfc63bb618017729a9977abbc6c225ab56beaaccddfc205e51e6ff3d15bede32ffd21a3db2417784e8f359bfcbffb4187b10ebac1077db9d3efbd8e7bc594ce8cf1d95cdb4152f19a30eb51f0bf90735e45a56e724d6a3c6a1305604c0c44a4464c50fb560a6b406b6944ac0d03c8faa9496cc67118c56c9339c540204d4505b7c2ed78e4f22e64ba8ccc66447f0d1ff1d11ffab43657e94779aa137d89a3a9f463eaf2fdfeed4ffec2193fd96ade6ae80767f9b5dee100dfe3eaf7bfebe83f097dc4ddeded734cf4bbe7f8d23664eef07e1adb457ee055bf88edff156edde39e3bd4ae9efaecdecd03c01f60c66d0a74cd201acbd86e22ad4d36c636ab2c6f3e5a435e594c517f126a5dce2bdf63e3104ad699412c7781d98c0253a6d4e59614619783c04a5deb3e01c3c52c1ad2bc8416a53c6208ed52a06eb08be88c379bdfb20f871ef7a7337fe41abba8bf7ff87e85d653419acbba1f935fd2dddfdb08bfc846b04c63ffe8b7be9d471bfc44679fe5466a907f5cdc6de68eff38177fac0434ae647a9a820e253db2e74c7678ec138e1810ae4e30454d505a487a453077ba5838fa8188a6cd59ab99c9a76ca1b6216f1eb88738af862ca826bbd4e3035e76b5b810375d91f3794ca3a7582978c45fe779eaec2236b7fc258e2db539f609edff0face922b9f6ae8db0c1e3dc2389624ace3dd5a475b0953c59a905dee0fb3689c6c8cfb99cce5c724b01d709441577e12aabb039634860972cd46ee8a45ed1cc1c58661e0a955b0ce69e9dce85bea17163c9be88b80b510ef2d56f61a7430f3759450e3e4b5e1530df0d9b67ccd968d09dabbb871ebec904da256653a4bbe1c1bf99c6a4c9c4eb7e8d73dcf4b8488c429f6afc8779c9f8193f6a9cbf473ee5177db90bcef549787c9bb97c20e349ff92b779af39f5ecebbfeb3738af7598b94353c6fe4163fb1c57d087ef0bdda6e2dc9ccf7f3f1fc14522ac8514ef73a2e7f8fb8ff5a744bcee4b7d9f73fa70ffc1bcda1e34717383b5998b06ef3402be3c8f7985165248988d607589bbeac8c996fcf7bbcf3c6802574a6c5b591fe3a1b7f30087fe467cddddf7c85deb16d3c92077fd6e8e749155c59620dda79444725ce050f0222c1d03efda482c9c6d084097517ccf1d2448c99dc4086118731bbb8ec17b2e53a0d240e899708a1b512f077c2c5958b681643ea4b5df5c8bf9798a6f2ee69bfe3b87c732397281edff7fd281bcae0621177ea9ca3f5bae99410dfe80a1bfe2a0f1f28a2fd3cabfa10c3d90fa2f9c423965de5fa810d972a005769a49849a69100d4773d777594daaa9899b90fa9443a283b15e248cb4bc2652c44d4c98be0f7500e6f575f57559f3c7132ee33db6b7bbe437ecdfc3541c73c053516c32a3fdde7bf9ef31e1e17d2431b6b22a685377b849cd97f7f4eee7a7f7769d1f2158b2e5daf6d2aa1de40b65cf634d18b3ac14de0de6e51a304f02c248cf5963330f998afe3538933781e8ee71c98d88b23e87f612b3bb2e856a20fb62269c12520f57acc4e9cce3c98c592bc1481a5693cda976f4c91afb8d34f437f289bf856739e407ee53a19aa79ce2bb799cd6f4ba7e068af088f57e9056fe2cd4a4c28bc90083062525bf516553cb9aacc88277a46adbd0f863a50e897207dd4446c1a9d1ddde1ac560e69212234ef3feef9619aae7cc32933e3402aa6e67a26d30d78030bca6d4afe4052d9a8fb9adc37357998b2ee9069ce911fcf93e9655571c75025ec63f706a5eab0bc0b89582864da1d34546c3b88141eed975c4502d35fe177864ca6b9e72d12c2580bb80aa55ce09cc185ce312556a8151c4f15a7266e6bce1f36a981047b290158c3801a0e5704376c3748e584f62b9a6dcfea4dfec637ee9a24df8ef35f8c35a3ee175f397f57c9ec7a936701d4fa9c04be13ae62cf68329e4e3a06cd762ec9869f5a757daf7e60bbb98572826f11d548eea4495c3dcf9d353cd2dc21a112e1c533a70a7385acf4b3ca686e4aae46b6914d3c40030a025b805fe98d5b209b46f4c81faa4bfecf02c5612fb8fff238ccf613de702edb2fbe7b53c8cff23cc0ee75da8fd2ea5e44151c56e21e908b0ca9ca17f01b20b06a59703e2459a8f582c5733c1390796c774d985407ac46b64ea74710680196984a4808f99274562261bc1789bf4be49753e08cb60871dfec863fc9edff8126fd5527a93367575afdc831fd54e45f38dbdfbbeaff8676b7d6eeca3dd25bba928f6fedfc1dfcba2bdff77c2f85f17872d03a4590696bd8c55971b280d0ccbe58814b8220105a1999b68700b782d9d00dc82e1225ae87f8aaa1b5192351fdbbd40388c9c621718d892c22239b4bb5cf82272d4e3d418ba82ca9bb492288285a7eaa6bdb217e97e1f3be045b8bf87bec6deb86895edde729c7feda77c58c3ed3e5691070c71a7f31ddc24d5f23b1891dfb85bcbfc1e2ef77f97196a9708d0e62edf25c60163bd96278ec64fdefdb9799f38c7afbb8b19f38d449301733b4f81e221e8a5cfcaa4c3ba0832a851a2b981b94673f6a79f8df92ae5c136e2413f1b079dac30e58e9570343167632e94235db1f08b149566d0e39bc06dad99d318d80d8d480c56cc0c560a5e877b38bfefbfcf2174889f0e31235eca08f652c022ab499398dfd039ff95fcd6fe3b7fdbc4408bd4656d6ef03639bc377c3cd79fcfaf3df5345ea7f367a01d73db7502f91243ff1f87fe14036c040b15318f9429d24b1e639db9ce460906a746339d578d96501ac2211da5be4f1d6631ea8f8831b022dddca66354cfc66a918f99919b6c432a4598d92c380c06c9c7f779c9b73aacc731bee6bb6fd8d6038ffe6fc470c71c8c5de435d6f9fd7e1f1deeb30ff33970095c8b0d8e4333751b438a64835981a25e451c9292c78de0a258cfbc664562b6a26e57106afb226e4a1a7323d1d849637b106a7f4b8d01e0a23067a8b108c328a177db99ab051f1749683437592f0719d7003bb8a1a8f9047f5d587b3b928a4b79c1dfcadf3e8f7788bbe6b1adf34a973fc3f3629a887639777d9e1bc857317a90b53412c8a1aab61b526d7b3cf66ff1820f24e80211fb728e30cd17bacbd872435833bdddef49d3a7b8827e865039351c338dda5052e2040eac99e903a1ed605eb155c23efa065ff73373988af04bbc8d8a792347ef303427fe845776ea3a7d8be7712f6a5bf467fbae7e98573a3ecb9f766a1ec66f83dd111375b5a6052b1e182091ea652d4a06a312d6d2c02072fc45aa6591f67f07b7a045bc2a6824b4332fe5231f6b3a13484b036e67634ea7861f49e60bee4e00e3c44db83fcb3db28ff5a0106896bad63d2df9bfd4f0a7c9fdf055cfc2db5cddf93ee1275e61783f8f6029852c94e8bea125ff2b58dc275ee536a9cb56babc4a62be3ee6dacfcfeb5a7e88208294c636484c794f8c3fc6cc415d42d1148b61992f42900a3e55c6fabadc9b8047dd7bd115f3efe06a7fc5d6e8f6a8ab0fd749dc1cf9c8decee3da5a5137657e9cb161c879e1a7d59feed6b052ea7423c1c9a3acd55a697bf5a59ed6c7f8a1c962bedbff97baa8bfa87d37fa80c9fb990e8d8030aff6ff15456e1c34f0decde37afee5d4281a1ce35d6a0c3769a507ccc50c1bce2ee0c5fd9c41cea37673ddddffb6de7de96ce1ff9e0b68b24aae53a196a7f3f43cfee90c19d79ca164811ea82015631d51a031a2924f092b625ca998f7e85e565f9ea19f72f59eabd19b7985b6f9697e177a759aac2af67732b8a8a5717fc454fdf7bd682de581072138eec3e7f14ffde0d7c5ababa929bd84df8129d4eb84e2785e6b1c9a9231364c84e07ee4c98e821664351a498fdf70a7d8ce6b9b88bab173a39d5251a441b95e11618d528ef12c6e3c660c7d52719ca3623a771d2091d6a2d42417dc3cc4ab1ff50a9aacba64e70ebaf4bfc01fa01fd3a39ed4637ac0f3058ff82a9d11d844a61de5a8086f01deb1b1ff308ffd81aaf22e0590e7a870e6dce7a424b18afd415259828f91c1b83db885ea6616f3b188318e622415c7238a9215735021ca7c23c76ac5ca6eca4ab99889a143633cb935a07b75ed26b60bb98fedaa8bfeff6f69b336b97bc0bd3fa6c71ad9ebcfa7d8f94a5dff9e8168acdb482cb779e50f58a9adbc2498c41c123e19e0b22b335771d96b97193c9db90432313142c8bda0d2515e3a3d2ea1e41a8d9869efb8936c44c56d654a8b51de1247415a4b9f39601b967a1d7c82cf39701fc67ead047ce600bbc891fb1bebf956d7efb8a66f7f76e2c6bd6e5d03a61fb0dbfda3dc5e4fcd6284453b22eec08ca2f63ea809600e9c26b4e8e75581a2d84f88c713c6c24d66b03e729a803bdd3217454d4cbc5586b288111a940d2d057c9e736908a1176491ef32b7ad896bf991fb7fafb9f8658e62fffe2a5da7279cddff2047debcd475c2a7f7f6f4f954d3b9ae573c701a81a3965280490a7439af9a51d4eb7bc55094c064108c89233d6686d426320e8d1c144d0064933166651533324a4604a2546afff1165869ca8bfbb05a03b22049c68a8aa0c64f633b48177a2bc645c9aed64ad3fdb16716ede611fc0e56e1b7f2e7a7b5b58abc2edb17bcc2c7f9fc2c9fde60c27d29e3c0c81d62494f4362e8323798494d3c997be43ea22ae615e7440c6f249c6c64af76726c0fb8d0ad60d65ae92622d1701a94b0169a3c70b3348305f765c5d7d4e522011ccfa86ab3984404165fe7d3bfaf2ffbbc2627eecec33d9abfe318b97c6e869bcce54576ff9acbf57fd1877e787f9bcce8742206edb33ed68123f9ecbc4eb6f0bafc6ca28b9271b5220c8f38d37602f04ab2bb4e09cb8ccacecf512313e1405e4b38178ace79b0497a7f2d177937139045b07138e55c3a24ca3cbb0cc688a72572a401e319f2ab5ca0f0d68051c26528bdc98656ffd7b6f06bdcd6471edf8bbccabf80377d8bb37c7e872ff33861b7aeebf98816c84900d433c425777c9a97ad9ed7dce79c706534496e149b60511a338a61a60b1c68bd8c34676ce183b9b3de4896036cf806ad9c8d32f49639b215a5acf3fbe10c5749478063e08a18810bd19c137f7e3576ebf0dccdffccffdac1c5c9af3d8cfb23cd7baeab4887665eb55bc6265b15db656e900975549cd77219964d9518f2869656a1a07668a92dc68bdbf9c2f679a53db9c821ed0b146a7bca0c62a8dedf91fb362000f7624c5cb12840624efa64e158d4c5694ec96fd9bb451ac17d3cba997c5f77ebb06699e9eba9801be9f1cb58c6fba3b6cb7f8ee10efbff907b6a3383c0cc654f7ec2bbf9ec63baf0ca1a243042ea57a921bb20f62bc9519ad6c54e948d27637f4b1dcc22e4cf08f31b66a84745ffae32c3d7516d23869a888be12672559fc68d31af93ada89a5b05863781a1e38815655413c1c172a35c18e60bec040b67f36b3ce31f313597de5f99c4444fc5936ec7452ceaefc4e01f39ce9fdedfbbf980eefa981c6c920549798d3d0c97502009a2b8e8a7c69dc5fbe25155329010db73d64ae9118f43142435b270d5d881d08b4ca807b928e2d018b2c8509af5c49c530e8440a1e4f646c58d4b199a2595f530a36411e8e5eac2fb3b7b8f1cfc8a6fe05e7e8b7bfded984f768e0f947bc4c19cc6f97e6e3246be0298078247332730b92b278928a08c5192f4453dbf6f7174656e32dfc14a896ead0c5d2af7a0e15dca086e33435fc46a9ce1e7f8f93ad57c9d79aa911e594e05de4897b5b93b7c1d8f7c314fb0bb56cb33eb158e608166a85909066319a30eb33f2bdc27604603536836f82cb6fe16766af43bfc412fe33ded9f13866a747d6d1fb37cab9c16849ab89180ff72461ea933d9a54e6e84f5df5d2ef09430592af10728d4c019836c0aee0caa913135d432f5ca3e70ff401cf32a117210dd0f03e9dc9933d60579ef4f65ed3fcec69c51a7b542aa465cfc26efc5f3b979d16d892e71a9eeff9d7ecc4db2f7e5b41cc103062811ddfa127fd09157e4bfe390f6ef2f1556afdcbdefc8cbe3fbf3f7f3b19efcca4ffffec82d775d5f5aacd29977d7a5756046c2d9a6065fb0d1701c39601300344a016a9568120c55a8345ae19ac300c8f53c1ae2b40f41ee69aa444772d79a903e3428800f91a39230b67d5a590223b41414536e5828047f76f305ffc0c7fb437fe8f46eb6ad74f5ee6ddcf781f7706f0f9e70698fb9a1cbe7fcf8ee32aee9a0772ad0f65b7eeeefe456da24fefb64c7f67f3ee517afcba9246098128d4866366c7f1fc805c173a773e75557475087dcd30fc1426e53814ba1c96036f69749156c849b80683704a21cfe13088f53000d4ec93632f486e9c2234e77cbaac1960060f2d8d6d86823dc4fbaf985f37bfebc9dd35afb5ff44f9d1dfb69cd1fa550c5510707dec8d8df9c628debf0e0d4bfc16573c36299b2cab142ea4b6c16635c11c204004463c6209971a399465c4bee852058848664904515f4b3de26b7b0b1a889395ec864e67683a84776524eaca022ae146acd9c6e977a6a2bb93fa5bdbcb657f1f0acb90b2ef732bdef55f8f99a6fb3e7186eff6700aebb8b0ffea3854b3e8e845ccee2021087ac99a7d754db49ea350fb9a957918771a497ddcc413477513cd7c80aeb0910dc6709940f3c9637092b8a392336e1c12e836c1380769bb9cd3242fc41211cd14a3bca28b7646137f26b5ce5799b51f336a9f825cd39f317e3e34725e0bd8c27cffbf8f4f9c41b7825a7e3188d532157b2977a86889521bc951e61b9cb035ec24e693c225cde708f80c8938895a189c7ce2a77ad74e6a0995afcdd06638259b905014453e69075d4eb0531e52c1fcb99d02ae5cc5f27a54a445c0cb20bb9a34fec07cc84aff36bf277efb5cd7ebe97df8ffd61dd9ff37ac77af1955cf93e0fdcce9f1a030bc736ce209f2aaa8d80f9291b731c563855cca2bc6c5654b436e9fd32aad1187bcb1d31ba15817c26d99d314318461e1f45c077a6b07065d406115aaee4428f22a30d080f8dc0b11a292ee42acedb8feff6bcfe92fd18dea7cfbeedfecfd7faf287fa6699d7c8213d5e2415be997b058ab4bfa1b05850a301d2fbdb45f7c3f53cfedb65cc7a0cbca298575694f777ab2ce6a3d4552431fdc7a4c6dbccbc8362cc2b6ae6dbc8b57056f915f11a232b392631e988c36f89f833b880cb3e6b3f8eb9fe830668232fe6320f78fddfc965c676b18f998efc28e4399ff96e3e27bdaaeb729aa40a81046894dcb75602949db176a368a1a9902034f996197a874517cd3d54611739535396818b9da0460bec14413056ffd2126bc50a9c2f8a28ebc93803b0900c4f8933d94e011f87e55070a3610a72835de065386b53bea7effdc4a3f71b76fb95b6f7cbf8270e9a2bfb4811e5ba70e78bc9207280398f5a9fc33b4395dd3837f840ba9d31d761c79c6646341e298108450ecc7adb27713ee08c48de279be0bed5218062ce749f946010022b1063bf984214671c6fe77121092b2406f80307cd4ff39bfb38eb032fcd39ad4d17f5d3185b99f0379917bcfdeea5f82ec6fa7b798adf89e572833fd7740e7f3efa91d7c568d17a97181623bcd182f29ba9a11362f8418aec1d05a88876439cc40ca63dd7c273ac74e180d0b423ee4a90537b1bb206062534b9f6a9a80a4b68359ad7777dd6cb04f725a4ded2086bfb1eebc99680b60a7af5758c76fe1e38e954e4dfb97f8ddfb1534f5aaa4fe7e6e9f3292779155e19eca4416e92b2e52a468051bc16ccda714e8810c37186ec6546d586c50c7041b60c36381f3b1be2a83a05c5888f0b14e865978d6d8b0a728fcb10cc4bcb9e7bca491934660e2c95e8a6ac1cde1260ad03e46c7f7427bcd291bcd8fff63b3ee509f7b67df26d9e3e9feafce155f63fdc0dc7ccf1bb08aa475591c5dc437ec8fdc19c0d97d84b3ace39a2004f72573909b56321d43602c4a531be494c3f4c0c59c99ec3d45354427b4c9d70c7a11a64b163a4316e727339c026b9e1e3bf9df2b897fe5a6fc6977ae39772f8601edb5a8ee0790dde8f39fcee9d26f08fedcf41af5b846d12fbbb131ff599f91c38dfafe0593df850f416a888b8ea3643939e791a25354ea6406e922ab412136d45e943a539bded8b22877e2718c1d4c1f7418df0bc0ebbcc5cc28cf2cd1ca1f1dc19d69c9141ca554fa19ca59458094b5653931bd2ed2619d2f0420cf6ed1a4c12cb223df13f9cb841cba9386a14bfc5067de049faf61d25e3a07da581f2f25d7af7188ce0a38c0b704edfe435efee2bdde7dfe25d7b79f7ee8bbef4ff0067ff61dca73bf1b83fc9ab7d785d5e1eb3e23162d84d2be984358e02836c7384c2cc5548d64dc14cfbda1ee37e1a2b9d88f6a4f9fd3fca45bd8cf974464d29d02a1368fba3dc13b368a8272005773083f221e0dc547562e1dede29ce57214c4cdaa3765e2941ca3f60ffeed4c25f50e49709d52ca37a92975b33404da8e210e4e5702261b925a5b5e331b3c212df0bc7d9e50621b7e6dd36318a0f9cbfdff0190ecff8a49b7e31b7fa0b5889d7633eef418317a9b9f70b4fb1e47576709b5262a4aebfe465e151afd8a4889b18da4b626228790894f63d520d9314fd356fa1efd185fd10016dcca2f58021254388581e139bb8569dd7c5bf8cfa351ecb6506eeb6b7463e50bc49c3bac1792d0501a4fd89df70c45f3fd533b6dfe161ff9d783dd6455e0dda674eaed39abf9bcf8997fdbafc14af1a2ac5649339459b1a434b8e8bdd9cdb2262ad41017ec44ed8a5c610e7bc5ca91a5969d5705905fddcd35385fe0289f4bfb90300f6709a5756c738be6106e903b3b0a8e973ee742cec75c04b2c24e81ee5071df8cbb6e474ef7ec727fe95f57e73cf3fe9ee5fcf650c31b34a06649d9b7c993038ca8075cb175244d0ae1388d9dc61d7edc1a336d4bd12b23aea3e5dcc65fcc27a1c75c2929a57b2e2074d8577f338e530aec0fb7035988db956f55d17084bcfa80ce68bc2490db9bc3550286a742bfbabece0436e0c1fa7315ea42e6f930882bc4287f5f8864e36f8959af149f733310a9d09a7ddfb2c47fb7be8d9f9627ee0c8d37e9dbd1c24953f8ec6bc0ca1e6988703ea6294ba054cc76a122dee06112a20ef719783b217d4bea1b0712343a684158b1ca926426c13d5c54dda27bb19f377b981eea706c4292b88724b4b0118def67700733f94148b83dff8118fb192b1362edc3bfd2ff5f01ec63aec3f835bea1ef4d773cd026b2edadb691f1a0c0c3633d686341af6a9c0cbb9764c6aca64ce942358eb71173999d36202b09db9f98eb3f52082be85dde63e70c3410ee4e2b6b7991adb52088ba59e3310633f12951acb3e074cdb036960f16b3d4f1fcefe41b3f9627f6ee622200f5a97aff7fd577683fd124eb02b94cb7b3582cfbf7fffeececca7c53fc0272883b35b73b24d2159318dcad020320416480134392c087720ca4d35cd4b394a0d0012a325144091ba45973a1a4714713ef697542c5781d08d047a29214e33ca6beec21dd3c58856438f0b5570547673e7b7f498ec2231da421a4f5a7fcf5a83fde577a9ebd43b6a241ec7d8afefc59e985fb16fe7c7fed34e8db31a8bed69dcebf2da2599b132d9655c3f28b7f0995608833f03391a2618a01be2dd81cc242472b7600a5192d4ac67d1d065b51a910ad7c97d9b6680145c8430f2d40c530c192f82506813f7729383c18a57ce9696bca03037727d1d0f46221ae38503d279af5771886d3363b84ac58b3ed2397cfad5da98f517fc89bb031fe547bda6386c1363b8490dad5ff8169efb3bc0a57e8dcc1d6e72d7d7597551bfe6b77877d69931dc26157f4c8ed8d9d79f4fbddf57f81882d4a4c76120f0ad2c8b30709a2eacb81118aa50a3761b95c96636be8677e0808f2827af7549bfce13ac3353e9bcc245be3feb06b72e623fa3dfe95f3bc3ff795ccf0ff339e50aaef33dbca0ec1ef00201e190475e4a971ae580eba6cc772dcd207a50088d0383d499d14ea543bca0822ca308ccc7a4c5d49e71568c286c68582bc25861cda92d02eadb81d330d293263164cad8dd6a8e6c2b1d1797eed08f7bd7f3e1541c395c2fecdd335cae3fdbbb79cd9ef8650e6bfdea738b7f806b8caa3f8674965bece096190d9c579619694c03d3e692ab568e8693c0951577bb954045ad60d3dc1abc0b381f6731220ae0e5adc1831cea7f826153d0d20a44b923155a62f7ae0b4b8e43f30ee49c2c89e1f729bbce16ce055a67ae3ede3fcfdcd617ee2f8156328265fa9dd8e5577c1058a4063bf4b61d7c8f97f1dba326de75ef44f6d895fcef2e70ba99320a9bba930d2ef10d2e49899d649755ea4652fb61be5020a99b1d19fb66c89355d66b57326b2229d9d1516b45bddfcab17d3b3564c38ca4cb0da70b19590a0f35386a37bc56ff6834d4e442acfc7ddb8575b6f7b75e7c8df7efea4a2e9457bfefedbe38f32e9373bcc73f3d674f3a84fb33f6ac4978f29daee74411937ec6c928e1844a9d1873b68ffb6d3e1beb2d16722a458b820a6c68ad1e893b5c5028778a2397f5ce46551c4b83dc286e2fb27288839e605c62738ef2415ade6d32af4009e5bbb01a3a927353513e89d087de90cfedd9e8efabfaeba7e7e931114a9f7a0dfe47fd23b0c82a54cb27bce4f15cbd9ec7b538ee6e4a35be055c60a36db1c9402e7293d40d0f35e2aa2ceef3aa4b93fe1ccf12d4ca2d36f23b5cacd16f683b3d8fb7df7fad8cc93233487fea31f8763d3a88a060065c05c24a39635b6ce001834dcbabe12c2943c085b3a17d78dd9d2774fb0d8db5f7bee2cffc8bc3587bdf1f369938e0f28c6b6de97c6c8b6c51f4b953ae94c96f03f6c760bdaab3ca2f98c807cc2b96d8b166913b3123887d5a41c441db30870156b6ff72b73352d13cde026b9571dd66dcafd938196422300377b923c2d7dc91516efabd32109157f7d51e9f4dba97754bf138ff0d1fe2a8b327c8fdf14cedd71896c941b73434afe645607e1b46432fa8cb5524a4663dd9a426d16a8c3ba6972b36e62be616e308fac91c158f8c712891eeb8402815439b5367433d67a7e2a027a321085853653d5912aa23c2519857fe088335ccc170312f1b117dc2997c7a8e43ddea1bdc27dd7411fc868d3abcbb435dece8fbbed1303c61bcfb2bfbdd1679051f424aeea947a2990bac9c75dbc893f51ce1718ac295708734434d33739620bb1f1691208f81b9b4828a6d380d4db1b0c5d4d4eb5ba896339e6ff1587a1248110ab8a17ab291152c13ddc804621a71ae3fd46abfeefd79de3feff6e55731cafedf34c90eeef7eb3633accbf9d2df8a513e6a0e3cbda777f3f9518cf280195f28d75a45635564428aa9e9c0c8556d66a07520f21d63851b697f97b021c8e2bb6d54db7e2eda41eaf8cb281aae238dd781b0708e1c80452192d83769c91935863111bacd2a926284a601f227738f0faee55ec9847e4c052c947b31beee7fa90fe5b53ed169ad9f3f9f72f8d7f5a1cc5933e11aa1d4d31d733ace5d05666c3208a09d282ae3c0f407d881862a0b83416e7077b891a66d6640391472726b6a27d7936d84fc8d1ab51605b80cc11f5351b21463bce58604b86ae3b0f417b9b8dbf28f31ca0ffb50fc5d22f6b1311fe42e7a7c59eb279ec0fc421c7378774dfe9d3ee9fbdfe893864d56e976ff77a7bbe169fc535e845d99670356565a5cc47e14960851d4103ec603c91b820dd952361cc95e3e7260b551d9b2c4507d54f1827a18b0d190534044eea83e5ff07f292a96292a6a5c25ab3c26b7338f37e2be0d795cac08520b097442bd4fee860fefe62c67dd6ff86d079ed72c7ed231ba0e039403b562dedd8a570d562eb471099360a13621256e584a441d39167a09584f925c708fc262ac16c940a1709556935e55eb0dab7511411506c86691a963e5c28001b04deedb4222ce482ceff31e8544a049507fb25ed5b094021ef7eac5decbffae21f732deded7b336d2e56d660c4efefd755a72c2296ea23eb1c278efe3f1c58cf39bc89b74a9110c8818b64cdc81dc6818a3c58655c9807bd8cb356e23870c66d19067427ba4d7686a401c001f7257ce2493a674ac91aafd8ec5ce8695451078852f63edd22b744c2f70682c33a36da48b762f1a3493339a41442735af5f7f077ff8cee71c979febfa1fcf7e129345fa466b30fca01977d465648f79c5db79f4d69e7da2e77fca53b347bc3ba3f363f2ed81ebd13bf010ac33f3d5f7cfe80e297708df68df9dfb8eb0f6cfdd2742ea371c0cef75316bbe3d61e71f339334b2d22ff98bd17fe4727df5aedefa5067ced26e3fbff7ebf7533b741cf7a0afe6f27b25f2f6f4fb7fc0e78addb46ea460a8c1882c65a589aaf44d5e4a2263c9382a26cab5c6395795a46a1030b49480f70924375837f7d4f5ab0c7411453694909039f3413a96d50c358869c999a9e3c891ceb457b1a20404bc78dfa37ececf39c779fbf9d93af9a0af70a76f756edee740def8ae271ff0a08522d78978df33fdb92ff55bdcbcafc67ed6bb39ea8780fe931ebcaff320312999667d08549a57fa961bb0a2a5aa327738998dd59ad7dc08c6d7e58f3e3ff717d70aeef7e5077bf4c3b5ca0ddeaa53ffc8f39fe9d1ee7ccc9b5cf4effb24e60571930d434dc92bb5a388cc042b22e5d9494251c32a3d4d0ca4934a4f1945a3a8225b26ba381afbebd0947a8e5029c60ce68615925a4f314437b9c7cb5cf8e388da9d7064450dd4472eb16849bc0ffefda73984f3fbf4bc2dfdce3b60bfb65fcfcce1904755b17de0ef3df0ca18dd26bf07a771afdabfc7bc8368445aab52381ae0f1df0165ba0963341663b2e1aced25643b12239b984d1f687b7ba8cd732493aa696f618338e00bde132a4b39e3de04280667a28245e0720bbb09cc5c15e4553b0a5c940408e1ec438efcb83e9fe2679ee3a74f6b1ba7677cab3f744e7bee4d7cf0de569d8b1baae1f67bdc33ce2fe440ac4dee1db0948f99693ff3555fd3179c54e136f524cdcc82088fd3c418f4bc2aaa54804100b58fefd7e0777c2c749fd4fed1868d2617f825f67b191699ab6fe4f73804cfd8fc1fc5cffb756d13d135f38abde210fc389f290daee7d4a2528b3a80d40b7a6e92711ae30937ff5aacf73d1e9703e9a155eea8063bbe60e6b22706ea52c60c19373059fc8501f511331b201037399b18612ffdc8f0490acb1d73adfba9011d8c94cc8c66cc6ab550a0bbb6d7f8cdf3abd8bf849f01071bf2dffb8d3f8c7b88e5aae12e13689dc68d9ec67c978dc069bcebfac1386fc644fb1326c82caf24cb1d55cf46eb2e62962ffbb20f17f28650bb100e14a46acd802b5799f21f46782d6a6d722a0beae6901ac9368cff6e98ab1689c62676bad9dc9398c302cb98d70ac0b118dbf6d5b5ec27ecb3407d6ee8fa52ec77f48d7f213ff761dcfd5e7fe2ab82456ee2461a83933eca157c4a4c932c2603cc1b998eef36212f02a539c94ddf570bd50725f6e8594d8de7b19bacc6dbfddcbe812d3de811fdde5ae8c7dcb49f30eacf9c92a9b0fadc7de2f172aed7a5a4bc0d41b366e0ceccdda14d2b399e79cb01eb753fe3c12e620338ed499a2c702116412f17bc9f21dd6506ba0981bca165b7ce40c767de04f2127bb72037b931eca827ed90371b5ec2c59c62908ffef4626c87d967f99897e7fc167f31feef67fb650d8f79fad79f4f5c9dd7e5b602035bc4c356e42a9089d28ca872a4c634a27e40bcbf0603eb5de62943b97e1d787fb76c8174807c837bc8c5026b62deada2de2fa5c60f1945f711209897d8258cd82c96d6adf16790f4b2c050c2b41c96d2fbbfe7ea7ce7c3efe3e726dbdf419ebfc95dbe53aed6af3057dd250dae97f7fca40dfcbfe06a7d3ebf2b19eb633eeeed3c7ec4cd4a6b6e138e39851ce755e70b6758454e7b43c6f23e47360c4c22d5180f54d5cc24f27d16b5aee4e13673ac7becac071c4eccc0c105f18aa56256ad78b0134ebe2246b39a336852b3e9e982a7a949fc4cc825bdd007fab9ddb29e6ce67734af7e21e7f961dcd7e7eb3189719f0af578d0b6bca2767dec9bd0033ef603ccc94478d8ce3ddd706ecbc880f16defa3c8b313e1321889b2a7515b6197ad12d6b8212b8aace745c664c47b791b38c37fb80a3614b1415831804d0e42f36e47c0763013c580808921106e2393ff5fe3e33ff668babc4a85a5a7b1bdcb4c5be73539e5924eff267ac713f135a6fea3e6f68733f8fc7b2ff8bfc3c7a9b0b41ac1f5febd4b71693ffd56efc387710ffb29bb878f320edb432f98cb1fafed8538f22d945d847c39a7453f85fe3a01be4110372358d04cb4ff8803cbf9984c99c97d55759bd0b08860cb1d75c9282c832e89b1c44e01645524ca603de76a95955d9102c444491e93ba59aab1efa775de538a50cee427ba5dc3c7c4b8cc77fca1a7f787eb991c6b9e9bacc27abf6ef83a7c514c3c5ce4631c7350f01cfaff7290585929c77891c30016c58c7d892ffa76af9f32fd22f76cebf4fc5fdf2da6d479d56d12111eee27b5f78b5c7db96671a863fd82dffae9f807ff75ff2ed79981cae3b926fa496ffb34fe75dc704cff93a6630a57ada5db8ee8582ff2317f4881b3c9849c85316fd2de9e895a8a84f9ebdc69960c862b59f16d4eb129186a3388a2dc691e64991b212fa13215cb80da706ef7b8e221f35425abbb2ea7e4f1f6634de302469b83ccc04556592f38838f788063aff24baff55bbdcfaf6c517dd0547c4c0cbe4e847f9917f9a4c1f65fdff151abd15a48f1c215fee167473b745d0c1e0766008b01854b30af6d10085e0aadd3792d97399305aeb9c144d0a95af184dad3c0f14be5e854428443d63ccc98be97c29fdc826625419b26bd5ede82c916737b1a39dd3fee6e41221a2f607e4b6b5f88aabb962b6a9b08bc3af4da89032eef82ad4a3ed6697e62abccf798953fedc79f01e3939ce197ba4281e19719f51f830507a9a90789d1d0c86c4638be1ba4861473b7c3d2557da2ed5de0a895a8b0197938c85dbfc0151ea5351aab319a662e1ea74e8b545d4c228159b8402e2f2154c6b049f57287eb42cfc71c5fe8d3f8f6d992c6f0a96e674d17c959ccc673cc231054ee5dabdce1ea785fefcfd7193ec0e379787a07cf3996891ec0b3758b8f7dbdbbffd7d7fbffffbede674de5cb79e2ff1e979976911a07cece6d22dacd739ef8ba3c1a489d6e3443b685bd264d0c06f39e5872ac937935dce6b112ea7e6811602df9028db27131e32e1ce7d431f1024f245bef6e0137b926c6add16962f020a0d8c9aabb9d32e47d2e8626d7761202fd2ff09640b948aaf378d4277eda7e2ad0fd612d62720903f25b1a9267c73edc4d27ceb77c078b646f2b3d0eaeef6b735ab2b02133d0846a3963a3f540c601cc179ae52e7a4c3db210636770556c5a1ffbb58fbabbdfd0f918fd82ae9af966cce3bedbafdb09a376da7fe6753c1d9d13d54dc84b8e08b7a35bb304336f6905c0d912116ee7bcb89f79b61dd6dae3c69f4dda73290491d2b46570ff674762fc2f37da3eaafd0e1bddbfc82b76f3d817d4187452341eae86763e2e8ad493ff228e9c9977b59efd36157873eab5bbdcf3f41bbc11a6dd24c6f0d43772b8af5f7d06071d952befeab5a0884ca1dd44a51a0775f34fdd0f6f82beec381832326ad360ecdf8786ea49258db93b4c849b18e958add4426f6ea16a7303de8818edc25849bcc03dadd4bfb9c3c0dce1654eed78cef9a370e554327fc74c29afe5e8c85dfd78c96ee2fbbd6dfb058e47d36eb223d7f13615d6664a93c760bf77afd3082c736d835cb42b66245b25e420a8542185d373cfb748a547914b669120496424903a836d8a089e8d7d2a9c12cc91f455c5760a7426ad722ba85847796864143f841c078a4a417ba5092c8d5b03b6c4e0d68735fd3a5f522507acb6afa58b16ea4dffd107cce9e9bbb890156bf77e7b2aac3a15d27ac3c3f4becfa792eb2426bdf2266ff2251ffaabeac37aef7f6f398db1ce2b7dacb9c57eff529f7dcf33b0ff7708a602afa6421eea746a046156f13e31d0563eeb48871f793ff7fbc9183ea6e2a423157d5f3fe9b80f61afdcb0cd0dbe4b4f75aabcbe946b0d8e31d7efeccdb36b75bc8f3e9ddfa91fe93aac018951823ddb24c8dea931c68a0ded90f311e56ccbdd354ce16423041e53ca2baa6d34afd498f6fe4db4e013a9efb6aaf29b68ac2749d9d4996b5992a39e2e4a23329bc744308372e5e0b1da8a72029358b2bc3a5fbfc83d5fe72e7f942378b8afbfc587f4dfebc2dbbce25b29ac722a0e3af6079bf0ee673fc04449caa86d605d7469e93f064e319b426e4b978cb2bea8c5c2bf4daee348d9cf0928af6c935a838ffeff471e08fc3b7b71276302e611bc9fc7441ff4fe3ffc0cc0630c7595ed74499d6f835eb32cf6473993d3990b8b69affed131ee89b7dcf0fd737ae4365ffc057834249c35201adb66d4eb75b2d00fd4732ce5345614175c998444656126f16417d608a4cc0129c33133d566c69a20351bf7130e946d5e0d1732c6072efcb9479ac4581fb440bfa7f5fbdf735eb9e76f1283f707cefdb800477b8776d20c4e7bf1b3f9fd84ab0bf499c93935edff8fbdb76b6e5467d686ffca5b39dd73aff06132f1aa7a0e621bb0b1c1c38724d05dbb5601620c4660c6c61ff0d4feef6f01b613274eec64bc56ddfb290e6662a0414248ad56ebbaba0d7768a47ea2fc702c9137e7fe92d8e10f38ec2950a2b60388ae15dd9e2b774db5c87be3e271872d5ababcf280d16ee89add180d3309d99473d2907562286b94acd5946e7d4e03264727668c656f2e859f8d1b5fb507e615eaf357e0cb6f11ef99ef151e478aba8d2bfdfa5cfe7edc7f6e3f58ab6caca1a17af296b564636d325423a5b855c578391d8663248d58ccfa05b0898d500eb4848e49226e1d1a6644ca268ed9752c5bb19cc4c871a9152a0dd70ea27130a706416cac4a5877005ba064274fa123f88d5ff14c3bd6b126e82455a8774dfc2db3d3b9415b563a96625328306285a63d4feab1df279c7dae4d4b22a2947400623b2627b02a27999aa517d0cc9da988055f141e9c048fc78cca224912dd52632197d981dce1540bec1c403583371690a526928c1d1c489286ba6392f84b4fce42c7527e9849bc8409e674a66b4c2fec0b9f598bb1dec55889378ae9c5d765d5ba812076fb25bc12d8f1288d97fe40b38c54dd81216570bffb0b218dd186644be6ba60ca14ebbc144fa1b2724ae8c2c458aa92b39c4af481ccf12f30877d4f5e95505272206e7738d5b929343a60d0532c980dcd28b78188a11a2bb23b24b7ca0148bd44cf3dcec91bbcbc943fe3efcfd88fc73da1bd6d5a5cd89fabbe634ae71e77d1efd0e4b6bd81df812041687273d573ebb1fc3dcff173312f6168faacf20bcbced29dc3dcebe7c2a4c443930975942885113d76fc818231276e4dda63f05002268c0b2403d6e3c2311075c1e724d18c33150cf1766ae653c0285b9f620edb384652263889f04b4d346e2a76253ce8f5ceeec5a53dd697c56bf841b7f081556535e3c1ee855f6a37b4ddb9b1d0f3f99ea2534df69102c67cbcd400def85cf79795f6902f3a82260b2bd3cc7943825b1f3e091809bcc51a89399c0978de4bdd015cebf39823c976a9a514f8436decf3748b8150100e3f80a1322120ec6b03e963fcde27c683cf69a12f831c73ddf0b8c6bb22f7af7fd186acd6c437f1aded1abb512a9b75f6a7f9a09a668d3ae6b0b7d052520216ffd0138a21128638ca279392f0aa1c4e7d2e2c279cc11abc3645520feacc6ea4c1b0e7a34c2232d50d9e4c2d4650e1bcc7e8f1ac6325dda133efe524d6593385914721f053f8cb640cf049ee6e932302690b07096b5cc7163dae85998ff58dc4621bd209623387573644964af7b2efb8b8052eceb7212508e41ea2733fe9328ead2debf9fadc79abc913fcc9f8bbac0304cbb170e28939d0401602961a419c6ddcf28931d30c580369a05b3834b890d36c25b124bf0432d9e966aea9b1b6f0a5ccf062693095671dd7325c23c9fba00c1d0d2a3b9731faa628f2fedc5860b428cd92bea38b2ef9102ee67dba818df9611d2addb52388cedd824d6abcacade70409fbb10de31ae7d3ff6cfbb3a1d5ef6e7c34dbaa09bb30d023eb5970aca60aefb35855e79a424a45379034847198c281c219a9ded18154faf3de0aa7d8d02d18fb52b89942432756af08e684018c1243d84b5d4e093dabf76bc2e15f1accb4e9909ec765a4cafc9a1864d3df5fcb174ead6794f9bebf763e8963299d98a43ec87fa9acd4c7c35075e2ddd2e3d895c7854b926abda94c621d5108d0ced2e36cad2761e245791f0cc3549395b93657e2a964cc75eaef349b84243612ccc18ece91b9c3694b57d65c92523e80120662f75636518c11dc36f91ee133feb07f36b65ce625cd7bff6ceca1377b98a7fce817588237fc42a370eda7fdfe313bf73836c74860f658c6ff3aac8f3f9c831218e27d7ef097f6dcc77c80d7fbb55feb2b184971837ba8f376500731d5383c773edfc7e9fb5c9e078a337318f3969853385c301e23ac5d4e53cd285f41aaa95a8ab72ec0140d9c0d1e681bc0cc3a41acd91a0b3b60a06cbc445bb845ce4191f4554b2f832194dd38b454cea050264b93eb3a6848733494040f5105bfc5367e1c9314090b6c57e3407dce0f7ace8fbaf705db9c416b3bd51e9de2dd5e73446d23f3fa6c8ced5e81911612199c62e93e9c0feb5889b16b2b97fc7fe55b6ed5d7fb419d3fb3de67792ebf5a57699fc5a0204d738780778ac78e9f180b97091dc86b78cc75cb4a57003ede9a095d12be37328b4776ccd1dc2b72d59761e8b3863c95bbac612b233fd961972740edaf965e9265810d4592a8bcc560ac41bd2428e7d03cdc7900df0a5bf96a8f6bdf1fa2cbdfabd26f7e5fd856b682c71b822f8375cda3bce8bfd9afc77e7b6efdb00efb314d68307c5a3798b26e1dcf6692e095834813ffe92c8ff1a3b935cbf4c430f55414544856c8222c88175b3c547910e531b49e0ad7c2aac9c51d7faef5099416160dd7632ecf31d84dc70c4c4c394cdc54d240424bd5cec6812cac8835ebb84371a3c94647959e0a8b7d2a75d833a1d8bdd57ae1fafc1dd760682ff68df73034176caee856fde26cf9873eb1b78bd990d47bd8c6c6e56083a98e3e9be714a72eab459a04380792b13e372c63aeb824de455a89059d517e393c66310dfbbe8d39c39eed4c59c94db6b724b651122eb3553b9c42aa60b59fc70edafd3221359da49b5a73f243952183a0b672121a1a50122c9bdeca76289c67ee413199cf2ecdd76ff04d1fe868f646b1c35f7e2bd64fb6afbf5f75ee4b71a8a7b234473074a0186f75941b648e4d1d747f1996c6599ca420295bc201e5bdd2502d06477a9c6300a0e4258266c5cad6e4a518da8aa25195b1a8be35d99ee2155d1ba678acd986346167ac253a1b284910cf7bd4bd594cc8c6a66efc5eb5edfc519ca802a3ba0d0a924857e4cdbad5377b2eb35e5726b01e3f7e8a43afe15a7d2acf8d652923bfc87f0588e511c8458b114b600316c67e4703fa4e63baf3b37ef0c3daf812beb5f199e45e023be4266bbec33da0e9affb36dce7b2d936fb39fa673107f654dcb10eab095e9c431318ecd4a62b3f91428d8714d205efcaea9600293563a50353cd004cfe03895dc19341c7b1e2d287e1c2e1174b244a0e9a8791698b051ee04c13e102cbc65a8b2147faabed8485bcc9adb85b612e5dbbe6ad17d864738f3358ef68178eceaf2f1adcd5d639e48138eedf3b9774d43e26195cb928bf0e3ff6fb39cb9f639ea15de672c76ffef2dc3e5fdcd5f18b7613946387f3f920357e992276751ea70eecc98ea5ad7cd1172cb94b3fdc47be7e1e381feffad8e6177c89092c0962df624fdfe6eb788d3df99aefea585e63b3fb3ccceb5c26fdcfeed387d49df73086d21094f8074664371dcc4a9d973417ea5b535aecdcdbb42fe356b627224d5eb3b4f6e1adb54b7adbbee49faafaee0df841bc42c97efd43fa4c13c7fe53b923594d95472582c4f04b62aaec42502d62032a092a0847ba45fa8e45c4a91c7228f1390800eb819de0325907402ca949c6aa22759c98ac1c10ea40de2d9199dbd69cf0067d5a12166a4866fb462c6e1de87084d226a6c7dbfdfc0257eb4f7431e7f8adf023c7f2f6731ce3d6fdf24b3999279614e2e900da2e03772a750a27ce69d0efaa16f3b883097560d2294c86606c193ab269a923036339cbfd44c22684254c728758e10f4d96f271395b6a10460e9286de40dab9f223e3d8524f87bd914545c660b5e81d4c44816d581eb05fff408ecd6379fb36647d8e26875c78dae7da104e91309a0ec250e5f07cc2c1a5ce383b6ff0b481f06967a26ee9da5071530adc0159e8297660cc8e1022c8e1f090a47a676a1107f3f0974ae10f4b34a869c1be512ab9567459c2d3d09230d0121c1151e3e1903ebc83652e70625ce1f7546fd3071363deb41d8e9d3a2fc0a7f1a1484dc20d498c0723517eb896cf4f5812ba896459305caa7157f5ccbc63c594026468960dfb1a47e7ee9c446e891f5c4b91a72219ea7698614e5b1b22de9a711859299d3a1c11ccd8c8407fd5f1e26e812c38473129f4f3e3b78e2d36410a8b93335c86d778d01bf1ce7c4e4ab079cccf53f3184eebc1b0b54efcdcbe55e10f34cb2b9f7893d3620fb11327261ce6a469204996998e78272608b078a94155306c716744f9d69715d32bfded98a5d40146c7e57dd690f58e457bd33143442d517e7994e62ac52c18c20192d92d8194f380e6bca3139b77d9e7d456af8a3f788339ba69d3c6f73278d1a6c77a7c4947ea0e8496916ad001c294809c77192573936e0f8861cf2c9d0d060c07135a9094ea90dbb91aa3f4801d33463f5fe83c5e68e288f3443a1c73828ee5303212ac38f469895963a8275a8187da0f07c252159d258a951f6fecdf0bebe966ce7e8a7e3673f3050e9e461d1e5636f13ec75883a3bf3c77e9b7d01b25461aeb27070ed8c1d6aeec80f3f5aad62e9fe1b93698049145d1a3a0714264311d96f4bbea84d7465ac2623586a1c3e15f3026bc1f6b73c0c5ac31d02222293fd498b8d3612f51c16a07418747733ad2c082d5b8f017a4a00076d6f1e752c72a72d903cac2e2b1e4f2d9c042ec3bfb50eff0a35eeb94a253de22f7f0f99869fe5a2d3aece7daafb7c1808c119a754c71c5e8d4f831e14401ca0e8762bf2409dc4c1891471497c8562cddc2e3a92c085324442a33dac154d9ba3c9c8ef985603180251c9634fb89330786ea702146a956f50f0373cad818c40c8adffa943f8e7db12b88c9ce1da42d0eebb433392adeae190e6d828c0c27ce3539456ee0133cf4013676114e4ebe4d538f7d6e914fe6be62675bd39e6d74269b9b43da9fca2a13a07c6b8a44d16dac06a0cb5b5c372222b399cafa124ad252477a4735bb9181b2148861811325d40612f26558fa73f20bf5bbcc54828b313b2a0d381330902c0d2974cc6506ba100fff37728bbcce63d67210ff3772100f7ddad6188f572ecd27db1bd9a1c776f77963e3377eafd7e7be96e756d65c1213cdb2638124ddd800d8f23950aaf2ce7691b074a37c8c996e9fd0de7a3a24a6691b5b0015cbb1e9c229568ccf6ba25faaa566c3a527e709a1926126449db084f340a8c264c120a4716aaaf200688685dee128709099206d53c71436f7f3e5c57c48f59c79036cad46499f3de4a8db73f08ef3cbb97ae54daeb8cf616d31324c7310e67a9c4b90119009b16672f0979508ac99862b6c4bd830bb2ee08c391ccc365602f3a9d9cd3dd42d838158f8b2c6e0c16ceb97ca8fc07ada9a8ce006a9b2c10ceb8212e68e0d276ad4153cb0dd39295e91f7f8201c8db1c9ce5d595a7b09bcc26f7d93b5e86b2c57dd875f9ddbfbf13e176fdfb7a0038694f101964c908f5c86c42e60159fc63b5566394b52388f4a0b6d30da8c19b2d1939d0c4b2d52e39d6389a00886e1d8973219cb8ca00d09554525f458a70429190780ec7009795012ea0f4340e63d97a46fe6888fe34d70d2caebb395ed1d9fc4b47e83a925b489e356e3024a17a91fee239e89bf76949f9a17ede30c7342e8f5591ac8f452ccb8f26d2ceaaff601b276d036c77698357eb1d37aec31d79fc363410ccdb92e18b1da8196f4231812d71a868a430de0c70667c9423229313064d2418936990e4907ccc307bf14cb60d8eb687c1819a5b3f512a3efc9e1d48f71a6c65023009b1e07458fc97e683c615c49537d4b2f0c947d364664e97142e6146ce471dd4b389c5d93f7f8f7dbfa65998d2e7bc9db63765fc8afac82385c4c18b143863d5be315763aa02b3fd92da165f47c3e73c8408a9d94582ec536e6e1d04fd85520029ec8120f1356d4939da2c29e6289ec128952c7a406efa330f51948a1183eb87395330670e0813005889d7e122f1a12b9dbe44fe17614d7bc810f625925bb900c35c68f5efae3c5e2c2b861fc84ae31db8d31d23658bee80fbd952faa3a977909f9896558e3d81b1ffddbfaec71179fc4d7844b4067d5f8b1dd3893f120547dc618ab2935263cb1211f861edf937c46ea434b7270926b53515cbaf3a7e57400c73a205b7fa8efb4442b544816b8c413132991267797d0c29a8fb69c1e777f8d79c8fafd2e6f72f0cd18ba604fd7fcd943bef5bdaf9fdde758fdc8d7bf6f373ff7399abb68171ee7908fe385bece25f0c5d8d20dc66b626b9987e8caa9716171135ffa6cbd18e6f3be5966e39b8f1d60197d6f60b82623e96eb2e8400e162650c690915493cb432029899fe2058e9d8e5b74fbea5ccb345978f0939de9ce471bcc3dee3c2bde9aa8c37bb1bf51d950049cf2c32b9f96fe107020c5032832028889f69e3fecf04e84a3f155b9f76eb3f66cc640c1f22e329af8c36fce317b5ec9a7f4dddae2a59166d118036d37859a69cabb8e6f493d52ce583311186de873268f5593976c98d0a596747b53982d3d2954ad98fef08652aa894e11d80a50018b1c68fcd26d8983298971025d8df77907689c19eb3c4164f9491e7ae6176c42d06eb56fefbce1bbb05b8fa3ebd79c85d731efab6fe5f7d9d04bb56cf4327fef75e3e914f355db2ccc35797f98db7def535c5a5d2ff3e5b73f779da9711d9fdcfb5840465b4e38bac373b2f2074f1b1d1160ccfd0d968d1f2aa03691b4291025cb4d760f3a47e7700e333f961016c10ef3ca2f9f13a8598e38047c2e10a5810514098b1a67956102a10654093e1822bb98948a11982be156d880776dcf33795a70d566265bb5d916db0ae322589e70c0dec428804d4c17de289c7ddce1bd6ce705dee3baf9f4dcb7427bccf5c5783f37d4d3691dff6e53e7c83385aa6e79cd57afeca74b324d8c16e693d8782110b55fa4947475aef508b7ea183606beac09d640999af668e7ce096fce550147f9524b761c4804cbb2174bcf5e083a431ea640c040862b435e316a92ff08e6ced247db4e20678959861b646782ca653d308006b4decebbfff978c70ffa88ad318ead5c11f3fa366bd8f7751f5b12592a48ff82fed9d7f74b7d05650b2d01c27460fcd013cc0592caaa43234696b206345b7b8cca4e385635e2fc0788a18153bf430650086c63e9b1b034a9320d86589930a09cda12abda9aa88a5d0632716931ea16c9640238760e79f2e0da041398dd0a0bf94ff795ed04496b9fbbc4cd3e136beeebf3d1a1cca36d77985bf71ca3cfc430dd19081aa60d4bc7f60b1775e750a611b2a4b16bd73927a65e39fbd4baa8aec77e7f70f44ede8ef7e67abfbfdfabaa71ec2cf552e3521cf4e246b1c3de2dffa88fcff2643e1bbf41cc8188354425d66528efa16dc7186a5303859870ddc81cd2d497c9e673bc758df565583888502fbd843552d7d39be0224fca3ce4b0a17e22a555bb4caca69ccfe1f1890a6c43b580b631009d683214c91cff30786369715dcbb2f5d2e8e71bdfea092a679481c8b2a8e65448536863160e426ac40a6bc96c02e6bd0c41fa608aea0e5be1c21f66038d6665202b2c1860d144d2ca02f866f393c75576b050b5458e119b91a1415facf58b3336f1de070c7f39472ecee86cbeb67d9eb20f73ba613b64f0b3dd753ec75682377ec2e4589618c73cdaebe59958b4357fd145461dc7f52546f9ed335fe6ff7e9f4f74cc8dddb4c7b9f8b7bb0356518baab5f69bebe7385dcfed5674d897bafad537ade3006124cc0f76e65bee9dc2e2b37988cec687e26fb4dfb52ff7313fe6a5b39ae77f211fd7c048b2070469cfb50ce0ca380336ce82549101821c940cc71c1a6b9d976c9c003e18483d572692cf69209863d78977114eba2a88773a4104009bf6893ce3f03c740da82008350132a16cf41f79c803860c24e79a7c5c6773f6bd3b8ef67dc5565f8e8717dca5d3b9a3fe77b2b779e49e35f187ed3a6649e8bdf6bfbce71f286ef65d3fc74bacc7e057f20fc2c8951f3b6669fc329132d2ed704dec30d3b847468dbb054a883c613360255a899205e75165124098bb5ca81aa9d8d1995021c3a70d4e63ce952497c02c07fdee5ae5a93b85b80f91b2d586d9c384639da91ce608f6aed9dffc4afec1b9c72b746243c645dbdcdd7fff9fe77da9fb32e9da9561350eca672cee991c96fb36f439a9f013693f66ded91369643f8e2575e4c4bed6e7fb773dc5a0eddf039cd389a7eb8d573edea68eaf63931cebc81299ae26c8a07ed5873889d9ebd6ff3ae4063fbde7e3fc8d6feb7c4d4e3cf1edbafe6fc5ed89e7b0ccc7bef02ea683d30b08b3be191b4b24efb0c690c84cc3c4674067c2099cc9e5d0806067946ac729a5d2051d0ec027ceb1a80e0754f340d89f8a64ed0fb539e058cda4dac69887aac5d0820c4216f7bb3c181a1b37a5a526fadc98bb2217de87faeba2cf7f2f772eaefbeb39f3377d5e2ffdfc2f7c122f38c4efe78bb9a4bb506703b8704d6223d3623c721205e114677ef2b8845cf7970bf00389f2722ab2ba05c2bec36708c35e02ed9e68c63bde637640954346455b06d9a4af734a361df6c6ba8da90160ec25f928803d014a4f1bcfce4c9c92f46fd25d6fb1ae7de5bff63cb68fc7a1fee1da926df20ac1f252bec266ff607403bf14ac7d71789fe3fce4b859577e2ea78825f575a4707edc757d86f45496029d253b276117aa65a8aa4425dfea49064307a8df5deb8990b81c4666d2e101af74007476a6a56d2d487f013e1b4eed78a3b11954a9236089ec025b5aaab4f783f0e1ca993f097878b31c3539b68d85c719a73ec937f1505fafbb1afbbc5e5f7dec3760fd616fe3576bcb6a9d29772fedebf16f6def2fae71dfe419ad7d486fea53631ca3cfe66e90b63a237120d90a3e6fb016137218e4a53727232fd1c620c59c663ded7c404387c91f00dafd9814b94af8703e35575bdf52786b48394d341292ea1db5df1581dc29fca1f4434fb531168dcce38863b02361cc7439c22a6f7c461f631cdfe413bd660f8271ecde25ec15fb361ff997be4f5d5635f6882c6db1b9c7ab7f8ec393fa342c02da1ba86827a8492e40919de0a1d4710770e882ddd699f7fabe28cc89a8b1b8ced3d0dbfa4ce86822615559988f79d881ec8809c4fc1794671b4dd4128076236d982d08353435ea4a48664768f8c491a8cb5ec8a7f8f7ec1fd84f79f52ce718a7a9e663b2eff9f84ef3b9bd598bc7757ef33a8fe881cff8f4366753bd8fdf2d260886cff1152a9bf36dbc0dcced36ce018f5963519dd7652e1cfb0473f33697d5f9d81ecc1b395bcdabb91cdbb3976bf0b7189ef33161deb4d945accffbf227fa527b9347ff5c1eb67dece733f53de1fc3eef2d9ee7f6bee62f36b173dedd8b7c7f4ff1d82e6fda99c861e1f13075fb2f7d271f73ed890c0bcf644bd7ceaee0038c6ee1c764b0ade4135bcb8206bbf9f2b85a6b7e3ac71261565b90c40c8ebb4337753648ea095349eb9b523670e56d4767189e0076ae41ac590362f9881aea301b6a453ed6202ec6aca201606c4c592c7446005a9c8f201280c150c71ca80c0486e6b2bd071d42c1b17b7d947c366ea7b1f0932e8baf8beb7f030ce7b1bcba7d0f9cd09a135e5c1faf4a3559114bc67852e2dd54141c4f26a593684b033abb31636c1c1433987e983fec4c7fa339b60f7b4217e3f0df8423745a66654fd45cca233e43fb5cdced7d9f63e764a8d8c64019219aa904d095c3852b97010596b1632633de9c2b13438c05634856e352091ddac3b8ece53e4f0c53c63f749b1ab0d47e9989bff3a59885096688a42916cd5893d31c8f1995464c045fc24b4f3c1f7f97c8741d98ecca4f2fe5e6f02bddccdda06f655e1ae7de50611b3be0587eaed531ff9d4fb563100bd82a7b139290b5662b4e40c9d61af40495552c75404b0bac388d8343074abfa6d66caba16c659674a8a53dcb4146e22714387cf66089a18c647113c89aadc9ac02129c7be2483087d49814b98599ed16ce25769f0bfe4c3b3ee65f881376c64ff3359de815ec7b3eb9f7aeedf1c19febb7a62d161a0cfb64801f8c015cfb526fe1893b8444225b737583796aaa51776731c6dc648469000d0d0f0cce4998720a42e8806ea603860122bb5365a8c158dd4039ef0451eeba89513a2560714985c05e2c912d6e55e993b950536373d89b9bd84ae825e40adbf626fb6bfb762634e8b3858384b4e1a8bdadcfc402758cb1cfad351d160c4816ccb1a3d954f2e7d29c705a4aa8d47112452125816ea9a5161fb358a43191168c1f1b1c06bb9d3b5462933e2d2d39de98c319478674a28a82e444abc26034c14be0c0025966f052a10363001861391d6ab75a6b667ec1ae0962a3e7986c7ee3f7fc700d696c08d2aec8bb7f9338308cc7c37d0e9ba6dc7a9fe2b371d520e9078310061604d6d0f8015885316d7169594fe584d726c650717466370a864474788905ec53e1947a69c960ab168f429d27834a7dd3ce18972a0f5a8c9766021fa640dfb8f28e064072a0a80cad21e11185fc145dc8af7ffd375a7b7c8f39f11d5b1ff3e21abc0e9b54f3e265deceec26e3abb66311a67e931bfde571aef63b9dcfda7d9a6c44414c1f7c1bff2232c92c0b16a494969aad48e6d0e8eb409878c860b11c0e03a0480ecaa6ea404a0c9b2e1c2029ee50db988c206869cc8f193a9d5a9a82d39e4c86044f11ddb916591afdbc43987c016c6d6ac69fd665822fc3d8b195c2b1e3bc9a635e62762f8d8b1be44eafdb18cbcddec2c43636cf7ec07aacbc5bbffdf8f91c87d4ce6262858e0504c990e1d6647273cc86d862c31ea43d06f23053e59da08a02e37121f4398d1fb330774098e99080a91c16702e157ef4b83107188dcb9e48e24569b1e26e0a55412ba9a6cabbd092b1331d2af974a0dc52c79db4d52b6eca47fe17d64b944dd067b77e4273d73632925c9527ed06585fb876926e6762f78a6add4c64ca3573d6b9f39fcd2557fb6a1844c14665849d596ab16ec1d417c1cee40dc10519f463d857e55dc78bc9d20278e40f8db1c68b1cb6498ce661a95a8ae1c75d913042e48a740c782337933c56a1242259dc5954e94d65495663711724ab0db27b6f734f7d35f7660ad787bcbdaff2e59fd987a87d1d955cea3ec7963d7020cecafa3ccd9da4bb3a957d93879f77653a77fb6ce4f121c56ffac80becd78773295c631926cd3ed43571157e3f6e37a9f108b8d93ba8ecfc97c74d6cb1cf616790502029e3091b1646bf0b264ce6609ba6662ac53af3c859347355b0e5b4382c0291d9a039a96d558fed855ed29daaa2b3f3e25d47e576bc19b3ac164bbc49636e8ac2d8b5c3d0a0d20f82bad867d85f8605367aa9dc6a6e7dc65e343e95dfcb9f9a34388aabf6cca20e3799c7b7d9333be0370a66b3c7ebe4fbe77f616f4c19680c5cf989317640b606b2d203fdd5ce405d06d97887522d523938f70690772ddcc749cce9710620d2a61e4fb65aa2713edf4b553973824430a1988b6ec26c0c8bf4b04c649d62aac31eb280303719529a22fbfa5b5ed00dc77e7f696f2c6fc6ef314ed3691b1ceca6fed36bcccef3bdd7e036ce6204be349fe7758e038e2d8ff1fd3e85c3117398908cd84a421889f36cb2d5912ee0841d1a73e3170606f20661fac9fde10b7323dd11f49cebef1f8a97f5a6dcbd0ecb7c1bee7137748d8b2fc58661ad44a2aead486088b788120bf319efb3bd21914011506cc1a1b29e94a1aad9e2c644b0831276a4ca70a451ada795dac003524f83803178f20350a30380e4fa65cc4251722c51d861b0db00a937b54a98a204db17725b5dbf7fc12b823facd7b3a197181baff125645ee2bff4df5f58d7c12d9625069becbade9348e8e55827d55af9167392dd8b1ddba013246c884c13771f0fedec79abf6d97f923b4b5778805d5552049da5437d8ee72e437fe1040f2d56fbe181d071e7526a2128699c645afc82b180bf4422bbf410ede874c6b814ae31af0c9128e0604e7820e67dcf3636c6c0d0bc5809d5585a138b9880c917a47fb378cbb57df1227fff593ca72b4b2bb7f8303fe7dce384c445a42472b738c659f9c00e0a90541ccaade3199fcb0560f7367eaae79e2c3d04e6c7b27ec1ce5df343ae56259379a9c63868b7c248cfebbdac445a79fbefb9dff37a83f1746d35afe6c4577babaff6806839b169e8279de373f7f267e257d47169c20603c19eeafd77f3b11f72161dc7db9b7abe8d5973c4d5be910d64239d2025f43918bb47ff8cfe661c7f126ffadc57aec19bde6e7edb975bcd71dac241bbe5fb79c72ee9698631065a5fa324d106d2c462a96924461924ace8037660f0220ba9b32180ede9f311af329962c9ec8f71a9fdd2d16e3195668c0f0c060f8d546747254e43c689779265675630181500190b2f36e6668a5935053b4c31ff464f1f6dc2dfc39b3a4828dd5a57d3d533ff433f87b3de3ff33c7e63443bfcdedff6a19df3a1dfc856b209ca2e711e981bf1f6593f892b1b7633318fbf73ad5fe3b33fe72be29509b4a9a0969aa1da743eb5c22db0245147ac4a86c451ad27c1981360226c7b92bf43c8d84c25b25211cd54a85153a614a3d9d614c304c8505513ac2171c505f35e3995e1dce45501a7ca8080dd982442acbfdd23fc706ef687701dd45836708ab5ff782e2ebc63ec6276e5d897f6176f951bf04db9fbefb33de46caf747de7b339035593957d1a4e268c943873bdc0436d18c8ac6bccb5d49d4b2bddc202e1fd9bd842e7f2001ff24f5ff2f79cc5b65ee465fe3efeed4cce93badddfd667efebb91a9723e6808a3b2ba5893ff44b2f66d7c8c61c28a589c9642904243444a67376dfcc86d9255e6acdb3b9c9fb5765d5fe2dd6457abe7feea7f4c09811b05f2a0606ac1d98f91032f8878118219085b516870363f8b4f506c4d063bde63e05f10e7a60b19c5a9aa10141564561e330b0f052b28472eec0184f5d382b271cdeea250e31553b861c46138e3c68ec88c7efc4786adee545dcf18ffbcf6b5be937daef65fcc5a61d0f6356fd426e038b3372340c7bd3a122faacc823bb37858932014cb6b4d20c905251c6acca425e8b2c60ac75de5020ab190eea96562ccd216fc804c41b04563b28670f10c49c97284bccd19d61d3c55426b69790c4e19d8e6e6bf114bcb30fce8599c3cd7227e9762a9bd0af39d394716dfc4fc566ffc8d7578dd38fae7f36667bddf64e4a5c3c74b63ac8557fd85b19342e4c3633d100039252d69a938d9b6485c6ed7897f3390f6db77ed255028b626c43cb9f933128555e4da59545fddd548206b2b3148195102474e870b080bce45a1c2b79738aac0bb897eb718eb49c2025c32fe3329c5f6354b67ee471dd1546d27a820ef8ac97bedcb3eb83c37e657ec07ebdf4e76b676dfe179894637dc0b9679701aaeab43dc5c67d384f93858bb445638bede8de2ffd0fed119c2dfb657f9c7b5cb58ed298aaec3d17fb93f960fd4e2043006d127a72a7e35ada64c2695845c2100db3d8a3d8f5641aeb8916629e4e8dd4e86351675d3e5c3b730390984cc09cc8986a0a28b51cd93d1eb2ea0e403820b69198fca263c2b803922c21e2683b2e6f96d7b4fa9eb9738c8d747e3d56e31739c89cd8086fb083551f22d441f955cf231c0cdd3ad6decbb5eec779ec0e3aaedebb457abedfb7bb26e7f60de28cecfb91ddec194ed07e4fb16036efd46b3f9f7c2e7e9d36a0922a695b8880a0cada2f5feece3546f961a644006268fa50ebe1815838a5b80588291cc4c606cc0a93f606c852a6c6300c61f9b40be2508143857a665e783104c8d262c22b9139d020b415483829c5b1868db7f9ecbea8d324ce4174b5c7e8347b897d36f453250cec8f63d75d1f13efaa18236ffa1b4e6a5edfdc3de96b6f745b4290302772352fbeaecb199e578355dfebc25d7952efb363e3b4dfbc8aa5f291bdcdbb956dcbebb927d3f5455ba9b891adc4d1b8e695a05de61de6ef937a30e5e7720bd5bee3a9cfb11b244b2b9f25c810d921b17b1d3487a63a08978e45134fca7eb90955491c221d126c3139e3825c9b0ee12f2265b63fa77390e0c441ab25819aa40d664b8b1b752c4e093d29dc129e5288a860883a07004e6fe53b7e8edd45323c3416eff213ccd3b2ea35960cd70e47cffba41bdfc61e77758dbf09dcd2df74120ba2d265a7f561d877f6072edb6634e670b260b5b80b81d55b404b9ab8319e1a92c49a31a6412a4df050e90500c726829c0e8cccb715db1c12cb93955c8f05cd1c3eb10e5a1578ae6f81cc744c6ac801600acf963a2ee3735e4296a6f8b85391b3f1e4dfe4f52530f7b8ec242ec6a5fdc9e959fcfa57f7274fcbaff72911bb7193f8c01dc8a7efe5ddb9649f00d672297d705832b518718b6dd23387bd0755643bbe44659292544be9afc092a646a975880c37bebde0b4818174ee7103682ff5d2d16ec29021e9e799536a99498d07608512b134804566a7495a48380141c40e0deb4ddc867363efa3bdc5cbb1ccfe59bfec85fa3ce613aeb2e931ebc9bb7d8c39b68ecb38b17b1b771f6fe36b7e5cf621406cae99393be6b581cf6a760074c1074288518654c69049120e4c4e5b999c910594862685ac298a1d9555543719f11ed5588313622c6a238377b6aebc5a9a6ccceb31dbf3869a8dc18a8108a65a0c914643e31a3fee877ce533baf2d2586af66c5ee347fed61880cc3bdcad8bba0d89cad8a17a69cd8db12b61d683a1a4ca706349403044ed97c349f2d452269628eca0ccca3a270c55bb974c65838576281b3c61c000f78c015ebb5cc64f91589ac8c8406aa82a030a526a6343a6d2840f3395c73f30786da35db0f92fcf67efeabc11ed743ee0de5f1763f0ecdeda8bbe613fe5cd3cf34e1e839375e4077dece573ae89837f3b7d701ad3e945fca1a63e0cf7d57953b72167b24601656c58944e4da4310e1dedcca28b0dd63055cb67b598080edb2b7149a229526238a722b125d69f1b2999e3d0e4a51192a5853627ee54a43928896dd80b16403cb7786385a95ff8349308228cf6267ef5adfa561dffea15ef0dbcda973bb579f7f3f287b6b09f485b7f78c59aeff53ae36b6bbec2b17bdba0f6151e7e7fdeb74c24cd98a2ec4163949d4bc38e95e4d848714f95a42901ec840c9f3a9fc3d5d665d009c2992783dcb18d8d87e8a53c58b78adbcd57fd169b6ce2a21d9d2089f13836738aa68dced5eb4b71bc81c499b226a0391c7b544b7c4bcb3c5613dc54e9bbcc4c08a0cf7816e90568d59994540bccae680ce8c68b734acc47419331efc7ecc6e1606e958aa1834cd6d16eedc5c674cc66222872d78d2553b361a89a5d1d46dd9b61693d1b16d53f5796cae39ab3c680e8e7fc691fe16e5ff3d9dfc4693fc6927ac37dff187bdddc5763ac3f1a6f1d2cfbb993482546467605cee5267cb5577bfad5daf3553d18e62b39ad00232c0c908918652e820eef0ec0564fba0b6bf02418f6488089a460840b35de693a724a8b81b92f6a4b37ee666a695064530301c981d0f86540894171064c4e9355111410e4c0ede71b9f31549f2353173197e2b6bef16f0543833631112fc629bc816e6be2915573d7bedc7c1fa7e273fb1f628ea125653a0cc74882a90ec3f51442d34d283b6658db1d5288c4b02409de6a1c3b2790e653645810e413b5df1db8a951409bc8ba1d8ad3c168e301cd765243f519f2cb886988073ddeb4b50d1e180f3e357a063cbfff112069e5c9f4ca581c37e8a3c7f22abd47434fde653e7f68c3cfed21a93c890d8ec628a53b0df6faea60c62071278112025fec5a20164bc2658e8e760a64d805414ce1b2ca9c448f8c0ab5b59ac01c58bd38409a014b8345345431ca7893c7954d5f9244893d09ab63066303698cc69cb4e1b8b6b552667cf7ed2e7397419adffdf97fef7ec4b3bb3fefeebedd696e1254bffee77fbeddc5a99b479be00f126ceee3f45f195dcfa2f45f3fd7a9ffe77d1e241975f360759f2e48701fe679769fb97eecce823fe6ab455a3d344a7f2eaabf24c8dd88aeaa9f69f3f813c96f77aba80ceefe141e846f77c98204777f7638a6fef9571ed5f21cc3b1ff62b97f318f16dbfd93effcd9e9fcf1c8751e38b6233cfe8b11fe6498bb6f77d1ea2f122deffefce9d255f0ed6e55d4450e82cddd9f0f1d8115bedd8dd2c5dd9f2cc3f10cf3c8b3dfee341aa5f1dd9fecb73bb52e97e7d9c7c76f7720229518c37ebb939f7fda7ffd95b984b9fb93f9766790eaa9ccb73bf3b9ea3d1a372fd261ba0fd5e1c28f57777f3e7ebb7bcaa3a4aa8a19f8777fb20f7c976119b6c37fbbd356d519e191673a8c2070fff3ed4e3d23ca3c760ea2c797fe9f6f77fdeb45edbffe5aa7eb5540eefefc37f38df9c6fcf7ff541f380c96750b558d76771f2e92e07e1ea47194aeeeb78b65bcca5c3fb8f7a3fb7d47f8571acdc29c16fff2a37f9df687a3c4ca4d89b7d8bdea2ef764e1afeebedd8d926cb1cc7fb87978d2d9f657070bbf396db9cb599037bf8dc562ff4b75733fbcfb335d53faedcecc5d1a1cbf747d64046eddef2a5979214534581da49b728f8783203bfeb68255fe4aba3af5ea0e7541d65579fff76e5ff9f787465dd328bdfb335fae836f7f7fdbd66fab2ec8dffc05678b3f9205a90b83c17215d52dcdfec13ed49a22ab5be5a0463e6c9cfd37bfac40fee7db1d7173f7eecfbbc6e252d60e62e9f38cf794bbb2b4c6f28efa076be86d66ec17def1cacad6e67e42b78dd7bfd6cabd918c592f69760347c366d7673454a8cff7365e6294a3a1b119892180d2d3acd9118125191ed0bd4aee20daccd4095d631976264976888411f99c56b8768f395d3535119c9a7b840d96c1ac4154d6286ea6bebfef2423f9e4dac1720e9bba0bbffc67cbbe5a1d87fe3ee2114ea4d02faa998b2d0812eaccc9a37e67e32221c6f66ceda62f90c92fd8194d5d60ee719dd9c4ac11a7db7a27b9dfd9784937c6b0bbcf300fcb098743c7566b749a9fc2751d71c0ec462eea6c1c6e9735ef705a6655d7bda519b91c1408d72d9a28a53dcfde9f776cc8b807f4dee19b26bbcce1e0dae71aa4986ef742870bf7ac9c83cc479e77257190544eaa158dadb05e6a641e7a8e2aa315fb889607eba2b2dae20f9fb7f638837acfc8d7e2d52e7bf43252d7c9cec1b3d51e3511854e11c7751be959b73ffb3fffe7f6b3731eacf28f67e55ae2301b57d3533319736ce77be7b1c376d8df98931b6df8fe94dced741ef847e13825738729997d78fcfefd0b537255ff776664e69d1999650f73e7c37786171e1881fd7f75467e3d195fa3b2aba33caa0db68fa6eabfb7d67b2be0df777fdcfdf7d10c683ad7a915b0aa8efe3f1264414a82d42ffefcff66511eaebd3ffc45723f5bfc6b16e5d51f2fa2b4b8df082f8d867fdff9340ad2fc8fd9e2eedb9dbf487f46b3e6f7cf4aa058e541b23fde37c9e9d15f41ba59bd3a455d2fa0af4f26d16ce956bf5e5f5864e7ce6e16749d04fbb3593c0b48f37319648b55942f96d1e1e2f14cd11caf16cb3c20ab60ff4a07f5707a54dffbdf2faca57f57ef9e07bb4a2904cbe5625959693f93eaf0455bfa8b65b058556db90a924db0bc6ffe9c0a9d6df00fafdf2741f273f59e54f5e7fd673457ef57f962e9ce82ea498b65712a9cb8cbd8ab3564d590cb0f2f56ff47e9ac7ace2bb928f7c380d2b02ab4eaf695aafb76375b64f1ec8f28bd2fdc84feb1e12a35b8a8ffbb8f16eb3ca277dfeee2c7d51fd1e2decda2c4f5c3280d9645554c75e27e19ac16eba51fdc7da4e4efab0755ed9306f9fd7a593d73b1ba6b4cb1fbaa9fd63659d51566c12eab7eacd35a731f7fdd93c05bcff6bda3fa932fa374563d6355d463ad16ffef83bdfcef3b6ffdb37e0fafc883553d32926c19ac56f75e1965dccb133fabfef4f2c4ac8cb297c7258dbc666ce56ef5f2f734aae79ee70ee72f8b2c5f1c7fdcbb4d91cd811f6561fdd1f6c7e4e545b2729f0f02fff4907082c076df9cb88fd23c58a62ebd0fc8d65d92d56b314aa32c8ffce73361e2be383adebe7453b2ffc4af2fadd65e4e83e70b09119e0faafb5e1cf99d17072f5f6015baecc911273c9c1c0b2cf7e2f85591397dd14e3b81e99e1edd6771b4ab067bea2f4894ce5efcbc775729fbf2d87357c143e7e44c94baf5303b9e992dbc978761f0f2e1f7fbc5fff138ab87d7fb8ae6c772912f52d58d6835dcf6d5f6a2dc5f2f37c1ea1ad9a51ba5d96241af900ddcdd1552c76f5b0d89fd67bf74cfc2f7ae91ca82349b65d74b5603e43e0e8aedd2fdd45dcb64b1fc847ce093f033e274e626ee55cd72b8e3f0fdafbde1f80d5c3a5b2ca33c4cbe7273e0fb5fbaed79a45c7b6fb5c80daee9da871b565cfc85193748a265e6aea26ae94e56f7474dbbfa50ac52c35748dcbbcba55bec75f6fbb2f932783d30cf49ec354718bceeb9af840f33de9939dfff397bf7c2fdca77d3f43d8ba412c81771907e70b9c85ebfc617ec9930a059b0bcf7c36565275f299d2d68f133a2f4f7aca5a3d4627585d05b3df649bbabb1982f083dcf98c1265a35cb8aabe41b5be723d18cae13efcda07c57ecde77fd30b85a78415f2bccf7852b3bac5e445f2bbf58266e7e5d03bebe89443f7f7ef296599447b374b1fc6cfd22b2abdeecb377a524d87df29e8537ff4249958afdca6d714ea3f4eabb16de3cf0df1dc9afa5b34ac5fb0b5a572efbda5df7be9bb95e44a3bcf8e203561109bcc6d4bceaf665b079abe5df17af565cef2ffd5e4be74b375d65cde2e37337dc370bf4cfdff7995ef17cd72cfa4251619e5ffd999fef3aaa397f91241795e29907ac82e507abef0fee5b85d72da7af5c743fbb4a3e7dc33d59e4979bfca3d5fd1be1da74785ea15c16bd429b3682c715fd65d12458c634c897d1a5367c2d7e7d63beb9f31aa57be6a67d27fcb974934f57365d90b71dd05bfffce9d2c57d18bc9d6d668b464d79eb9fcd8f53812821ee325a5445cc5e5d9a7b411ad495d93b0eeea3571271b089526fbd8c83aa87ff756e66fd942be86dfd5f4b1c1b2f71b3d5357ea5ab7c4f41e205e48b5eaaf372ab9c2c5ed7ef1d7fd6b3c42a58cea2ea6a353eea4192b8b91f66b557f64472e7a66551b5f9bfdcd95e552fa89bcefe582c67f7bbfbc3929c2eb63fa346f59cb9ecbbab5c78ef5ae8faa1cb31ef5d5e2f37c1c18bf3b1c08bfe1e0594bc23ffec3a3a77f5ad97e79c5465ceb33cf3de2badde6d88d52abcffa81dabebcfce88fae45f9917939f1fc8c7e9629b868bfd82efa55035a69e3d716f2e3dbf6bbd9f7246225b2e76c5eb0bab62751fec02dff5dedc535d7a36f0d395fb33080377af465e0baed3da4975f4b246e9cf3f36cccb335b779946e96cf5eaf4b33b3674eb96aefedcbb84064bfe70f6de5ffacd419e545a3d4a9a29affe7b34fe9ba3638debc3fd34d05c9a674135ae4ffc432e3d39e567eb97873f937cef873d9e4a833c5fbab51ff8786eb1aa1d242f4f658b7a7df8c205797acb32f849033fa7517e727a15a5331afca4d12c3c297555ac7c97d2fa5305e9e6dca5fd17389ecf83554e17276ff7ea231efcdff5f2f32b7ef077c4aaa73cbb8c3e945a05f945998d4b23e2ee37b9ae943c2a8d2b7cf54d23258d67befa73ef45b3e79f7505ebdf7b7770d238ecab3ff7c99ae651e6d65da43ef16bbdc803922da33477bd5ae5a4b55fa91a807be3f3f0b3feefd0978e270f1f6b7fae1aee87e9f7d5a6c2a219b9cdaff5aafea4fbfd85b7fb0d756f3bd979a87fdcaf8a34afbdaa6f7722fc66d7ead5bec4e1f8d9c3972f92da07ffe6cabe49df9c5f15ab930d0e7f51f7e8375b1dd59fe7c7effbf9610be4dbdd3a8dfc6619bfff75bfce7fb20fa7c78ff561d5edefbedd6d82942c96f71726ae2ba45e4c191f49d77f2a2d73addcc1a1ff91f0cb29f403b9b099673e90783b3b7e207ce18dabae49d255f52f0956ab463dbf2778ecfcb3753db82eca1d66ae8f04b9fbb05a4d7f201591d47de772358335aaffdcd5da865d05fe7a19dc7b118996eb775bab16add76f3f17cbe423a1431fad1e788d5c5a3defbf5f61e3fe7dbabdfdd73a8df2bf2ac57f76a3fbddcbcf5bdeef8aec37bfdfbdfedef9fdf6f8e9f5ff7e85e7fbf7758ef40f7479f5e4c66a7f29544d0c59be3c28cc67a1c3266a0b21fc4720843586e9081d6cd09b7f0390aad668fb9efcc77cf531aeea95ec0161c576bacc3f04786ed0550fb7033c37756f11cf2de2b95557bfabae5eeb9267e0b3c2c3129bbd9a7eeaf07a3add2ec60ed75dfbbc3e0b8a5e4964a920fd5e77346066c7702de62c3d0702568af87b3fd1365eaa3135c0d986b47ace0fb377a4778efba424768ffa691dfa231d5babf1f19e1a28adbe92f7d793c8cf2649187a89b1c2d6ea58bf06b8fcd4dd9795f9095828bc11fa3278f55c58f8f1fe7e7b543d9f190d98ffaacf474fdd1f7b7a14e90bd44f958d1f85d44f47d974bb988d86fa1a23211ef7e3effd94f9de9f6535e876dc27ca09607abe981dc1e2452ff4a2de084a863e128904fbfe6a34d4673fac4e43ed1b6a8c632bccb879df6c921a0b8c3a0b9f8305496051d7ed00061eea6b5fde855e342baa776ace1ddbf678cff899f2bac61c64c67d7ff38313420f812e91698aed517a22638735f87a3c186dd57e7ca4154d12d8f1653827fd59aa73dd3591e19af45910d83daa14dbd984cb4a8feb6c4e9e55b74fdd66abba6e45fcfcae471aaebec6b65278fc6851fd9df49f522b799cedcfa5c7776ba8dacca44ef9d9937c1b865e3f2cb0adae9da41b07e6b6ea973b826011588bea770dda9f464fe9e13d474366f6d38c4fc20955dfd64bf4c5ab724a6c2b1cb6476b87db6d7c0e9c5c3f3ce3a7b9adeb691ec900213336ebfe50f59171d30f67a9b9a70a3a761d12ec61241ffa9c3a735067664a0600fd9e6eb11aa8dab2eabb87beb707d82fea341b45bc267248bd283cd4efa43d495fd87ab2b41e0ff67db4ff8238d03fde933dbfbfb0f578adee134af1e25ba75add26efb4e1cbfb6930acd3822ed4f9d3f66c3fea9381c755ef2f30136808d5189cf49f366eaa6dbce8f1e459f577a8c7deb6aa7739369fdbe1e5f77a311657a33e997a456f7fce3fbef7b16fc990fa62d506d26a5cf74121f2384398f47bdf47723d0e1e467dc2b888503ff2ff33fac709098464449e1dc6c3ac0983d0cb70d45b634419578645a34b7a1b3fba651f12afee43c4d6174af178a2477c0eae713f7caf8dcfe995421d3c9ded5b0a53e96b837aa99ec33a9d96bf1af5bbbf7caebb9e1427cf5ae3fe6caf47aab942cd4e74e6753a24c7b6563a88d4fd1e245d96c860062408a6d1e3cc4bbad57c54a769a9da79ff5d1eea7ec8eb3323e9b25ea2a7937e3d4732c4d6061e6754cf62d481fe4ff6afbf89c851add5f38b0b8f83d061c5f1f89dfb47171cdf6fb7e0a8abdeae37daf546bbdef8edf5c6412d5cb7d06826ac57867cd1592b45bc3e18d5d36d36f738a124fd5ec37a7bb52069d86eb561f0fcdc8476c81016d8ac9ebd9a7972379d46954140d738797c18c9f50261e3c9605d5dab0dc76ae1d02c4e160a0bd7aeadbf67c80d0d584f00ccf3e4d36326696fe5a0ce42dd2bef49f1383391c0795c4e47436381cdde8bb890dbd93ed6e7cce7c20d41bbb8ae93dd5b61dba08d51106e88ad1f26a075f5ccc3fb35f9cf77755b346d187e1ff53beb4982b36068b07e02562399a5d533f060315398c3624462b1ad084d5b9c9bb87bdd66223a37896aac37d457557bd68b90347ea8db3691726c2d664a9d571f164ad1eb5646e49945d4895104919091c13b8b27a9f703b0ffcbda983dd6b936407fb78d6b83e58a85ce4b03a33ef7bc50855e42996954194adad6e384d82f7abc6b1b8b7a019c748baa3db00c662e72665e02abf6a07e54f7ef59658c02b16bbd5dc41e17a6bbfd7b1cc6e7a1fed542bbfe0e63f9d856cffde1b5c1cec315e96f0f4e8757061558358b6683f51996fabc1662ae6e4f0ddbc6c2e3f4bdc126ad3cb9cb63a4a71ff4bddb1a4c899b463f8355fe47e126f46363e954f41894e21331291efee038e681f9fef0798b49e872dd07e1fbe30d4352fcbd11291e0ea2c7577ed75e3a2bdada4badbdf49f6d2f9dea83675bc94961e6c906f553f5a1d2ed58868963c355354f567344600a995774238fd7365ed4dd471fa8a32bfcf20b362288aeb00c8b5bb2fcb3220f2fc6dc69648e8aedf19fe4f7b38fccf7ef8ffcb37eebfc2ebfbfaaff97f9fddff9475e10f8efddff57d7832dbfbfe5f7b7fcfe96dfdff2fb5b7e7fcbef6ff9fd2dbfbfe5f7b7fcfe96dfdff2fb5b7effe5fb5a7e7fcbef6ff9fd2dbfbfe5f7b7fcfe96dfdff2fb5b7e7fcbef6ff9fd2dbfbfe5f7b7fcfe96dfdff2fb5b7e7fcbef6ff9fd2dbfff1f0364edb14b7f07afbf79f4bd4f176b126c8234bfc0a9792978e4d53cfc93582aee8117982efbfd76b9521e1f7e034bf5c830bcd0f9fef0d062a95a2c558ba56ab1542d96aac552b558aa164bd562a95a2c558ba56ab1542d96aac552b558aa164bd562a95a2c558ba56ab1542d96aac552b558aa164bd562a95a2c558ba56ab1542d96aac552b558aa164bd562a95a2c558ba5fa87b0542780a77f0657755f89fc91151fe3ab0e42076c5587ebfe33318bf7b0aa1b86e0ababdec62c6e63f0b56aea166aeaa83f9e63f1e154d978666febd8caca45528e91c08c649afb72b720fd5e93f4c00e9949bf474902d7e46931eec787df598c9133f390947951383fc84ea3e7fbc6d6621ff07d148d664d607d23856b87af9304cc880c735fde8544068d9c54c7b73d3e6b34ec857e22e5d836a81f35e71d44d77ed1635c19cc8c6417fadcea4570ffdec64932eaf0facc41423c92a575b00fe8af73bb0d418654d7bddf2b30d2a86b638afbfb78b14d6cdd3a390bb63566b2afef281a45fb60f7f3d1b057b84860c6b213590832aedc8da751efbbd32413e990bef07c7fb28f9b3b64a2b17e68077506e5908e860a25435878518f73d08ec5666f816da58ed7ebc9db9993809963f7b69e4cabfa8587f7c5b2c438662f2443a37091c21edbadafce3cce9939666fe0c95d168b90abbfe5a19c04c6a3a1b1791b3fb8977929deb81c2c9a77acdedf60fda4330b8aa7c843b0f43929c5e6e861d457461e4fe2c014a3d19019df36f6e24947fdeda8b30fff509cfefd9cd7bddd9cf7d086e96fa7bc76cabbd59477d320b4764fa814ba173d07a19da6ce76329fadb5a7db05de3ef31acbe0d73a5a064975f047becb3fd6896fa40f6a917bfc27d56255c4add422f77eb4da562db66ab1558b9f538b6f34c4b366f465a9f0641a7aa8ce8df76c2aa66af787f5b456cdcef6f6a1b74f6a9707abfcafab9c1d2792472dc7ffa31e0f8ebda19ae35b8f47abe75a3d772b3d77a21f9e759c8bd8adc72bcc48aef37d8e8fc743b8766da34e2dd39f65b5ee1b0d9899cd7633cfee6dfcd4f86917b3a8499533cafab36ceec952e9173d50dd63342974582fa14c930248a8cfeb9c5462337ee8cf16b3916c501c35699e6caece91baf039b8c251fcb05f82d7a9759e53f208b983e87a3cccbb87dc848dbc10fabc46fdd438a4d669724226464864c91b25c75432916d6e672f97ef637d31769153bd579d76c7661f673f2c6636a2dd9fb53b87767f8ee68bf1a8df7bf92e4d3dfaf1ad757fbd81fca19edf6f31ef17f7c23fc816fedee1d8efdceda8c20fefa795b9822afcc0f1428715f8ff57157c4b156ea9c22d55b8a50ab754e1962adc52855baa704b156ea9c22d55b8a50ab754e1962a7cf9be962adc52855baa704b156ea9c22d55b8a50ab754e1962adc52855baa704b156ea9c22d55b8a50ab754e1962adc52855baa704b15fea71169f5acf73772846b2df125723027b0ff0854b64651f137c4c956f56e71b22d4eb6d54abfa5957e8312dc9f2d66fda4c6b236b85059db78a94183a1fe30128fbfb3e90b1aede8e97f3b05f86a7aec6a34186dd5dbb3c2eaaff6bf8b0e562bff4ecb056b757fabfbff9374ff7f1e09acaed6efb2bf847f86fd556b35e196266d4bfd6ad55aabd67e5bad5de27cfd6770bc0a6c6bdb49bfb2670dfa05ae577d3f2a941cdb5ae92042479459bde2787d747f5deea4ff54a883a7ea1d331cf57eda9c50a9fc9f76f1d4fd613e4536dbadeb63b38f516dc7bf68bb49c2862eea2cc6facda781ff35e15fd847e6fbf747be0dffd24e02ed24f09f3209fc6f0cf9f26bed2ee3f585ccb907a18396131ebfc4837dac4633dbfd0a0ff6e1a8e83abfcb8315de5fc45fe6c176b9efbcc00b2c7b8da2dbbfef358aee59b4e5c1b63cd89607dbf2605b1e6ccb836d79b02d0fb6e5c1b63cd89607dbf2605b1e6ccb836d79b02d0fb6e5c1b63cd89607dbf2605b1e6ccb836d79b02d0fb6e5c1b63cd89607dbf2605b1e6ccb836d79b02d0fb6e5c1b63cd81699f51adef4777060f7cf3ec9c7fb218ceaa5e0014ac5725fc3523d3c706c87ff6c4e812ecf3d3e729ddb81a9d80f285157a0a9ba0c2f708f8f8fd7a0a9f66f7c0d9aea59b44553b568aa164dd5a2a95a34558ba66ad1542d9aaa4553b568aa164dd5a2a95a34558ba66ad1542d9aaa4553b568aa164dd5a2a95a34558ba66ad1542d9aeaff67ef3f7b9dc791c50ff003197b952de9a595b3ac1cde295939677dfa85cf7952c7e93b337bff58e034e0e7b46d8a2c168b5545f207fa8ba6faa2a9be68aa2f9aea8ba6faa2a9be68aa2f9aea8ba6faa2a9be68aabf239efe8fc82ae07f7eeea2fe2d64f53fbfeeb67e624908f87f73ddf4275df55fbc99f543f0ffe0523e1444410cfdba94efeb52be2f67f57b27f2f37a3ef1a4b8003e8644d01abac4f6a425c7d0d340bac43eef5f45a822e57359e9b42615cc216ed34bd98732f2d08dcefb4a649b35e5dd39e61b992eb121e4dd822efb35f2a9f3e3af07cd9fefd3ebb33cd6a4acd4041e76d12d562a9eb6c56d3884887b06fec76f13ac190fcd1f65b9704810b78869ca4e05b78e3c223760b20e8d7e4d3bede32e55bac4dac0d3c01891b084e7c0e8d1cbe2493d1d289795dab47de8e3bbe67b7db1d18f4aa721c9e3f36fbc7f94df03dfaca2f7672d79465e22cb2576865e2fd3a59adb1e07871e2aa73c7786b00b2afbb0c730f821a7d29945f89bf75213f36e91c02e1d78da94fa0f39e1c945e98a25a63138f4a52bf2c83501a522801728790c67e81d4de06b8dd251678c504dd29943e8abffed6b0e7f6b0cedd6fd8b58f22ef1e37a6fe8df0275b1b7b744ffb7a02e84df5112c4f01fb104f94f495df8af7fb7e62f415df8bbd3bf23080643f7fb3f8924df3afc4f22c9cfa25f9cee17a7fbc5e97e71ba5f9cee17a7fbc5e97e71ba5f9cee17a7fbc5e97e71ba5f9cee17a7fbc5e97e71ba5f9cee17a7fbc5e97e71ba5f9cee17a7fbc5e97e71ba5f9cee17a7fbc5e97e71ba5f9cee17a7fbc5e97e71ba5f9cee17a7fb85befd4bdae9ff0cd66db70ed8a768183e019ebf46acbe17fa4e5991ffde7588ff1e65056338041338fc83b282ff53ca8afcdf5f87f813d8252010c53008fba2acbe28ab2fcaea8bb2faa2acbe28ab2fcaea8bb2faa2acbe28ab2fcaea8bb2faa2acbe28ab2fcaea8bb2faa2acbe28ab2fcaea8bb2faa2acbe28ab2fcaea8bb2faa2acbe28ab2fcaea8bb2faa2acbe28ab2fcaea8bb2faa2acbe28ab2fcaeaff1965f5037cfa7f415b016ab4659df7f986e9f7aee9dfd9d0ff54d116fd3d89f5770f7ea7b3501285fe775729fe1598f52fae52fc466621ffbdbb143f45ff0b360bbaff776f53fcff473aebeb36c52f67f7ef3bbbbff53b3fef5a54ce5e16e93e376072cf7c6908e1021419715799644904a94960774d690a8c78278f91f7f7cd1a787b1ef82e18f1e4297ebc3828e58b2de9d4952e1fe3fb25b2c710c0ee9ac06e2d0aee1af2ee290a661f5a1495f05cf5aecfe69b2af4b02bb4f6dc6ddd33819b2d2e1fa7523d72f9a3eca3fc59461cf4bdcfe592c262c4c9638fc3441edb529a8212d8c953be1892936a23ef6844de4503d8dd539a1ae292aa6218da63be29e2566b44211d523e7f976f7ecae87cc82d72cd965ad412f8751ec3121878cd2af26c1ebc7563515b587eeae1a74c54913efa5ccedf723d72917ee4225f80a9f0b82b2789a448b2063e550470d1282d79862739479ed6c49dd62427a95a8ec6d98dc629b6b8aa3feaa1dcb83d9a0451f3a4758fd46bced033f2a0abf3c0a7defda8024f9a438b9a033fc96344cc032f3d43efad677313f9661585f48c7c7388db6416056d0b3b13097ca9f9e8236f0e09629e91274129ff87b151bfcb27f2cdf587b23cb98a3cb78ab44439272539a7981b35675bae3a7fea2f955cb678baae91bb20673935a7bb6cc33927f5744a8ab1418cb55c53b241cc16599217594ef72c4ab11c8c5568aa897cb30f7d310ffd624f5af74a4e6a4b4a6a887d6a8e3cb7563ef563879ef3fbf1cbc396fcde872be1dd2af2c22138a939f0b02ef5b82eb4a82e46c22669b1b75ef28477cfd86bae0f9bebd43cf0b0fa533fc7107b0df879ef2776fd957e3e6521e4c883f6189140911f8ab465d7b87541a5ec71ba6d968427cf94a6c6c00f0ba56db63fff1c1be213ab229e7b3f3b27273aeafbf0eef39674461eb51c1c581894f2cdac34bfb98b13a7f3614f3d698e3c350fe0a378dbcce7bda0989fb4dcfeeea3c99348dc1e5be0994d5252389df71f769a08d290b61cf8d657ca73e0bb8eb0fd9cdbcec798639dc8a596e15286e94a2fb7762d076c9e76f920455adc95ca59b552c4e94fbbdfe4f2ed473efe7f1459b3095b0e8a0523775d49fdb44b734b616c8e61aefea6cb25f0c3262e21e4bbac4a3b144949b5494b2e0a4d0d6149adf1f9e8c29f7d709376ef3e6c5378eb221c42fed32e3edbeeb74f79a83d691b38f0cd4614b48fb10c3e7c03f6edde56e9c3064cd6e50dd7555d8e646d28d56d96a44c8e749d7acf9fd6a38c04134c04f53d97cfd0a736a5858ab47557a5e5f6c0d3fad0c2b6a44db6f8f32ed653819b4d41cc2282b933b2c83ff6ef14bfebe8fd9afe42bf93488bdfeb5c52442a12816a92122c457ace5d48a21c8ee29c86f44c57b22d87d4df9f8b253606be58eafbf7712046f9a75e72e73dc63405c6e7375ffe87fa3feed9dd435f0223cfbd443e1c62de994521ed234feb451efa8c0dbcb6c59d59441e9a071655c748bac63c59849c7bc61f7affac23b32830de7fb69ffa1f3e654d10b3093c238fe1e0730ef33f6d2586b1e6df1d4bdbe13cd3c15ebfe8c7706af2ad5bc7725cdb8728ca65f3fc697cafffc7ab545a088e4bf2e738c1dfc6d94fcfb7cf0d7d714d04697b7f97f24d939ce28f79a49cfdf86d0ebc7d9311f866ffd659e84bcdbfb07324f28e59e4dfe5b4777b1ffefbbfd87fd970a597c3728e453fc8ef32fe7c896bec87ab82fce8e39fd8dcdfdb94dd724bf84b5cfca123a1ce53b8180238cf13b8d852efa83ffbe95eef5896f244fee18b3b690879e70f76f073be1b79ea4bb3c887ef38f0d1c64fd9d01ffe46d9ff373e8db26ce8ad1f33f4418cb21df7579dfd98fb3fda69de762dfee237ddf21d837f190b38869b5ae4a1f79ce87fb4c373678868b16fd579b6ff62739c86bde7406c615bea1b6fbb1ae2ce9ce3322f158b627fcca78f98f36e430243cf28657bfec57750fc679e231509ecb2912f3501626e4957e74f8b5a433fc9cdb69943ab289236bdbc8b4a7ff7bc9df91a187ae01a232ea874d45b6630e6d15e2cc1dcf5b50f9b0a5aee9de3d4bfd47f176931974faa0c7cad31f9776ef279cfb5d2a64dca7265029373ea9bcda7bfc98777bbbfda9e7212b9e57d9ffbff6a9e514dc637572aa8b328481f7e23f28d8f582df25a1f7ada24f24d2bf2cd2f7e09bb3e7236c4bd529e5c7edff66fc795da035f2a62cf05df6dff5af6537fdfe66ef35d3ec9f8e1df9c0ffff87b7dff512f34a5196ec8d90de93b356738ac6bf9d00f1b944c57fb36476bfcd7f67fd891f096f3418aacc99935e7da9cf93259d2b7ebe36938e6eb1d5ff55fed8b6f5af99b5edd1f7dfd9137609f7262dff5dacbbfb7cf5feccbf2b03df5cdb78f69020ffc16337ee616ce8ff9defc69f9b76e52ef98f53fd60fbe6df58fed7ebefe9d767e8c81d3ac89e0826ffd851eb7fc6b5dfc56efbfc868fc361efe653def5cec870cce6fec371ffed8f77fd1c78fe73ef3a47f29fbeffbfa9b39fecbebbb0dfd7d1fd61076c19fbaae7b87939e6f7b75b9e665d79c66babfdab06bd9f4fee19fffacdd9745551ff7d7d38fde72482ee3b526113eeed2cfc33fb5b9ef76df5c29ef2e4a4b4229fdce499a35e58f55a6c545645dcba9494be43f72c10f1f259d1ffee81fceb18fdcaa13cb3f197301fc162b8e39b3a8bfb289bfb5db7f3cff7e376e22cd92228f4131bf0fa2f01763f8efcf8f35808f2d819dfe2fede3b36f7f92237c7e2ef25a91f25a2fd2856483dfd6d6fc7bad4e35f25feaea577f9fae312235228dae3ff39bdfd9cb1ff2b2dfcaf39befff710c6dd6f0fc5c4fe8e5e3237ffe6eaf7fe2ebb7d437df7afb8cad0c98c7ad8b88ec879fef3f62a1630e49eb56294f9e998575a16f5241a76db1e082a1fbf19b14bd6cedff2217fbaded455ed08b1e09a50205a59f6d7dcec377fee061e0a76cf9a0b42e1af91af8f6297faaf3b7ddd1dc6ffaf0119339aa485a77fd56772f5bd812c1e690747fe5fbffc53c7cfc8ded7fcfa7ad779fa5f79abf4a5ab7483fc7e19b6ceffcee677c14e9e4635cde79c87b4e7c8b4f6fdd1a812f3571f7d91799ae3ff46278d215c30794f2ee47ae2dd3752e9f8f523ac53ff1b5ff351b02e3abcfc5f7da8cffe358fd894cbf954530cf3ff529bfac893ffd4278c630f4ce41fbb79d2af46f6df2cfe6ef5ffb4b897dafa7fed4d7fdecfb3b0f0065e6f13b79c13c8039f09dbfcb9cd9272d897cdb73faf3f9fef7bae4924e7ae7eff56f75faa7e3d57ccf451dc42c0278719296abdef6ff27657fe4b0a15f0c299d1fbfcb71bf8d3d45fedd9e47da924348ff22dbc7b8bafcdb67bc732b99d3c0b74ec3938292f6f8bede9abff9853ce4df7966b37efb9d98e1bde67beb2b39a9dfc4bcec77399a48173fe5875d30f43058a625cdad31df875cdb7425dd70204e2ceb5cb4c13ceedc39a61fad54527ff31c453990e6db90c4fef6b93fcdf17eac1ddf6bf3a4c58ad8fbc867ffa95c7f62cf5a1ff852ec5befbc5abb52983cc377def1d33edef3ba89bba0176bc8b39bf4ed136d074a9f4e6d94b2858131f8510795745291fdf9b853a96ff66fdf1879efb8449e1fbf03f473cfa9fff4db1f7bd26fff31bc6d3946c4feaf6315f5b07fae47ff22877ac770f3bd0e6a42fabdceffd6bfdfb51379e42af2dffc2ea2213122d5c6c75eb9bba67c537db393bf91e5f395b42e98fad22af258939e7fdf9efc5e57fbd21a7850a3d0bfeafe2f73db3fc67a01fcbd0ff8752e7dac8b53d82d13b80143eb9d4b7ec8f5c3577d5faffc6e0e5aa1c7d51fbec391b0947799effb9ca22095c1f59bb267d07ee4d1cccfbd506c0dfdf4c77b59489ba0d3869477d6773e1537efb9e916b1f5b9cefca5ae0f7f697f8b293ff22c3edc92f387ec7f5a46e6cd2641deb9e537ddfeb6de36463ef364032e8ab8c59a98ce07a533cfc0c3aeb0754fb393b6d82ade7d9945e6318becb1c56db2da0e17f85048d99ccbfd599d7f9ea37de8e48fdf09a04c77a0fcffebdf62fa7194d4465bd6fd7fbebdfb9f2afa175788fcb1f8f7e36a0cc421f0fff2bc1afdef9d577f93fdaf0eac41f4ebc4faebc4faebc4fa3f38b1fea3dff8794eedb0334351c6e3edfe1e8fc743341ebfff4f7aff633bae63589064d7c1f6d829c3da13f1f36bf147c17f5097f3fbba6c87d32d27e41cc8586d27722b9095f7ea6198af8c4268d6b7e4dc35e3f19aca5ecc676f29784b36c8b9b6f92707938be7caf994124f6047362247c2c0305f0d1f150c7ec987f3683ad39ca348e53821488da6c8e393b5a60c614ebbead95eba75ccc99932eeb731bbb5658518cb555a38c2a247bc958a42162cecdf789d5fc5894e3a430c268d21063ff6eaf398a5859e467ed14eadd50d36db591c4ed486457b08b364208385255d5d41929a5b97e810c0c0a6f6a137eb2ea46a94bf55313d8c7fa4b7e7eff5f6ed4ce13f198bf0afea8c3c624d796e0a7c695076f55d97407f3e43ff789aa394c76e388f8f90fafe86fda3e1ec8fc7838538976517cbc1f81fe73f70b329dddf9ce7fd076d6ac6bfd926426db1f5dbb33a199c1779c6d50b57219079baea4d9315a2df9417a5ce09a242e7225d2c3a9fab292bf424d9eca22a392b6365e40d593c3445d2708555731d4bbd65a7f6425dd807a7bf879ea91f8fc77bec54967b3cdee9c75bfce20f1d7a1bc883fa380ffd0fc65a79ff132352a7c0dfcf5809e653a6fcb344febde83f9089627fc8f483c3f8aee7ff60ecf8b7dcfc07cf517c63597ed8e4cff3a97f28b7f1277233ea5fcbfdcb799dd1925b2abc73606eb73d6e78e7c31fe745beb87ef200baebce0dcc8289b3051ecf8d72483de23aa0b572974421f51fe22358833d6073b158aa1ce40386868758f1cc75f0d77a622f09a3307f75ebd6f5e0c07ae205a59f170ad40a2613d1e4ce56185ef664f76337b8697ac3a7db7d0207120080c0d9d98ee8f947bce354a3c0c5dd4c087f7563afc1cbe1193390d5fb315cfa0adbdff33d30d796d1e865f710ee958764798d163e78e00c72b83fac75967006402781399495cafa36b19f37355b1e39c01437707ce4f989ab68200db7b9e99ec936769d35ec453d0967d636deb28318d91f37c73612aa44ae0d9564d53012d873506e009498351011be189fad5c25881adfe6e427ed57344466d7a6cb2a7dd98e4915b0921d2102b68c1893f234ecb92abf34e2a0cdf116711245da711266abb68c32c45041123053dfd6fbb6409dd96eb281db736cd1972c21c63112b01114243ff5725a902de5082caf9e8f6e823a2b220a1cd93413195cad788a4b456f4304a6e258ad3abb9cf015b92bbfccced1d30c052a3eb59ef58d0bd440dc44c557cf591765bfbd05419fc328d9826bdcc89c54a5db4040f63a431a9b8454271927cf73a226de3b36e93d4bec4295c58b45147d6f31e1192eae2d624a333c0a586a37b89081783477ef268f1ea45a616372f49a8993fae456de91b7f28868c11716742f2949012d53aad4fa462bebe04a503d109e3b129d923e8879e5c2a33e4d8d9f47d6b05e2d5df62b6a8a75cf86a572760f626bdaa4c5e4905eb9c619f3e906dba6dca94355cea33f732e5bca0de929faec0cee1ea5a0e39d1d1ef07c62802115dde050266f4dd9b7aadaee39261ea1bb384e2b73a8730afb13c55d9570f6c2c62216e3914ae90c2c6f2dafc776d296c53bc625533e983eadf4d16d49991eed67fb352c6b6e33de2ab22b0823721d887779a9f5a1405861ba37a8e0018e64579499b265e25ebd2150ab738b623a1d88ad36fd160a05917fa499e16045adc593cb990f0d2a8c444be615b331f8bc2e60e0e04cb1d5d3815bb4bcc7e5cd08940897a742165b2680c21e2a86077e4f31bef677c17792cb237740365f81ca402ebec00e05a5b76269447f7b7991c7a2a0303e27c88852a0bba54b713d60bde610a5bf48b6510ad774639ea5708967d854742b39ca78796da2265923a58ca30628120c744ae062b57bb3ea23a46b7bbddd847a5790baaf51f7c6a037f74951d1cea3d81d2f45e4502dde4d1d19b68e3ba6bb7ee3efd6f39c19f6f06d8f73b278ba4055ec2e59ada0cd754aaef54ac9eb2b43140a8d1386d5c00e69421ee3111d5917a0f1e0191b0b31e1e91ab579bf8095a4d366946ed3ed21bdea2e6e95702ba345d3291c824115bb53f6c542b8626d4b4bb7fe99613b84192b1b8ef0d4dd4c176175049ccbb8498bb369c887707b69664562d7adec41702c1ae811f06ec1dd6d095a684d45eed488cf817e8b3a905aec75904caed2ee4864202050bd4299172236ad733484a99e7bcd6d77a3726823f0bee95ec903794202058639426ac6b9a1536302c79855c030e9d40699d07d445f472f32e2cd559f8d16999b7947813d136647b779b90d08e7328cb781ea50f3c2683cc47b90ef418ea71ac0d3c0aad2600248ab4eead964d024c6c8d7b22084e128253cf3d709119d68435dee6e6efd5eb43a9a9b4fb13f88265b17356a417565ad0d2a1bd4e4dd4de8d435331245a6944154fb7dd4936aa0eb19adee0d4ad93a0bc9213b18dd7406b3d7f807d844af0cddda65ae01d1c5f5d7dddc6a6d0425660e66173ec56a8e32618af063c3a994eb7b3eadf34e3e05a1ed8a2dbd192dd34360728396670300ed6bc3f03cb0e3d3b2542a028a99730172f6b19522725765cfba062b0335300b384cde17fac3dd9921f587a139ac6a89b77d72d6276acffefdb5000ff71d832b0b7e5ebc913b8f07ff90ff590c16ff510c3679b70d7c774ed99f7bf9a12fd6aaf5edb7ca31d78e1dc2364cead62c41d6892f27ea3794aa276e69e9273f910528c7dc211b9c51b8e58da7bdb4ed9ebe90c59b05b3afbbf3e2645d7a128f57189ea42b6a0fb139ce04d7aeebba9e211fc3d89ddc9e3be5109a4df1aa6e810dfc6290129780fdf63c18eb499a844a31d1842ee4333f34df4464e7c9ebe0b395f3d364f05c055005758e91d06d871459dcc29cb02f427fa01a8e68af39e62c37e971a4ce1ff85346a964ada12a09ebca73d954cd757e2cce455c9d22077b9d89f653ca7357d50c7180fa17f98c8417a14086ca1bd138234c1ca14c76a05c8d8760b1890df9545db9835b99d8dbea2e31833d776bc1f6a74dbd6426be2deb4080e2c808ea737e414cb5aace0ea74786201db04c1ebcb8d8324d2d5ac5b38e57748dde2ce3bce32fbd1fd5bbb0a205b0392cb7866e63dd754f0a64c6d45171d743216b322600aba906ac6173dd76e982fbb6a2a570326b0cb8c154080556e4a1a58e9b874eeda4595613ca3aeef9bc69ce82daabf5f91271289e71edf0e0b1876f921bd099a193cf7caee18a8e70291df3d26a671984d494823d1e9cfd0ee385709a35d0233ab2673607ddac64d3528b6e40657c25e55eec8b832a2b05ae1dee44a606465b8ef0b28d3148a5a2303a04de1353b1624b867724b54d96f7582f9aa817ae8c686590441daf4c5bea2cd76527800b698dc05ebbc162ab825b4b1f68820282e0c0c666635463c286d4f08a230e61792f5ffbdd1e62d58cabfbb3d63ef264c69f8dbb68bda70b66a8bfcf93a93fcb939dfd9fe4c9241b7a61917a07f85b56d5fc760e01fd86c3700469cb84e68f6700ad3607be764da199c687447162fc7ae0a6b29079293725e06d5ba394e3e40f4d6e3f4aad34bae82847e99e3a8ed994d72531619f944f75ac91651158e1463fd5197dc89353e38e83c0767d25c49dc0b01a9b81ed82f0e4f5a0f0aa0c54160d5d670a28c88b9e5abea3384a2bbd4cc64b52b83361dc66ee562fb09999210baf5097087316a582e5691e9a10da043d7370782e78670481368ce659d3cff6898b0f2e5fb7bc1089fd76ee4eef63ba250cb72ea4c7b30c913a3113aad203c9ba3c63e65ee435e1be0235b783ed307e3cf748bc3b7736adced45e0b842f74242a22d9a79d7999ba34109e5913d5386a94b51861d8eb86afdbdde11a0a4ba4134ed9c1e7b95963bcb5d946af2f10d54dd6691472910544a649055bb168d6177908e7d856497b11e8a920d5273b31072e183cd826c82609b504b5016703296b55e1871d0ff3e0be44fb4cc5ae5c391af3e60ccb71cbc640e9455155a0ad61ec6a8dea0e615ed84877f31797e386fbb23a446fab2de1e2be8fa210b21b3e7c3f5131d94dc4054227c70911f710b923c5d1b3281a1b1dc3e79c2a817322dd68d1617680810528a6e59997d01a973476ef50265ccfc0f1e87934a9b6ac53f175f16921d75ed1e2b97a0bb5f6a8395ed8249832bc9929329fe12fa879a1d57ae1be8e062ea222c994e949964c788117c8ca01499fd849ef99be16c81c919e3c11b447792103aed6c57a6382d76c486989877662b4ca4dbd1dcbc77af93c96179dd7efe9b4537f582fb37fb65edeffb85efebe67f00bcf0a7e3f1b337fc3177e9f338d9b0b01b5b9fceb9e29af4e472b5aef98c234fa5aa45fbc3185a3c94acb03250c2abf81ece94723c5564f62a96fb5e0b7a9a254cc34e645105b469e360d274566b3457511d635ce44e042692489e1388ef42486d55e1cb874de99db8b075e080e0024fe1c000cbf71ec23ce448e2f7bb62d0e44e307bd55eb43be86d56ea6e12e99935d1f41dc5982e649ad43a27a788e69321fc549fa397b2fc94bdac1feacafa739a59a6f85cdcb00dd479b24edbe1e994a6bf152adc45d4913bfbae1d9eb4952481f303d5715b7157bea191f47fc65da5e345b70b5318f398598f54a60d38f851b90c19023c5f2eeeaa240385d6c91fcde215ea67bbb42755d93a203360d6082af5c416b6d89f13eca8ef31d06f110a966862f46b76b461464f2095daa8d7173daf5f87bce95332b177344dde762d694071195668fd1140b3d6c942fb5dc549b2b6824e982ca0a0ed3087f4d825465cde6f39362fa201b585d6be69365269e652616ab5ed9ed04a13049055c495e9dda0fc901d66d388282b9e81631dfa6fdd04fd5b8fb1d8c669b3107ecc13f75a24c03694cb1c7d1890c2c163c6380caa3585f5757bd173fadc6a84e8f85424454567b04e812ec0c8f256be4e5e65d40e075449ee579897384a8c146601063d1a37871c4ee964c025078fba2da837da28c95f41907e6fed0d8e974f6f9d233d229d9864c55bae39a0cb3521e318b56c8085e62220accbcfc0d66080b0f3a24cea6055c5462c153d4ab6e40c8a56b817a074fd875001ee18322eee6ab2a7cf13924804ce59341f8582e4d1666bc4ac1f1899982fb6a5b1ad9131f1028d44bc41ebccbeffb9d5ab71ae5908486c5eed2c2bd0b242bd3485aa3b1028572164761d721d7d31d1890cf164e50c0c2692d3495c656dafa982f5e62437828c39df58a62c91386315e6a98c4606e70ede37ab5dec1106f06f5f4f2367932d3e015b334724521303b14f333a9739cbc840a5f6fca12ed3171a7f78a659a1b653d62a06354f36e15b61a0389819664b9cfe4719f4fbde2ca558bf7e90e42f5d38ba830c0269e9202d71aa794491e2ca19ed564debc442bb13ddb85bb76a6e80185dd1d6944be5cf37d60c2647325f026f41958a3d473c6c7d68b3c178d661fb669003a395287859c9e28152275b3f362de2eefab1d400d1beb4eeb9aeacee8c661d913775f7c7598cfa7337b1d0f57185dee9bcca9504a1db94cdb2e0dcb8af8f0d1bb13f98d1cd5fb5cf37e1e360d4b2797d4fa21d7d47a3236f6754f727ddbe96da06079d12104e4efcb46a785ac5513510b24fac85ab41d523bdae9ed889d686af955609e5a365ca6136c1cea3be8290ff30026496efa4d599a24d18d84913c214dc112fd0113ac9d1831a4afb8c95adeacdfae155bb36cd03271e535826c10507699787735885d0fe2e89f0401a6eb8a7a06732232c8c7838e54f62d4c2ad96b0462524941023700c22c8e73a733e4f5c13dd07131445f034cb7119c6af5ec0c921f1cbe72a7dd192bb9ae5e08d6ea1824c5e29f99667b2f2120469645f2ab4afa1959b13af4828ba1d23e136e03192f72d4030f6a47920ad4d4de70fa3b141e9e928813ec14242cdc4df22ef16e2d089565d458b948ad5d32cf00ddec48d98f3ef3ba821a6795af56aaf0327d3da571b86479c70e521002084fed7d4c342f8b63fe864ff8b5e76a28e4e70b216f807e3f2c45d9f78350f441f7f8cbb703bbcd66492204d4b34dd2139e7442ba9bfd7816fedcb0ea9351147a7d86962bc94881589d72c985cd8733f4c4f6e5ece74967c815a5557974f5b625e34375c3720c840a2e498f6e2b547f6ad51c79a9672f5c5c8dd9a034d86668e863b8395436e6952a778c7ff0cf225245677aa56ce8eb6393d92090277b94ed6b8a596da8b439b7666ef02c45e5c1cc5d59eed14de2f53203b15b7d39a5e72a2ec9ef05fa9421b272189f489055cd1f717d0b892aea3d881a215ac15ef9f6025fd4f26871b3e9850ded36ac1d85f619784804e74383ddb190749ef44af5a149595388c894211034039804ffa4fb753f1e17c05d7b0ef2094cf7c576abe0ed1cd70da54ce841be243d1d9d61bb943d02f6962197acbcf1750f9146b1ac37293de45bbc799638e85516608ec66cf492faa38b4c342c4180c865f362d5dbf1089857c213fc8b7013ed8595f79bdaef1af08000e9546652362fddd9a8a69286f94eaa5209a5e0c63da5957c00c4dd9b612b0296edf10298d74bdff1e182156504378c94c8ce9e147a964e0c64a6fcc539778c4e85164f037f6cb50b2ae6343f68b7c15355b8455acd324883c1d7861502dd69090b474f87808f5c696c68e5a2d55296dcf0ed0bc10765582ed3546fec001f0b5e54431e12d270ec4b3717aacd744ec874da02cfed1d35663e8366a66f94fe6220f37ae14b6baf1150097e1b8a4b8e4c869b405050aecfdc73e8ccc4c2042ca29777aaaafebc58a9aca09764a73087b87dee3faca77f2d57930ecd7a0ea12383635f16589db5a873eef0610c912397433d5849182882c5ca0b5bb2628b59de19c1a6a943222f3f3c611677916c8b67693eb190df02a0bea07024d0d3a4a63086cd2a01083f9195cbc29d76b2c7e7e6486b8bc84990427388b3724d0458cb0b2bd34204cd54f93a3cd2943346c65aeadbf32a41103c9216b4bafbbd64e849b79a755903c4b6136cc837f8c9cf70288bb1baf23c13d63ae992d5e93eeed865321d8debbd42f282f04a482a6edcb0a613fe401c53f7eeb08208d283cd8911cc47819b3cfff280a7b60c4f89bcbd5c7b0cc1c49c17315651273c4162046eb7d2d5ac71a92d9d8466fc8ed3437d56e98b048e40972ebd9181eec91ca467a04f3db1bd5772b8043d227c62b9d70314c2bd5393e601121b2ec713e19c401e6033d8d86706c843d1399aed00e5736c4f510b8eb419816ecbc4c4a92f0d70475dda9a87fcb28f70090527e2c353cf86834a9d477418f19488c3dd8b3027e89dc84a581710e6d22d6c166fecf141accc1d4e8f7b233802cbd6a2171b7abfc2595843e59ab66da77af7855e31aac292ddc1b89704a8a6893245884e39b9bad5f1a45bcc4490be41c17ae84f8deaf1c8ab63d61d9187ae67685fc7fc4d149f3e8d47e63a689500bfe2c6b6140cb3b9da3cef711f6fac42f8d8444d36a45de1233a3243806a165888a36c08b813a9974932647aaf6e3cf808473325fb6ce31ed8e4df86e4c9d9447566329a721d5c21da2d332299b8e71b2c89d7c36ea47bb23bc56ba47b6125111fa2aef34ae802091b58c90cc5ee3d509043662bce357e261b0c55f8acdd5717267444d4c497477164eab7584d9101d3649a8b93d8b2983c7e8cdc489a09bc5c3dedd5eefdde5f2b7faf995b8d215415341a7498d0f3750bb2890791bc25aa2029004e98c48e5017c5c98a25b37772600e98e160a6ecc0ad0f010c3840c951255c0fe663806e7d973fa25ba9a52f931511d034037187c5e59a03605f038324ef3e880998b5f52580d3c4515026304307a039e1ce387148895761b60a2135a7eee11dce8ce62191af0d7d0da4cf002c696418503c122e0026370812658eab8461b302dd8e56f5178cd3a4b61592dc4f4eb94bce3b20570558c602d0492478274a12a89207b31d0da47667016de16c69fa0834f69458d705824a8c10dcaa3580e6bc16531b15c2c7cfa74f2f6dddd436f0cc3db285ec4cbdf8a86d5f7b1edf3d096d6fa89889799e9ead5273d9469b9ebd7bb48f83b484899408e828a5698afd44ddc7fd7565ac523d4142636fa53cd20fb935fa4bd6c77ab733eea981fcb0052e3bfa9aee729c0b9f6b565ad72b3fed08c9ef764898996b16fe1e60b8669a6a13bbfdc9d876436841ba9175442304501404ff72af3b1ddffcfdc4319150d213e8e6178676324a0195cf5fc86254ab7b8bf7010981937a9d09ae9e4e5a27009be8c0a950dd810bf813c2c599efb258d24b4dae5e165c0a82f0625d3e1ca9e7ad29dae2e9045c6a29b3d88666a52160f3ba5a21e5580214d83b7f2cee8dcdbd8e4d97e24172076baaaf680cf0928298e4345bd2b2fbd6acc7c0ed7cc9d0030691387479ac229a3430a724a27190ea30d90507094c2d12a98be6a679de4aad77ef8b1bca951846522f8859862fb41caf5e72eb606d084e277d2946198fb75212e6301e6630e2355b9cee4517c05b94781a6c55b78bbceceed89eb3df8470cc075aeca9e41a261ec1981c9d5ef736767c0806cde0882d39c668db8d407866f959260cd082ec1a7af557e64ccc81f559a069890462859fc10b7b6ce83d9a6d1e680692f42473eb20086dda5b048fec899c23e949910caf8fd966c817cf4e579b11e28b201cd31de9310359297aca9c80f65d3416f16de6182e04fd7863fca9d1765c7e0129a4832b9287c87c558901209b9429d98e6cfd6679146f2d0156a75627d77470a3cad96942b74fa8d96dc2258f48b43cf5976c2f6c33a3c4f0f4dd45d01dd3c1bab2bebb8ae4958ade08ad3ce96c9af687df1b4fec49b17252120cf08d4360b4c07a268ffdf1e083e01feddbd3f53fdcb7ff75aff1db5e3de8e9bb81530645f3c09d77ea81421f8fc457aa58df2cd9b4688bbdc17db7c85d1a36fe049b3b918b89e5a1a624551a00b4440bdc346cddf5a0d7e1d2288a3e391e6793f0e6e174edc49a45288d27eb6ae9c8da4a2d824a41d25a68619cb8b8d4f40c0eea680bd6474da3bba1afe72aab38972ac0f92c272b30f70eef0f846a2190b1274d1c715d9146010180f45214dfe40e6dcf1cbf07685db5f0411739d3e49686d5526b4947e8c4f92b20d72333b299fbd8d315cd833ce48f3d2474ff03fbf0a77bbaf2e31fede94a71a7818177ccbfb008a92734b9a0bb107041c3e0b6cb31646a2c6e8cf288b15a70731eb68ceac516bc63d49e5b7a8736e42a19e998eae13a31674d6bad390f5ab4ce8a56c2f309b3e90fc3b667453403aea723f719697ac3c195b944e1942931b2ad0a816470e1d7c59311a0815449004736e88623c88584371228a207e72baa213679fdf61c935442f3235bcfa6c463bdb213ed908fe8424164011ddba2fbd7b23ef867f00c16a8ba4fb277700536c2b88273429dcb5133c55a0bf4785ac223ee9121b979640f93303922a98e8cc8c42c5ecdb9c76e92f62566657e5fd8e40a30ba7a468af2a4c77456ce0995cb64e1d9be66776903a9562f0a7092e56ad1656d9cdcbad4ef581240e179a121bbf7f83c4c323d78c90d8220f18c9e4d043e4d4790d3feb97502dd1be914250de0484f694d7a1d62e468502fd54c8cacb3421f7459ce8a0999b35c40d35a292f5acd31cb6548c7a458751cd7c45c83ba4bcb8bd73a676cf99a4f823c6db058d7d252e1d5648e662176848dad65584879cbc705a83a846c5f37f5f2a85ea63ca42ed96e6dc350ead062809b4be6f769c523f361af6db6d7cc6b1692f255b5297e0412f3c06ff8744f6168b993b8b5e23e5380eb0eb3d4e2bc70b0a2232b9d6d962d8f8616e379a09054824a22e5275991b6fbd92777885a027fbe4cc47e9a391b51ac3382a6a7484efaaae01d4aac014ac0b14c637d4ae116cb2517046e2f8677e94a65e90d3fc123a9dae084c774585b77afdb7b484a64b61c1e6a8c1a29452ad1d90de92fb40b8e16eb624d50dcb7e1f1746fcdb3cb122ed04f7dc48e7ed6f2ceb5f361c0223527267e98e3e6704979a25ea9b7eb87b920d44d1ecd31b615abac02cf4f1991a6f464eed208969aaba09c05cfacb9d2061acc019cb69e7378704c523af11c6932a0602bfa2a6eab816694bdd7eb937fde52bb600c244e4c39bb5fa62e33557f8b5501a2a669a8d19bbb5811dcf7afe6906c6b116f423abe40cd559b1062612a2b497f16689ff7ed6777eb92ed65ab6e48400c11a4a774239d3b40ad2d6fc52c16ec4a1d8ccf7b7c6587816b475a9687681f736585e7ded99754a878ea6b6d3ca988556cc8ad7b5c69b1eead4075d4658e8448e538916df8f4ac5e68ad18a8771b78102ef27397651c1d9843c5595e2c55718f0d80e33842160793112800165b31efe82dc385d9767c37596db8041c590aca7075fde03a653c2eab27d9b018c29691d52e3d9fe2e34c53b31e44d1ac7a3157e33dd90faedc28051ac5427dcf06efee115712cf930e9782677019c27629dde83d3b00fcd38857695eaf888e23cab8efca1078211c1d4ad1490578252571dbcdb64ef1b46a693d549d6e0ad31c515f56bcba10e9d8d1f8800a9ab25ff4a34c80ca78895282021bcc5e440d34b5d0d523a299d458796ec6550759b06d04f07a5c1d23da6f285bb47c5d85f6090b48176760cdba385921e1538c19aab87771a321b67951ecfd224706b6bac70ec09e72a1f336eb113266be0ba994dd7968d68c1b86c1b371f16dbe000f186741146d6203a248bfc5c09d98f0fb74b296e68ef36882107164a09bdd0f96bbbb77c275da90bf393d55d8408311dd6b426b147b65f1d1a3a5475cda21c909c75e627f85a5d4520d6a76cc52ec64e868542bc30f97241a9f9af2aba41e1b8d71a4d54255c95c03bc1724546f2825612368343cc09988c61fe7c9a2c86d19b880eae901811f3dbfd9b148860fb5ba46ff128a968d9750234ec29c2c5b6b28e9b81f776d9e865b7de8c4fd5c10d076e14ab5b10115326d9e3a0b5ea60e8e22b9b1bbcd3eb81995dcd298256d1181f0218f75daa7ab6e82b25488a8099ee6d1ed13ca993a5076af1ea8cd7ebb8130e1071b52f849464742f8829d9e9993d7cdb2b3604355f721d681dc56683bd80a4943fe5415f23d3c626719c56b2e776c5b3c4d0f9779bce767c22881ed8c275dd58f5761bd98e1ce3435a122b7785609e28127c49837d8f688ada9b6c0b0cc5cb16a45562bcab8cfe7d77c7a0c153d5ce805e1c78de9a3138577a0ae3ba808151f4c74ce868b3e2a5d5b75a5d75a6f869c0cc78e108987826950c387fef4464eb913b4e6c86e4c8c410dec68e2f447d90fe44ef84a5845db0b2b831670c4b36768374a90b6bcbd5a5fda50f90542f6e4513b389cbe7cdc78d07ef669295008d6a119ecdaac33812ab0266860f8005874c962f641150437fae59d0f4bc1a7fc0ae8c4825d812e11a2c01fd75cda05a500774d6dd2d76bea46b2205aa051cdf88a944452dd34128b5b35339909141bee1d4040d244800f19d9083786b09f8436cc6b488ad9dd4b3cd60d1137400fdd746a0db5b0fd0a53d5a98e6850bd93ab87355db997cca760a613dd782edefd7985262ea0a5236e2f9606dcb36bee013ceca088c77b04c364ad312fe5b0b02d8e7a9c73ea728addd2baa6780c86f934dae408bd067aec7c7b0b84be87e507c5d9728c0c0f8c7c0a56e4743d7371f554c8e94e5aa1a88ea26b5b7ee638d892761c385aa32b82e3441a3bac78125ce62fccdee969d837efb91e891205b839b891cc0e1c3e547ae8a8f7cd350a0f394f4bc60e89561260ec15773be3c473bc0a2e13c8e944d8d088f4610d590245379ec59f415f24a6ad3a4a69b299a5d7422a9589cb4ce32201acf2985bcc5f072df229816cd9c9ce432d2ffc34481719d68ffc35c1a35c445d46812919243c1069fa5901ea88dfca44ec41a53d062f2e950803c5938440085b13fa713b17f61cef89750d792107d316ba51d6461e3e4add796ac42d957a12734b40a7afb1bdae8b64254aa406d8e166196423de0c92e8c1ae3b61c5c206ddac030ff69bbfea2e69ed8144f2bd711cdb312966c34277ea8e3ba0edafa0ba49a0310c353cab7078e2081cedf62a38daea4651942c9b8d60f839732bd25f4d7d0bc1924f31a900f5e12896b2e4839b72f7ea9cb4830d398b60b93f0e518e5f939dd6e3d31fab2a8f173606451b59a7c1c11b7b5414cd1b3752ea2ce5ca50a15eea9a77228e974ae676143053196a6bdb6c5e751ee3fb966cf09a38f2382d23b43da3a5ed361ea63dd37e6c7a2195dd5d6f29c6d5a991a0f59c35dc6068c129ece556ea5a246a18b6136b06e2bac72cda4ac349a42677ce15ef5398c5392861173d3b2201d3c506d1e9ca036ba599bcdc22fa90f1b4842fee6d8cf3865385b119ed47599897673fc8bad89831d9f09ad460cb5a4389a13a890cb9993db7844cdadd6330e9f4403955b2c902a4935ebb842ca973381be48c120c3476744ed972e0e144a8fde7c15e64861203451ada7c15537a0d877e5b04e8b809b6d2f81b0abb4c60a4576a5a298ec3140f69ddabe9686a60d68b406ae27cdde7d72c707a8b9a80e6029063035b2dfa1d5b8b298662859e41fa4d146fd6e5d34973acb2af0c5580ac78dacfdbe9e93cc08905c5260a53816b01b78fbe8a9fc47c9e69051d96e8a44e71ca5cce89b9b10c9bb83c887b8c48a9d62fc702ab4b7bd489592826f4aa305d66c82a742c1cb845a4e999d403be6b665033015ad37d40dc9dc47cf889f318a857e1e797ec1044973b7b4b8c9afc6cb8c3bf5ba90c6ce9199f614bf809dced720dfafa759f837d80712cbaca6eda50e862b65568f05cd89efb82f1801d558fc13eef79293e5eb720b86617cb95c552337975b98704dd5ed563c35ea79064cf06ee1ff5ec3b0c3f8af6ad5fd79c55566ccc1ec0c4935290e6a65f8deaa08aa89b0781ed311e0fb9ce1245e7e2cdb797c6447ae0eb1ddeb8e98ec1fca5cc76c4103c0e88e05a49318c176e0786afb0dfb6070166c082073e17234a725551932a990361fccc7a3d6e87de0dc4f2b98f44148aab95e6936cd7eeda609ad32886882b6289f15c20db7165ebd848c24d9dcc94151118f07b8b96f6da6fc9443e2bea55df2e1776c965f4ca690c4b462227c275f1ea4e8febba8be162a3f62a16bbc72650eaf8d903dcab3b5f1cd52e49eb3386b5c5ba1b0356d7d2282f1a2ab7e4ea3b48c3bfa702d1fb149bea2fe2d6e8f71034fb68bdb71be1388ec21cdd1d2d66ecf9522c0ebdaa16e547144311c7ecfb2923b0dc25b29d2c87b5185e77a74d648ee38e8de69d09d0f42ebf5b00be5899c141f20dbd4709469c8f155b81c656b5f652b911084bd96d4e2922699a192f4e69768ebfcd283062025d2c877ec585d28844ce04c901476afd92f1958a800a89095e4b8f6b05ea41c3b924cee2fd3641497587cf7202adc7e64f59e93eb3d2e69f4343312ff169546240e6854f705a52ec38662309aec7534e1c49d880ab8f377786240b77c41fcfe71ebd0608836b963def978cf988acdc1368a9ed9d47cad72d5efc62a3635f720ac97e150bf020f185585faf62794944f80a5f20fa7825a4ab0016c0e22f2ea5aa17c16fb7757dceb27063a008bd3f5b1a6085179749ccbd64ad571b6ee6edccea096c770c00487ad96cf23c01cd9d26cb8050a03251f60094d28efc4b09a2abde2e425a240b80dcc383d71d2b366d3cc79994f125e005f2c64b3ec458af033c1450004c7189b23bae75f6f3debe4a15a21be866b4cb3843ace0047905c1e25359b9bb30ebeba44faf16baa55386431305cd247a2fe0e6c9380a3721af97a2c2a110de4e01b136f3328c30c31eda7d0c444738a80cd882fda9661038843e60a8cad8e8f763e3ccfe7968d0c39547e08e49377ab82d5966509d725f48fcd8a89712a2917d4c000c499e8385edb4aaf4f5f2306788864d4e6451a7dbc4666914124d479d6435ac21a971162cd32cc12ced9b85f0aa6bfbbca03586151e11be9391dd221dee0cdc6e469b466080ab7bd556e255cb6732c4aee8249e3374ce77dd7e9e1ce4295ce65d98cb03c5bd5b5217a5664011b71770e2625d6233ae863740f527dcddfa368f1bb16ec597dbf2816b33f44411cd4dc7852a2e354e49afd47aad01e510c793141226c584843205d55674d1f413fa264a7e9e92a4d09197ce081d532dd22d1b60e04a5ec343e9fc4aa35edb998fababa448287bf119cd46edba276f3de3bce6315f1ac333ce4acb8d152ebd5e15f1ffa5ecac9570d7b224fd4032c464fe6266f6c4ccaca79fb8a76bba2a66da38edc8912563af1d2bf56566f02ae5a5cc3f3cd8e7e4baa45a178a29f0838c0fb7514d60fa098013530f49cbb55441cd4694bc06dc8687b6bb94525778395382d3ce4575d14a61dfeebb848ec056d7a41a96bc7583aa662fb58025d55f909391cbe0f4d7cd42ac5369e9aa8641816587f811677412537972f77125c840607813274816567eb489cecabb6e66d9db9da4fe25b56fc0025b555e19d47cef5341aae278b66618d20f43bd36ce359fcf70f2d75fb7a2644fe986658e8784c6ea27096841768daf4c1bcdaf18ccacd37110006c11985ac7fbc95c09905f890d4c4b56c052e761fd069aa5bc57d7df5ab7732f55f578ffa66498898c7398ec5abd07125ccac977cd27545cba45cddb18ee7c79d5fd4442067033016e69f7114a879d6a9231b9caca49ff880fe280e149d4b576c2c9f384bd9d4fc075a8065602ce1102b61b54f149509e16547728b748b8b5de7d9432a88e63065dba57981843e405837cda68a868c74b38679e31eac1a157a1496b31400501e69e4a7e3654565f441aebb8d6cb560b6c080c6d29daaa75564a72295060949c442e290273e6a662076017cb1f11e24815a841cefd117db542162734ce2ff3d1955197bb46b3cf4c17bc91499491012f3eef6c17d8a31a8594081420d2b65d85a9c5a6b68cb558c04fca245603eab77d9f384a0b06edc4ee960139bcf6f10e1608d7386b8cf430e216c5fcd165cdb009ef2ae7eedfaf65a8bfd26595bff2a4d17a8614d37f68b2828fc01604ff622bcab314aed4db14eca593ed478456da8d1e96b263d68d4726be3fa514b533bd22ff50618a8c0b2aad309db2f9ce01a95f85cd186a924d534abb3f9019457fd3617d939682d505626cf973a6b19e75ceee8860a06e03e2e22ac27dd90bfbd2e5ea840da5682c7b665139ce942abd3d6ab92c8f6227059164676ec83298dc8b2d8f118ee0ae9317abb39ebea755b72ce37c63d5d17a2f7ad2d1127e25553bf9107a4a4abc42c5a413051bfa04ca252740e1691ef575fdb0e9de6eef56e2d27d071c68ec2574dbc848926d068d0cfd2902fd599515efa6897bf43260407dd6e4b7474af78e89a55848b8fae5bac533faac43645cb50b02a18ff56a2525c082f9c9782e714b099c3bc8507d8c5c18df0a3db4db42e94960fddcb8464f5817b5e52a4984029e12bf0a46b8b6d931fbd9e2b8a714399f0dee03e629af386212a4ceb2458a27f67c02ee1a17ff5341af64ea59b5176d7d702c4dce5749cc5276113946dd36d8a66e596f7e72902c1218581304d6b95a556cfa5529da6886cca65f0dae10ebc576c86084f5ef5a15b226861cba1ac6bd798418e65efa4c216cdab6680aa36ce12498ca86b241eb1aa62d8c674c4e4c1dd91c7f8fdfe0aa7a7c0fd2bd9c413e793ae92c78d2b6067349b66c725384517dcd84d57fd6aecd971662b57234a039be9049ab58143efa90693eedb443a1fd91c07f9d09d99e54c0a27ef6ef97fd257faefd1d7f6efc3f198f461c0ee77fb2b11573446205808826f478a6f5e6dc7f621b19bb1864efd8b9063f4a197bf154fa1d8814b9f0f0f53b01fbe760980b769bec1afcc230bcf47a1d7c2e5958529dd3c0085924bafc2a2b6588657e73049eb8096bccf5016f48940000d0140ad2247a51806159607dd726dc76f7ae31ccace7df3b2b8727374caaaf6f0e5b51a7068cae7cf683bc4568ef40e3cee4ac0db6a675eb3ec121a3c379c9597969a68fa0c56290013c37e766f5738562d68d9bceb71a44b9e2ddd57cd34ceef8040b0d91c497686adab594cf5417dd881c45b9fcb60cd9919a2446c56d76fd2bd87c1e1e0e2da77ef57e54beba286a2a26f58d358b305cb25cdca08a21d8ae5cbd6e25ee799744d3e7c21d418755d1ada1244e4b42ad4b0ebfe8c01323034311b84ea9bcb614b5187302768d06e39c3c0f08bb55c6295ea7b3b6ac24b72264c33b178bba40d8a9160e80f8418624395d9773838e7faba6ac45132163aa5e093ace8070f89c01d95ea2e5203f5fab5f1e6f1d6f44d38bcc3b245d20598c431f5a55ac6ebb27a2519846676b81e916f8fe1bb2c8687241d3001d1ab4f6bde276da527dc5932bcd1842582646cbfcef7ec29bba0f0e7ce67c159f514569cfe7bf5fad9efda7dc56a80f1a83408358e2d2b1fb999e9b75bad1617a6c2fd17f849e0905efdfbc41351c0087f96f422885e5570e5b21eebe445203f6333a83ec6701c070bde80f6087c78ea04c4a3b76669bb46daf6eedcc252dde05f0385d8245fdf14a2d6fd5f6b18b507fb790267c5e0857c72188f6361cc1603b07f9ba2b18d934c83d4c080ebbd2ca5cfef92056f08e160ac2d8ded7f1eb027c3dee8823a3d33758453b94297160d7cb9313d9d399f76ebb0b27521143ab1ef05cc97e948b4f8233b81dd954a1409b91591057ccffca021fc5380b042febd15564e4732a94e10ceba44d97e13974da98193a5a884fac3272df5312b46a55c561cc59193a338895d663892e74a62894477044da13b8fa421276b0f3f821a73844b66bdc5278b183ce8ebe087907e7096659f02225b0bfd59b96decdf198d99e9e1b4c65b9d466157f195ea6b2ae2b9294376efd063cd1d5e5eeca70efa9ec1e61d80a5d6641ddaa10b982d3d46cda380e546842a8dc6ead3f218f66447cf7a13c6f1de38029aaf757e179f396a6e25a200a2aa54da0b3ff7c83d19c0225f647bfc97ade219c08748c9eebb9ba87fcc092764828669d186c31686aa4b21dde1ecf74ef281bbef9903d055a23cf28a604c5de0c483c5056acf1382f4996c78b15a6733105d4b1bf4b0fce0b8790e2e6c9dff49ef7e17f8caa14a7d6bd161e3e619a21abe108aab2f95897050f78cbc2419d7d887c9e14268635b6116e5cb7dcf638968b46290f54494cc77d4cc66b8e6086a6ad7c8ec8ded29d9abcc12547cb98b9582f87230a2b860b2c1403cfbd2d100b2604989118f17e5b2ccb579a1cd14812c9cc389be3f44b102f3d7c327437d5351d23b5e3b478e441669e3052c473bde7099c776c2dd5dacfefcf01fa4bacc8193089740df4b683a08e5eefeac3b013ffe68a387ea910d308a3f32e74b0eb235a2bb8ce9762c56682fa93c4958d1347688bd9a362447731946145639448283579dd5e1da1d880403aa2cd312d3c084514f9cdc21a5792b38118f4db601a8d4d2c3cefc972139b005c3cedd3dfe10fbb6a00ddb9d8d30af740cd0b12e524f440239813cbc30db293f21cc5aa0ba05528104047d4ef073c8c2b9b26e6a7d65e353bd8431ffb5111df7cd16233bf4dba7c5266846d123ab53a19337e5f73201b2da62f8a40e4d0daaffef0b81c95c604302318b34e881a75b9dbe787f64cb64542808d9809c6180b1b7e67b5f0eb970ece8a43e22a2c260aa606d6315d8b7be4e70f4f7575fb722aed4431bdd0d1fb1066b1b4aed332b46e107dc48459e6eba69359252219c1dead64d3868d042aaeb974ed2a09e0db2f2fa21cd7b308e1b0c8cc552b7b3b4cd970e1c287545e13f1f8198e0e4d37a94c951098a79690ece660545d02382540e1c63d4c0a3dc6be5c983591b529bbe7feab1f7c30332c720d9128c8a9b5b7a119e1af76b434ef00076c15f6a3c7eccbd125562b6c2c4d14b0756804faef577bd909e97c355e898569a0be0a11a9a0a30c8b770a3e2292cb7d817c8350d903b0a642e9e98e9f82f743e7800541926691ec45c8d627e15a69dc1178ea3100f1944209c199d3f052b95bd8e42ad2ea1f605efcd658ef45dcb795733c913cef3924ad9182d8db47e0c0ef278c32165139500f62eee851235c45a30c8d164874ecaf6156b19efc71de434f53fe7415d06f5b3786b012dbd69c7e06272d959769a5bd0a3702ac408e9685e7d7d8c8147d22807ea5f5655f79e1e3669a01d7881bf1ef8947a15d6b579be7ae0aee016db1a326cb2ef1ec9921bb0fe1d3aef173a725d246c377adcd9d43dbc5a7f4914606378b5012c23c0b8f1bc42762d948d04b4e6b851e9e22338fde2a4459006dd09dad017e3c4e92433ccd3e6c39b4d21c53df6ca10efe9eeb082f282f9efd369897c0eb3328f5fb2c51c51e026fd5d06f40dc94f5308ffddd0c7a1fce5d9952824ba80352f2e85ed89e36c41f6929b803117211af98af3e132186d2b0170eebede616aadc24af05e497257acae188d4ab13da6895cdb457ad2eeb42ae141feb4c1233d9ede303bbd5ea8750aa6b2d44f233c60899a3c15aa62025206f829a2a8cb7dc9afcf1dd9af5c2033ac6e6a76a252f8d5123fb267d69216090fe503c8e5620fa0b379d37e3b28c758f2ec322b7a008e5d5174d8e5fb1535cd7696dbc07bb7f016daaaa7be1413dfe9453aa35b434c24b69bcb6a5314c979582cdaebe9b4b45460677ee4f753ea14c9501f3acc2f715baf515b8db92079b527ca40bc730cad0762e12c3b9074c79069191079b50713759c2a15e162c397c4d0a15bb18ab0456d2e2a762aa6c8aaeedd2266dc5439e0e1cc0be00f07201c845f75bd5326e8c91385df5f822385e0b80e350dae558f26283c1185cdb565aea0f63c24318cb37d47f84433007b50165587f65bca467d7ea78c6cc392972da4a0286154db9d45c49888c43e1ddd9a23a14af77a37def53d1a0be02320b0f3dcbfeb55c55748f9e2c5612c241842f28d7518c734a5756fa438eb765a16359d6700a06b64e61627be09da281f12d6d614f8067b6a933246b00e33b55dd1e77f1b5e0011ab7fd65371c4c21d8a1ed0e759cf2fb51408804765e54159f5e468a243fb52819f458fd98df802afb4d2aced506b5beec15db9fa3e0515fb4515973d7d23959487055eb151ffc1a62458b004247a346c694ef51fd9c25281b051e9a25b0772a975592733ad20ac680005812edf326a008d026463e0205889f393041cfc5defc3529bb2a519d8ad67e6f996acdc5108c3e7a7fa6c20941e9ec0dc5fc00b7864a133426596afd49cc6a119866d5a7550e9df3317709aea3ad01f161f00eb272828edd2e21bfaa3b98609b9f1d5b076f8fdb2f780321b337961084c3acbc6f0328cb26ecb33e624d930b2d98207c68f97db2b72c415d80fdc08a92c8a4a42308ec0845c38b7725aeda4055493bcc428c1234b76277fd55d43c43d762891c6d61a5b382645647ed33ca14651a3dd86966bc61235854a9f7d00ab0f5c90cc7bed5dbea1c6fa00525bed72fa899e789efc18bc099c8a68677bb87c9172459508a2bd9a39e74e7718497364c172eea1ab8acc20213b46bd0897030f3fb48c12b93694d5199642bb4d021616ea868cc45c801edcae3e6ce64f5039b3634c32934b5c6e27a443192570fc2e38865f459f64cdc54bff8fad45990e15236fcdad49d465ea4fa4e9b9c669a02d564337d87aa0c8fae610c0f8173ae51f2da17c47418e6bedffab377a595a33dcc2993c78cce98c6a55f90e79f43962c1ec85277a12bc1cc7b8f5c285adf8b48261f346d86e9e62ab3d18c002124995889aca5cefc73cd871df681d9725294f9d94e0b5fca8ad07e655711eea983020e21c57cc29df43b277b646233ca68d7f15a2ff0d5335bcf09d8903fc0ab9c71b9f9f72abea2654354b5575fee1a7f26e428d37a4075c15bf9e35fe523e6bb0248fbfd384dfc3bff2af057fe5598690ab16172d418b250d99348ee3d91eee2f0e1ff64628f435bfc57aeeaffd5b50c7f802d1ee66d2bd38f1366a250cbe0df4733acd8478519192ac737bc0c2bf39ba6d6d5d4f97194c871ec057e9221f864e3d1c680f9b3303e77f0014be35994aef3d3c7a4ff128054a685a441bba8397c2f255ddd3cab6875472daef995b0de1d299b3a9cd65c300a680906ec4fe745786244c76190143e5f35d259bbfb0c1687541bf1577bbd9bb79a1d55c86c256a5e970254026b2236663892e9bc576bee0261969a839a624c420f21402b869b5140ff21341cadee56f2076979c94cc74c0c87b3f7c6451ab800e355eed3aeb1ecfe1a2ad81845a5fd4c2bd419b0b47a3c01a3fbb978b3a4830b443c95f1171d643f5dcebcf1909d90e9012da90cfe3e773c23e153e7289cd4a716c435585b6b746b960cf34604657f6244aa0fb9d71aaf13f2c5fda8faa21a2ff501efe745f94d658d89e25debee51b77b22f0186d05cc7caf74bc5836bb7dcbbfd15cc98a094e3da8265a404db6f936de2779fa35c1f137200b54770a6ef9d6251476819236f64148083c9c6afabe6fd164fb665bb09e3205df6222bea498f85e91722073af4df02932a64121c05b2f109d648c1dbf8b6e3169b177b513a9115e01af6536957bc08c64780a0fda879672fa87c37f72bcf28ca295f3e67f3fc9e6fe8e45beff8a45fed395c20b5f8e04473c3effe69171380422caa31f814ea133d4989865972e8dd9cd7c17f968dc14627ea6a2918cfba2095d477cb62f7158fa52194449c46cc5323e589f151ae9f507811295a72c72661012ca8148876c78f226cae170c468411d891628fe6d0f4e211902002078593d522b1616dc8cc1f6785cb4c422649e5e2f780e2b09a4a39307d7b380fa849902383b01d6dc82068edae46f4138b40861c5056258c7f37c248133816f212b47604c2567a54dcf7e8ca8a12ad786f3697913777ef2a0e1abf559cc334b5a3caa7d92793f2ff7226f2aa4d7f11039a87d2b8bc43a362aec311acfbe0d2f080a66fdcd2c1c1610168b79313924226c7e1a204a0c770a0b256582bde18e25cb69e681c19764d27818b3bebbd4cb9f34640f2fc51f26370db15ac2134dc574a8f1d8b3b03e2c80b3e9c6995200adf55ab3eab5b9c974d5349887dadfa01249d076b3aff1def9d4c8429e5cd3eb233e9f679cf46ab6bd1c099d810a8c4472baead1c664b99d485b86f1408162ac418dc4cb7d2de51b218df5c8ce26c6fd340940565cccd66c5208b90f4076265653ce3a764a7cfdb98285c1a579d98f1320833a7c800e9be7b36fb5cda55317dc6c2dc8512906429e16c882fe24377804035de55b8b777bfb6dac1a67a6d4d4cb093e3ccfb875b63eb7ae2dae135d4faaabd281bb68441a72a2d250b5ff2c226aaba805eb86455b777c607cd87aab25969f8245ba046c41463bae59c121ca40c4d566ac4ecd33657fa7a5fc143286f53ce0de8d8074ea0c711591b41359ec3688463a6f0c3d1e34bc45007c63246a64758c55dc51549dc0c26c63f75929ff045545880532bcfd0a864d58553b2a54547d9f9f2b32f94f22ecf2009d4afe3a164a5d558df81617a887dd55f09fb5200f272e46f8bd167a6101c16aa9af463f631ec1723f323e441247df469136b7f0c16897c0ae6466f1d1175f866709421609b68a19bd852898ac8f797bef6b695641ed3a36671e2835e94522201b35812823a5709637f2009029f22d4d9365912b6e441e4635636f72b86aeb3283b9fd0c11a5935bb5d83017834793aebc7a757eb9f0336be436cb3335a676cb1aadadbcf33466b34a3c6f2a72c13fb130192cb504be1ee14f05a0ae734fcab20d8bc4f1abdb2f9491f3f67dbdbe1760b56247611667adb5aa316b17fc160b77bc5379ebdb22f4f3bd9bcdf19ff7498af86b9010ecfd35dd70c271a4e8499fb0e263ff0ad9476329b4610e4b6e2528f0f6812a2b9f84c0458382756b5c6ba6ae17849fc710a0cf0f4d7fffca5e58a5dc8e04e7ce7779c333dd8550bd66d5f88e93559a9de6b3ec57e5075018d86a0f984c1063d2021271638e9154175288fc6b4f1de8a323176aef20a75eb42064ac57cd0370625c46224284d398e05c56d400284e19b336b01aaf14c21e51d87aaaeafdd139bc71f599c321a8e0e28c3583d282af1e585462099a4d3cd5000f22ea04ac318601ea11f73adc02ad9aa718a9133660aff063d2c78268407ef072953ce3c09173eaabd09240c85fb7f45aab9a03fb96a5c5520b0f32f94d4e0106255bcafaaa820ad653751af07352dd4b5d54961c4d495e059230d22a239ff883206a7652fbcbfd4aae940f2651dba2b59d677862e7c67aff73ceb1284cbfac2917d63eb4b41723ec7d72a68e197385197a1ad5e56aa4da67c8f41979674d18892cabd38dc69b8d516acb0cb231309cea081320afde6e2bcbbaea7640cb0e6e09886f49afc80b2b90ee62570a188da111c0cfb3aad7a2ec8d305e49a63b6908e6c76e2e847a67131d023897c5306e769721254c44daaba4a7c1f60e51a32aa76dcc722153b528426ffbb961cdb5bf1a0e2bf00dee3a8248a1059a1dbb3b226850d12dc4f8431f7d54a64a3ce44f5f37875ab0ec874c09d9533bb67c89fdf21a6edfa84976d1dd7749fc16540a66dee11c0b59a5e57a9dc09a8646f0965d1691087ca9a7a6b82e5172bbfef3bcf7205c9e6559d77e6abeb85bacc0dd10c17edb1a22234c893cf52d414c35c495239453b8682bae48928e96e7dbe32c423fc010ac6e49de6a3c1d459bd6734d846f121fe06a10854784815de6679b1189039f344df0abeb491398f62140852ef1b7c5eb59d39ce525288ec2962ad9560d5ca5b8c8d1eb4fb369bf9ff06045b92b57beddc372792539073fbf2845038bcd9103ab8e44d2146ac5c0ec747f6315f9e38595514231453cbf60417b77b58c2f70ce231c5d44b5d89be547d30454b122e9a1276da4343240075bbf81927c2bbaaf81fac114445b6735dd1afaa6c00cbf607dd2583f5f61cf9186f1aad0554977011d185d7c8c097252006806035d589c20d1ae54062f1e501d60677f9ebef0d12e129cdaf5e4e056658677ddba05162d953c4517465e783d502fd3d5a21d8299022589783f72894eefa03ea57a0969938cf7fd0c10165e4bcff4071bdab83702735c1c13643250c61e50fac812a21875f16b2af5574b7d428c06c6a67051edc1cc61e35e76561f981601be062fcac49196feb88d00da40cfd27671048301011df04b8110c1cb25df8bfe8adf648afa86f2bd922ba9122b1f82cef086a51f4752b06b4e6c047ef4451520f8eb1794adea89660187feb3ff34e8bd4d1f25fd7e5cc9d57fb5ff207fb7fffcab3f23f8cfbe2e438e43bccffe23c7670a82247c8c4894088bf965eca98ab3ed47fedcfc64df1161469c8278f58d164b5b5fdb752ca975a5b3ba84d5ecaf243632082e5ad734aa7be97983e4c57bacab04acf43a4b45f9f1f156e2a65899078e5e25090ea0454a1b4931a68c5e86787ba618926dc635a225f69c5a1a002dab1f798a1854a39270e92527d3e43153a59ae91167ee48e2404655f3c50e253406dfeff673b14c4c4c67421973163dfd82983a58cd6e9e98e88948615a9c1b4a0bc36dbd919960cdeb532ea6651a52e2371e98646d8be3913d673dd71c17e69dd6c66664745a0289a1e0639e66cbe5c47f7d4eccd37079de41c1fea7b862d58c56a40752c7e76a17f19cee0da730440506d256e5fe68c1c539c93252984fd863d055a5e928eeeccf189671b33f1ada482da6936e7c4658a01e68a097b15f788fcd08b3bd8591ae68df0ae922891a57c3c3ffa0b4abbb5dfbf237e386a4837159066049c5b0959441a7a760c673371a475d08bbedc6a32771d359a61fd864cc9e5dfd16a850e71dde13afe89395609459cd035a460e3c196653cbdd01c347647145881cea445bca2f1997f0bc7c997dee2a1fd02c4b0ecb5d0f23f269642475272af6a29c26a743883c68c49c0fbb13f9ad1fb5de59824610e6bc8c4f078d1ee3f619b68d7994df698449cb298f9d571fc194330ddc6c4f306826844dc6fcb87715b5dfceafdc1238caa29e564aade34086d81d209e9876ba08a28565f32688600dbba7da4a71830fdcea63bcb2f79ca582439a035db1dffc5afa58149872e770ae1d0568a4805faa61920cfbf626ed787537a6037b1ad8d611c48b5f9dcee1992c8974c9d5e3f98d47ce194b2dde7695660bb291174cda5a71c4ee382bdfc37feaa288e325c9292eedc2fd35c4468e0466450bfe69c65a9cb8983ebee720dfdb04facecb47ed8d8620c9837a201795e173b27a963946d7934905437a867386d007f5c621729b194b1e61cad8a232cd750b9b751fa3576d309f1428f6ba0bd669f8d3f50f4629f50320ee7ba3cf6f715dcbcc7d83ad00b92434454ee3d22c99356f25fc2ecce1b9c723bcf5db3f034d823502ae1c38932a3bfc0d9dfdced4ab3575647e335a4af431c7185f2c09b67baa5f0cb1c1cf1a3fef7e1dc1095759c2457b473fa343256a3bf2b6eafcae1f73323f393070c7926b81e1f0b50bbc7bf0505d2d32ba99fd45a3588df342cf832ecda7485d98c29520d040208c811fc24d80069609bc67682992c8e90cbd70ccba9bf4db113c17fa1f48cbf7b441e582b5dd2c1e2eda45349592c36ac921ce02047c3b910fe2ce04905388c7e3919aee2adc2e960155593368eca643511653f1ce0d668f18fd7dc03587c3ca4467773b6f2a112692a2bdc1403d6669aa08b7530971592ae55b03301a543534e8d509e5d121d2e86697de8db9a502b9aec3c4a4e58ce21707143f55ee818c9940a625acc20c9ee2717716cc02ed64dc39ca7d0c4491a66601e9759e933e728198140c74a4f487fafd55201793d979b200f5e99e75e19e8b69afe7bd6e8c974606cc91404ec0dbe8f13946fd4ce8da7fdfaa5714e628b2c72ac98a4b62913fcf74e67d967858eb5853f07215c312b9bc6c1a587d2c2bb2524f3c10de89627177b487e44f5a500543b692464ccf0fe835d850e568cd54463e34532ec82bc2f89276a729141cb4ae24c0a1d33de62abea9e4d5011a19c40d0cce00d94652a405391c6c72b09d85d2c64059c3cbb90e2b79bc4619b8daafdf100b1a27809580f0a181a7f8731f96b7526b65cdff7e5cc4fe7ffd01ffe37df8fddd7df8dfac0e9721f89886059cffabafe7bfb99dc4abfce70804bd04054876a139e41975958f425991dc15355f85c279365c7739ec47517ed436eb4c11df747a8ff454dc82072a0e0d397b6a7220c481aa9e7f345ad89a965b96dd94285101f4407e675681208eb3c84ff89c4e142d35448b041b1ea0208c79b168c3208b6f4453fc4cd113d08469fca0944c502bdaf53b96eb7709c0574f1ff83cb688c0dc8b7ec53056830c6d3b0ae2e015763609c256c64590400e08f01d57fc184d58e204cbff2611274af2f57ac08a71a589b3130b89be204dc8173154fd76c156b0448f956a2bc960bd823abc4ac316455c79c165e17edb355956e4ed675f80a75097d0e759e7b94fc159b40fe07193d4f446df7ce893351edafa68010733f9613562385d85cb589977215652b20dd0d10cf4620364e47c8e7c4ad619772aeb7062adbf893a5d4702359bbf11edafda466fff2690e6445ea0183e3ad085a3e23f382bd0e0f34cb1043638a59eb278839bc1413e570a3177a2ec505ff3eb216102e4f20adf08c1b01260ba31915154a1c45a5d3af63098975dd4b83b75c0a655901c528f9cd6ed1a20070b7d21f5bdaee4998f0c01e3647089e1e8a8e7053f15773599d083bd83af15d46f1da5f528c8650e091097f322725fadc86df2a46fa461204c060805f398198eaad4f778f47e47d1e9e16ffe21711ed9a8248f3380283c042229b8c7bd86ea97e5b93e7570e262783ba513f2f1de9b2b4a62f6b1b9b5ea66821d9f4e8823d866c6bac88d4fca9d8ba7a67f686944c1374703d96c7c34d860d3c44b5c773bcbb772ce216d485f913eaf9be940c16d18314defe2c364e19fd28916eb7b4abbf070d375496b4b2473c133f5ddb4e8b784eb83ee3cf52f4f7589ade3b8def734a19d2d0e1e3de82780b3a936f05cdf197914e764656cf1ac4b4e509711e597fae009fd80818ecfddd49615c74bc03036e0f569f2f9d584fa93e334bd6d03dcb34a3eec3d283443470f3f7d1adc6d00b96a54f431fa9377e05ab7bbd495bdd203ec2b435f2a713ea237059ece850e149d81a5ec62e8e4ee446dad89c2df649538bd5203218d281e42bc306327c9df052ddb49c6ca3fa09779b097f9a3e9b97055e3fb37dacbaf3d5abf563c8095796a90159fb2ec9495914df825c9826f920c71bc308fdc458521c3da1533f52d138d22fea976c5b4bdc78501ef320b79bba200abf6e071f2d0b8bd5a17091b1bfe1a2624c3d7e3cf18c37a7d45db59dc5e99f384f3756a51d6b0357e496dda67e3f6fc2fc3a37a737b59f7eff607fa3b6cc91037fe16eeba94b5006fe1cf2c3d6b1e8c939afbfd7ef35fced2f37f394b85520cba2272ae7febcf41c446bb073f3efd43e5be4578cf18d930107965dfde79619d61a1b19f4125a1261a2dab065d1ade56ef456b2adbcfc14fe92222ee70e219d426472aac044c3a3594d54ae48f19391da09701258dc47d97db3facb2d0b4c0c99c2ebe8f443fd0c8c068dab95bca28036b0476544723996c6a5808b7a7f514a9a048d444e85270d49ff31cc7e9040c20c84b0ff927abc1f285dfd82a9b9266deef35263af38e590dd18bf45f8901695a74c055627ca89418081b1aac74ab5cefe27b6e7f70840f22949c794fb34b868cdac86e65b4fb2e9cc1bc3107da8f8a1f0f2bb7671691ec5c9520d855524ca7225a57ba356a37a8a31a3eb790dd46cea02ab25f0b4f8624a6baaae765ca199771ba15b6b90b911d40bce04558bd5c3db382cd77112f03a676a8a4307c37452069740ca16595856d4c3694c050d86b62442509cab5eec3c07f9f47b9a157be62667536e37544644ecd522bf6d07f34537bf26138247e297930fd7828eeefd9fda1e59a6080af096beacac8babe89de22a2125f712a4cb491c209a30f71d69260077707a192a6d4d5329df4b1153796432db319c7270b206780a72487464118db5b671def153747eb49e3d57bd60eda33827e8b3fa0e63143122f781e0ebba21e6cb6d63f902aec45ea507add8a1ae8d51159b16824807208c9af0bd786e835d4eecde006cf3526fce066d9a27d15e3243ea992dd528c628ff845550c61838d6085b7823ae12445ef2c8fe9cd01b6b31a8cd70e851067fba6c23cf3bfad0a2baf1c48df945d9a3d9662a4f9753478259ce11381b758d891183513dd7cb7a398d347022805eb19e3fa8e783d1bd6b88d7a30f454ccfaade8ac5cb9b375b95d255f0c5fd42e5bc5b8d3a7b93d86423feea4b4feda7d36cdd3655051ce6c749f316ba5db5f172ab0a307ebc6889bec041be42a6147347103862ddaf681fc752ab89f69d8664b5ac04786ed3f6e1ccd35aafd491a370a4f4bf87de903497b31b75f7c556d084079a89400cbd54cfe9dcb1b1adc25e5b2a8860415316168d73439795c2ac267d2d894701aa68d8b844a16c25e489d9f1d86be8e18138f00d05d2013a461a377f3fe28a8b088075899c88f75796a43a22dece8ae2500611f991e0952d60ab63f48063d0bed9c0ddf8f956385716bec1d7d44c7ffa4737cfba00ff0ef73b1aee539522ecafd698d565f34642ea74a5ab8fdcc870375d4a4231a915bfb7b6b0facd8137d7e13fa033840e33e9524b643b5253942065e209e921e2b76de23d0fc75df08b0708e342e5b061957bef8e7673a197e43dc330c520620afdc45380c2b3e28563d5ee4d2443a3bd560e3973e4b02ed0cc83873289abc30dd7c28b43405d25d46c44fb0ddf6b5c29c9cc89ffae6fb21630fe0e661d4c4d3d8ce831ff554c64369ba6ef14d63aa2a40c18fcb12a5c3ef8bc98c7949cfea1137ed3095e12ec38bc2afc6f83c8aa880b7559568d388051bc206d5efd17051b215f8d957bb9cef05ea84eff7392830f8f1476b82377332c6c68192f62905612c90a854b7958b160997e4b1bc00612c2128704207321d3c2076e799807ada8f8cf81746140ca8db992304bfc7899e215ce404421d92e53b1c7fa25210a60e3687ed2a78177c74c71f7e57ac5de99e8ef5893c260ada0441597600bb83c5c7bba3035724682588b6fcd219c4911c89b618109241e145c8ca220fa15b9fb1b69ad19d3dec1d66e4f8944f0ade2999c8e3d2c5793b6f26c392eff75cf2155c5418db0642a249a56a511e5d9474843bcb22ec9661f2904912a988fb1be35a90e12c63803734faf08199f0f5889db5f3c5716a33420526c3f6b0287ce3164468cee326d129999f5690bc24389659954e610608836a59a7866abc020e3da43acd18b8eef9ad2fe6cf603ec835269382b4830ecc615207e636bf9d59d6e5f4275beebcc62bbbaaa9bcd648219921cfdff11e77dd90bb59828e760ee886bc645361c578e112112434c0b75a23e70ce4c07787e36cc05ad3146082397ce8f570e3c29fced993ad0cc02ffc1383eb5785d6f39ab17bb4445da42f7f6cb16b9e658f96282504240f22be4549253c6301ea3a74ab64b79d03ef8c7071dce3dcdaea60773be553d422f9b40af95be98e2abab634e7945e223b8751acab4e227c63a65c18511ab5d9fce0d3a43fffd1978745f9aa38eed5243ae7564c8d726413baec663c09b0bd2a1121e85636704488ada75b0ff9e8c45900993e047798d3cb8b927c6506754c5b4a4729e5a703cb40e7088b2d8b7d898cf1d5cc3d2733ddf4ac612cc3dcf086c98906846e6484fc91f2a753e49895ca27ecac127d333006e2c5f8d59319d8bbc3b885675f71532c613aab469d78874f6742f1a6afc95a1ed95eef90d0fce41394e7dacb4bab44699f293f11a5717c2a979ee511ecf206a2f006693bdc4adabeae8a49597caec7ed99106ffe160dab28d0e92aa6ede83c98d84ebab98ce589ef86ecbd0780d64994fedde3492fa6b2520468f4cb081fb6158e4fbb8599cd8ef53e24ac9831dce95c8edc353659108176051df8d59e3d03151a6ff21f7e2de9fb73c7bdd00c92797f4e2143c14f41dfae19bc113fa7465fa38a560dc4d4f34842c47c5ac22bd0cb90e0e66b3bf4aa39088fa36e874f453abf55ff51aeaf9011f4a0c08e51625b02926f3b591cd0a0d3dd00a742ca90de2f1f9ad64c41ec878394696104297a8b43213c6c3db3f7b98fd3d81b8df51bf38c1722142cc9c99f6bfa79b870b2a2e416d51a7edce4ba53bfac5e6db82f06d4437441d20cbf7b64e5b321946185a1be25f5b4a2c3bda8a5b59f46555b8a063aabe6a178ac85c2ef99d24a224fabd92b1fca738c2b873f3e03780b1a28bea2dc4af9f52dc059807d40370fd69bedf01046448a17fe2cf46e97587b8cd8b9820564f906429976d96bb0cd2a16328914694513965c3a5638c53cb4fa8150c8f83d304556f4d6630c450aeb25c0c1af328c42abfd2d13f2537ddad1d99fc972e3e27e8248c4d0c99f83098872d275ca0ae1d447a2573cd8fb13cb5196936e8eca508ebf8586310285e00a772829d5c5e652796ae070ee0c18400904b83f8c49873d848ef776fdfbb1b7f7771d77d05f312631f2fc6d47e2ffe8a5b2fece4bd565627fd9a1f21592d2c4a8c365087cc421de7be27026be71655332e493f39f8c4b4040586a3b352d63d7ec6e50c087e8b604457c17418abc9b0f1b6d3a0acc26b7d272dde42618d5cf5e1281802e282cefca33d69ea35929bd3643eb435f4b65b068c9aa922c13c831fd0628d0423126d4139195203d7d4272b5f4d5b809213a33e93e142b1388831d76d45d53204c6bdce8ca7cf357fc53116e1347658b1758131f0961f999530d0954ba4d09b1808e014146784caeec4f937281b68d8ed0817838875dff796debbddc3ef838cfceacf89bbbe6278a7c3282e14b458d82764da2d4a24e879c40aa397dfa1492d8b94d1a62af1325701250fd392fd54e7004ce19425923350d5073f292a7522caf53d306df1956b80a9f137d06af6a08bb284ac18ee13f2a1c1f8dd9c00b9d8817d247041234668ad29c6c91c921b5de818ce5a0007ca71c7b844ac60ab5ac0fd820c38ea293904b4176458fc6ea1adf8bac35b6537f231b10eb056861e42d01a01560f9fcdcb77af9e9077472813d0cbbbf6dc7d1139093bfed941b02f25377f8d8a2e94c7db9c9635ba4e8a43b086b8a433867ccb15018c261942eac31cace994313bcf430bca1cb1486c441339e8c833489d74557e91f64c3274e93b5bdcb133a4daae54b0b4cb541526c1418bba6a4c4607dd276932069741e527a1aa8fe4e9db5587d43d29a0fb7acfec71c6f1e1b9f1654f95614bb8d1009150229793984c6cf5793bf298ad6230939d30a78785126805f7a9bf89360069829d9efe94b2343ce30ce7edac7b9a849d8bc219615ac8cbc33298fab7457ca5f1c3fb685ce8bdec7f418abe4c1d26c8c05238fb7bdefd0adb6f3cb66bbf304becaea83d369158cfb257704eda7c171d16d9a9f7086f7f8c44de218bc88860b4ebe8717ce7839c7986f7fb6f5130d577573d50a4a78a8b794128f1625216b57dd6dfbd1e12291810833e9cb05b7a52543a54e910d95e7b1b933a3112cbc823aaf1c3aa2050d000c2f581a41e3ad310475c516fa062b0f9ddf94f155e6a3caaf093431937ab014982281eea6dede392a798f432db80a0729a73e5338221f1ea2181ef95146652fed74f3aaa92c919a5f648cbd5fde66d77fcdbc3b110404b4e5df4ff8e7f1175c1dff77199f7f661e24b439eabc716840bea45cb918bc85380c39645c590837d9e8e869880f36429fc5f8cfbb7fff4fdd82640b9f43102442ca8cbacf8cddaee3b96d8265cd965f48c8b02dc8520a4bec03b3bf235d8a81f54f0f8d02f4a6a28c03a58546c9400346cebab2254101ee827c7abf4726518d9f268df19840384e7de4d40dd3777d0f4c00d74ff8a4eed552518c7515075c2f98127f3084d2af029f3cc34c59d72190d5705c08348af73012434d36478947e0047b5abf88d17d59cfafe908ae47d6a16e192c27168e0bbc04692b58f28c31d46e27d4716694444460388ae5e73ba691a63ef26a15fc48280f0754083b0ce5e4070bdae9f42e6055b03f3148a1eccd36ed22c0fac9d9e92b56b000768ef3d313369c43c3818405e0f876917d6b1849d065536d95108e58040e1dab449d7011aec3212942eb1ed6f1d966e186f77c2c3e844473d69d406e96ec7633696dd98c2c57b4ec2c35f3ec7da7ce4897a3b195659f686339cfc7bcc700f5b4a9bb53a2388d774755a9c0f6f9f9107b98ae9cdfad550811877193bc8e0dbbc7f1c2228974a5ef52aaeb49da6b4c8b21c4fd2859e4bd9348eddcee1f45a84d9e4608089f8d6b161145233da34c38a332cbbd99fc74386042dcce672a8ad129e6bc5b2df9cbfa550ffccb7c5d47631217b95e0ccbca2c4fe1b7a4270dfa7ca47730c4a35ccb043211708abae9584e95dd362c4425315bf18d883c7ea4b3174f81c4e6aca79d284a90561ebd6dfd754b0f70ca9a5abbf581f7740d06be7e79dea07a28c96b62ba8d6db90a814a1f4f99d24595fd17e867d27df21ac74e733901c84a26ee6086688c8aae2949e41a831c95c26414875c9c3225c99deab797bff11d2e0cad584315b49b773af83d50146b4c784f1ceeacd3f6f943066f403573e16b92037fc848414c151d7024b87675b7b2547029af9976bf01b2c286858ec21a2a7871762627a933161bff1c38bee1bcbd461b0bd0cae53752f4dfe54ae611b9181426cfb6486d55c3e0319a6576758fdf49798b38a2fa95708af17f78fb8b25eab5e45c147d2035c4d41433b37a822966969efec6bfaaca3becf0be67d9a7e2743563f6c618f95166be8d12a380dffe1c82181d1feddfb4912840514498e4085c5f99da1749f145e87d8a3bf2876a7c614a973884d5f51c9e698b368a3a5c827cc601e779292b37a4113700bd8cde495ab390644be2a71c56b4e44193d84bfb834314a52a09cdf9e5d3620030a43c67c6bab20fd22bdad1ef6984c9bf0a41fa4988947dbe1dfdb2286df6d70ffd2c929cd9be181053a0b92b92c353e9256b27432940b0d1d818e99ca6e160f287f73c16808a18082b4fc91ca382f5d6d0a7b9a0d482f7cad46ed9e1f4594ea670e28325ea1dc0a90e34f75edce1d157f8491668ab469d8f3de8e247f2cdef219d82d305f469b4fa2ad8ccd3b6ca8eb9bce8eda1cb61f3eb49407c2ae549ca9cd4eba0c8cd174066d214ba9da929ca0d52cd268703d93dc56d911a55256cb622924f8fc809219d1313e760c1a39c1ce0d913fcd0e885900ebe9a3c55c2da12970922deada283dd1fc864b173f1c24fc78100060f90c2ef7d6a5e6b66a7abbda95aa3df48ac0e92327e7997ebdf7d3804b4176670340b08544bdc6b3274befb297073ed014f0b17915628d2a3fa263bb751f21310db4ad4c711b22c2be9d4714c71389ca46457a15284de4771bed46c684734bf81f5e65b5d3dbb0f5ba8925fdf91cdf74db2871d98fdb8b60ac3f5969095db518f08399990027d200f699768751449f10e12bb06c6e0741c742c57286fff55db9a157f5969ab1d863130e3efed9da4fe07b5edbfd4b0589dca081ef2c9157f923914f27fea89287b41b4ef8e091e901611d96b15669184192d58e5d55dcc688cc0f17b2ae2050b1f4ccd1c093c3d191288d447b1ab9a01075d285905f2783077aeab224800a4639a02e38362624b775c85acb5c5fbf99ebdfa4b5d425cefd3fde76992ee95137cd29452cf92be1786782e6a21f99c877e2fa10b0da609e8c8018d5506c739dd9b5105b87cd71a7a72c9b3e953e7a959fbb34280a85a0da7f8cd5402091031226d1c781743897142de9b5cd24b0cbfaf159c7207f671968a70de15ff964aac78bd31025906f20ae76721ddf9768c8fbc1bbe93839bcd46df956f9d674266287305da815c2be09cf9f4235bdc343214868e36d4e03c0193e8f6b4125b0a6218c871cb625b5e1df6a2190dcb34fc0544e9ae3bfd00a95e8ec08216ebea424bfa909996d57bd81e9daa312912848af179f31555bfb506f0e638b6a9003eba6191cd7d8b94949d26a264430d1e19f83a4517b30f2643fb2ffe661f87b9b801e3304c7a2b7f8bbf99ff13fe86d0471e89672a3c4b3e867c8ee048fa5ff68a0703fcd759ba52946175f0b6408ca7572e145873680caf56db543715f98ef7141ec6af0cf61c3ac0a9e641569682fdf134dfdd93df7845153ac9764e81324ed71853fa2d727baad3212113153a95128efbc2bc2352a3c77231ec401859b8ce63541e760bd86e2ccee235bbc66a733774426634b2d3508202a61e431620a088dcf6f3c1fb8a96a67ed8f201af127bb419d54962d41c4a1c8dfcadbd933a567cd885de59640bb8c7e0fc6e4757614595d9753fd86c9543ff0de2fa189009860d60ec73fdc508d3c1bf491ccccc20917cbcaa695168a39b24ccd0e8148854586ad12a26fb0b87c362eb6feac2b5f7dd299f07fdcfac8826f278a73355186817038debb6cabf6ece14cc886234979694cdfd307b09327f81d8ab1d6533644823b6402404413cba351479b8ccda7972825c3a7a4811f70cf193da7ad6455ad8b2f97dec75601561c7b7f44d0433fcd5cb425b2a10f88cc030fafef77a5978e77ffd2ef928fb9fb2195318e6e163c6a28d59e2fb13bc820dceb0dd22c1e595dd23c39edb6635f06e36119c4cb0dea84f7c29f7dec2d501e8ca1a124f63f499cf7b3e097829ab4a6b32309c680980c002ef5f1581b3a18a3e75f8be83acd003fca1df8463005d55b779b3073d67ac901c296cdc7b9daf0192beec682f6988614d875fb2e3add99b8ebafb5985a9a910ac7f67594264021dcc00e5cf6877811fedbca60209748cb1229ae695eb7503a9395acee3310af7e5c9ae3d473cf30da710c95e7f47fa4e4eebc3e8796b65512c6d87ca9bf863185e7194a0984e3d49aec43dee50d638aac1d3d1d519bf381dd34c1c2493789d46904e41ace7b875d74d689f7419e3b27f071e79b1b48312275a9660cd27d6f40b6fbd75fc813ebd5c6f8d86bc4dc8c28278fa34ea6ae8e20a2f277d6f58882f574f04e23525bcfcb9255873ee1ceccafc46d8969840f9441b89c7156c7426139e61bf2ddb338a7751d1b8319639190d48d563915daaf5ac4e1cfc1d1daae1915de80f9814e666b1fa71e9aa6e9504d75046693b9119677cd4c3d6def6c16b4954086f42c356f47e33b71913fccebad594f638a744846c838c2c6f7205debd3d9e1f792860996515d1ebb806890bb5878d52df21439c15fabbd77e9bdb197b3ad12447286dbef932b5155bd9503b0b2a2e9ac989c4e01c98ef1852b5309ebf5644c926ea7b0b4cdb6af9ed6c59ce5b8b31eb1ea3295d7ad28ce5746fd3a942bbb5bb6ddf89946b05c1b1b796eb2ae3074fb05678fe880abf85efd0b7a99ad6d06544be184a221edd1ec9d89393c61366e16d5c424cfb75a13cc8ee53376d2b4e3873eae516dba1eebb784cf72b1eb037f4aceba45499c5ab0401d94566cee9617bdc4f3d89d43b08937183c326ad06afbb180e29d7ff79a621d0370f2132d1ccc42ea4679738ca5247d130a0026cafb4b93ac43cc7f75c743d79766ec0d8c59fdb4b6da38b2592d3d42d59f963bdfa702999a0233a3f70a3df3382978bffac8de46406c033bcb8c7c4e8382ad84f3a0353889512da9ab216f7c3cb24cc7107d7a8613191c58b3453d20edbd62fe387f8c1bb0d1e4d7dd845e06d7b5c437d39647ecd9c59ebfc3ebce4e55604c21df91bb69bb74a03cb2089e15f00a7b6d7e7c96baa928ade8bbd8a3cc952ca45a2587252138ab78cee614b39b74442bf02d52619940861b20123a8e82ec450e83de97450ea0dbee040cfbc84b4c0e45f3126285defd6149f66c1e1190ea83253822045bb461375324b3f825d2d5c7d056f2d7f10d635ad54287217a65fcfdc0f3668e4437f725de571671d96de1789a91e2be765e41a73d3e157a28e71e939a436f8083b8065104f7aeb209388c965749475f2d8782b7bd867c34a78378ee050a97294b594d3e27703c19d6853b52b71a135d77317183976b093e4f39651500e863e6e274e06e076910ac4b337e0a707306f0550649c691097e532669e498ecda09f151a4f70633a04e79914a2df186c6ba50658f93cce4ec55203416f901b2a4e4bd1f94712ff320c6c721760b05f35d3f5251f350b4cc38ff33a7af1ddf32a5c2346739706da8dc6101c9ff65b23fadf1c716cb55789059088dd03e535cf3f14e162176fd602f830d64a6667198114eb6874dc7726b1bd4ce4fc6a0b98a1e56b4c95bf08fe2de86e96e1324e3ff208bcaadc60cb85bd978dab8c94db5c7652c2c791e6fad113b1af38cc134b26be044a4e428aa79a2d0ccadca77d35ce0ab5318a3a04d2cfb47e30ba339b1fe22f0fe3a5bd82e7becc17c00ecb9ea7872dcd8c718f48984676b89353161acf46ff74249a577cfcfde0b202ff594391906475e10fec5231fddfaf5bfde71a1a48e25b20e1ab0ae2584ae1eb8ec35ba0ae5f46ea7f68ecffaaaf5f98e6fe63ba824d8cba77ef2f1ce13f9d0ef516b93111d13c0e4557680c1ba3e2f72517cbad4af58bd5418602925565555f02c68aeb3ad9ce983d881257f0657ac653203748f9fe0a24b7d01db8d09b31923e656b95bd51d539f75d4d0c303210de3daa620f91ec5b883ecfa0c6b4d4d6de617fd2cd81d24ce44760559d7fa833e97c35a97e19b5a3222a8586f990a54705fd92761b15ca592c5c41f5307f6ce188530cdb2406513d6eb7f1c389e009e4741201be13054c1f0045ab121270df36ac6ead43af3b0b226983b7719afaab31257356833a74ce8d7cb90c1165f8f226c39b875fd49f905103ddbba397f003626fc83132b11423453175f7535b51c2d991f545c37d05eacb49575900471b00cd926415b4586556b64bf49dd343a0245b095396bc5b560403cb127235bd9039a0921870867153df70cf96705a60413f4e9dc74d142d548c8475b99d92549f7bd1bd06c7fbe5d33eac31ba44b37f0ed4bed7b69cf221bdcba0e55dc7c0466330db29b429fd5c1e0c9629729cef0b191b419aba53d7fb7a9fad4bbb7d438aa1b619f44ba5170c4d1f09fb90259734cfe6287052f4ee46bb06d4e3633ce1a724c90a744ced500f7ccaeb7aa216b2922648a569e0ca62555d0c1b545a31d27f2e290017bdbc5d2f71bd67e4e4a0ca6259dad32fa9cb0a952f743d8e185a41d59cc6548c09260952c400eb9329850d82bab396957c5adcf87be35cb369b47d0eafd065a685e4f9aa1e4637f82a0e8bef95a676ac6911cbe2c98fab6bb7a12570e2d7dfc9f4d4b6c586d8635eb3d345eb03417762641735bd2d1218522d8b1be026e55fccda2a2ce5771c384ca57fa9e5abbb3acdf2814796084bcf32caf8fe5d615610386a682a0921f54547d14bf29c95db48497d01ca73f39fc50cab1e1ec003babcffb39c0e36e89900116ebd45ea0110f16ae8190942cc2a56efabbb63960f52a4c5e1176171555c6e3ce64b555ddc8fdee56d7395faf3cc7459588d825adf36f1f2d544fe4130812a795b5250dc9a9fedd60d99627c5b886ece79a8d56a5a11b2fcb19f7f05703b051906e9fe9abf84a4f85f054e8824102e972b321edb52690d563f432fefffb89611a14f7636b53c10a3d0da2cf1e7b86fa44f364db7fac7fcd10c7c91fd606e86519dfd6ff14be7efcd1ffdeff8a593c4ea97c64aef442994c6aafd0fdd02fffef59e2d6978f88fc90a4605162f72c4cc2e8a8e5309aeb868cfab00bd4aa9fd62688bc2fc414151b9c2939e925f1530604000bde00c50e1d8b752bcdf41944b5973a7efc5a8455adff520e9942234c0db1f4d31f8c45c5c62dd985e871eed8a597064662e74431e6fedb494e7902dd970eafe9f07541f6a8dec5b5449211527689af0c9e524d36e9c7bc12ba896a9957108ed9faa395a835a0292e82aa9522faae84522393fa9de10f4304615d0b2e53e8453d3fd61cc5a4e0add465deec5f40dae926eaaf909f6e61382c4f5a698bdf409fbbff16c0b6865d116c1545738bca688309a4fca2fdf9b53706121ce0f48fd7697f1e3ef3758af4cdc21771f6c802576228469b82a2b4c6c23b2b64f6fdef5838519642088dff0b82c07e25e062c540b396c171cbab484da62ded0aa0d4c87027e12ab998e4a30809115b742512a739dac03143ca69b2780fe6660dcb0f6e9518bfb62247140fb36f9192111a5d94946dbbaa73046ede29dc6a86ea3e1ea13852df6d4aeda9cef47a72d72b70605708448d98f9f8bdb560aa7e1d38cdc691dc7e9e504447b7d91775609b9980fad40d09f781bfa4ed68f003596a607ed69f398a25e60e47d98d7e734ddae087b29255011427382bd9f00b072ed416c1596df5667927f2fea4f6ed1e7b51864c84c7ad427aa04fd832a59a6b9401a59fc0812eccdd0468549139305e624e5786ada13af02cadb9efd1f0ea79b940b979fe611132190a1dce34d31cefbf91dd3a7dc339e08a4e05335ca50ee93281fa3d90d1d15785b0085895d1dcdfec88cec3955618ce1f75700a2db5176f225b059513c8c5a7228da76a08ebabb6558d6e56adaf3e3eab967933f2a7cc89b8aea78157c07f8ab9a71a754662771f07bcee23b2dcba0ed1bd1475d2f51ec5ae0714fa9d8a41788ac75eafd472fa3f41cb98a1b1cc3f02c7bff9dbc31fbd76ab8ffc7bc3162ee9947ffe75c40c836c5640e45eb7269945ec5184a59ac7ea568c249ff2f1ce4fc537bb2cdf0847d01291c1081df42ae71b554b9250872dd99fb86b334fde186a476b72e60f22541913421bbcc6f739497e216742b22059d1ccd46397ad370a3e1a705e9eedb4af5ebfb5134f083b7e9deba6900cdc88b86c97201690a3c2b46d6b1b08f8cc244616dcef024dcb67b6d531e0bbb5cdec667ce6f5e3b56e98ed0b0b3ca23d38f568afdf53e2e40ddb0ef8a85fa444330543b33e5b680e93ec1878ebc6a11827a8e712019ad1a47fdee4a705b4a19c77a9fcdba5ff17e6414e77b05a775176470d585408f0c879f6da0596b8e376219a0381cd397f1af8b04a36c646f21381df6b25c74a327fec9b105bfd3048b21aa6f1a914c2d6a33a1e5beae12297d92c7752229927cac1b16dd05d1734a5936c0550319ba0a662ab737683444ea9a29a205954223c4d45bdfd0053ff33a2360fbc1a4f8c37caa2e5fa83e98bb162415bc4ee18861b1cab9ba84d51fe47382f0ae96f066ad55ea8f126a827c58afab43c0c4d9861b91f11e26045f02a7b4556617dfdcf2713bd65a27c6126c77189883357123501874933a74ce7c52f564772ca9d6271d6eba9c9b682ebcc82c20e16d7a4fd3dc96884f050216e402723cf03555859ffdba0df0632b1b3b1ea0e7d7d27652a1bf462a1bd0959f089b32fb879af2112369393c2231633edefd3692c2375a9bb9e2578194e0f951419f428d495563b379291ffbba6af96fe9d9198f5d200d78d1f47432d1dced3d35bda51adce520acdcc136d1110f58c6793c681ce22c1d8d69c4acd34cd28a4f3d07a8a39512eb5db6e83e1cc8e7805b578961abf195206f38be878f27ab21cd134bab08248ff22ed4fd33109c10fddeb0804df97e8ae440258a604c13cb7d173383bcb915db926ac1ca8c5f5d9b5d622bbadfb1f2166e576b5c882ae9b487cf29d5468937d6cb321fe217851bafe20a9f2717e2321068e52ec3b82fcece55b42ba08a0f0d9111d33e1507d1bbbe59ca76ef1f3be267bc74c894bc0099ab621b591665c1c6ab95055dcd73a71e058d37600bbd25354c0a3d557d1875f377d5319d7ea45c283ed841752afddad6f39cb981c991cf39834e6521c878fc512ced97b828e4d218985e74f90921f2d4734aa50b47151144d2cc0fbbed6702f9d76d7fc9e84a52e803ce4a8af2b5bb557929436752a6a9ed137a425d36bce81d0f3c7caf0f690d0fdea5f7114cc8db064b10228139b9930c42b679fb13dbcdb6521275f82bdaaf1107b445fcd7b47fdee7e7bc4dad615a7f9411f38668f2c30e54c5621b9e7bf364e9e0a667efc08d88abd0df2911d7a72b459a7287e931eb3fa0853db434c495f61392aaca9c029f7b583a7bafa7ae3b0dab600e8bf42dd3087127b946360b4f07b10ce78251ae22ca9f36d9380f3079f6cf6cc52eda5b853ac65f16c0dfe2a8e2ff5ee7fd3f1cd56c0a2454f3c91cf2c95c4a6940d2f0af395d67fae73f31db14a308e5e87ff80947001fb6000901386668a985fb92674c3ba44e10afbc18d2fab8d4a3da4399ca4d0b007392313a24423d2781808f0dfaa2083d94c193e444be0552c2cccc36ddbddbfb59dc38fa4d95951b6035a1343b32b675637b339b0cff41003e1b1f96a058c875d70ce4dd5ef2bf5b2d7fd6d39a27bf2d5e1b58a74388e8b87d81ec069ae8cccad78757d0e866e6dd465950dce6f1bc60379300e0386ac0348f151376b038c7eb3bab922a2e43577660cdf90221afae46d986d94235d08d5b2e8321c37063a7f1bb7365ae7c21979d067c1298ba45fd626bfba0b7357a02a418adc5686e4446f3ab87a4f461735132c96043dba1f790f443437ec7079d5f132bce5455cd45e4c05e91d58c04e0be8111a3a53e2531bdee0074e4ed484c74d407740ac28fb3528d473e811fa196b8505a9dfdd35f34c7de508973482dc1c94f80a590c0348b611d827ee1cf3ae81a0584de3a45e8831cfd8dd3d9dc0a882397ce68d1d4e49fcc52a34206507005a98c4470a8f2e655c2e42c12f26ba778219e6783b801142c243e076e07bf5af530534c06f6fade296c53a3d6d7156a50f4c30314fb978acc7e56b92dbd31d6fae49ab316030c7dffee980001a9d71aafa7d34522b62bfaaaef1ba4500a9afa2168cbacd0cd917254e77e009c95f393799fea879a41dfa585058d3840edb7de45f0e506735e9a958dc864ca9edaf6d4171307ed660787dfb69dd245bee09261e3ae1c0fc8b46ab81abd53bc952b39226bcacc242a95edbdadaa6e3c89b5ce890cffc30feeeac53e64ed0f84d228e1ef6946fbbfe13e1e678e96e7bf7c987f7d0f50b729a5e05fb8ea88ac0115c5200249a477bed86410a38312565f1dc9fb0ead6e25e5766e5fc898a61e258f33907638a15bb3e0f008e3803b1532d7b9e52c3cb9fdf66eb624b3f69522294ac09a4e43b6c1bd028c087474045db7f52b65eb163e9ab0648fa6e3ea024b74b8d2df55a1dbc5dcec46e52367ccd2311c500cd36a360f80cd232d7f367db56f21146d55d7a68e8b22b7c94bcdb81fd04da74846fe1ae44b90d18cfcd3d34f29ade66ecac891a8178e590eade1164648b9c8a4f30599f354455913c0ef1afca126531f94a508f0f56c8a4b7074fba87e8d14026538d342098ea3c41d427a4fc859a35128082fad4b67614aa8e7177467f0cf48e0e012911b15977c9426282ad77c4f46c38fbea5ab083075477a0f78679893ef84d0499de125e45b823249f359472c4f14253a74d4bf2f17cfd74b5469d3a564380ed4864f732f861ad620428bbd5cce585c3d1782f71d696f8c56833b9446d13f364d2d20afc2630b78d27294f06439718a5c471e8ed82db6229785a4fd1a780d3c31ec982d0d3c6ed78ba8451e81154f38e8f7ba71b0160bd1944989323e517839db405991e8ee0f388b53f6faf1b7cbc8ddce21c1092d71c7cc63ab4548b4a1a99342d0132751b827db147f54700aba786f85db9f22dc790b79c5194504a6a6ae1da66c2c9f53513de25778a12aeadb43c79da25e53912925731bad31f205b0779670b47950838687f8857044c661010787c3d55e2148ef192c095a41e461f8b8d18cb166d618762fd3fd53c5eb65fb9342de87743cbb37ddac25ce1842145d8c776ee5caa81b327d8812b17feeed483a0ff2225428b9e05bd205cc49520ec53d874363c8fc30a83c7d97a9239b1d7ced9611de20a15bbd348042d69a92cc5d8408674e4cc95f17fa383c16cac973440e49272d8cbe45a149e32d85edb8fba7401e792696d83cf26c2c439c511a3da402c1d1394f2c4fa7598ee36c48b458d8569fdd19e0ecbb878630f3553bbd55215984e1f0b5689f65ecb628509dda1cbc0f49c1227ca8d8bc50726e72770b91309cf7aeeee568e835128e82ca69bc6ece021d0f5ac54c9a83c6fd43643f182d93021b7b4ec2f9ebd608f9f36d0cf65c43e76ce6e55c8845a6744599ad9bdefea563d7554e36b4d95b9db8e5c72afdc639cb6595c5a8ca8512e011e736de07251fceec6c340bc8d708b933ca2ba42b86837ba114dc8bc43a8909170c1723d8cda62e353962f89cf316c23b41a19374a0def1896d2e50d357e5c63bc5b3f5d938442534cc942f834e1835b80deae63a2120a8573d21fdd84c2461e78ae0430b3b66602dc7c815845c3bfc7b60adee9c931a6312885ba63a0406e35b6b066d9b541968470df229bc975253136f89850bf896e586f5449a58baf12a7f3794e7fde6635154e9732132fb416207e73b845ce1f5fa9c8c43ec25edf7fad332d10302e1a0dcf73751b30e8d61fee63fda6141be3da93e2d9f73fc8623ec582e24fc741c88dc08551575c88ed325e484e958f95a23bc703cfa29e125ccb290ecef1a6290d8ed05d7df36a35efc4f44eb4b7d2b3e284df6785c937789e02245e6209226beb2dc201b6ac7418ffc54bd1ec9a1a3d23b06eff80e2f9cc01703426280a5c8089abec058fa05c33559fa09cfcf0fbefeb90475764196eeb8030b4f793b1f7c11c449d0f4e2da77e32980945df4a7fcd02afcd6db87d64bfa29900a8117268cd699fed439374a00604d72bac1b938cf148a9a9e9c437aa24c845c6bae6f33cbb8cc651cb795b6b200e787ca5d4fdd09f9559b76834b9f92ac216a9a7675465a378036a6b8195500a281ddbc1ad4f5fbb2bd93d23f68bd388a76c60e8e4ae77490705073c0b85478c839ded435fbb763bea431c8037462f0140ef6cd8799f4b16d7158523fcb2619c6b017c9031bdeea20662266e72909f65138d4e36e54dc8faf2204be40c1f518af3c0a3722c1e98832fc940156ce3808e80d5ea45f2380a0544b57f893979b43a3cb7cb6fd87351b156721ce227ed24d65e851b48b3cba99198911f4f0150a30565a58b6fea8a3254fcdff540dfb3d446213a49d4ceaf50bbbc6ccf31060467820b8ac963313d7f0e4630015d62c65ce2a4a0ae7a1cb58f19a7b84c2c3c1c183cb8e688ef5cf7b441d1f68d59d93f343fd41723578dea0cee77913cdf8732d2c0a3938ea5ef5f261835c91ce80822ba96cd1226a6f8679910b80825604ae48d42a5024e7fddec6e16b879a925f7a4bb600920138b1004810453f2a9750f43d483582bce76be66ec4c645dabe651af0fe1a0056af1cfca1a827328d7efc303a77a0f41b58d4f89dfa89b16f7a6f102f1b8193ab20c7dc4239a30359f54600aef639df46f7d77e9c0e05584b8f56ffd417cffdce36c7eeae29526d3ee379a587c277133783f66e8c9fe1a041fc3e84350c725a5730a3d84a2d27e30056994b0106ac714442a87a7c0697e5a2d46677278b738087b621dbd38085b7170dbda76bcf51acb9284527e19f18d1810d3d981e88eac7593de5ef8ab3c59cb32a7bbf38c906c580b6b295a6dd26a2c37c8286f36fd58ae0fe4d4074090e807ef601bed745332ce8994032dc3ce7065076358848f136a13f1d0370956cfe9eb6aa676049e23b6aaf9bfb4bb7175252f3538bbd19c6779dbfa5db7bf5ff7bddde8f86af40fe703bfa2ea5e1ca7bf14d61134a6277f88f2c7d1ae6fe63b2a25181109e45fab09fdc5acf6dbd251ca9b7a6238a4221241aced6d9a9e787f069e381a6e994b1a3ddb61b8a85f2ebba9efcdd0cd8369d542203bcd63a04ab100ee13d6a02144d7f5905526015e4377bffd285ad7f96b49c7b905f7a72e86a7571e37468253e73521ccae691d1c31bbf04f2ea45208524eef408bda364395439e4222a5e04576cd64cd1d68fcf57caafcf98a9934af5c7492e169f9823bcc3527b9043e6c241469c9b78716567b89304f5f1832fce61555aed945b4a7184e709eb53b406851c1baa6f1e198fe321208d4ed3582e36e9ccd51883085183af9c8a8415d153ba39424b47f0dc08366f367630acc3541b5abbff004f47c1faa49ff7d49e7cc4a4765762ee875950b7ac582d49527cec60d1e36f58969e0f0537ce3f78a75f65735ce372e25b1a3105fc69d87b717b84672a173e93c13fea57c332c1e1e527ff762a6f09552232c93087a6c3ed6d9a5e4d1072d2d52b348cbb530ada8e986e31eb768b201c260ce84a05ba978d7037890de2c9c15f9d7545971d51d6cddd761e2a81c4b0441316318fe108d10c614d926e10f9fd8dda3b8ad19461e4bd8335b91b3b0e2ff32fbd562c6d08d325832bcc746bf6df56a61753b909451a637756f514b7f6d1a355ee60331870e5429987096b0f881e99da8648f3d77c8260178870b7814048185a1881cb34fc69a69583778090580dcd4354ec31410698f194f1d00b17a66afacd1c17ded407cc254d66095d4f566920ce90351b7b9d219fb64cb312763d022c743d5ce87bbec40e78089b573da263547f40b934df597a035c85067327e78d94e552bdcfcfdac8b38b749e659120d07f25df91be82be6ae1a57d64093366185e27f663f7fa41a158466e82ce7cfb6e5b7124f26187ccc970276949e54e3f8726e633bd6d22927f0c66077b02fea3df6f65d713c8fe504ccf29fedebbf0bfcf8bfe9f77e19f7cd389cba6f88fefaa5f4a22947affecff23c3300e28df711d1aa29368588288359ccbd11ece43a2061006d779e65bad110fe63df600064417ae0c8d528403171f646202538c71ee13afc218f09dda49d74375a550822af5d4027fbf02008a33ae08b23ae3ede622cae324c1b02485d8a51c653fff69e0aa65770ce65fb7ff73a89ed43d88052687520b5b04b1724ff475fcb0c4b4db60e0d52230003d4c4534c5d06e69b136c6b8dfd40621c3c3e2aad8226770484916ec0021ed0217d52a178b92db8e114973b437a482bf672b1adbf56179d57a828753b2cf1a9504625929368a5aa85fbb6e7267f53457a353578e0a274dda6dd5e0f1f2bede8089b3cfde8e2daafe70b578d874fa4b6aaf3bc507323cdac2e4c0377dfc2595da43e7c970be8ec242bada3953da7e9b7b48fe30a0e61227b076656dd79f49cab6376adab5a1966118ed71bd6dc29e1705f0b9f7f9541b0ab413e6ade7e3f3face767b34057d91a2670f17abf452d41b9c14dc78a025a7eafd3c9e517ce84babe18a6190d8d76bbe6c5c5ec58477b280ff43a542351a19e606faf7fbf5ea19953adceec04b9a915baf3a31380749d194a0fe5680d6dafc49a8fac56d4220087f8b15e4f70dd70aeb452a4db00526b48545e579b97006458316204f964dce74d69cbe1e5442733f448f3ce019e018925e9b76357eeeb6b4cd50d435eda00c5b5772b7ccb011b6e1b9716afaba0f395bb21041f0c4141619bb0fa39a63a3d8e3a8c209803fe7c64a31eca63642b4831f78539bbdacdc93157ecadb022b004ec71bf9c211d03578a63059c543f8d6d5af483b9fa3d891dd7dec50acfa74b2cfc6849c998a75dad9ab74c31d06f07df8b312cd0ed4a6d44aab145ed0976f1ff7f0c26b518b27af0b45f971fbc0dd8f2a90b00490621cd55a73debb14aa5fce1f17bc53f9bd4011de9227e42fba37c6b39837b6459dd0b6a5c10819e7dc79f90d2f02f0af5943344337ebcc310c37fd4def4ffc37787ffff2fdfffc7e27b1da9412fd1fbd784be8fe9f4c53f606450bd5181384d9b09f71b22ade22e9616a656cffac9eed1f81406afd94a14889b628c8c994a5e892d01b1f88553389253872a30a07694ff2fb0ca444d29d344a12c36394a6c15aa9bba8c898d909df975ce676d52c58bb5a1e5e88933e820cd6a21788781fde426fe35003cb97e93e72a1ca84e7086192358ee127eae1a7c30dd3d216a1d9991437e1e499648aa4a51c42029650da0dc36fb72d2021d06dcc9be633381de7a29c27ec4786f09ca57c750dc59c0dada61d6578706439e54648a812069dbba1fc13f5aca137ecc12d2ce147e10071ca4c992683cae38146bd85ce69fdf9da01b4e59704ceb34a12d34bf361ce4a13733fc1a3b543223bfaea9db7ba97cfc9e794f72c41840b6ef9f15933f444e36546523ece816a3e656def6bdf5ffa66b854a4076a0ab7db7454ffca83d19872e9c66c5c3edd6f708c9ee4b25705a7c1182b97200c9e4a2a5f722875c79c43249ce63a05da4dc8b75e64bc7fe471261b693a5f29c312a15e4f55931d63b863d52eef1611d67ac00d01d0d44a32f5314a7563affa637b488f35c7088857af628aeeb92a7758cde4301a3aa63fde8f71822f7398611c799d01a0eeec0d6a37766494c9bf13363b46110875e7836c07425c2d0cb43933eb41f81af8f0b00b3cf2db41a8689cc3330a2535553e3f1aa697529f45339b3309f1ed290d493f1951f876b76b310a34649eb48c606163890401c5f183843a49fe20175d190604709abba153cee339144d874502e7a483bd1262d0dfd07a67778300634cc1dbc74b4d3a15e63707ea2950006065f23df4af1f21449f395e823b0a301a06bbcf987ea3ae885970b5341b66261927168a8c0df09cb41192b40cf0580f239e54743bd9ecb28430778a2a3242fe991979d62158f236d85c569b4dfc2295ea1633bf1cfdc85c59a9f32bd8b7db4f4e7e865aaa44e73725800634a890403459f7a19d6ebc502cfe61f89fc88d97502cf160183bdcd998f40f6eb2734353997f3048fd373188fbefe026ff7f356f6bf8c3b6218871aa9f8579bf533205a4a94ce3e7080bb11a5118368153079c86f40b6bc57c7e7226aaa1c7b1f93fd1a6189ba84795f900468683878092b515712d3c169a82b22f477f3ffca8860ea79878d4c826e1ef7363974d58c349d68a153510cafd6defa21e93e4107293e2dbfea91ebb03e196b600f8cea53edf21e2ef8365444eafa3be8a6c96688c5d028c297e63ce64561200599c820289a0280d15a82ed2d44b020d26336cf1e5de430fa6d5a0fb1d33d2412acdb9a6edf4f4fe781359b6bab95cec020a0c74b4e415e0067d43b09296d9e3c19343ce89dadc3970e770b2dc6e06c8193873b7265708210e82055424469d308e73ac4d27e098f0284b77d792d12b886924b9db804d845ff818b9a15e74f5032818dc4e9260ebe9e8a8ec96a36c5db766c57cb1a1d1b452b4af3284cee63410405f92231a6a47d54c922e6e6b0bce9e6c2edac5d661d512b9461b7766850942a8f7aa550a93290fef882b016e3a310b96b623d94849eedced02a62f0e69226f49cae1adbc1dbf9fce821110e3944d89dcad3e7223a48420a49896cfb19bff63e78b36abb1373002c368c1dfeb9311847f835ff34f1e3dfcd3337dff899589d0ff83950397a103784536e95c5867c35a67f3f4cdd9aa939561a778d436114cb5ce2a5b7b2f6fd08fed32c9597f16b0d62b3514bc55536d8a0353c19ff2a110da79941a9a287f486e7dea8843084d4e24c58d82693ad8e2509835aae5c6c54b1979c8a37ee89cb7729ab34b7e5847c6a1c8ac6ea43cff6c0de70425f5390255a80a0d579da1d23983669f6a8eda1bda935ab6883a5af9684d66aadbacd9ed4e8630e412aa8d1e0d5062a8f29bfb9f4084ea1573b4b735b6c7a1384f9c2d9f789c0ec1ef146a985df3ecac282690a6d0336b5225642196e516acce569cec48e8cdf0c591c5c9f455297c4cb9f97b83fde4964b72c6ff4599316d6d23c1f125ee9e5e6064cc6de8b1f0a2c589e1faabb1e6deb3afa1b2d8afa45b080be56c1a5551e6ca0a0502f3dc0448fd6a451b6394a1d5b29fe5349054633b66a8c28ecb416705b656daa56590db01e6ca5f0d7378de3972db2e41682c3e637c1217f60a096e9fa6728a44b809dbcfda0076134da22e07d4402b17010bd93bdb34c8a7182a50283a344f2f7a15ecb96fe098d62ff1b3a2956d7d2c5be78633521c9bea3b8c1b4d30ccf2ee429bb6b9acc0562592bfeab2407a0fb8714b116f9dc35f79359d784e3644a0708e2fa7227d2152186389f4bc3995385ff96bab0d67feb1384dfaf6aaca8cc877c203656e27712c9baff5270eed1a24cb5e99dcf435ab15e6344935e2d36c8af5919f0cb0aeb535b958c69270a39418b040606b463e939c0c6124919d8c0e3fce6ae47b2a30d9147aeb9282620474e6c0d25e8dff30ae2052fdc394a1f0a9ced7c508ded4fedb24f5043eae543f2150a8662a5c0b150e3da8fa20aa32a7bd2e60a42c1aa90cb2e327101e6527a609f95ff9fd68613bbffc0369a544fcffce8bfd2f77fbff92870805d8162021a9c68c48a330d54caa8d0696cdb801619337161add5bb561b9354f72259a1f73573f36db249b14e4f097fae54cace3ec9c741f3963df9573bbd2a4cc98760649d23f8afa3efbb3880ba56980113bfeac278b32153b9bf1b91d97d2aae14755e3cf707973a9df623d0bc2cd4157b0d69ae4363cacbd86675374c4e56d85e6e0d41609c912c5b51c59ad5f090acc47651f7b55d7ef44a979c525954972d532572d36007c958a0491bd5042a047e5f5d476b28e606985bb7b03f1d9a779a581a69fc5acd28112c8fd87abcd653d719317133354249a312e5c220e16c7f84533b3a17621a2d9d18b4f2f9b89569a0968dfc2e96870415b0c3a3379afb9a6cf4036447044ed6f7fe1d4527e37445485b2b70317845e13117dbcf71ba021866293d156cbbc1a1a17bc15d0f63a6869d338f21ac97c0bd4682ff0e5b1b4d63cd3804df02897fcabadc90302d679c4a105173da45eae76698651ddcb482126feeeea2edc8fc486a0983a434617558c8c3f3a9f4c3793ee64c983575d89e4bc7faedd6a7849ecf0cfd6435dd0db7ea80965ba074e529b57aa642090acf4b23ca52d3af8b039dbe3dc45054ec72c6cf8e8fd52997ae39bbf112fea7cd39ebe3037482e552e97b83c271bb766b9311b7d12244fe582450f450da24c8e0f634d1be339eb39aaf5a2295591292b337ac2c12d146afdccee7d3f433ff99b16b831fb2a24aa1c7f264be0e3db51e8871b6bba69cb4ba15869a75c0701c4da20e461825eacce0bb44b9ce7953050c1163fbd256317f41b12cf21ad7989f00bae2a15015c8297c34f294405dad84c057b429d34a63dbb5149801b69c67fb887262aca1647a1e38da5e29cb9b9718f4d6348d7bef4a60b3bed78379cdb47db67093ae65fdcd624fce917537fb8adcafead39ba2cf36fe0b6ffbdf64544fe1791bec37ae207a18535857e5f27d93b014d05f55db20983e8b1a2c289629e85419473b9a5d9c2e023d633622e4979121fd4fb8f617edc24cbfcc24048ea26e3367c64bc83d3676540356dc04d313acaf60a5462d26f6c342ae724a84745b1f44e1780250518ca0d654afa7025668609bbd1a6ba2f3d12899b086b8571e295c5b91e35bc194292c871029d6956932a4e42947cdb85bbe07817d6073217c5a0e079496e6f6d5299990644ac88c976f9d76ba0b9a784ca13e81e027e513f281f35ca7205c488a4d349dc0630fd2e8bed173f556e373624c0db470304dab0ec00ea92bb13e0eb6b65d56d1cdf01b9e6d71939c6744f1b584485484d94a24d2269375e1082f836751e0351baa04b7497b9195535bfe88745d5b141d5aa8a2a584d2ff2daa3073ce7b2a61a9af52c1687bb14fd285cd16e77927068f551fceb7ef2ec6f31ccbb1667c4a8d74f25df3bc54b77927dcae67e1c2386f3cec58ee2ce4f325622d5bbdee5b144f2afeada31bd98b340d21717b0ad79680710741d55ef1f9f554e10ed14b92662cc17b53e4007cc6a4e145952e68bb13ff2f9e02017a023387226c5bc2e691ba4ea001fd8432875553d0a13800f67023eda51210c755f3c142199d04b72bfa939cc15af2ea8f54b46bacba2e8de068c9888ea36cee7de2e73e399688d2cc79157f1b2fe81793bb2142d9efcab379cf99b19a5ffc10cbaff5b5d14c33343f0ab44f07fe940fffd9da1c23082fe60601e58863211db46d100c514f3b0e4eaeba763aec271b3eab81ac49358892cd68b9c1882bce84d5ce0e3b8cad93a20c0d8181b37384515410c3ab66495bb19326bd6cebd8da6c3f7ed376ad0a06195284e554959cb72d17aa6f0b33ccc0dcdc095f1741ca34719e10f76a3b09d7cb332fa77c1e1372a5bd12ace88a3b4c39baa79ac50af1cf2437d62bb383f025d95c96607b9b1b9dacd99511434285a0abf78e1d6ccf842c53c317a7de8db2047a3949dcb8f599fd633752b7ce52c9084f60440a14226634750203669ac288f47bf11ab25bd9e084b703f6d53b9156e92cdfaa693b0520e6a273db4c3e952b84ee4fcfe7d4bab9966164304b20a8b9e055ddbb44d044e364c2d3a3441ebd02f5ef1437bd7eba758388f9a42940379422eb78e65f2838197c9388817dbcd432d2f130dba720cce2683a2718494d3fb8a473c9dd1259ec1b1c08a063ecdf64183c291274e5dba1d9506d50c6b6a54407a571a01e5f65d71102163b7535121592cd49940cd41c18cff1f7befb9e3b892b40dde4bffd59911ad441ee0fb4152f44ef466b17841277a237af2c37bef0baaaada9f333d1658601aa86a51c5cc880cf34444669279a3c54624f51a2c5617a58d6e6dcbe6864db60015cd1d38af7774524c1a0143cb8c0914be8e6a61c1d28a0562899a37972cc467403d9e43688df0941b4fdbae15047f3e36f64af10f2dc2b2301194fd9a003d523cba0a74716bd38b321dee58dd3ef4e709a9822bfcdce7a7116ebbc4d2a278bb863dca38bebdb28ee1a910e058727891b88dbde6d98dddf244bb7088be943dd691e97de4cb7e6e639a8b1585c315bac1efaa6f690f42d416627e7a54f93c7525c53c2caca6934704eca9910ddb66db46b12539ae9a2aacf92beef628c64ebcb1ab648cd42dd3804a419dcc886b240c50e907dc50e7dc9a48ac82dc565493796ed467d893aea5ebb747e994618311325642626952104b41ca48ed59340ce53cf18fc9056e3a0ccc065be9240012ce958a78caf6d3c077af9abfe0b51e3aa67b830cf0729eb8b3726acfbbb5ae8d48b01abc73e70798f35e28b138034adb1dd903a0797b17cefdaef6fabaf004a158dcbffb9d131fb8f265feb8951e8c69d70ffcbc39e6b4ab9ac8fb05cfd329cde75cd91a796b68e48de0212de5418a40a448b83d8485d5eabddc8813774981bcd37adda1c0e10929bd1d30be43d7c4d371f2798afbe40a3b680c5b4977adaf76ef42c875ecedec013d54384e3683904ff7c98f4e180a9f470c3ee318baa033d7cc28cf53922f9e5889661859d1f5c0d5c2de076bdf4fd64d5bad30457c3806eba724d9d7cb3450b00fb21e0bf9e18598229ecf224823db280d1175dd8202601156dd266b64b1ddc95972186e734e2d2145c153c8e7cca3e5e57ddbb667d3167717afd298892498864e454be817adf6d36768817e57513ea313b12b99a3b3a07e585fe6c692e5eb7242d49085d77097c23664d2f4b9b845ff687a221b6e4b049127ba3bd57819cbd5a0e0e1935273a53618421b23cded25a3b65b1b6bc4b0c5625591ef10ec900f7429030986167362bbd69409b736cebcd4d5a835512d750d7cae5db9d40b76d6336807b64fd448ea3927d39903d610196d10d4157c37e4053d7b742f05378f71d735436cf2d679ac72b791c19faaa0eb144e4a9f10fbb8583af6ace004177c6fad33c4dcc95528f00d1e72d804747d9481e9294c13c3d24fbd574dbc21bb115d567537640d369fe6d9a3d7d24e2f391fa4588d2c7c5ceed40defacc1b8247532f9e2ed023d9e4126b2a14c573ac88980a19b191ecf0fca52f63c4862e351686da55ae75b16efbd4e08b1ef69d7dad2125b14283dc173ceac96a0cb6e342e0d5d9ab89e18e413b071452f7b85cfd454235e2a5b22918e075b50d9d12c09c3b109ab492350b77442a8045ba46ed2b8da4e417971d7f97951cb8d4069645e62d71359161ad3dac9d8f6e639b25bfb2ea77b2b8bec8b5c9dbc1398475eb301365b616909e97630c4ce452ca82ade24baca9f6cd4dadc252efa13da7b957b2dc580273aa70355874c9bda872e44565b4d7af575936c031db2ed726d8455eb302392c1b4570c9e1e39fa8256c32df2cfd9c53c995b26dcea2db6d8738333cea2ea240106cf9981eca730e98ad84dd553f02d9d9df6b23e53db00ba14ee554ce39b0cde8e697c4333e121926b77a9eb15dc412f856d115a20aa03daad8f7439de94db29a9946e3ea1b2423d5bcf6ad55b7b52c79eb039b5230a2fd72c01f5a2a70a2af30e864d9bd2f8cd0756717b3ed55b9cf105f1f41c30237c2c2a0532d1b2276a1192b381bc9c86a3a949412102cadcb634429c3282b2b67ade4ed9289ba59997da5d0484cdd05bcf9940aad8a87e5696db7d0f7b881712e1a9a31e72ce6e089ee6ba7b0e5200a62eedae482cd424ecba03c03d1cc4516cec89868d87c0b9ea9d740cc5946fae94dd5ac1717bb084c31330a00f3b5627d4e163f5521059958d6e7437fb6975e141c1785c72d82bbb95edd3c750b5159ec0f59223970969707b6c2251c8b9a4cedd82d531a6cd2e525e9e8348af77ce4c812bc924d1d3586217536f69c1422202ca5e873cd2b9acd878f2439196dc5324f8658cbba5d351330fc7b78d72b50d9370b20eab26d9bb2ecbd5d9b6ba93785e51fb7176bbf48ac4c5a94184ecd2002c91c60321d84f53c24c753f2d2595d616d4bb612681e6d433953bf7416ecb0a4c29a5103f1835e4e896610d0e63414b546f3378a671dbd6b03de5f5658d7869b7af8abb3de81b6c00ad85df9b53c8ba52c6864124c9798389cbb39c62d592da9e89ac13679c53ddb553e0421310d66c23492369d03d05473c17292d03c3c8cb8a8f7488e05823c5c5d2364c03b6724e4067e030606cdf657b97587e733b3b243f9dc17a65b46b6215dcf39ceab78711a61eca77b8f3009fb37a89a24b34313afa904d2e38f54db42864f6bcc5f569a4ef9ec25989253f61931207cc96f4f33351e7928eb1e16ad24a7d59b1791f622a4a8ad37d2ab56c03066f0d1f719587aca155e42ee40d4393f9b39d255331f50ba8b45e9a2f5804ad5a44a2ed0075de652e8d91b67bc04b2455050a80761f019148d26c9f006588a74d8da25eae6a4144f499c3467342231648a3a00e1a934d6d7102d4a0bff5010236f5d52e6ccc558a5ed669ccea2db5a72709dffb33a336455f32887123b9bad7aea7fb63e3c4270e2be1f6007a3d667741516a20b867daa08af0f23c2f70cf5c8974392feac5ad78d88f6bd317da8bee2b0f3c3cd3b47056d5d62c2841cca207b2caca19758d48e11bee7152ce209302b1ef5ccef15933ce827cbede65cfd8a0f34ee8bd3c3ecaf962b35cb85e9ee6a9c7e4eb8ceb8f5d8bd08bdb8e34af9be1adc448c4f44cad34e01b18783edcd14bbf09274943a32832a57bce996b43422e90225bab38c1c448db76ed98a739e9fa6eb2062755120d02441d3e0bab76e5a49337d567275e5faaca76d6db64a1eab0b94dd1c4d0c29faa3c578c87d7540a7962fb4a17e909ddb2d686297c2336386b3647d8ae2bd5e627f1a447ae110a3ed91bbd711dab8bdde1008a9c8029b19e627d61c49298c228b87b9b9c5d7c7194c15af777d810669912e329332532363ddfd933ceaee3ebd91167cb706baf8fd7442e3b426fe57ca88661bb5ebcd9769e17cbe8cb89097a211ed9b54a7a0825a5045d61064944c2e92ee386d94f28aa2aae4f86d8af8b0ddcd08ab98f4cca97693744037a8fe2e49e5a09646cd7aa5b93a756d56db2d87c510bc674479678a4ae59610312b35a1d8d5ab87dca8ce772d91ace3f9bd7cc4c1d342029791bb10458fbd3b3b8916cec0c99583617afb0215de88c023d090d4ec3f4792a58e2ec306aa5cfa8a15ebb9b1fa60c1652fe8c7211d9d40f52a0c249edd4db58a5aedb5e1df7995c9818afe531a993867b76d0d5c0af0b2a9c71b1be7b44bdfb460c3e9f1743c6ee29e3c766cb99786d914995b5a20f9c9f65961afec36f2eca3eec509c5d6e43d99320d95193bddf7bebd2e4376333730b0dcf5dd5e159228e8d835e43dc1894135841a58cb6659694ab1943a0494e941183b9e190e78721f9cf46b2aefea510cc1a6caea2546d8f88b21438c9ceb59e27bed0ef920980cf42cccbe54cdd4f535197f92d6cf3cc04bc3dc7f82577af058ff1b1dc5e20f8c9433673bb85e298ae1b0288cfa4b8a07a49da440fe4ebf92e56343ed5ab6183e3dd51e06a798e58695d5c9a0bfa4bbb123c9976c8cc980cbd6d9b4832699cc9016ab25e0e07a612e46c62ed81ca35018fc2056a8e72d585bb4b22eaccc148bb9c090c8c1afd4698bd06450b5b3c7291cffd294ea4d58b54b733b22bc8c46793511761f43be921b68594ed8c7d61919c9bc1d423fca1b87a226e2a83d125e579a0e3e0b19f1c89ceb6c509e6aebb3faa824468f0ea448ba9239ac2faadde01ba320d37cf9435bcb4b11adb745757ccd3a659f5b4cbb30a86f59c834252a9cb356f5cfc56b6d1760e8b10596a266033971d7adb664423064f5ad8e11306d608a4d5c193d9e2602367ff14de4153bd0fcdb09c970dbcabde150495078593c01a9ebc2ee8cf4c34745a18f5b39fd79359143a3d5c9bd0c0428db86c208bad0fe58e54a9e59e4f910d70bd3a463e86eb835cde62f29c480cbeb325eb0d58d4aee61d5436fb7e5236342251f544a253cef1e7913195acc9fd829f818bd4117de314f714ba68c8695f905e71d62e523df8be505dbae50949549413dcd750e49d2c0e89596b5527c876d2b78376ba344fdeba06a6a1f9bae9b2eece53d7a0c02b6c167514cc6ff575482a2a6cd08e082654c19f463f89c3348c27cfd6d9d0c7f0c02ca2fa89940b6a4517888db0be4cc21075f4009f60d3218cc55b54a9d1e122ae28d3e2f4c7b31b844bdfce17cb7b84254904b067f4d5e33634477978ef11c8a41c253d156dd80042b4244b2391bc8884ab108559cfd653a8cb64cf4251ec6960a504667fc22e03e06bfd9cda8fbce7543b5917827a3cf8b8dfe4b3dc92ca234ac3b584957c4a9cb541d15a51e1dbe9a6decba5ece24497116a24f0cc411fda853c130415f16522a7f9f34e5cb0c953109545f73cab08a38244b0579e701993d6954bda19b64c4911701596c47097ecb68afb6804a77159a75274318abe1b698adba87105b84996aecadd9d379aa9785bb5ad73f38cb573363173a73d590d0d3dc8891f792585a3386c29589fa51aab690cf4f7334e91a796ca1f1c464ac1b83ae843bc900d95dece556263ab0bb5741c344f4476926942718323dc89e81f9bdf24b600d4daba8665ae0d4138eecf2a15e17cbe9173f4785ce5c8701a1a816c2aec49bc72a15c6f67d253cf76d0e24fac597a8813878ec3a8d0379ef1f00401b5cdc4730571549892c0954a72474d6f39d86ad4e8b4168c8f2daf413dcd7061ca35714a72eb9523e78560cff476bee594342f06116e0c7fbf1061b3892ce608a56aace956d1bab4b765d0781219e7396eee78b32861278213d338c8ea77eb051e12e762bae332dd4eb40a45302cc02cfc20f010359b480454c45cd0ac5e77f6fce055aea38a84b9250b70df78f7bed1fb923f306f7a2e5b6239e5d860ae98d2b88b38b17c5a9a4d9a91e081dde966f367247920ceb98b84c7bcc4e794d93689b6e6ee0a4d97d204efcbed9cdacd8a367bd0a2857bedf0e9d924c239396b827acacc0a500b9d7f2c05ba9b97989741f42282e13c779c3fab8279711065b2ae6270b7ce84aa9a3bd2ad45e070e169009de98c08e73166eadb13b4c9e062ab7358801747985a8c029fea00478941d0934480fe94642ca7231592e612d465eeca5e9790f1693c5f9136bfa55b718fac7506ae72c2c22bdfdeebaac9ce7bcdc37be2ac005350dc595c9e5df690dbe004e2d4b212271ee291d399366d4776bc664d2afd5edd01ff449aea79c4daab0f505be85cf53a7d307bb8dbedb4258f4247ee2e4744ee1cf744c8d16891c7866dc019a89c0c6eb568ed2c8c555fda4c6f7492789eeef7c4860b3f5948d64a04904135f4c15cdc32999efde596601448f9eb9a286059f28def7366500871bd63f0aab66179579d59ae6efd7a6d444719091f60d5e700ddc8938ed1750b8120c7c8b92a74c6ccf24f4b1cbda0dc59111e69ecc96e27bba8120df6b7d11e334f59605e7898fd504815d8e468c12136a03e9f98c9cf970a54a9c6d917d46fb1c85120a684786286566d3e4999b95ecf89dfd3e7db868bfe668b49e1c468586c1ce8e6891f5eeefe63a1c68961ee7cee1a52fd600805695cf9ec63f5b970e868d5ce2b6d5fc975374faa80d8ca72918aec2c99d252477b3a2deab8dd43f78a79619419ca76c32f56b53730db207578254afb218d88c249243fb8579d762e965837e0985466e7af8c096eb3ba3942a85dc77a332e6869145d8b6ab7a47c4edef29cd74ed1773b5041f5643f9da8873c7daeb79d776a7f749872bae1ae66a1405d88c51a9cf8d61ad66c0fc4786202d5b49f17130d456aa86cdf2d45d40a6077954cb1baa4e0f33974fd3406551358d8de6dc9683677bceb9b90dd80674fba672ede5cae1bc435f78b0856d5f07eca4b4018f30dc839504215a463c5e723d01dd508e7341c07b0a506d7b6d95908c14b5e5d1fe90614d7b322999a51335016744a8be6a2917829e02129788a8c964232a1734d5c2b3a53778c0e891763194474ac0740079f25e8b47655b62181dd4266ea6981141acb16c798bec5e71c275a5733a675117a89471498c2ca13f760694b60ad935bf90a3ea0cf3e4aaf6aec98771b744219aea0741139799e3d9cb8480d5e86b9e8434e2c9317fd626122bb9dc5881348e101176b9e38136452e872bdc127a4204e21e82b807803944ef7539179e6319cea64e0baee45312a1cad6d68bf15e373de2a496330c057cfe695c017ae404b95bb72fd941678c5cd03c65df9e504dd71162cae6c8c6c285666c63637190c1a11ecc4b0ad521b706bb521aac0d27764270964bff2e1a6ece68ac92621dfc0c5df15f9045ff19d4f9db0ba0c91e14abd2b846c17fafc753a5d72c38170e5a99aabb1217c591573b917da502157cbcae6f92929de9cf4331c8ab6b76445476a3d4a5e1ae77461b65b68c0b2b98ae0edfc2ccdf27931b0e6a440a6a0c59c7466f125421f1d6063c58dd3d7d52fa42b2f4d7db0372cbc6c0ace915875de59b580e9d37667c3863b45c87a5fceb7b7f7222971713d4bbc4610142012bf740e2bf077ac1fbfad7939df9d9bf479bd187482d779acf6a95f4369e3ef6451d02d65f9e922899a14069a474ef0d8aab7a79e884f1b3081dad0c8a6e67b922d4a4fdd470b0eafece44a9cfeb868d1499071b3158c66bb4627f33c3ceafa8cb24ef348a0a834700fa14cfda170118ae33b3cab11ae9fe34773be56e142a8088fe924615e247372c176bcf823c34ba746d2730eaf44c0cd9120de2753c1a92696b2c6979db1330cbc143088a22d86f7ee0af3b0ab3b7ab629a900f7f353d4234d831ccbe546e25901beedafbb27a9012a8bcf69f34ea169c1dd6ab1b75b2f94fd85befa4aaa399726e1842a8ea7146185132643fc7679c094875f35270c94922157f8696b773ff6974011e2f924ecb32b942ee70f8fc8542bffd1162d0281eb162af46c002704344e131264ed465dbc5d9208d072e405d173e851a0f3ed1eaa94b523576dc595143c9174f6684dba0f004dd7f98435e334a7e91dd84b67b1037264124498439dbf3eefad2e472ca56c3def6d35a5a2f340098c15ef8d33c1da40703ac579222c294fc591c253fb94efc81309ae7198228122c5b9a4131a4e4c90b2384dabdb620af9fabe5e7946cd545c71573551a79b64e5d91d114f79975c5c0decaeec83271d5f6ac57bde5a4192ae7474be6d95b213fee2b0e40247c592a76a6bdc45aa19b505901131bb296c30e6a1384856f45c494f35da8d250bd70a696d7741bfedbbd5c79840d60b45f7650408d699586810184ac4e1e8162815f18ac894e373e363a16884d7c910047a2daf921615b189e7ad8b5b61488867b57faffd0218faf66436b132b991b32c68be8505cc9d38325af2dc4eedb2e8b1bcd56d94ecb07ebeb34376d3f2a967d9e87c2bc3b9974e6b2ea55ead61e1c352772bba019d8859a29c280fb381768fdc7aa0767b3441b38008f631928b68a34e1d6a88201c6d93ee57857f3531323fe90e325506ccb154559a605b4f5683e09782cd2f3c92e51170b9157798d9962be5c45e5107c14dc770e9ced8277bda248c3bf5bad59c64bd548d3140636e83bc538067baaf707a413ba446b593b046e09d2fb1c89a200aacc97b768e8a3046ae43bae63a8f03992285ebf5d171abb43df932b63bc82661162cc07b749581706c2b27adebe7a529fd8726c900d10d25d127e335cfce97c1bcf33b5b874b2f93027c2ea667da952bdc25cbf5b1725ebb7aab15c1be6e4f98d35cb0826d75ae3158b6220ac779b235e181dec9dce7cef67be8949c51e3440e148ca4ea29917a423d5bbb74a9763b5ad36768e357d1d47b49efaf417e9b714b4bcb794f69c8db1fc09da8e15a347d21722175e6d2183b03c5404d50bbedceb8253d6ab45134fbcbc60c6b79a6c7a2f6da2b7ca51a70252687c6b080417339e4302b3cc90d969d4fb06bd18b18132c44c7ee595583e07cbd9d85446e869019131db63cbc06ad043deb18e414e47ea6248abbaa2828e181069dab7bcb03559bced43a8a76a38a458740e9636dc2f07606eec48cdf97e4baa42c40402a2a340252a84e6d5d3d640b87aa82956c1f2b885a4bb415b119887469c4249776106323fce18a4acf5e75f6a2395da24b78b2a65a6c144e1afa30348892c700d5c54e897e8705f6544427ba1e2b902be4fb5555d6136703d15a3451acc3f10942b302bb01b6bfb71362e3c47c26d2a00955d98cc9c5a79efa8044e970235245b1af340e4ebacf91032f9c4fb4432d1185c3948d885eb5cf1c195c31fc249f42f886f3abab93dcf99aeb9b2c0f260ce7feb05e612f35612f0beeed9a6710b2ae0d73aec0e9ee45749109174c29d38c4b0334a54136150164c744a64e16a361d5f6793bdd3a15380da85cb092bcefebcdee9e23278de89e1a437bdeaaebae85e83dc8afd19cdd4f2242f3cb665097709274c873348e0b25c43faf273e110da489460beb74f1fa98f8a8e5efe7ead9af4d753f9f23c5a4afa726dc04f144816ae6f98f287d9036c7e7ccf364306385938ae224d3c2ecf7d13975b7cb6ac9c0a052dbc878e7b39f3e871b1e2f937f0e549aac38cae833ac483c87c79691bdb1ea6d8f786d285c66ceab6d8c9afab24d76e73242a43477576febb6dd33121f26ccdbe27da09749dbedc898a78611e221592f2ebd2f362245e394606cd35d5cfd2639e82222766ecdcf74534b5458c9e06ede6d8a01229f6e2a669a91c17d56fac9bc56e72c90b5f90a02a706aaf62760c7fa25343ad1a87694503963e47bff9e8ec9f3c639cf803e65e9e98934787e55553453a8d8c66b23c66d2fc3ef626e2f759a424455d3a40272d2ac68cefd01db094839944d5eca53da8cb846909cdf8967fd1e86d37dcc1ede23eb8c092f4b1b8e8cfb194583ca16aff914afc66c09456353db73b96d8e53559195a33a9c9e6e10e69edc8658acb2f7087248b72b786a41fb727723c55d9970eff507bb54fba870b567dd17303d3f65307027431d66b7a3a1fe34728bb858dae9669f10b81c12b5793e27a5729e3d7535a833aadbf873cf423b269c1970eb8b205e845375792a57b373bae029302116c0432c8806cf3cce2db7c667fd2d77cb29aed1d4812508f242ff5aee76f9a77337eb7dbfef97f32ecdcfcfbba2fe245a134954cea92332cab96a7d3e3b0563b974266a7a89b64142ce81118ee5044190b39ae7dcbc842755bc097947d2b3eb7390830dd709c83ccf75611fba8eebf5dabfce92434f27b949496710cfc4da2bc1980f5e38339aedb4c08362946bf860580dcc822da640065f9ff92cb0b31d167e51cf35245ebd64042d80253c377f70f04d41589f81f06bc86c4ec8bb0551f87e0b544da23abb3f3db90a0f82d84fd2f9423a26b481924c6d918a5d2b154c19089714a30914a3e55138364745f3cf7c559514bb5bdbc6cbf7c5b7714a1d3c3ecb464205c2aac12c5164e88849ef6b9e8b73abf9646eecc2090e9a994a8606be51bcb6c7b10453d966a0f1555af3e5b977eb7e32cffa2ae6eca5e5a72d653c3293046ee4a84cad0cdd366b318cc41abf4ca619f52ddfdf2435ce73f84693f6c4b0eb9463002c242c40518c6a38976b229553ddb07b3824fd7abba97ba4222d0c5c0ab28aaa472fcbc8d2246559e68b8a64b9c5e4cba60fd724e55bbadce29b055f9fc0580a9edf159b9a4945228215c4f5379abdec7ed5e5b04de959e9318a741da6d8c2a769927b5eb465c45f379fe8ccdc2ae0406deac6b9fa3ddd243ce3924d8ece2c6a3b859d419d64bbba0b4702ee598f2da2b34b8352684c9c63b1a3ec4b44b9aab6da3d36f0d61c567e80e7dc4d65a8d971ecf5a6c4491d5e88622a05bda82f7288e34acabbe653b75b1bbab77abb5e0cee628e446924d6eaa4b19981a4e903e9d0a834e260de2911ca02e76164a2641e21bcac4ee316859fe0484ce86c20993c24ee70bf6d17e3e49d789c2cb16558d5f81e49518feb6e41ae45ea5cd1748dd5c60bf1f55a4c0b748ececa3eb1b99a2c84b13683c6770dcbec824b84cc0336a5f92ac55b2d36c9c9f61246af581fd81eba7a2149612f1e642cb9645fdd2237a13bd41ccbb5de927be9b13a9ec489c6ab502c5542b544ac30f56d549c5724bd5c8d063c79195a2c17cb4e6e9c2c5fc5fbe54e11daa949540896ad119a426893abcb9978c314e406641a1ebd1e61fbc5fdc4fcdf8329518d3ffd7fe0eccace67147313489a0f1f74aad3675a88e344c9669e16ccdb7e2d8dac3621ad5adc6cce1aa19577190ff4563e03dd5dc8ae18f1405a0f3b116b4f99ae7f1fb52b6c578fa4331b079f0be84cdc0a6adf78872263f174b9f09919a7caaa17c5b85ea544f4c6646080096ce328490687eff5595cba48d0f43b0415525eb53d3d0e39929b50818f118e86500e9c98a8d02686d64731a25d113ca5400683022ee52ad769ad6319d4203cae8ff67ae34e550f10b96f41586b2e1eacc97d73cf9b722fe93be53fe673b60f75782f30cfefa2d50a9eb944dacfeb635e991c49bd0c1ba10928ee7b41171e0f52dc70b69868c8e80de110c14174f1ce41a8675af5954d900cbd3881dd5345051a1502ece92a287d74198116f107450eb7e0369b44ddac2574be98da0531ccb5f10273d032d6653163ab0010c8aee77228ef9c8bf627d6dbf8144d71842b5116ac71882c80188d9e900e620f42e8ac24944472f0367a0c6bc95f87def238ab5aed64555a3994f7cc75dd93a7c1c9a995aafb283cc970b81427b469e334bc782b826f34214c97aabfaee0cb4eaf803066484a12040112bff64c37f777d8a999b80ae03be061af8bef0a40e0d8fb2f9c235695d1a8b23b6d65337ed3329e927c72eb90b9939eb555485dbe583695db791a098ce127b86ce6c9e40f5e51acaa356e6d2f901ea6919888e825a54d25cfc78e149def67ee317b8ff53c73cb0d5b18c4a710ddec5cd05d653e1cf449a4acc754e8feba2b3d484c0dd4b54d86316defec94515e3d515b6965daa57c6cdb7a1cf24b4189d9d9b98400c0e4e3fd269f1080ef0cd9375c8512152d7c58e2da7b7ea46b8c2482199d875470c9cf1ce2dd4073a7f99ab9f56289d18f80a9eae124eaa66ae42168e257bc513763389dd7ed7aaaec5034448a9c417d4ee09a48615ae066bcdd9cd2c5bdc57c926a6bc60f2455d98dbe7155b06876a60ead1a0ebea5cd53c0d3c05992c435ade19be69d644c0610ccdafb670529ec55d861095d2ee3797380d34603b009abc2aaeab75badb7a3760dea159f33b96bcfc649ceb1ded59e0ffe8e1381d107d4fd8a8d8113267e60e2defce8f11b1a7b2c75c902077b8a8ab186d3991f863b6a66cd99bda4ebb44f241526f09d937a90cc21acedad0897076cea4e523805a97356db12918db890ec6bf6f67c460f87cfa12d0f3baddfed9424328df8c919e85fce2f27ca1f12b7b77de92063d3f46858282b81a44468bc457cb67982e035526a63607dbe7a1b0e9ad68f7b505f67b628baad939255a97a8e2b9a850a7a699b36852a7af5b37edfdba69f7bb9ffd02f2593dff5fbe15b9ab1d014f3e2e5f56c34f1e5d968fe7373f6477fcd098d204ccbb6340314ccd2fbfcac74e06053cc32bde70addcfe5f003bfcd0ffc8ac31ff1db851b0a78ce984575f94173fceaf9ec9f8ec794748234dbe30a3d7e293fe6de2f75ffcdf17cec0776bfec078e587c941a720b61b28a1abdf35de597644afec8c2e3e0e18581bf2637e9872e1499fa610ff3aff5a5ffd01781dcfe703ff4aff5e9ffd0258dfd719f5fedb17ef7c3db37fbb515c93bcb3e75e43d1ed112c44dfeb66f49236b42fe9567f8a910c281d739dd2ea9784e3559b09e458d5e451f75d3c7f8d66f621678a5d59c3e2e55eb4610c4f69dfe00c21c845f199fcedab5e7da434ceb730ca1430831a5eff2a56cfc19fd9bc4829848693c4170af6765cc1fe80780f4cfd0b7e06a8f597bfc26ff030fdbce50cdb58180b5a798ad0acfd5e73f971579533ce31e1da0ca7a1e411c1fbe9755a4fe13bcbec7f40f5f93bf79b743c67130dd1f746ec5f15bfccedf478266d8e517f20de0d769a2011392f87227088ae7168210891f68cadcafe438403545b09e85ecfa37ec91a2856d2ece8729b0c0618fd58f3246865f91b1c9e28dffd5f30b3ff53f9259a22b18530b416c6b4a1014f683ff1506f22bfea7bcc65c7dd0175e3ef8e7b4d77907eaeb1173e2c3c76fc80fb4f5bdfd15da9ae7eaade62abbef8079c8da9b40afb3073183ce567bcc099dd7d8df9c1ffa537ef8181351ec4c2e0401a7084150cb0ffc84c5f20ff1f3a774b981f228b87d25d64b491037ef07ba24a0fd0add9fe6d006cb4cfedfb6bb0b61e2d90b6ba954200862ffc1ee6ce59770d0fee0a754e6b0f63b1fb637cffdfa1ce99ffbda494e0ad5a78fb833d00b4148e9f7bec6c8a6f60bbe067eb6412661ed22fe19aefd798c8b89efffdd2ae7979f23fa39ce2f3ec340e703e799e31771fe41be9effeb3400267fc53a4701fe768df47379075394ea4f8426889b7a008df1039e728bf32bf27eabdf48af5180a8668a98f9266ffa6e2e5399c3c6affe765cbe5d4333b0ec170e46d44fe5a5db8f7fcf39e73f97d7ddcc1f15bd9004415d8fc8a72c3fc8cbf1fed1e7bc7f592ec4776746beed0df8d68ee2fc5f75cef24ff1eafbb3dde8f207bc3ad5d1bfea2cb73f39c7e9e77afafedc29ed07bb6693e057f2843f7f1e9ff40f5d95ef73f38dfca73c5d49f302e3af78fe7a24d1f801dbd8344cff13675ffd9c3f4434affaf67a5fdf7cc4219bf8c1b6c1e89fe7efe6b94a6538e8ee3be81eb87a17d7b679c4e7b08e7ffacebe9fdadff7ef287ebd53e55bfb6b5deb9fb63fe3579e25ffb98f8a69d0cff5ebb2e43ece35fbc6479d0cffe7df03037611ac1cb2fbe0918ceaf817f8a3aec00d629faf3344a2833fe907fedce7bfee3d3525037bae50fdfcfd693fb74763111d06030e7b7cf9b0fea30fc7e93fefc37ffabec89fda1ef14cab58b48e9cb5d36482a07fccd5e0a334fab7be73eee732639e9a07c0de71591ff5f48fb8c755f9bfee1d9bef7e1bfd294fdfbf2bc5f831668af9bf4e8f7f3f96dc47c042eec3a1cfd7afef5f212869e4d2fe52fdf3a7fafc7bf468eefb13888e9ce766bf30eec73a372a7f3d2ffb2399d961fd2b67fafc815ebfdbc3a8fc102f98a4faa76ded4f318ce79398b82c1e4170adf6d33cc815abbf23677fd1f4e96fb1eccff32002e7adbbfb766911c4adfdc176e6cb2fd58b2fdb79977ff99d0ddd7f2537fd7e6dc6f8411fdca9ff753ffb87d70c7f2a2711872ebd281cee25a40766463fc8e92cd1bf2ea79fcd67fd1a6f0cf99677cd04851164c613c4fdf95ee7fe9ffff3e9b74f5dd027cdf8e9f7fffbe95ea69f7efff4e9b74f4a5027c7a7fffddfdf3e954d30e673f2d73899cf65f397ae9ad2bcf9cb636aa2dfcf635277553026c3f939057d390de7a86aa7389993661cce7fade7e6bcf441d725fdb90ee6a4f9cbfbd55fbbbeed927ecc93e1a09b378ff6f83f4ec620af5e5f356f1cfc61abdf3e0df99e7cfa1d02b1df3ed56d9c7cfa1d8180d7c7ff19f3575b0880c0bf80d05f00cc04f1df61e47704f92b06a117084410ec2f00fa3b007cfaed533efc4f9cf79f7e7f04d590fcf669d85ee46fc9fce9f70b8282e86f9ff8a6fdf43b845e4108bba2bf7d52aabc293ffd0efef6497e91856110c37efb64e5f1a7df4100007ffbc47ef9e8fecfff74410c7cfa1df8ed931e1f9d02bf7d32be704e56e5db381000bf1c976d540e9f7ec77efb448c797d706224d1a7dfc1238f060110817ffba40cc737288600088022d0fffef649fec9ad00867cdcfa79ccfffbdb27ead76f75ffe77fa6661a92f8d3efff0ff01bf01bf0fffeef610e59d2bf0474c8ecd3396bebe45c244d9937c37969fb72e882283947f9f9dd6cfed2e4693656db5fa2fc2fdf5acfe73b86a089c376fdceb8ce711b1d6ae6ebaeedc77b3066df98e6fb5f6f6df4f6b519f46932be7dd6dbf6fd931c8c51f6e9f766aaaadf3e196350259f15fdbad29360689bb77bd996c9abc31edfee7ea3fbf9f296749f3f9bc9307e77f7f1d5772de4369e0e7afff7d33bf37fec482f4ef3e6d3ef633f25bffdfb65fb1aaddcc6ff660da6ed5feb367e11b3937ec85f9206ff0a5e5eb8d2bda4f2013a7f2a9c779dff4be0e67f7ffb140763f0e9f74ffe77d3a4b62b0c772703628edcd51c3b4aca25dcd0f770817e40f4f4164ede42aa9ce33f0fb59fc30df8de1edba5c29be42f503f7e2cf9c91b0249853c7a7535494dd74544f73934fd833c75e186ffc9d222b6488535299f9722c12fa1d02426c54020a9eeb2286dffade141a7899b4cffb58eff3c047cb9ed03f341fcf29f017d1c86300cbafceb30ff8df3ff82fe7f41ffbfa0ffaf01fd2fe8f005d8f98d6463072ddef60f93cb475e4fa59deb3b6b114260c573facc73d51cbb7c1ad636cc330ce8b9421fbb72ea37f6e4c1affa238d38610e6abb88295aa42abd0d5c398d20668cd8b5e239720ba1aef2602df58edc9b65bab09153cf20f7c0419b90b5beeeebc2b364fd99af469ef42f7f9bbebaaf151d62a01abdf58dafeecfc967ec2a00cf0955ccd9db412770f59d6799cd87edd17750404a5b91dfe4d464f1c27396d477b3ca83df821b55825900596904db9b6f9040c03200cf92a2e7fa197fa3579e51680322d2637c8183ee31cb0c216b97479f368ba5d16b5f81961eb5f25163f0ecdb5a63c89569d4d813cf1293048150d84469e4da59548f60b477a5effaa9947656c05a878cde6a3c8a3cfadf624e4e034e07228adc7d57807c974f8f7a98671930668fe0a4771f346288018e001b6d641dc27cea415916d6f1713dfb39b987b0bd79d08b46e91b8868385e1a413818d54ac5b3caecbfe87f6e03045f5df35cdc85ec927ab5f5d277c4328de7ea954f9140b8915beca0d3a14f9e53aaa8f1ab284752c3d552cf59f770238f7a6c8a36b2f41d01f4a1b80beb288d587c8b2932554c62511c428c202cf5593b8f9db8798d1362269e152a9e6580f815c4ed9267ab9a67d1ca770edac8616f33cf09609893807fe8fe4f641eb3f61eb3c444a56dc16fe49bbc591f0c6b25e5694536b456345cad893672f39d57dd5885f5e731eefe311edab7cd527958a5cd19b662595595f2ac3dc575b58510fab2319ef3b3a8ae32af5e2b29ed528f25f780b5879022770f16ba88d344fea0e19283e72815cf21b3540b5904659bb791796290e8a12b9e535adf59079e130a9ef5bb90b5be6dc7eab3078d5594a34732f30ca16cf259fca5ab984dd3c4c1c1283fc6127711ac6f89d6550947ce878dea95ad6a206ee8562c58a06e3826588690d2fb2e3f050e360735de86b53efb5a57795036f394f0f7b735f8f45e20e923c726af66f6e0180771c88310a95c3e7440c54e35f86c35f9cbe14359176d64f131e7c3b30218386b196de45d03ca3470c0cc87acd4aff18de7bef77d44a46a32f53ecb4c29a2ba5a62a27bddf3d1174fbd26477efcd9c8fcc50b453e3d97175f58f3f93b62949cb7f6fe0b0b192070fd8aa7e4d46bec2e64b52fdfb14217d6cc21ebafc7697cf807f5f2f36a3ffced7dfde565a71ffef635ae862f8c5a87c420bb3027b3579b46cf0207ada2b4035fe722beb7fb908d070bd5bb5f665e8d43879f7b2c994650561dfe1b41ca16b82440d587ddcb2fda2fb9112f5c2c785aaf22769d13e7e73a8936120e0ef97ec8937d615579d864089769cc6615ffe6532f4ce5d96a8a592cf5a0158c60fdc085bfa1a777fa0651f02c331c987014203e145751f359deaf31bdfbf1d771ac0b1bfff0ff373c4f3b3adcc82984b597cdf8900dbcc534a53a70c7b605d9a348c87385ce7384e1c0fcf05d9e518d83316ba521e47df8d1b7b65655736c90cd8109af3173c21cbbfaa17f9467fd3964d7397ed3cf67d9fd1116bcdb5a17d6fefc8d2e58c5b6cae58fe475fc0d7fc5865b3b4bd01bee052cbec7b716916fe9222d5d11bbc2c05320c453faf518efc320232a2752c94a53be7cd9531536da6873d5e29bdd51fc0c81a3646fe3c49f11844f7cfe4d9b4ab2aa522de89c671691a788d1a0885c83acd17a8f256aad0c216c97926343af98ebd888e7804bc85a3fb479a75bfaae3705107ad0857c03ad12f63d7ff89eb6ad2cbea340be2bec878ed5829e648a4f5da24d790a2c794ab8ba9430faaeb27b4e5cb9147fe1992517a80c0e583c0b9db273290177293effd6ee33cb66c8ced7da9ffb4b651be60d6c634e5f8e22f3dd37db105600b54817f546cc547d14a1442ab95e2a70a36d952bfe365ef2164228f09285ada3116b5d3c975cc2b7bd7587afcf41a31cf6fb1aeb2117c3d12eb2f1e5fa1764fb2603fa90d11b0d9fb521a91e27efb59e6a4dbe9b65a14b1e76fea55f98ac3cd8afa24679e55fb2812cef3c7f96e1ddd0da18ca66cf013bf11dd7fe9d456f1d34f92319c6bf6e415dfdadb9cfaf6ffd5cfc5ee0ff60ed7bfd17d6be07e3ff2d7dff5bfafeb7f4fdd794bedfe2c397f2f72d8dd08f94e27240a1ffb1edf8d6be4ab3c478a5d479081fb08cd79ec3ec92d341a101bea584acbda98db748453a2907ecb21d149aff68dbf7b0f767edddcfa5f7f8916a7e95925ee28298540a01a8f4dfbb5c55cfcdf23710f9b8e3331003c005ff0cc538fc0b507c39c006fe07a118fb19144317f01f81e237d6ff008c21e45f8bc6efa3fe1534fe72eb7fd1f8bf68fcff2f343eb0e1eb39487a7e2de8c04a4be5722a19c0f86fffd1da82a7d7ce83ec2982ecf2ad1e7ccd2590ef0b45a905e175ccc559545ba95ee36058ebeff510d16ab6c28a06797c5745393987f56b4e668e72720c61a17aafd1b7c011c098c5379efda065a59e136fbef3360f196d48ca334af536cf68a566895b86a5305fcdf39481fb3ac72d8fdfea793870f5f6e03570e53486f02df898e773f43278d5116816526f756454836f3c1f353227543ec46caf7996a31e854934aaab26e0b43484e3e9554bb1d522e5446a1fb52ccd987afeaa03abb051dee702abfd2bde8e3a190d612b8d1df4352712bfb57b5fd023e58fb612453a1fb51a7fe3279922dae3de43df7cf95936b9680eaf3a9b67c12c31de6af6d855aa8ff1fa7575d42dd5db9e6c2d0d1ce435571a1df275d0c23ff4fa3eeff5c6cbe7be279e22fd83d7d061509ec5f3d71cf4fb7c4ac495af1affbb36a9e76a22bfb4c56b6e887dd5751769c3e1188ea6cf0b99f56b5fca5772c2e5438766a53092c94f32d116c7386d071d8e5aead043e4da5d54dbe5db3c01b3bcf88798fca8df429681f997cd304d54db1ff38e07af70545740e0a08d441ce35466bfd15f7b2779567fcdedbdd9db61cff6742418ef36fd590ffc4b7fdfddcbe213cf32d39b2e1893a72b93cf494ab315c1da96d4062acba071dba64857b30543b350cbb06c93a77183a795bb59ea824d5777b3925313f052cd42fda32f03a8549d5a52dfa980e0e085b591e8183b2ca787bd06af7ab5aa7cea3b1f60abc277d0dd37deecfac34ea2a34685aa3a70e44346930fdb6ff380100ef9aef03eef4c5651fdbeef1542f7f779a92170c02e66dfe683a2439f7f201fe9f013ea3f803f0620fe67b1ee6dc19b6714c073058067ec85a7852c6695f6cb5cd29b9d5ab5bdc64eb5f98e96ea16eabce6b15f09f21ff3fbb21d8a1435db275d20bb9b96954a063984d0c71cd26bed21e3e98e3636b27dad2b1d7698bed1fcd863e839cbd734457e23fe784c14919aa6f030685cd10d627c9ff37f9f6fc4eb0343de16f9e39d67bf3c5fe753dfd27ff563318e6ea10f13242d6b23469e7b9d9739faeeab38482396d9bf8b136feb418caff05cdcfa0ef29a430d5f67e9926fcfbabdf7cd536425d5d1f46acbea95d7d8cd677db0151041f6e0e7cb0be7dee4f836171d4136c0d3206997b6ea02b86633322ed9d9dbdac9468c0e278061dd95314c5c624ec8c24659425800ee8e0eb8b0f25a1388a9f563bd084f8c758f5d65f11db4bcbbe570c48ba8b6f7680710f9462cef3a5434db67cc0a370da0d25c50b8f11490faf59af96f787fc4a3d79ac64bde8efe5ac339b0f36df304ba791b5907ce5abdfcec3fe54b7555f3cc904a6e9bf2b9fee3187232e66fc30b4bc2b415798aecfc9c0c790aac790aaf62569ebfe2ffeb7b5fba907262f65dbdf8d83812d5f2d1471d68dff7c5976ff6884d5ffae353d720ae2fbb7110f14dbfc8c1276f0220237d6c526984823fe8b17e47a5dd5bdf1b79b736728f58bb081cbff336728f5df2a5e7234e0b879fe4e42374ed3d66b0b775b98ff96dd6ee8e31443909448d5dbdc5143f0bb903e7ba227162387010dcaf992182ac2b55eb59d4c45d5880b5e7acbb6f0e62e854930f471ff7881ec4ecbe41e41e674f9e03561e75e038f29adb74acd8352ce4291ae4e7be634e007d83b8aa4b9bf234289865ec8a79997ef4fbfabb395c8fe25b67992d86aae9f8bbfffef9eeea5bec58ef329353fbc805281c8c607e0ed92a7faddb6ef8f3f04517cae6d0b1d2c0f1d2e33a70d6b7b5378a9c5f7268e22e7aad1b31434891b9e728fd4b4e142e078eb079ae804a4097c5353d1b2c3efa5afbb12664fa47bf9c0e449c7cc4ffd23ff4c5e2cbeb19bad71cae351d798804ad9dd70859d4bc36131512cc64c78f6cd2b04ce18fe09527a553c0e96348bcf57ff0eb6cc498e4442ed01d6997cc3ba6f1a96b7e6b875fd91ac253fc1cbbcaf6a259db88efc87350339067e36ff89693b1facad9ece990ef07aef86ef6b21ffe6b5a26907b7f2a573be5bff0501d36f42b7d4ac0177918076f06cebf78fbd2d761e76f7dd4e59b9e6fc395aaeddd73e4effdfaebf892f30c907e3dbe0f39469f7d35aec2469fc30ddc7c67adbcc376be6bf35dccc23df6a5ffd183f0c9afabe6c0afa0112ac97993c16b92a82ec5e3e77bcc912bfce5cfdf61cd61b7afdc3b82f021ae8ffcae9a02f888a5442953e4e8b9e5cb6f3de3c853d0379b7c8f5d022ca7c1872d32a4a1ef402edc889c7aeb370ddff3c3f7bc7c7e5be75ddfd74fc83d71c0579fd1e17f5cdc1eb8fce2d9490f9e35ab8c3ee45886cb9b1e424ec63d76dd790a1c7c8ac88583ee26a4eff27af57777c82ae1c8edc0bb909373fed6a6c2863c2513495d2a9dc46ae9042afe6873d8ec97fb8ff16f7caae644236dc853d888134f1d3ee5cd61630fe1ed079b3ff8c4f95c7f93cffbf7fe8151da77f7d4477c125ed874d0b21881e36b6216d8b50beb217fe7e7cde658fd55b71ddf45d081d547fdc4e31e47c2fe6bcdf6abfcc204539fadb6f0c8098c2f32913664faac0b87e97d83ec628aace3b7f5da357698e1c06ddfd10e8cfc6c2377872c5eb2a581edb33d535ecd7f45db83b44347fb111bfc2357c9f9c33f0afe88052c7660e15bec35f9a34e49bfeaebcd3e73f9a85b379e56501f8ebb303f7271748f8f7a8123b398cddef6c4bcad2bdb6659792f1b3a6a468accdf9e153cea55148dd9ec45eb5573b23878d43d3ed1757e4e941e5c3507567f63f32f1b437ef40bcaabdf75f08d2c12275ebca3aea5803176d02ef94e361ef14d9f3fe080907b6fd8f10dfe80e9c15b74e4fd14314aae3d056efa43fbeffabe9934635a2049da74fa5ddf8aacd98a69d18c65dcbeeffb90679a4a06088675756073a9012b69818aa6d93acfd7c4773a01bbb08e61e9c0d246010f39bffae2e4f4ad9eab269eb155c34e5f6bd6a1c3003c2b54aff56b83ccc2e6a8a95eb96677d4e5216cbff6c5bc3089d2c7a3168ab7af738e57cc980ebebee4ccafbca416defde98bad1fb120fbc13ed58d5c6248eb3c8affa63fa3641ccdfea98ebfc156be26da779bfe46fe5ff7fb135cfd5ed75f8fe9159ff4f7bd5bafb5fb83f717ce292dffc272a678e7f7236ebe787ec549eb88990a18b3afbafb43d7296f1cf709af9816e564c4e7fa8f74ece50df3c0a5754024758d2e128d38e57302e729610ab79fc4eed77e22e61dffd255345eba7bcd717c9daff02cb3f39c02780e5a7aaef0569f33ca1cb2cc76f89f6c121fb1ebd59f79f4b783690c659d07a56954db99ffc2bbf16bfc0d798a4ebd570dce1f72fdd2f61d8b5d2a0bdd9c8c5fd80d11e9dd20f2b0c6be93f9ffc7de9b36b98a2bebc27fe5467fad7dba184c957923ee07830d06db940133ee387182c10598b18cb18d7ffd1b128387720d6bf5ead5e7ee50477b950d894849a9cc54ea4969d4fb2c22dffa8bd1ad6f0bdf09db0cfa51a04f80fe4aa910f867e6ddf6d73d211d45973ec59d3e02fa7d63b3e73e81e583bee874273bda69fca8f1838cc5b93c5e87feeb2d7fef65474c2ca3b533c09fe70e91d8c851b75704ec239315837b3ecc5fae77f32ee8235ddad8e639e8dff672378f80ccd191630c326bd4bfff7acc5db6932acc3ef5d7aefc3050a7660e72c73f1daf34f943ffcbbde3c7def1bb2efdd82b1d32278ada56e993c336fee77b7f0ad661234c1276a5faa736a6b077238601fa12cca33d304f0273e2d44f2ee3021d26b2c1275df5c3a9ef83731de91bfdb387be2029e57302fa899d3f71ed0f7ff23c8c735f3fdbfa2217f279f97cca900e9f6c9c56ae5a5d76db37e1553b6a92a4b0b7734ea6c3ef715e26eebd4d1e5ce96de83f527b9f6562dbb00b17c626a5bd978989452ae55a1d44c278902ee0fcb4f13f846814e81047ca556e4a63e7f6d4822b39393f37704c39587c2c579776e91eefa6d5c6f95ea2eb58936d5084638a7b37c5133793033fe56ac768e2a9406742fe20de6b10b1299c5fb776de5f6af171a2e1f442d6f517190b396d83ef3d98b74cc7b61186beb9a83cfe98aca7faa9cb15f409ba7679e5344f8fa16f50c0f6d6f3f8fc1d62d2a64a0d7c37af899d03bf14b4e5decbe2c023c1bc56c2a02fc6dbb54b60104f6b11fac9ab19d225c52d8c4fa5fac6e7e97add60d29ab84a9bdf284cc5bd4b420c690af77360afdfe11309f04d2ad7b42b612ae1567a555e8be7a34e8ea12430167d89d14ec13cffaabc999d2695cdb58930091d81f914f089676c1cac0f57719027208b0bd08f40b62f6d43273b49e32fb5fd72b00da9b0d3a48b75a7609e6cb6b1169310438fd0816f1ef576cf54702f1d040bb98b9780bf3d1d2d44f211eae7a97ffbbb9f0309914202fe8568142e553017f11ab9e395fd8d8e8a417d7c02fae0fb798a13ee5d9dc4f46db2549bb2cf7a5d04f6767b35e61b9f00f6b5658a7b1f625de11c6e26c73aa3b1d8e065b520053604ba6de512c7d04b9393309e1ce6b874b04c713393af6308d0679beee0bb5fefc70fe0bd7efed1b4cf7e1e0d5a3f4c09eef098b8a9dcac8f1074ed105ced927a658fce73a8f31815e275df5f222d04050dc7022feddd540a7d5eaf2c5301e32174f9039c0bdb607c121698ff42f966d39696a34b8871ad83429896efe26c8b3bf5b30d2977eb5124b221e645a39d578f32931f6402eb05623d1ab6cf157d9c2dc3666c2c321aa6bf2a93445d1a1fca5e204472ee4dfd78a68ac18d8fcacabac49998226ad10d4f9dce5b959dffbf8138c3dffd39e41b61a20f40fb7b048cc7837116427c6acd84bea9ecc11cc33124708d02fddaed81d7acabc098f7fb24b8b408bd8849bd94de7531ed395c4b516acb38cc1a7c3db02d5ce9f234e9d5cc155eb94db80bce0977702edae7a1346b8e1cd6e8a6b0b0d204137829b70d690bf902f3a40e6bad32b1652a215cc3f927dab85ecc2e6250913839cbd5bca6767e7a95abfe415bbe97e9b6cc489ce0c62af15ff55857e5985e013bb954dbd8ee1d1fbd1b0bcddab51c347aeb3297ffddbea6959372751f5f49e3d9658ce5aff2211334eef24a25421c7652d9ad6dbadc6be17d0226f5669942f94e1ef90413d841358f5a9f168ce56b9dddcc7575fb45c76955d199a5ae8b8bbb3151be08bd44afdd31d6d74d8b757985ebea8afd4509a23d9fd7f310d0de3071551521a6d83be5fb3929261edfad1f0c6ed7999bf76c84bd630cf79fed51bb6007f87c63dde1196b79866d1bddea7b308f047e93aad9aba50a6c6733cf14f85db25619c2328eb8bd2a039b1ff6f5e8d605444803d70482d9b4df674ff7d24371d5ce533b74a77a226ccac0023ea651062fa7f2627e2285561b8fb479bab2d54677cb31b752747aa2ea9d1dfe5c9ebdcb3d20eaae0f1add2d448aa4c79469e236a7c5e252c3c0dc0a0b9a358b7b72d2fa2ef1ad2c42ffed4960c15c0bd6f57d9bf67b1e823680be0f7d6d3786df1d0bd159cecfb1b777bc9edb7e669922dc6ff236ce768e5df9859b2a7b9f5c409fa86b4f35e56a0dd288973ec1b90d2f7257e626f00dfcc467bf8ae5fe85f66fd71edab9000f7d10e0cf107aab0b7adbd25cbb7a67a71f4677d65c5a7da64b9c16534c17537c9d1eded168fd9c41be1b17e93e6d5bc0d80194795608e6daf083f6152ee312efd656dafe84392673b5c93d989bfac93605fa0eef17344ce89112f02fe3a5dab535c368b864ae7071d2c615a0fe11a2d16e55437ff09ddcdc6f472671efc8804582bafe761968f35bae64a0b9f60fca40db163bf7a3768d6ee4c3b0be96035ec2bdf400e3cc1ea1d702dbb59fbe5274f145d670ee25bad7d738f4cdefe8a1e8560eecdb36bbbbdef2ebfad0328e65a347c5d02280ac0c03bf5ddb68d60c1bdc814bfa95cbd3a17d3d5e2e626f7dfc6c0cf7853a615ff960b77b124ffa77b4fed8394ed3e707f22e290472ab77e72c7302f36c18776de3f7807f1dc860e3efa62e29ee2c13cca9f5146203216e836ad6539a38e5657d3ed7eb17314619eef7b4a02d5ea26cb25f7f38afa3f43c8cba1866d32efd5adee87addf57a7d3939c71d9b98c747ebc957b2a08e9af5b1bfd4eedf78df15afbd9f6728bac8ae70898371f829c40edc9903bf2ba79bbb067395817bc339c611f6cfaac170989dce56789a7453887b69edb11d5ef9a1b79f1b9d73f1d9081369ef9a4ce1f2e7f9502befcdbe6687fbfccedec54bc5c28d9a58a955c3d8fea57c4433f9b69c9b3173a7df3ff5b3b0c6cf3aefe37c6fbff4c5a7bab1f92c02ed8c996af25e2fdbf783fefad979c8eda79b97082c76c9c7777442308f0695f0017fd7e3e9f213dcc43961ecbe59ab5081fe970e027b3b563ee707ca7e8b5dd33871a9c6fa586fc61ee8bbaffbfe6ccfbb98f23f3677166a86ebe24cb61962700f5883aefec198c9ecbc4ed2e2f070465d610527e38def0e6346aaf2dcf5011c379a226a9b7c77eddf8b741733fa117bd9cae8677d0ce34a57f84560f7d870e312d4c63295d72ec676818b93b5989e299aa4f5fc76f30fa2205c9502cfa68ee14533f5fcee061b29dcc51578a45f3458d216573055f602779e57dc59c33eef15d1606e66cd9a625be6e6d760093e98e39ccb49473fb596fd2d9b7b35d61b9b7b5e1fbbc012b0d7ebf097b8816fd6e70ab3708367f8a4cf6fd6ff3f96b16fd6f7e33172897fd0a6e2de4f93d856995060c5930fcf1f8079094fb62147c2d40fdbf58eda3695da3174a2c386cbd8516cf671017e5618fa6cb30f0128b7cd8568f22378710f78bdf0c3e01cc54de96aae5fc8e5c5be2f5e3de8c7918ce113133b8aab587f9575710ac7548fc59596abd816957a14cbacf05e476092a470f442d528cec43855c1173336f15559676445175f57134e5fc592a0e8020d37234bbb7c897eb3b2b3ad8d6f6d2d1e3ac660c63678bf1e1f01f8ed72e4c56bcc709713dff8146d1f7e4b177c2316d1e6f147734de97887d843a8133b3c89898139c64e69316df314c7dda952ac0c3af68d63a275fb064d2ed6a75658bcc63e9627b8b601eba53cebb8c8681cc369c9c51a5e860577fa2b1227a3e8772447fee97db5575b4fd525493e3d61cfbf314792fe7539920de71fa448e24f284512a548a214c91f4f9184dae19c26297322b7523f4887f9c51f36665445c3cea95886dc8465aed3fb562e61633e0121a44d28ae4db112d890d130abe8d3ac78bab2e562a4c5bad4a421e00db494a0ab6e5f51971402f79cfa15daa498d8cd112ca779340a34424fda65c89715ae8832a635e9807db9b729707d1a60718654c0e5f5d0e69502a625a55c2900f7b8754f9beddf9aba7ba99e59a6d886f8a5bd374d6ac7f0739f65c07437f1322977cc5125b0cd1662b22ef1e7344ffd7495b2d8f1d86da5774e1d6ddc9a7689e722f5b014b87e3b9660110d0e021b02da592b07d1394d4e285eda34cc26b511c278708fd0babac3657581d70716a11f7c162eb16e5c02a6df856e2a255d9d1bc8c86d1ade201038c83384aabb848859465209fc04f4df61adc2d4aedbd4bdd01f3575eeca8653f76e9b22d227fdfa764fd673dbcdb1a32863fa8b86693b50f7b68cb6ee8ceea6479846e85da4aa59591cf4dbe934db389596e9054d6a2c4cb96dd2b7f8a412a67e0d536553afecfbfb22ddf772bf5b28fb57e9ade7f450d8bf37b4a0bf2c63d0f793ac2f02555f440274a793d59c654c55578415ae6b02e7335a2232ab4411157d11ac70219031fa4599249aaad12f5acd2c9588615649dcd57dae6ad464ce32097073014f10a69a42d8d01e2e9f9b4ce9187a7c33662e5240e118b890a5abf4a2d232a8cc37b8cc5699cc25edc46b4395c01d758de404e103d9a2dd7ef058b8468235db1751a75e8eeeb7573fb67e53dae3ec1fd1992da4416bb781d4cd5120a75c1322eeb691ba9667d53639dc31c5c466196e955810bee69d3afe7f26adf27aec7d945ed9967f9e0eb358b3dd9cd96e3dd7a7f50d6a988a72b1dda5c037e95610e6d4bde71c06d1642c7c55344958c1744ab8d51ae6d6a3cc2506599b9e5675dbadc1d09f21e56eb374d3eb13ab6db77e3bcce999e776fac2caba3256395a96757d05d340efbd6bea878ed96cff06f49643e814b0152eb14b2e4212899b429d70fb8ea5c6292bd0361ecfd59681273eafd75ecd1c2c7884dfa56d6cc2837a0c746998b8d14598a385c75cea4381d72abb1ec0e79b2d2fbd5e7e1c5339d9c6319d37babc1fabb6290737e19e9dd1a595b2b8e5657ae5a40ae98d0bcc4bb9ca23e1768db43d555e3d82de38848ecdbbed393738359f4ab847428817bd568fc036d6b6299d96abe0b0188f6edbe217a485b6b6f077a586b6ed2da77a06b70b308ea5d0d4a98597b52103d61f894d9afd06a68af5d34791d127926062fa589d0ca1ce1709ba120fc5a809cf317b3bb5aefac7e713cc6db70dbcd8ca95740c2a76496fd6dd17577dfb266edac0552fc641b486e529582b3f77f901b2d3f1e318562044faedd8e0642c5c8aaa102c575820a474259c438bc9fd31abcdce7651c7045687fa416cc23270fb023fe54ab8cd294fa702dba4b236e92742d284bc60589316582112d810b68b1037e13351037ff589162786a26a0dbd0ec3578910c5fdbb3b783e0c154de19237dca309f49b7dde3af16269adf1b95c824a202fd0171a45a2d68512a4b9aa33af5abc488468442fd5512444c0cec1ed20b78ec9a816ced4679fb2819ab536f300d3745a1d3e67993df09d3a3fd3e5f5cc32244a60a9c802bac6a05adf11f6fd15ed3c9576367bd637a0df6c332c3c5206fdd7b4b57eecd3824d92a96d15961b09bc04a1935fd135f5d7078e2961e73ed1bd7e3ce234a84f6511782c009907e3e22bba207ff2885de171e2469b8a091b1423201fcd368887199b41ddcb6989b8d4127abcc2146eb91af5fda9f360fcc054160ca69d654a02d3232eb7df84db4a8b7b57650e2e299d9cc64680ef58bf55c174510a533f8132a132a19bd2cd161340f7b75bffb2311c3bd056baa3de17a0972b8c16384993755113389b594d9289ac2be20a1b80f1412fe5a2b0a3262d4788f44bdbfb5e6626f4568da11d9cb129840755eddf4031c5da2585a7ab140bb5df861442f2803e6ab7154ddccc2ebc94ae5c43af7c76102c23abeecad2f8367db5b56d70a9f032547db1d570e3df36db75bf83c5f343a08fa14d85f60a42f3dbad7d6fb74f68cb6897240b3793302023dd51ad97cfce83a2690f601753ba6683fc6945ec664d1a75d1a47f023f198ec5cbf6d03d2b4d2ab35902a86c334cfab6e593ca31e5efb62b98e7b4ba7708fc6fe0ab1096712cec6b58fc15dfd7658c6828ff17ed0a75e6ffd3fdd0eab13106e41ef87e93fb329fcf5ed2b6bd3bdd0b219aed36b8fdd6ee0dc41dfa98d12170542a9947ddd22d988749984b8a14d0c310f270b1d57bbb25f01eeeb7178da2665959a8ceef037ee519026291a00e602c3473f746975ea73074e3b41d4f151b1457fed1bda58cde1660fdb5848d135e98504bfdca56bc0f3b8baa402f552112787f0f7d36838a151eccfb244c4eb993adc12d4566cdd61dbaa56852032b57f5b1c26acd75ce6ff938df17e5fc09426227106e3e714c61a66a56a0e8a1a8e1500f99cdfb45af4d3f68fbb9a36fa150a36263b3a36a1e14a2128d225187ef4a840d460b11e4a1e7ddeaf88da9bd3fb161fa41abbfcd4b9e6d82ee53322eebf892be7bf7d76ddff2c3a6520cc69aa2879c8cd30d8f67d9adec89027cec8d7fd11eeca680b2a7f049bd4a69ac8535cfaeb649b9bb3cab73c6441f37cbb0daac4941bdba16017df5515f827e58c5b406fa53d5250df0fd491d13132ee1539e93d9bb79da1e715d0b41db8ec0e6abb6c1c5f2e5765d9396ee90cfe40b1b264cda39927601ddcf1681625050c728bc5e5a6692d8137de0f15c733f28608adb1cb30221d34fb601c6d4ee28f04ae2f2c9ce3b6191c06a09d425d128bff017ef2c05e98dbc25c7373fc5aa7e5b04b845c7b0dda2a630563ab0f514af6afeeb65db68dc8216b44fef87901719f8d254dcfa11811835ba5c4d6ca95fbec1e94b3e65ed84259fde073eeca6f8b2bd354cd7cebe75630f805c2ed51b5ba01f23c7a0bc06ae41256b5e8bbaf1a2c59cac4d74153caf6db0cf75887e80cb6be61912e87d08f57d57fe91d1356aac4e747569d0b57d19436be1e21765dc3d72bfd391ca843657f171296bcaabae8b8b7f14821e14fc0aef6456d93b845e7927ec381f437fbf740cfcb45c35722bab8cb8fabedcf64ba926ff253cbc1026ca526083360d33e1c15817b54904deddf3dec2351bb951963a462d56183731715d5d8db144d484d9ac8f3d31dc7aaa246e1bc76d7c9363e9925e60993ae612707bbe6e7bff33c4917f9722732b1b9d8f2cb569071bb89d60ca95675f1bc67e9b141f72d1432a1b3bdc6e3fd5cb6003d9efedfcb45f5e3f78299d3b8658f82cb371787de3347353304f06e321f432b85d0f66a983ab798ca89f97bcd598534575945f40d7c118b9816f75f345b18170451dfd255cab5d676047c9c5b2ef4c0636a5a12d58a09b8ce3c9be7a5fefcfb7d01b91d326b4aec5870b9ffefa7d1ff46fcff7394544fbc5a918a3e217b4d3d825f5d2e60799cf36b65b60f56b3d15691fa7d55c41805bbffb0ccd837204e56f9507a276d3466c97de12cfda7a1c5cd287eb25f0e80216ef8f731558215dd7e29a0d6211a6631ae2c6e513e8232f55a6b24d6fe712224c05133889f248257155eac536e54a27f448268e0590fb97ae0c187f087630ad940ddd663d88cacc55fea49ad28b6f1ccb152972aec9606b35c8fab63dc3be13b18e837913aff9f6f3179070f07c315399672119cc58398ec4a99f58a9543a705e478dbd548f01cf8ec1955e3da2059e4afc1adf5b69937adb1d5f3a8fa9c467415d15e8ffcaa498d8bc5ef97c12baec47bc1f02b1d6dfc1bf45d52bfa36cab0c80c729155457795ead83c81b1c0c22274d92592ca9fe0a19b72996d8afecba658d986847b6982ad75a606fe9945d0a530c6020383fcddbd0f8f73d0b1a7974429bdd3a47ea947b14fe891d5f6d7fc0232aac02d3d417ddec951366747d97b3de2155ddbbeaa17293dc02fbb8101f731af0c4281a35eb75fc27e2776e1a6c9a93956e8663cbc1f33bd6ccfba18d104a620ec9b2d8e7a5ddfcfa3fe16b853bf5ef7d7214fd7db0cbe832ed1a29acfd8b3ad6de321baa5a85a207eeedb2502ab5fc5d045f51c6f54263aab836720ac500be64603fb6e216eeff4fb4f40883ef5d385e8ea1d67e85004ea750b1dd202d00ec0be29baa8ae7071a1807ab1a3633f176ce212b3b39f2f43ff136eb7d0f95ccdb3af32464f941576ece61d6c0ce7054dac8a1da56d7ce13a8ea6ea57bfc5760b8546d75dcc49b09da871b42ad717f1d796c73e76c7d3a76e7df636c6791567630f814b501b5bed64ec98d804b759aba3ca4a390cced51a5fa591b54b5a96dab8c6390efa9d782478f73c15439f85c77e952e9c8f37b1b7ce7ff352e9d503fcb3df8f7336e54a3bfb7be502be2376539c1c223968a92483e7fb58ca9409bb2d896df51c83067d711b4bd7269cae61cd3a71bf2d23ebefdda889f9de89d5b7eb58bd8ddfbb9110783c07d780baf87af71e7da2ab2b2d79917585836397bd7e0ef8623e3b4aaee44e85b14a98963ec78440d474558b6915c8ba32d192bf1b1e57e4e99fc7af0e74e9883a70dc80bc00c77deb2c97bf028e23b15f77964bc33902c721701c02c7fd22705ca71cced8b8e5981eb8c621f053bd8631b00d16c123ac36c3077673ecb79310a6e1c95915278b0813d7e0163d8e628345e723d43a1fa38765c373abb5092dcd4f72b5600787662bf8e69ce90f6224038f90fbf99ec40e0ef3cda85a4fa5588898816b1c2beff483ef6ce7646b1e2fdd6cf1b49e4a4517b3017cf8a44fce33efd4bc7f582fc6a3e31c0fa515278179fbce52f176ed00d868e101cccd963cbeb779bdd4fb761b6080cfc5f8b0770d3ab68d63bf6dff12bc7f7cccbc94c6bd49122fd326fe641178b264e9f3f5862ef432a5b0536ee343daf351804b96bebed7d0f747b92de1516e83c35c975e649d59a9135a5bb23471c307e8d3836d8a9863e8a765db364bbe4ba9d3ebb9c994bee1176e445d94bda85ed8c171c9d29b36cd2ff122fce04e2136a03acb4f9b36363e76b0f60b7aea609962e81a3a06ca5d36738be1b90f2f78c8aeb6117f68e7e9c35e66e0d10549096351edd16ea0fe2fb0fd3fa1e9eb7bef9d4ae8a57ee28f07c7f926f880af9ea6ab673f46e669739ed03c93f6be296e6c4d875b61011f6e99e89a126183254b7f8fbee3f3bcb55405cf6527c5e6188394c6fd2983fb932fde9189093c2616fa9ad4de3795836f2a9c9b4a7be87f9efa7a1c7d83ab1d523fddef7fa15a4483d33c06733eae5cb2f4e7f43dfffdb94b95c71f431f6e938a5516943f3bb44879e718f2437f9c6f0db70185e5d82a1eb904369c93df2ba393917359d401ae97a774edaa5433ce58bcb0c754e1d654cfff555d32a6b44c05a61ecf53bf7649fd3037dab1f6497d2ee4bf9e83b6aa29de31a8d01d1ff61ff073a7ad24dc4bf5d431c5e4a33108c7b786e14b9686dbd1da6952dbea87e370382799da259904ea0d73d1ea2e25f1e0fc43af2c32912c830a6da23956e53c3e2e688824f14ee774d0ebe7e387cb18da926fda4c35e40771bafbb25d5f5787bd4d8a7bdf64447b7c95723a3cf7af02eec5eb6fc98142dfd5935db997fa32529ebfea1bc0df3bddd6f2e7c3a337a94323a3f0c8c8ebb6984a1bd0f6cb34d9c13108648190f65774e303b023f06801dba036eb55371eafaff7bafa965e6b634e10ef2dbfefdfcbbe1b1f63db84f3e5c44d25eaa25d86e73e783736aeedd3ddbe39d3cf0d1b77338e9a1bfdb1993bb8e57ba69c3eea9725dcf2e23d5f1fcad9952d4df6f3ac978be19c38cbdf05fdf57bcff43b8fc043973fd66b43db39bc1eba5325ffdfc8a793e99563caf827b23dec640b1ed3fd5ed68673e22e9fc3bbf27733961d6308eccfc967f1d023a19e8abf291bb56d4ad8dce04ef05878431ece090ed8a3d43224eca6fe278ba0c198824791031dd7fcbe3f265a5eafeb7596f7617bd4f1d92ef047dc2692ea4a974d5b3d7b33b67f703c7cda779d2fdbbdffe7f4d31d1d9f01bdd3e73adce8e16e4b51b8eefd70b395c2f03296b97c9f8e3fb4093a74a7ef9eebe4626f1987079bd02bdb14439fd77670cb4fa0cbc173e3bb5b0734658ea9cc36a8c44b39cc56f18d4b28c91cf87824d40f994b70e51d7ee05882f75a9fe9135a30b6f696713cddde5bb274d26e45fcbebdaeee5197cf021bfa4e463e929b1bd9efb636bbe7337f3c0e60f9e77e15a7bbcf7dee8fe400e8804ee62ef5c4fb6b77e61ddd5adc1d9f6473d8dfd8e66bbb78b697f19afcdca7f9ccbe7698091fcad8bbfb505fac4d09b30d5ceee6346bfd8c23bb1ce767d96df072b09f59aa74093f6bfce96eed467868528b8bc825a5d33c3dee6da2bf57ad783a5b195c65197ee26d0eed16141418676543eb176eea556e4f738f876e5e01f18fa07faf5280419b7473187884c5eab6de877db795add6adc34f13e302077a2bdbedb6043e0ec6ddcd987f2fdf1772d3e9d239d18ebbf31cb2c1a49faee641f0da65d9c02fefce5b5db27471292b4b9edbf87c4258f7c6e3b4f75ba977e39887db825f960b8fadb896e7c3bec7284ce3ab3101c69b63daef646ac95fd4f12c63ed78a3deeb93fb3aa0abdbd5d8ee6c809d72853b95423bd5be670f7eed98fa8e6d784f73a78c4b9d7c6f9cddda0ac7a030dbf0ebb6af779d8ff289bdb87a1ed4c7316cea531bd1c8fae73c8d8f9f8d8577edfe23e3ec3deffd71fc850bf3c228b8fd03b4eb3d2e946ace3466a90bac6d42cfebbb34299c534e80fcebf4dc84db61413dd49f699c263ba077e619dcaee00bfefe795d78d9d6373a2f5e13977a5207f3baebad123ee9b739d9621ef4b31ed1fbadcdf57763f99bbaf24abf7ce543cd89cf7db07b7ec5d5f5cb6780debaf6673f8ce5b5f72ee7dea145ec429bd0aa76cedacdcd6e622bdcc621a09c626b93496e6cc4bb38427f9d80c79a3673cf26f6d4db86cb58d432c8ffd6f5b172eb7dbe360608ba753112eb56c5087cf03c180ef001fe1716c79a65898fd6c6c80146e134fedc2f8e0dbac531fc69f8fcfc138b6380fd0f96c6b00f56c670a25bc37a1a901481534fffa90b63b76b62df593901bf76519e7db162f6f772dd2ec6fdfb8f3ffff8ef7e35ae11adebc5b812fcfa3ffeba5867fe3af3eaffefff04d12eacdc3fbd3c7d0cf2ff0aa21df8e34649523feea9cbb5bb7fffe125d13adbfd19e47ffceb0f2fcf5ea3a0f9fe0a08ea72b74edbdf6d935cfffa9f75b62f6f2e258ebb4e6e2fa651b075c0b7db1b7971efea3e4faa74dd5e2de260ed375fb7eb222fa35dbe8dba9bfd95baf95de6dbddda2fd76d953a2571fd0b3efbdf178b96ff0675dfad8fbb3ffef5c77abbcdb725e026053f2fdad2cbb7ebbc046d59aed3fd7afbd8fcb926badbe09fde7f4cd7e96bf91115f8f37119cdddc772976f9d600d4acab7f53571ea6c6317ea49d090db4f6f827fa32c00e5dcd0453b2f5c2749085e0ac41e28ba7ffd11e4451cfc19658fb593267fee09a00473f8cf639457bb28f9e35f7fc4c3f2cf287f748a2875bc30cad6db1abc065c78dcaecbbcda7aeb3f3e53f58fa020d03ed97af7586d419979f947b322fa08e4142e8d025108d6c7027ca932a8b7fb6f8ffedaad82563ac09fdd36ca02504659c3b106c9ffbb5bb6fef71f6ef50aebe1d6bb750947465a6cd765f9e89ea282b8bcf00ae4e9f242708a8acbdfa724729bb1b57340e51f93a8dcb5171a81f3b675b1cbfb2f8f4ef3cae687171521ecb4f6b77f79d32f9df38fb577fdd327280aa7df5d788cb2dd7a9b39c9e3da3f385bbfbc254b92a8d845def94a983a17bffac7b74ee6b75d7c7babacdc5db23edf487deafc033c77f1cb1b5cfcb8ac40193af8d52f827abafa4de1c4c5ef9b57ee928b763a52187dfdebb188a32318ec9997fb51165c7c7d74ca0cbffced3ae5fa69707525ca1c38ccfa2b41ee5efe0cd797853f6e4a684bfadf051c5e1f2b9ae536dfe5d9c2891230dc5ab6dd68e755dbfdbafc0eedd689b222cf936fd0ae9de337a8fabe0543a2edf6af9ec93df73b54c53a2b82e2fb9460803cc6ebfab0757ee8a96d9a6f7f807eedf9e18f902781933adf6a96ee89aeffbffb40df074e12e4db6817a63ff3f0daf37eeab1f348f9eeb385e3c5ebef8876f74049c43f6171d769b42d9c32f21e83dc2f1f7b4d5b7e4a06d4f037281e9dedd6a95b9dfd31ed6ebbbe1d98f7285acd11ae6f25f786b8b378776cbef71a7c78e3b1f49c2cfbc8230104bb3c5e679fdcae8bdb6afc843f13ae9362bd7df4c22df093bf495de449fd1a25c95ff3967aaabcfc06d17b3df6837e57e3317f4174b698eb7d5436d38a6fd137bece67a44552a5eebb41f921d9a3e778e1fadbc47972ab303f26067e189c427f973edfa6ceee7b0d78fb901fbdbefee02341b48b822cdffe287f917f0435fbd1a7327f7dfcc1677277f3136f022af6671e8b7749947dfba9dcddacbd0f47f22d750154bc972790b9e2e79e7af49cc271a324dad53f594019f96bb77135bff5f876bd7fafe53f260733ae8fa77eb7d4bbad93954533f9f8b1071e9b09fa8f3ff72352717e2a887ee255e16ef7ed6e3e3fd5ab392f4fd32f95e29d02caf5f693d9f727cf95e1f7a6d3df9c749f43253ffcc0a39fefbe6ef2cf66f7ef88a1eb709ea17c4dfa0d6dda10f633faaf49d3f5364ed6bb6df4551bde927fbf31df3df91da57be7a156085fb74efac3cc66b9ff5e00ddeaf5d549f2c770fddeda0479a3a6dceab5f9724d10a5beb38d72f08ae0e6d6c65d676bc84c1b38788c6e28e2f53ecadc6a1baf8184ffcf3dcbfa43a1a0f7fcdf52f48d973a45f99db8d2b7624febd45dfb3f19a5ba4f57eefcfc96bf0fe259678a72bd0d2270178c0f38485267e785058cca5e511e9dec548336ff2f276855759e3859f067be0d1e8f8fdd943cc90faf51a37aeedcf69c72477d742f74bcd021b08f6e57dbfdba8be27c4e7021efd13af13fa03f878eeedd7d1fe5b94705dc799cc43eaa52f961439465f8f8593b82fbe76004bcf83f851bfbaf9fd0c7597ec8c2bc9df05d128131758ec4bdbb75ae2b5c4eb943516cf3637d7ba3accbc7f571ed39eebb67c0adb3839f95ceeb3a5c3bad1ab925ac3218a4eaa3ac51f6fae71ebbbc7270b6599405e5cde573383674604b833f8f8e9facb76477f5d1db7acd8f1d4c118bd2c6e4c1bfbdf3dffcea39863f5b33d0dcda146b30aeafe2434e7275c92baacb9fafe9ae8dc3f697b2f56eb775601cb8bf969730407279a9c8e1fcf0220479fdc876fd9aacbd5d12edae2e97511624ebd7240ac2abb79675e9394902bb6a9dedefdd6a7ba0bfbe5b97bb24bfaadd4d2776f16f38fdfc9938f80764a09473c8e853aa72bdfb9266ef2491efb48b5cdfa4ec95c63762f54d23a54d641efc7974a3e0fc153208bfb7e1e0b409d8833f8f6995eca2c28122022fbc55f96eed17db28db392e5439198c2b8101d83a9fdd57f84f274bfdc5aeb3da6b60b877e6f76651216f466ef3ad2a6197b6eb0befd71ba0b45dad3cc02f8f659ded6054f5fd4a84d7ac5addac4b74bfcf11be5d9ec218fcbb3b6d93bebb5ed6e5d502879743897eb7d401fe9c8b6fe5bc5b02f9d71f551679cd34befdf658ed5ef1a7ebdf43f81388fd1ffffa63bfcefc7cfbf885e1fa06d585c9f88c1afe015ae6bb745d40ff33e24b13fa095dd8d8994f28de5bc74f88bfa831104d3f2bc1275d9765a39e3f22ec853fa8e0e0fa92aeb35c9f11128f21984d7f4215f999f3c16d60c11ad57fef2ef461cbb5576dd78f6ee447dbeac3d682a470fef69a6fd3cf883a1905057e872e03e5fdf74d8aeabfaf97b7ffa7caa2ddff00c57f77a1fbc3dbe725ef0f49dac5ef0fef7f74bd5d1ebfbeffdf3769b5fffe5e20fd135d0e4a6ebcf64b2260188addb6539867a26e111565f2fee64cde72eb9db3789b6ceabf1357f598c22efbf4581e40d1a3aba8df88ae1a100382a249f217a2aba8bf80aec24982a4f0c17080e055085e85e055085e85e055085e85e055085e85e055085e85e055085e85e055085e85e055085e85e055085e85e055085e85e055085e85e055085e85e055085e85e055085e85e055085e85e055085e85e055085e85e055ff14bcaa813cfd6e8cd5e3c6d93b9f03ad204507b422c8df08b4a2700cc3a967ba075a917f156805d8ff69a015819124853d0fff630f7841402b04b442402b04b442402b04b442402b04b442402b04b442402b04b442402b04b4fafa3904b442402b04b442402b04b442402b04b442402b04b442402b04b442402b04b442402b04b442402b04b442402b04b44240abff1540ab06f7f48fa0ad1e3bd92c3fc75d9dc93af0d5d3e07782af68827ea2864f3df88af8abe02bc0fecf83af9e2992c2b0670c81af10f80a81af10f80a81af10f80a81af10f80a81af10f80a81af10f80a81af10f80a81af10f80a81af10f80a81af10f80a81af10f80a81af10f80a81af10f80a81af10f80a81af10f80a81af10f80a81af10f80a81affe79f0d5050cea1f86613d721d66e4ebcdb0ae493b60d680e8cf1f1c10d85f8064bd3a49f93526ebb9c764e11d268b24f1e1f027305990f30f4059c30f405903b2834f51c30136c0a8c17fec8e588f7eee95b7c8acb33cb6773fc35e9d01528d70b7f8a8b6a3af01529788a786ba5792cdcf06f6d17cbf3205e74b374f201df7bf43c7dde8985ee3fde1f1dcc621b8cc5699d437a88dcf277b375b3cb34151b826b3f73239708c61e5997ae8a53bdcab2940775cab140ffebe1cbea4dbba298739a69dcc539db00d0af36a6aecf2346e4f9adfbfa20c39d30b9757126f53ced88cc1adf4585835b37179eee4d50cdfd72d629ed9200f047614c8131b77b3c90c7c17a6fd3357e52e2734ee4f19dc1f0f023bd32b8b540a9718e43271dcfb86c2f9a95ef9e3a3e8660d8d635007df940b615a36e5c20fb35a9b12661b58e5923a36cf98da3128cce5077947ff72c8839ebe7b27cbec7d5301f783a5ca54b6e9052b52c7bca98ecdf8a4027fe7a912fafc249fa954669b8a649bd2c932fc64c6c6d7654ec5c49feab51b31f7db2da2365eaa873eaf81b222df484a9b0dbbf7f765bdcaf9ec55ceffef1fff809d14b2a2da7dc3485ed0f516f289f89d1672f80b2d24e01c594864219185fc7b2de485d6f896793cf886583ac622b08863e8918b406d5479b06e55a537150b3fe5305b6556fe542cdcd40b5c433f79a0bc55396323681afa72dae7f399ca3c03357b63961a13c386efcb52e3fe9dcd334aee988bea7c7f440b3c9e78a414da84f6dcbe97eecca037d523974f360227615e9a5476cddc9a929bf27b53b2eb682ecdc30ddf844b24b13095127fd2f3906ba4024c6076c1d7adc9c41c3e39cdd3fe3e30811fbf6fc22cfd54afbd34896df9c37a612ede7d0f6edf57dba6827be92010e2c6b4ae6b21985dd6fbf273e68b16015d7de64d60cb40c40f99588fb64d5bbffb64afaa77ee870c9bfd13e6f4a5da7dcf9e5e129e0dead3ef34a8f4af34a84fc8a022838a0ceadf6d502fd5c6cf59d46eb2d36bea29533ba60d2629c11d0bf2fccea2f51329a0ed77ef2d5e7f1f59d5bfdfaab66d3d2d2381bda4b9fc883d2f4bd5037417fd31da0aacef89b5f7a15516492c3bd7a1a0d9e0fffe9e896ab72efd454aed99ac33a3e4d36f4ca97d7ac6710c277e614a2df9b129fd3aa5961cd0e07f68f4fe234d294aa94529b528a516a5d4a2945a94528b526a514a2d4aa94529b528a516a5d4a2945a9452fbf57328a516a5d4a2945a94528b526a514a2d4aa94529b528a516a5d4a2945a94528b526a514a2d4aa94529b528a516a5d4a2945a9452fbbf03fb778636fdf66cdafed58f4e5124910725ffcf629b17ebed2efa0a93f5c1331d408b207f4f6a6d8bcdfa85a9b590738473463867a4ebfe2e5df791c239a39d859a19bb04953a868f7b298739065d09bc5db8bc36136a666b9b71b05419c2328eb82d1747dfe06a87d44ff3d4c6dd8ca3e6a93ef078baf6c7f8192d1d5cd0654c6811bbd026b4ca9f26077b8597b6e1871619ef9c94abd98cc32d53dcfae6a2f2083c74f963bd36b49dc3eba13b55f27926ee5d52de793c8739636cdf5dfff2b9f458f8a95ed9a6749a9b4ce8f301edf209611b54e2918bd9450aefc935b8d29d8a94ade2b96d70a5cf079597eaa1cd2757cf5f5efb1dc85de03e7c6e1b20456709f0e16f84ea3e3f61039a2207bd3920ff2a5417b0ffd350dd013e2407c327eae93fd51a20a82e82ea22a82e82ea22a82e82ea22a82e82ea22a82e82ea22a82e82ea22a82e82ea7efd1c82ea22a82e82ea22a82e82ea22a82e82ea22a82e82ea22a82e82ea22a82e82ea22a82e82ea22a82e82ea22a82e82ea22a8ee3f0e5f8380a6df09d0052f7cfc7a87e1abad8509f23702ad86030ac79e21eef51701ad00fb3f0fb41a92e46088e10304b442402b04b442402b04b442402b04b442402b04b442402b04b442402b04b442402b04b442402b04b442402b04b442402b04b442402b04b442402b04b442402b04b442402b04b442402b04b442402b04b442402b04b4fa4781568fd7271fff4eb4d5f914e6cf715767b20e7cf584fd46f0154d0e48fa9918feba036901fb3f0dbea2289c1c3c93031c81af10f80a81af10f80a81af10f80a81af10f80a81af10f80a81af10f80a81af10f80a81af10f80a81af10f80a81af10f80a81af10f80a81af10f80a81af10f80a81af10f80a81af10f80a81af10f80a81af10f80a81affe79f0d5050cea1f86613d72ed3720967f7ebd21d67bf2fe1842821cfc9613695b7016fdeb4ea46d58ff0b47d252d800a34874242d3a921669bb1fd436e723693d9edb380497d92a733e52365b3cb34151b826b3f73239708c617571842ba03bae556aeba61ce69876324f75c23628ccaba9b1cbd3b83d697ecb995eb8bc92789b72e618f8c125454ce093fdfce238599fd74f3e4bbdf90655f82ca57447d9eae0faf8f63931f14825f44809f7523d9e27f037d3fd7e399c797649319ba761e81a526d9b12368fa5bd97ea92652a1b87d76bef7459365ddb75cfc39b6f3285cfebf53ce50e8e4a81f2132f530a97a04eefdf51e06e9a60e0afc727986d0a956532c53c51128f94afda11f0eef3c9a67d5f6e19f8c64b61fdcf7cd55402dadae594fde5bbbef96ce592ca8b6f1c4b3de54adfd0c0fb475ad77738e469e64df5c8856549a5654a276162e36e2ac1e38861bbb3cc331be481c08e02996b9e01df85a9bd770c39807d76f1cc8c8d83f5a1a1879f098dfb5306f75966ef9bcac137e560a98e7237d549e1fab9021e6ddcfd9e48a54beab162da899b29ac6f24a50dfb41aa6d83c36c3528e6a9883bc6319ef154e2d78ce866e03d41a4f27ae9f2c35088e262a652b1652ae18c8d9fd968d4f3259bd2c93645f82eafa6c2b65f39d8ded3452ec461e2f2c7bda00aa5c07775a032db5424db944e96e12780e797b6aeaf72deb4cb84d1808c35ef620ebe21968eb108fc942e6c96c1c03d25d32b8b843224ba9992d8a418c2b1160585302d677ddbb18c0ae801afbe2926364b65608c01ba792aedc1b36ea6686b934966ac187a53a6740ca92d8b7ef308ba12a2f8a2bccb0f15b98442cd58f1d964c55d572793159e04eed0b7a1c98af42765e4b6c1c5b629e4422a2573238985e810081bb9fef633a674b00d89b04df1048fc086cf4faa052b1497fd75f1a93c9e3e817e9ed71fd3f87cd8b453266196a9e01e26ed6d5ecb179bd16126e7f79e09e669985886927851105984b6730c399ab3cced38ca67eacfd7cd3639dc328e9a5b07d1421d1c808c7e540787d74320f33356dcd82a7e7249bdb6080df0d4eb85192b9e75752414dfad1b3c121ccab67ef40daed4f9612e5c8cbf79dac9fc67658a7b7b1ae7428a271e2985f67bde04db38966e3d89666a37fe189a0d0afa771de37d6bff245860670585d5373ceefb8ff45e378dfd46a79bc47ea1d34d7f9c12817c6ee473239ffb17f9dcf715c85ff2bba11fd1fb9b31056c3e616bc90ed8f0ce5f6663e6c53295c24f75d135b8ccd63ff2f9bae7cffa5fd5e5c03643cc36a8d8ab19bee7abf165818fd7dac0e15e98e803db90709fd702607785a914ba86d6f886d34560653af0d92b816fdfa3323b975092f9df6407e062c7a72abd5d0e693538f6fc53996dcf4053113f9ad986630489614392e815f9e0afa6b6c10afc746edb133e24074f4fcff47714795be7ef28f23329ca6d43b96d28b70de5b6a1dc3694db8672db506e1bca6d43b96d28b70de5b6a1dc3694db8672db506e1bca6d43b96d28b70de5b6a1dc3694db8672db506e1bca6d43b96d28b70de5b6a1dc3694db8672db506e1bca6d43b96d08797617e5f47726af413df1e7396efa29a2eacfcbf86a034422b1e18f21633f02547d818ced1055e4af83c642d67f0f34f6ff45441582c62205f53d0575a93fce8057a166388b3816de544ad8883a7829fd661b12c646d4c6e5b9934732a1cf07b3792625fe5429dcd43fcd0f45e418833d1be41b6192543e4c5049666c441536af876c94578ec9d4f0af8197cd6fffd4d053893f1113cba04e6c4a457343dabba95dd8a45e5ba652b8c4a05af378096939bbf0483d745966e54ff5d83186814cd0b12de7959f491b975000cfa96548984b8a94c7739833ca6742cd2c353c98cd636565e2f05ed295e7caf9db3c93486fd4fc750f90fe0093b5c0b594ae1dc39bcd22aab68d7cc6468b606570846d0c663ecfd536a163f3437170090cf239cf94d0befa2d262eaf871ea1b396216d7d7334f3787a37cfc29dcb527d028a8789a145ec706f54d4b6714c2c534ae61953bb240393da6c73f1b780711fff4cf7d917f60350749683c07f2b20971e0c9ec8e1f9ac09f2af027201ff3f8fc77da6c9c113f6fcf49f6a3d101e17e171111e17e171111e17e171111e17e171111e17e171111e17e171111e17e171bf7e0ee171111e17e171111e17e171111e17e171111e17e171111e17e171111e17e171111e17e171111e17e171111e17e171111ef71f82bba5fbec378072d37df678d83a45d140763e865575441db28a1efe4e64153ec49e9f8783f39eb5c45f4556d11fe3723f42569d71b904416283018ee3085985905508598590550859859055085985905508598590550859859055085985905508598590550859859055085985905508598590550859859055085985905508598590550859859055085985905508598590550859f5fb91553de6e9b722ac1e17ce7e9d19cd8f717ec8921cf83fdf3839fcb3073b44d6801ee0bf679bc4168d85ffba6d121bde3fc063e14f68a344b45122d26f3fa1df3ed538e76d14e7753e13d83c9009fab036c5c226424c180b87c5d8db795331f108bdf2590673782d7049703fa92ce31058a68e393c5d0bf0c3e13e1feebd6c51b1d1e80d7c84c9b1b008bdf2083d16a67a65f37a2d4c95dc5619069e55ce6bc18a4f36b6419d6cf510e8a95e7b44b277a3513ddf8c8219a41d45671aa17839e4c12c622897d402d7e02881a7f63ecbe01e01cf0c2fbc9a491de39808bc3eb008fde0b34ce146ccc625f083cb27a19b4a8930f50b9f0f9a33c67b1e35c8b7c0257b5f65769619072e2162969154023f092cd0362ab3b7a3a61dce3c31a13fca835900f81a05f02c733ec4fce9e8695ed3a44f7a956532a14584c93ca56bbba64bc79012379312afa617aa2671ab44e2e62ba15af4e530ba9b1e138f5c045eaa1f7d23a96d430eac2c0e2c9301f5d8588658da2a535aa617b8a41058865fdb066867650fcf489ffab5632a859b7aa53095f676a690962926b08ebc5278a4523b8688fbfcbbbe5974fc097c727a47cbd395c07395c08a8c5633a2560b811c732b555f944dfbf9a23e0997ba2e073ac6a95accbde89384d36a66a945cc788551135557c41546ad8409cd0b13eec55099b9aa519339cb248ea9e4b62904b6191ebc543f7935b3f722a6704da6740c3d9e37edb3b20dedb6ff023ba5bb3a9c3c5edf38865d5835535a0695f9063c173f73493bf1520ab44be0f17aed1ac909ca5cb6082c838a9bf63916ae9160cd969ed4e9a3f6697819ce1c033fb8a488097c11fae9a472531d9b47f9339b263b8fa76b9f65de2cd30ee769b2bf7f9d2adc9ada383c079e2dbd7af0f672b838b33fe5084ba5709f4fca7972b5cde6331b1407df104bc7580416710c81cc345b7e52a6977207504785a749373dee2d4349bc887966831ccaa937150b3fe530d05e3ecf61a00c3b6dc6b606fb9cca04ce57659d91155d7cd5635dd5b064b98a46b4c00a87f946aba44878661bb9dfcfa2ee2c7f30f695c44e39dc9dca81ae8b8b462e95bd4f50a54b7071db963bcbb41337c2c98ed7795a845ec4a45e4aefe62c53d81153b9f528b3cf75d0bdf49041d99c82b6b00b9b6fe4a27977be6ff8610e5e9a1096a924c254827d6941dd40b55bb28a50069489cecbbabed0397ab2c2fd97d58466148ed6b5f8102cd551e44c15cc9b2ec058ae6d93d9cf533cf453bd9aa7dcc132a4dc56a9bd977a7bb7d966b59e13c97e4e2aa14370b5a3d2efeb570b5d1b81cff683f6dd0aacd095b9f34931f4a64ce2455824b065a0e322a3710ca725b4a1e8e24ad5e817705d88a837cb14a29743d70fc3b7d9b95d020df431cb606eddeaf277e5c32d740fb629628ea19f04de2e5c5e2b85a99f3b86940b3cded8065edabb99123ac620b054267649bf72793ab439bd7661bb3765ac5506730fe7f7fb26d42995472a8965c8814b58cd18e6cfb2e21254f2b37db9d23843d1a8d78bf691b598066daba99abe327186d12741b094bbf2fb4f344f71c28de8733f116d3f9b7e0d74ae6d0a953715f7e09ecf2789570bfd389ad7f95b3b06806e922d53c9419bd9a6987c21e7a4631c4b81077412781fd4dfbfb0fe3359175fb509a7a9ec88ee783c7f84ca35ed6a4ef675bc23739fcbd42ae576f6855decdb681a073e11161611041e11ee7de31837f5d44fc096f9fc3080ba38130b9bd7dec9c179bccb816f8aa5c0dbc00ec0779c791bf4fa667ef8119dc6a82b1cb48f629b18c5ac34fdb2cdfab1dfbf2701722d5ce84d3d0236f8a22f0897486281c7c198c8fbf7f05c6d93926baa71b03e5cc81c2751600cb82ab5f74d19c855e1664ae94641345799493f9ea0cd01ef1031db90a3d9aabcd01d0cdff83962e811fac431c5c42295bd97c5c152652adbf402254d4a5b0d432ff54fc689f16f9e5fad4d09b30dac72491d9b670ce01973f9412e4458a09b1294292be5808f135f94ff24b04230ab99c832a544e1816fd26c613d4ffdc49f709147d0a56f2a49a36f8202bcf752f6e6f530508d6eec7f35ce9864cd27277fba2885a908f58663cad0560bbc94db86b415f82415f8e4422f5127e8b391fac9e7e9ddedbbaffb953958a618ba868e81775fd236edd78edda4e34f947bfda641fd78dbdeefdb85652459b7b955429b5accc9da44574dbc974151d1a5768cc6cf97efefe5680af81cd1c244e19498d3579cf2aa4c6873151f97b2a6bc02fbfa72295f7c92ceda76d5fbbaf67e03d5f04975ed9acf6ee5f342be54833af8a602744c6219586b33cebe85d68ff7e42e3d681bdf38962fefcbc780acbe7f6ff3f999f7f47da0259537d531d07eb6c1edbe6e8beb76bfe051beb6871f96037cb19e07ed4a7e83e27dddbfa8237caef193bee4fdb6ae5763fce2d3c9d0e775a86c42c7ce6d1de71a272e81bcea5cf2ba8a3949d12f65585757ec01eae77bef7d55990ddc9a9e1de5aa46736b5e4abc29dc263fb0efca5c27f7c9c9e7f5dd3ca5719f053e4952f9fcb19ab1c24e98e8aa16d3aac0435f10ea28b186fae89b630cfa569910dde9f329d6da8a63b956998f64e253b9fdf6f8bbe937819dd0024fe12e7f2884e9077df8f3e3a3b288e3de23b4fc43f968ea76c74768ae0bbc14fabc940b6c28aeb0766ecd83b93a93cc3e6cab4b7def572e2926023ba8cefecd8dbcbcf3cbaef9b9baff6d1b9a5476ddcc275ea211f49f3b79bda3ebf7bea980766b6ceb180bdc54278509d4f339b4859a5278a9bef179ba5eab54669b0a6365d2de9dea98adc3e326f2997af8c217bb963dc7b072c1a0717fcae07ef3ae661c02ffc1a0b086b7a098a7fac031250ce894bb6d0ee48ee5aeea006d32c7845eaa576dd9f94ca5760ea1145ef691eeff621c8e3e91fdce9f56419d4530e7df78a91efa4d3fb4bc01ffee6c1f05d683fd02fc1030265afb04da56b64c3171b3a62e333686ed221be2c9258eb8cfebd0d79eb17130ab4791580b7774ed2f9321cc3de58100e666fcfbbebac3d3352f53a5beab532ee6c48d5eb06b97c0810f9a03399db3d732796ffc7eac2fc509984fddd575e7ba033f009b8d4737fc6281457018f0df679c927b294db631a7fbe3fdf3b6e4bc4c04fe7b7cdda677fb2be97c518d54428bd8695eca6d80fcdfa1ed7d58db0c0b9f0d8e373e6edbf70cfd59ccc34fe9c2662f7883fdaaf3406700df6ac649186853bb66702f3d76f3adb2d50b81cd033f33a9da23600a30e703ede5d5cc95cd5bdff868021b9ef92774cc362862c68a921e53a689eb2b45175f640de784280e841516b8995ebaec281523e693e71846c32573858b93ebe7eefa78fddc11cccdbd940a5d03fab3dfe5eb8e3c4bb9658aaea902bf5a3af9045ddbc0ef38cb0718d7899b59b910e3c62af1814e5c69b8bfd462399aa914e662b00cc6cbc4707dbfdf19df5472a01b1d03d825ba8647fc9c634e79a3b7614c1ae88f02c8b24b0af9c7b68a19adcef3d10f7c2860c315300f4a6c16ccf3dbfaddbcc731e84ae05bbd4b4aa44b8ab10c63e57ae5f3c9a695934f78693e5eaa63be2956024f257efdf9fb66605e6d8a9565e0c99cbd6cfb0f7ddbf7b67e8addea80cbb104e7c53ea1471e9160b60a7c49c857afabbaf9cacd18546d838ba1eed044cae7f57117e714a662649dae686b2b857ef4f81c0ba52adbf4fbdfb3a99f589954f8bc56017fca4dc0d8d443576de6991765417db96a6d4aef67f1f6deab7bdeefd2cc7825f148e05bb66d7b5d6eea928d9f2c1361e8a654e2b24131cf94da32a8939deab592897b570d415d4a613c2a85c971efa65eb5d238cbc46d66c5e9dcbd32effb68b04ddedf9b623336c3667fdb314bfd1a52eaecd7d97fb5bffedc385fec14f29ebc5ba1a6b0671cfbad4bd4c4af5ba26e99ff688d1a1ba0456ab4488d16a97f6691fabdc6382f4d6b9372cc30f20868bcd1683412e4d1ed7f22f867a5e99aace2e22ab6f6a30323ab074f686e0b3de137cad26ecb5a69dc8baad99c86cbd54a73f40d36991d362359795d33243b31d559a02beedb691be542501abb905767325dc62b7ec911f4ced067c1d61f2e1f0fe47e1890b6252baf09ef84e3e7d3eca88d924c514ac75970dcd4f2e5240cdc7aa26ed7e4b85e6df2492e3e64e39a5366cf66ea4ef669b421e5dd29529fc9c9e0e8eea3f99c0e2784f9c0bff095b065bd4c16acad341e16a66bc4f5b11477ecf68ddf49b594bec893f561f24c788b6432c8714a9d3dae89e9ceaff4a928260f99f7823f8e094582eda63e4dfd851380a6d88ee46fb5dbf2b6ddda6584bfd217f647653ac6b0f2796e6b9962313f2c405953b67986ed9fe698f9e8206b236845c19dc97bc1398c46a309cee993c94ed528be5ff22192fd3cfb6409ef2fbc53927ff29d24b377d5ebe5b91956ee66e5f3e2f4bcc0b1f1525f3c48b3f930dfcf5f9945e9910bbcde89a7c9a0ac2b653667b7e26ab25bcc83c98c8a1ca358bb45127a0917aa31974d18c03b730817bbc9887b015d3f8e47a311e8bbc5841b8d80c701d80fdf550808c888814ba07fa1afe7e01f9714b339d12dab0ec70d4f41431174a4dfe08999f43cf5d08bae9dff42dff1806f1e4238c216bed2cbe47949ea9b7ccb77f81e2f3ee6fb62894e4ee9bd3f056e2f7758195c015c60b844640a55030178d1f532212698a7ed2d83e7de66363372638b95a283284c7d73248cacca3a58934008779b00e3ad314b14eedc50aac2ace2ede424520c65567a9cea0661a9cbe79079a94f83c7784ecd86ce562f55db3eadb6abfc2d2b74df7f78de3e3c6db1827e7c7cb4b4c3241be6fcc83d3c33c99c089f146f6856ba6b24cf51b174c7b89a9b2e1199f349fe141c2ca54ac712bb3b1824f71ad874747a539f0b032b31eed92caa78ed71f223eb594a116d161373353cd40f8bf56e143c8ec307ec6d1404f5f3626089c54399644b6fff96656a7108e3edb45ea789b13b60149d1f1fb495ec311179da0fc4d942963dc2d0065cf1387727322910a7b139d9e873cb49cc15375bb2e686c5e9f569ff325bb0a795a63021315f1f6d124bc7824bcfb6c52158cc5ea5e19155de1e1c4e64e895ebd9eb4adabdcdf0316379d6789ba7f161bfc33325ddcfe4e755e9aaec692692f2f16d48c85648f3db7ce68774ca68d309bfa847d916cf5467183e937b49210b5d0a97c26ec3ee0b07f385b74df532d9d5c4c9d12b7e576ac79c1d33d8dc64aa3a7ee0ac8525ec85b9b9a8cb176166a60f969507c4804eb1ca4d669cb8f1f7c5105f55252e4d3c9bc944b9e6794e9084a76ce2e5862a64f662f21cee04c134760a5112e169ef8c23c53e868498ee8970f6e8be2907e361f666e00bd54e148eadd6c276b1e42a5e9beda3a3c34ecde96e708818718ea98ab859c40fecbc2a74118f8ba1a1bf0db3b93f1a9615671fe35a91f8f26d22abaf291be5d54011e27c6247f33a1b0df749eaa5d4cc662b2ed1de82ed03b15266d9a2d844e59b5972fa249a25b4317f29b5423f383ea61975f66cf1bc276336e33c10f68c7e48a23c5d2cd2434009475bdf695a3ae3065a3d3d2c07cffa62a81dc215e54c289edccc33990a52d5c8a903bd9a094f14e76d834231d979ee3cecfc713ec8cbd56bb1ab82d5d8a884498511e42cb684a7d92e7e29427232dd3e2583a9f1a889ab0da3f893c8d34fb93c652aedc17159bf18ee63c54c717b2af0237f2d6b54184bee56e794918487b227796545ad28a23e9d1e0b8e58cf578b5a23d241f4e4460fb235779e67db7026a4630bb7733c2c46cf4f3ec5c7e6616a6adec9a00f8f33e5d55a8c71fd7947680cee3f84bb4430f7af86634c06d8f46db9c565c77fcc1efc5d781a112f3147cef3133d49e6a1aee82e3f619e457e3cf1057d3373d6fcac4a9cc4ab9c79e43ac963e85198163d9e26d25352bdbce12fd221de3f4ce3c39c8cf378a03f8c070ffa92619c033fa09e9e23813c2e545ef7b519a11e9fa817dd4ccc83baaccbf1e468ae0c4e5bbbdb13b610b2d36cb1c1f7ba1671a9118946be9185692871d3a292a9a3b825476f47e7b8ceac815b18f27e828fed5a9763e5e9f458d1ac9fbc890fdb8791f81a676e3ab7f791b3935e98679cc016d413b33a4df0e7b9badfa56c6ad66bea80537235b1df886df6a0e8e4e485c4cac84dfcb04e127a347d7895940d4d9d1ea21cc3dec2041f59bc1e724f2b11dfb1d2827c62de9e4bebe5c1c93066b7aa0a51e136d213e9c824f6b879b567fcd499f87130b00926e75ecb347b60027c3f7cce93ecd51b914b7cca607640d2925cef07db44793cbead378fc5f685d9e30afef436783de6c25878d017cb447294bdf234783caca7a5f6b2e267a935d44eb20c04f4054f5e29f6d97ece313ec7389e491e0d09db6c2462f8e86f32319f7885248ee5a08ac2e1b43846e2f3daacb6a4a039fb81ce3d29fbfc10a62f8340590af97198acabddc249b1453551f778940c145edf4fb345b596bdf98c9917c2223fbcbd789b828dcbc1e6291930ab97093eb327859c6d6bab3412f38825ceeb7ab04f7765fc28e8cf2faf4fca3e96de30715c5aa54ed4c2a674d6d3adf37cdc3f333e97e7bc1f07d9ac9e4ed32cdcfb0f723ace71cc7bc077cbe4f1317ddd53cf81b5726b555d30ce635872fa235d9a54c50c037d31a9e318dbc80399521f8f0a6f4ef3a37e1817be5914c951ddecdcfd61ab55cbc1aa349f5e778f231dd8e08d4a2c4fbc1c68a3113f9a7dcf060bdfb2c10aafa796a997fee41cbeb74d215ea8edc9e394be72b5e14a5698876467ad33e15573f2fd8089b7dc2e6597fc960eb199cb1d673227877af4c0b3869f664b73ba76f72a31797dd25eb9d98bb81c8e5e6dbba675411a09c9b1f69ea5d3e9745adabc4b504ff47e7960b4a1b462f8c58b8a25c4eb988c9ec5c7c3c3f2385697b4325c3063673bd8d1cbe028990a39d396fc0bb64c6741ad8c9f83c5e3603ed08e6fc39795460b936795d2ec3cb4cd8249b8617a2a5d4ed5bdfc998c83d1f3723660bc2ac6379e1d6f0c7de22f8217fe2dac7742a5850196bf8c9d432d0681be9064a1c0f3577ae94c5f87735c5ef0b2f3569263d7198cd7c701173fdb58b817127ab9d0671991ce868774f3248e8b559955e124af57cceb6cec3eecaa6288096fe3e96259bee2e34db5d00e847f5c9364f6b8db1ac44ea776db6d3ad8b8e5cbf3868d070faa5c3f3dbfbee46f8ba76935081ff7da84ab6c3d519f5e0cd19a8d9597817078b1a7eb643db6b0cd367e548bbdaea7bbcc7ada5783685a8f2bf751b7b6e134a4c2c056176f7b63b04db792aa26f6ece5d930794529a78b7c11d7afc233ee96cfd2d120de72e241d42d762dbfd0cba08c890deb3c8bfe5b10a96939c3f085cf10068f956646f1537b5b4a9831cce87cbcd7067bd5db4bbeca26d8fcedd58b0ee161a70de6158355d9b3e62812e6ec03929fada831b9590c884161194b6a41857baf009674a54c786362385be6f579fe36d8c8f43076ab711abd4cb86c5d3f3e4ffd98248c744f08e902dba7ec71e00d1ea7538d90f72b8a49144216137eae09851d3d45af87a755e12e1477f3b48cff7fc6de1a0b7a34e9ba1d900c31992966664fcccc1afd5d55b77bfdd55fb7f10e218d932bced68e788cbfe7642eda6d4276ff8a0b6eebff774e66fed79cecdf7f3227d37c12264d113ed07feaa9cebf3e3dc0ffa15ef8927295d2f0dfd87f34f63832be2d718aec511841ceaa1fe968075db7ead082e1750d5abb6ed132d4deaf355a7b4a9f765588c2f79da1fd3e854be6bcb5f4b5478f43e22580b5f41dfba99bdf93be8f225effe51441e1788fefe0f5c1645efd18b26b639dc792c0df62060e53cba86f8cc4586d56e9ecc89b60a76c601780fe409cd24978e484a75cdacbb490dcd008b19c3236d8aaa1c53ac8c98e6363599db767add122e59f509f57ddc8d40dbcb73f47b8e94a0b3025ecfab609dae74ece7466acb85f68ef42457f1b1969f0003cfc848beb7ba732e1137cd1bd857736a8d89868daa46ac4fafbb14d452c59e590f62466b7bd9ce2780590e745f8c2c0e0b9f22205bf44a2b01b5c780ed71ace0daa07f9b9ad522df3a0cc0d85e4692ecb47b20893023f6ac52c83331317e6e6e5ce22c44b8878143de48991631ee85f10e39e3af2f3b2655f824af6de429eda5360f1702ff19a743d1c522a86e962e34cb2c018f46049eac64327203a02415888e3f4a9d9d3472a20a308c360f4b62384783139bf1d340013bf2629990c5175a2e5357419165f7d3b12fc2e476aaab858d9e76e9043243863d55d54b09e540cfe9e302e39dfd80fd97d7598b1ed0bb9fac4a251fbb019c95a0712637c7a41942e0561ec70e79a32e2c40f1e2aac3b3f3232b138407534df4a332ff38d6cc8063d05309f732f9f4327326255a08a57a4e2f1693f7421f5be39012eae765b295a32f1727bd4001d788ebffbf2fb1c155bf77fc5e966feab2ff3ffab2fdfffdd97ffcd0cfea1b042fffe1ce6fc8752f8efcc0c412dc5cc158815516ad564621d6b4e5ce3d8732fb395686fc9eaf0caf1c3289ba901887fa37465f8cea28e1ee8a5682c34ade3b6b56ee2ccb5eb6218042575862bed9ba4ef492e850ec6a0699c244974a671bc0fb33860ebc9b92a11ac50120469d25a409c0404fe9795b220b6333f360f6a888b39eafda37ecbe90ddb4228cee6f54f9c4dae6484cae8d39899bc6b91ef4ff3d251cd132dfd293734bffd67395b61446e32543614fcc63c1feff32975d6c88eeea408adc8a30e20cbcaa219748eb959e81ae0c42db314b354fc1c2f4c7717e92eeeb71730777e39e2449904802502fb4aa6de81294b943f652e2dde131a9666786bcc340d05b6e0db02e5e42934ac31b6b81861fcba1308442668b77362b306d3b06210576fd8d15d5c50b3412812b5d0eebcdaec2943eccd6e683f2a6d9d1967191efe7998d81ab5a30f5f3c28ca07b71d921429596d92d295c315899be644101fbbd3e8d49bebe4a1ebe42eaf7f25f04270921712a9e5d5a4cf4bfe40fd98ac90e41ca64bedc0763fe6abdb4434215879d97bcc3fa265526d112b6b81ff9e49e610b911391bd27ecd597d53f757f9190d4ef7673c9152aa73c727c68ef8e6443c3fd3b076080945ce15b5daf793f714d5e38bc261ce6557f913a83b68b91c64c8b162c687b730cecde75280ea6819bc627be7fa9839e5553c5b653ad30f1c8e3b9990da6537e1a43077500de1aae84238ca25e309cdcaed800e9d3ac8020b3b004c84e26cb0f01129af8fa127f93114e1545d13c9d692832a536f3615e1b5b2b9b85db5921f513b83ccdd750c6a28ff6048ea8f947fc440bc6f8239af1e13d09c45e4e933927b8a15b73468d660f106836b9ec490c0a7cf375838482c0f41d2a0c61f5dac50d651b9e64c6c2a79a0428c13defec4f0dc42105c54062eb73900e923d2ec4e024ac861d1dfb01e738bdb96b0d99555681a89bbe14cdc695310d423d1c4fed28ef4ce2882bd3b9e1b00c6fd65e0c4e90ee1369e9e81b98db5747beff443ecafd909ed6964f74640706f852993c4f826324a1cb8eb5670f98fa7f4b7db1c20cc8d16bfcb5b228cb7c01e3899087490c5f6acef854bf22b5020409a4ba8c7186b27d7314cc3004bf708f158107e05da44a49add181da64d670a33d16b89d38be181cf4c7f0c1cfde64cfb71bd4d208e485ff6d7f2f77012910e67dbfb52051d2e98a756592f601155937f1146f86934a8697fefbd18d5c930f06cfe29639408436fe6ebe07d445e9bd7cd5e0b83a88709a390481c175b34aad16d542fd1d8af1cb17129bcf466af27f3d36d144f89b38c72f91c3fbe042cf2b1575df605caf3da8986b675686a5a293bb76043c373f38750bc97db196c9ea4c3bbe16e02df899f65b918a57c8a06450f28a4065c760706cc9f0ff5cc164541c57962a1cdbda80a89d962a29d072479a78683446d3a2d29d005c2b82b08c1f626a2b9040fb61eb61c19a0130c92df9da157c2ea4f204fe1f526fba4cf334ca05e5fe3bc39a2b734bcb092626ae579b4feba7cded113ef9330fe38a6984b0958e8ec50d319fc31379a7790a1cfb63f1370f2845a2e6f88dfd088443834a188412f499d6bf7787b28a3d772568c5d5eaaddcf5c8653c3acbb2e7627d384a579becaba7caa7ae30f2d49314c16debde64658669908901bf9ddb59e48f55ba134009ac4e36ada7d3f94662e66287e91177b63b92b0a2561a1e7d0a164b1391d5cdecf6aa27de0758bd334f6b412375054b441dd49fbd4c613931db6f0fb78e77d3339fac4585d5d03731ce9ecd183a45d63a9435a3a64c70e332da3dbd3b008bd43c8bab55cb401bf6c03fb2d80cf946bdde9eac4458f6835a92efb5b55f04964ae43e941609ddf69799f05ee8e8936d6c25906b1d5cada8fdba7b6bd534011cdb68470a0fffc360cb48016ef06b35498ee7c2ea272f4d4eb5fd60309d5a57308332bcc6a78555f155431c76f249d61962e6cbaf07195462b0ed114a9970127f084f62df664e6c461dc2d4155c6962896031d4ab4d8f9bc9fdf070adf5d43628eb07373011d72bdeb79618c03ffe84a318bd55fae4fbb53f01e39fa285b40ec6798b69be30494e25181ec0a5d7931bb32c67d83bbd8a388d600dd584481415928f7c3edafe71773552e52624505b951e12d01e8f36d803f18545e6da755e733fd8b193a65d9095a575ab8802ec1524efa075244b8236e0a1ed7af02b9aa326f72f9104d5ba10ba7157af2368ddd951787b8adae049fc0d9421ac9228ed6d1f8e0662fea870d06b2d02520357a9e43071cf92ebc91d8c9c87924b57c0a796a6df0e053484f573b6a3bf23e945cb4e5f81c4707f805790eb2e9963aa194e5b98f696f748f9bfc849b8c03d94702b377b184776e1eb4f9e360e7abc863f4ce14eca4684ce4a346373bc861386e4fab0e7db674f024879ab40a5f5d37ad8f57da0eae14af40043498ebe8e75ad1777c43b10ce7bb24be0aad73dbe07d3962fe7b238fbda4beda2efde2e649ac492eaf1e7ccbcb23ee866f8a388e09cba2fa0ba55dbe657a6cacd6b1f044bc62b0ffe064a5b0d761b624439c2e07a92857b5cf25fd71f356ebf2957344d53c2ee03d2179b5a7627c14a5931b618ae5bafa5c7e4521d82be71e3d607d2d04414f3e42ee44102dc76ea63b9cc719a39e97e34b7d2196b823892a67fa298a5cd29b7440776ff023f0cfe1269634678d1625a9ca69261b82a46773f1417dc70c09444325e5c7d7d40ad5ab246c61f485a0651c8ba5d04015786b02e5ce7ec8998ef9c90b512b08006d60b8ebd1bb260def2441b24bff764545834f6c2a9f39a8e064710f1dda9865e65e58e54f40b12b2ae66ef0fd2029b9273d1f7e1075916ab651fe0bd631be4383f796a0ba34936f783ed85aebf8ca46fc14c30a4e5729e77eff1960b09aca35fcd4ca7b922391fc544c5eb35c1ea6f07fe963675b2e2f4498e27e3cfba99bf30128ed6dd0783c3978eb8f3a3902291e62907c89e77b39cc6c733e9132e9e1f62cc671d243e2604f9ce9f0fcf671a15240dd7130ae49b0ada6cfa07b2c76c41d149d070cea97f93598994cc33ee38315fd996689cd7d2602b26c452c993ae7627412526583e76a38ee09bdf312d99c5dbc4645f8c66c1e6c7cc92f7d4a5b827b1e3ca8a71d28649299caa139ba203a40847ec9ea14f45c5ec20fdf2260c92dc1a3bab754b14298900e3580d24e558aa82f4491bf9f3728447efb4db5b2b374d2680433dffbe56c832603a295b6e6cd2124a9097735ef9959f985c01db91bc419209489ca865c858c4017d188f70c1d73436904248d1f872392cf2aacb49323c737b3611f10c4fc9d22d173408fa34c170f06fc38b0550171b989105a8f5417e70d28489b3c51faa1f9657394de4d2fdc837002c2b51374cd0988830fa4f8ba429af1fe2c30304ff52f055aa3a81c5e4621c789e51b918f6f8fc1fb8c6d9a2622089770f79a5b9064a9a7611c70871fd0f0939bf3b38491bfc619354a195e332427925b9d47a1ab0bab163ae2409eb64b1c6c7eb910835b10c7b9b6675dcef165835dcfa847072e18ca384a791de5af3ae52f01aa5d03b599044e0a0d11544b835dfee3ae6780f5e96de02bd95dc35cc1c1db72f7fb2048cb504a388d0134fcea708c55a322f2b522f618fba1f740ab0ee911f64afd13d371acee3a2342051b014c2ee5ba2ede51eb85f2629dd0bb4336222156c16546064d8c310ccdb3b0e047545fc96b9d0551060fb4eacafed4d19e3fd55cfbdb2b05cb80c4e58a037e8d0c3310840079cfb275bfaa7ebd14ad092fa19c32709ae88e71d2701c7dc882f9e53c6fa08cb8b8e83e65510a6c1a4aac828f603320ba5f129729ad78c169af706c523106ec22f1430fbb3b0320bb1734015fa67a73527ffda2cf413e37c15763a68794480b26e55d9cca4c315b43ed2a17692549aaf8404c56c60286666c2c3f160a57dbe531713a038586ea1ba542e02948e209f1390280afc3892f8ee6470b0fefe855bac664cbc05cfe3a23ed7af3e8f46b1c4c91629b31872a0276fc4e19cb0744d072d97e687dd9bc468025ae97a922c06ac77981d69803e20812b59393549925b92cc98355b333cc81093196f8f58b4ab3db6c055a45da936cd9a154343c79239a2946ae340f0dc4ed808ffebce9b9ac3d1a12241363230b75fa4cf290e21c812d3e62ccfc084620277e3257cd70d60b5208d9797157291b7261af87abf92bfd8d7bf0b98c0d235720bc894ae4e09f0b23d2dd13c161a1e95071ae0986b161045264e55ff45de9504955e4fced1e475722bf7d6349c91545f94eb0b26b09f14a6aa98284cd53ba3619b00b9c9040517671d1361837a95660019bd089d609ba7f5d6e83e8a5945a79a3d77cb92123ba478cf7853ba93d1b034cbbfb4312cc39b3074372d4298db5af59a9dec10f3b462d56141c92e93b3e3eb53d11684ad86ae6208dea66f245313fd16c5bb8c5f06ade521cf82f0f813362d7ca7ff7ef27c6f11f717bb6ff436eff4fd6f82f560f85e66d938ccdb02248887ebf30d8ef97475a979997ab3a2eebf200324f873a15c9106d887353b59cbb21e6284a6780e0488d2060e0e76dc6b389b476d3ccf9f37b875c741e7f1a37de6912657df9c02856ded37a19d21a9a35121717e42360362b7e98676cf80873ec09c02aeb5475522834f0b5dacd8d9d7b22e707654618e2bccd9057d2d494554241b0f8342d7284c7b84b3f9a41d6d45d723165c1718463e08dc23d8a157e49f18be9f329ed7217fe66bab2f3d08ffa3743c2eeff721ffe27d3557f7fc474956c32a0387cf67fb80845280db5640630f8c1cb128cc7b3947a265f9cf6cbf05e0a6a1171edaee21bd1b7fb3068c3c7586a9d4e4d5c0f4993dacb6174cf5a845cd6e4653717c59cbbcc9fed79bb263bb130b36960a586390848e71c69b2955a865ea746a125d2447d637112bcd03a0d92e80503248a7e6802d06093fe8448d36d79a8fbbffe3936a585f75f79be434b6666e7e5c6a33ee98741e801f99ecbced571fe442bb6e203ee884d0d1fa1c15784d44841ea6b351db6cc18c1992c5a6425433aa1af909e111aa157b430d115ddb823ec85e0b91ddafbe4b2ad8983cfbf18673b2bd5348b5d8b5d7b374c6df343e4e79ebf950b6246b369a04d55bbc3548d750bfad624f03c8693f7c312fe9ec97dd954760973008661f94dad21852cc797d462b6ae496267bbd8d27c007dc552ce7c36614e4d17fdd39ddc2e273789a08017dc8c520537000d6354ea66347ca73d9662cd9bd3244943ae0d78fa8cbaa9cebde4db6a7f29faf5a0e63c5b57474e877b8683ba513e738fe5a0d5ab5e0fb09b507aac00fd0b99596542b46ff9e91c934499b06641864f15efed2453e7e79d6379f75cb54b795b7563413eb1c2fd4880dc8802810f8226dd938cb8063a6f84670ebf22a18e4ddd62f778be7d0656cef685410b056ea942dc544db98877ce099839e268ff1cd4b39c9a4f19de5f2127d414bfa83ae48673778173686d8bccdc0a64c46b258040a0e2c480ed749ebdc8177af26e8c5f642d96730cee7e24125aa1cbe309317b356825d5a9c91be8e860036875f9001fe286b8969f1500833595b9109bafb9e2cfbc1bf51478f5b2e0a95e539bb8ecd9f004b4ba315511dee6e31c2803a8abb3669ee6b65d1c460527b38c99ef539122caf0358c7f90a5bb77c6c2423548b2aeb5278fc0e5ad9feda9a1821a7e6255039c365632dedd9f96680185d770369ae58e5a129f63aa5c3703992ec1ccb62d3d0604879b22f35c0d8fe2b9870c48c55a4146a00f09cc234cd9d2d12eb1911879d6044cf955797a90503047c5c5ab00b44f80cc398a6ec6e3f1adf5f16a11d9573e36693c45db3eb2f7ec9d9bbcf7e47d4aa39345648cd9a6a36e73a1c0f4fb8ae6bc47899998cf592999a949aabcc8cdea2aacd76c2c041611429afabd5595c416eed1495e945b5dbe331b14048152e5c5e1240644e451ae27f62a4969f7fc28c84f0f69415f55e236398328fe5e95ccdacea2071e47f93675c763160b72dd596637e334ddf530137a72a6e7255007adc1d24cea8972098990faf26cdf4ca495425b28517e2ad8c19cf905142d3b3b95fdfc52364b199bb8b5250e13247db466521ae8cb5b0ab89db12fc8a21b5933d1fd694b8a1ad52b373b0398f6bd74fdc10dcb7815fb6b73b0b32b59c931f042f88feac1a197a67e450d8759bb302885eea11b7e4c41d1ccba67c5e60be39b51ecbbc47b11099db212eaf980a43b34b1e48c631a62ca0603f59c8fe1898f5e39c49d7e378884da87edd76ea6e85a4601ac33de1462e5b05e388eecf6278ef501fe109287306cc86c98a1a311876e6a2389ede55d2358f7d58160ea29a1a0241e5e2002820afc3111017f661a0f1c706aaa36acc7f0aacc9e196b43ea331e45cd05fe93e72f699591193067e28ee6a613df604615f905343544cc567f2df3bb585ca0dd11ee5aee5b90bba1e1fec218055f217b1041c1410df1795f1e438163116266661714f9cde2e565329dfcf4ee5ba34f6a463e3b12837a2967733d63609487780863df16a07f4c8a780f14f202a4d33d7cc1a4d2d8b7c9458e6d42d2541dbce9f21e61c794a0b577c5386430f9a96b5fccc5693a90aa3432e640aff34cf786098e09b6533583bd335f008450517ca14d94976c2a2515e2cfdc9e5780eb95f185e9c14fee6375ecb071f1349a85a3ad6b54227932ff58e56f6f6ffc3a42c34c8e7d25ea37e7b4d8f3d797edfa5fd5b815b710dcd0533a0a64bb4e513f32a7d67ac0af5fe66ebd0b256d19c8dd28f346d36673bd57fb1b724cfa0be00a261f809bd317436eb0ef27b849b408ca4dc1439a396d034f0f94eaec2f5bcd97e746a93cc4a022ee91c7b4c255d0088a357c35c8a835eec11bcbfdf969e785bea9484bbaf4aaf0361e415f7e678e0dd21c1d5ba01a23e5c2d40a82bd2d646e687923f50144c8b3e6a29518149fb012093cdedf201d3c732cb623106aa6fc70e6b88b6380adc2f7e76ae4567f319bbb4820b12d4a35e4efdb5baf61349030f4a1a8aa6d5ae9861ac14177b22fd572450f8a546e806ee74a076c2e327cc09866a9985c4a7a90008ef22cca58f633a1e59208f3900f123488b1c774fcdec05cfcfe9242f7bb275df4f015fae52c4ea152c5022a4d6a5adf2324ac2f7148096b7df9aa78160cde69206264b92199ccee1441e8dee02aed71f12b4b6752f0fb76cb82d6fdb66c8d97fdb5c7fc49c201fedde208c4d23c23ea8f113c3543971f4e5b929bfad3cc7d42bf356a71d36e22ebab1c786e54fa3e7e149300adee1ac8d0bad1f68d68a182b475857b37bb2df7155ae7936b694c3a4b90aafc22904b6726be4e5c81dd84e8fbba2afe28ac9683ebac05d79be5a11f76489bc3fe2423b641153f7729733805449eb4e2b9c91d4ff7b5d6e14bd7eca54269f380dbd6430179edb78f78742e461a31123df29b572746dd44455c1c2a623e75b521abdaa453c940051de722981ae6db81fa4a026d2ecf90363e4b98b55a8a43f24bc3108c9f39fb03de837f572277bfa56ed478bb92202dc7342457657a5f83020a65a6f1a0054df65bc7effb685e616466417c6157213e159d384f7ffc79536e265d30e03e647c03d16906b47bc70a2dcef6f35ccfa639030f130c41fa90179d907e2990bd2c3db2eb48f2922892dede29f9c619a4699a1f9787e2e4bb0b273a7f430f24502b16b8d240e6f23447db8a31a011615fd35e7ca16f131fc4ef91d5acdabca25fad68edba3a3bf80c923df4dc169f1cbc55d38c70bd686572b5afc4a4fee87bd14f05516939e06910aeb3f5d1f3f8ba9b422e8a5cd5160d7915495645596fc75a2f1842dcb08a791d66a95083db1c192e30999562cd9ab7837819a12d99d5519946341d387e927b0e16a6df2e7bda2028b4a14efe97dd5b526635a4e01fbbfb3285b0cd05b3c52982676738a23aa2e6528aac421e01b066f520e8d23aacdeaf6d9c2ff47e74df5cdc9a5f644f1b88eb9e89c231934227c2cebf574ee7e31d72b8f286905a68e5e682cacb9e534eb7ccbbbc03faa6390ed937b6177cbb88482ef591f5f01f5d62d4c2d0b6b17fcd567ccb630287043f80e46943746148c0c576f1158e5b9024c288b03155c3c4320b777e14da536f45ecd52e09e68839a01180b0ef81572f4713dfcb058ee18d59c22620cb80fb456c3e3ca71a694b17a32759ccfbf586a6080a72c3f0b9c675d0d920e36fee328bdadfb7e8e0c795fdc26f5e55a805b9b68fe5928f1f4564a85218f3f11c887e8c4f9f3b8de6c055879b2a477789ef922090d24ee8303f84309cb8e762ac67e79822fcdcf945b9ff5b98aa89ea4ff5296aaafd7ba45643b506e18908b750c1ab78b33719a92847a65beda1c8fc883dbe1784c4d3af9db60b833fee3aa581aca5cbba0f5c04bdb4fb2dde4bd4adfcab8038fef600afb5c3d54bf50c849f020355f7bbf0ea95f2d21a90f9d7ef91cf89abec01f379d6bc76e26bf903379156e2a276a26ed5175dc6823a8ebd900b4538f08f347d8f70072a834bcd38322772088a1b47c44fdbbd94a3441294a1b35332846c82094aaa64beae1f0595e041c69190a15afe75e95068a50fe3e2ce8733e9252100e1f53ea7320667ddc98a79791b84b138ceb6ca091ac8786e5b07ecf981ea3e174d05855f3aaa26830b498c58eb9df3956fb4d531550f7c0112d0c71ab6db9ab49c426f5410901dc1aee779cbc9e161de293777c8e770e147e50fba3b426c9eee5694d3ca10e370097bc1fb5e59d5c3c0d4913e231f1dc4bfa240cd11c3176645018349249033a727315e94effb1af74c04d6ecb85569ae807ddd88892b8663a8efccf35652781d50e54db7cbd92c15e18fb92a08c273b1a2bf818639d5840b92875bda02ac021891e638f5fe4efc04074f37c64f17563069d56078959466596efd046db80511d83170c525b6391ef3cb1a6d90a99a8bf30749f5be52c99349c10ecd28d1289eef04fbc520853c2bb31bd8e0bc2390b7dd20f777455bd90656d97aa2b50c0c57c996ddc9315d37112518797393b887e6a4996d35f5e4c9009d1139101c4d37c14afe2ceb4eab05c6919ee75fe253f108553522878fdebb45b4ad80ec889a8bcd22c56f14af6a0ef047930775565573540a9554490561bf2aa7030d74419eac8482e92a4abc80f3b47655023838c5086b64415eaa8452e1889677ab31b91ce02dfb0d1a6f1c0469f6b83cfa7d4123d836d78631b07330fe01b5d64ba34f8bd3afbf3e4a39141784832744ce1b6f2e637dd79d56c92316251a109508e6dcea811e0d9240473ed292208dc9b388b16a75981d60c01e8f758779c98feb0e46644b3b0542dacd7333b76a8481622b497863e09dc68806192cced7840dad2a4d471229015e09752fe7b3eda4c47f06b1c6b22f3d4c095ef16de9250c2d4904dabab60e26f15c82335b8f01ff027505095c01d80538cad266268d3868f2b9984a4bb0d47b36108195d0c793713b75f6ab42dc5fd2e552735536d931f778168365c7d737554f7a5819fc032f0d57725a0f7051510fbc48948cc1769327256f3af5467422fd45b89df432281c0cccb0bb5ab21bc55285f913dbe47787df9d303deb15e05013caf0c303116c88e928028cd9414dbe2af025e5bec577524f00508f3632b8e6b1ce06b91fe52a18c538f0387663a8013049a9cb5a43d08aaf70ab33667ceab16829e70a5cca1947d23dcd949d2867015989ea82a6a589fe4c4e9ab8ee50807241c02faf969f36459dc154d75baf67a01568a286d99bee761f04afe85a59dd8b78a4acc99b95ad1b649a507c554705af525ecafcc3837d4eae4baa75a198023fc8f8701bd504a69f003831f590b45c4b15d46c44c96bc06d7868bb4b29758597332538ed5c5417ad14f6edbe4be8086c754daa61c95b37a86af6520b5852fd053919b90c4e7fdd2cc43a9596ae6a18145876881f714627319527771f57820c04863771826461e5479be8acbceb6696bddd49ea5f52fb062cb055e59541cdf73e15a42a8e676b8621fd30d46be35cf3f90c277ffd752b4af6946e58e6784868ac7e92801664d7f8cab4d1fc8ac1cc3a1d0701c01681a975bc9fcc9500f995d8c0b464052c751ed66fa059ca7b75fdad753bf752558ff76f4a8699c83887c9aed57b20c1a59c7cd77c42c5a55bd4bc8de1ce9757dd4f2464003713e096761fa174d8a9261993abac9cf48ff8200e189e445d6b279c3c4fd8dbf9045c876a6025e01c2160bb41159f04e569417587728b845bebdd472983ea3866d0a57b858931445e30c8a78d868a76bc8473e619a31e1c7a159ab41603541060eea9e4674365f545a4b18e6bbd6cb5c086c0d096a2ad5a67a52497020546c949e4922230676e2a760076b1fc11218e54811ae4dc1fd1572b647142e3fc321f5d1975b96b34fbcc74c11b99441919f0e2f3ce76813daa5148894001226ddb55985a6c6acb588b05fca44c6235a07edbf789a3b460d04eec6e1990c36b1fef6081708db3c6480f236e51ccdf5cd60c9bf0ae72eefefd5a86fa232eabfcd14e1aad674831fd83c90a3e025b10fc8bad28cf52b8526f53b0974eb61f115a69377a58ca8e59371e99f8fe9452d4cef48afc438529322ea8b4c274cae63b07a47e153663a849364d29edfe406614fd4d87f54d5a0a561788b1e5cf99c67ad639bb238281ba0d888bab08f7652fec4b97ab133694a2b1ec9945e53853aaf4f6a8e5b23c8a9d1444929db921cb60722fb63c463882bb4e5eacce7afa9e56ddb28cf38d5547ebbde849474bf89554ede443e82929f10a15934e146ce81328979c0085a779d4d7f5c3a67bbbbd5b894bf71d70a0b197d06d232349b6193432f4a708f4675556bc9b26eed1cb8001f55993df1e29dd3b26966221e1ea97eb16cfe8b30e9171d52e08843ed6ab9594000be627e3b9c42d2570ee2043f53172617c2bf4d06e0ba52781f573e31a3d615dd496ab24110a784afc2a18e1da66c7ec678be39e52e47c36b80f98a7bce28849903acb16299ed8f309b86b5cfc4f05bd92a967d55eb4f5c1b134395f25314bd945e41875db609bba65bdf9c941b24860604d1058e76a55b1e957a568a319329b7e35b842ac17db218311d6bf6b55c89a1872e86a18f7e61162987be93385b069dba2298cb28593602a1bca06ad6b98b6309e313931756473fc3d7e83abeaf13d48f77206f9e4e9a4b3e049db1acc25d9b2c94d1146f5351356ffaa5d9b2f2dc46ae56840737c219356b1287cf421d37cda698742fb2381ffca846c4f2a60513ffbf7cbfed03fd7fecc3f37fecf5947230e87f39f6e6cc51c91580120a2093d9e69bd39f79fd846c62e06d93b76aec18f52c65e3c957e0722452e3c7cfd4ec0fe3918e682dd26bb06bf300c2fbd5e079f4b169654e734304216892ebfca4a196299df1c81276ec21a737dc01b1225000034858234895e1460581658dfb509b7ddbd6b0c33ebf9f7cecae1c90d93eaeb9bc356d4a901a32b9ffd206f11da3bd0b833396b83ad69ddba4f70c8e8705e72565e9ae92368b1186400cfcdb959fd5ca19875e3a6f3ad0651ae787735df34933b3ec1424324f1259a9a762de533d545372247512ebf2d4376a4268951719b5dff0a369f878743cba95fbd1f95af2e8a9a8a497d63cd220c972c1737a86208b62b57af5b897bde25d1f4b97047d06155746b2889d39250eb92c32f3af0c4c8c05004ae532aaf2d452dc69c805da3c13827cf03c26e95718ad7e9ac2d2bc9ad08d9f0cec5a22e1076aa8503207e9021494ed7e5dca0e3dfaa296bd144c898aa57828e33201c3e6740b6976839c8cfd7ea97c75bc71bd1f422f30e49174816e3d0875615abdbee896814a6d1d95a60ba05beff862c329a5cd034408706ad7dafb89db6545ff1e44a3386109689d132ffbb9ff0a6ee83039f395fc5675451daf3f9ef57ab67ff29b715ea83c620d02096b874ec7ea6e7669d6e74981edb4bf41fa16742c1fb376f500d07c061fe9b104a61f995c35688bb2f91d480fd8cce20fb5900305c2ffa03d8e1b1232893d28e9dd9266ddbab5b3b73498b77013c4e9760517fbc52cb5bb57dec22d4df2da4099f17c2d57108a2bd0d4730d8ce41beee0a46360d720f1382c3aeb432977f3e8815bca3858230b6f775fcba005f8f3be2c8e8f40d56d10e654a1cd8f5f2e444f674e6bddbeec28954c4d0aa073c57b21fe5e293e00c6e47365528d0666416c415f3bfb2c04731ce02c1cb7a741519f99c0a6538c33a69d365780e9d3666868e16e213ab8cdcf79404ad5a557118735686ce0c62a5f558a20b9d290ae5111c91f604aebe90841dec3c7ec8290e91ed1ab7145eeca0b3a32f42dec179825916bc4809ec6ff5a6a577733c66b6a7e70653592eb559c55f8697a9aceb8a24e58d5bbf014f7475b9bb32dc7b2abb4718b642975950b72a44aee034359b368e03159a102ab75beb4fc8a31911df7d28cf5bc738608aeafd5578debca5a9b81688824a6913e8ec5fbfc1684e8112fba3df643def104e043a46cff55cdd437e60493b2414b34e0cb618343552d90e6f8f67ba77940ddf7cc89e02ad9167145382626f06241e282bd6789c9724cbe3c50ad3b99802ead8dfa507e785434871f3e46f7acffbf03f46558a53eb5e0b0f9f30cd90d5700455d97caccb8207bc65e1a0ce3e443e4f0a13c31adb0837ae5b6e7b1ccb45a39407aa24a6e33e26e335473043d3563e47646fe94e4ddee092a365cc5cac97c3118515c305168a81e7de1688051302cc488c78bf2d96e52b4d8e68248964669ccd71fa2588971e3e19ba9bea9a8e91da715a3cf220334f1829e2b9def304ce3bb6966aede7f7e700fd2556e40c9844ba067adb415047af77f561d8897f73451cbf54886984d179173ad8f511ad155ce74bb1623341fd49e2cac68923b4c5ec5131a2bb18cab0a2314a24949abc6eaf8e506c40201dd1e698161e84228afc66618d2bc9d9400cfa6d308dc626169ef764b9894d002e9ef6e9eff0875d3580ee5cec69857ba0e6058972127aa011cc89e5e106d949798e62d505d02a1408a023eaf7031ec6954d13f3536baf9a1deca18ffda8886fbe68b199df265d3e2933c236099d5a9d8c19bfaf39908d16d31745207268ed577f785c8e4a630298118c5927448dbadcedf3437b26db2221c046cc04638c850dbfb35af8f54b0767c52171151613055303eb98aec53df2f387a7baba7d399576a2985ee8e87d08b3585ad769195a37883e62c22cf375d3c9ac12918c60ef56b269c3460215d75cba769504f0ed9717518eeb5984705864e6aa95bd1da66cb870e1432aaf8978fc0c4787a69b54a64a08cc534b48767330aa2e019c12a070e31e26851e635f2ecc9ac8da94dd73ffd50f3e981916b9864814e4d4dadbd08cf0573b5a9a778003b60afbd163f6e5e812ab153696260ad83a3402fdf7abbdec8474be1aafc4c234505f858854d05186c53b051f11c9e5be40be41a8ec015853a1f474c74fc1fba173c0822049b348f62264eb9370ad34ee083cf51880784aa184e0cc6978a9dc2d6c721569f50f302f7e6bacf722eedbca399e489ef71c92d64841eced2370e0f71346198ba81ca8073177f4a811aea25186460b243af6d730ab584ffe38efa1a7297f3f4f40bf6ddd18c24a6c5b73fa199cb4545ea695f62adc08b002395a169e5f632353f48900fa95d6977de5858f9b69065c236ec4bf271e8576ad5d6d9ebb2ab807b4c58e9a2cbbc4b36786ec3e844fbbc6cf9d96481b0ddfb536770e6d179fd2471a19dc2c424908f32c3c6e109f886523412f39ad157a788acc3c7aab106501b44177b606f8f138490ef134fbb0e5d04a734c7db3853af87bae23bca0bc78f6db605e02afcfa0d4efb344157b08bc5543bf017153d6c33cf67733e87d3877654a092ea10e48c9a37b617bda107fa4a5e00e44c845bc62befa4c84184ac35e38acb79b5ba87293bc16905f96e829872352af4e68a35536d35eb5baac0bb9527cac3349cc64b78f0fec56ab1f42a9aeb510c9cf1823648e066b99829480bc096aaa30de726bf2c7776bd60b0fe8189b9faa95bc34468dec9bf4a5858041fa43f1385a81e82fdc74de8ccb32d63dba0c8bdc822294575f34397ec54e715da7b5f11eecfe05b4a9aaee8507f5f8534ea9d6d0d2082fa5f1da96c6305d560a36bbfa6e2e151919dcb93fd5f984325506ccb30adf57e8d657e06e4b1e6c4af1912e1cc32843dbb9480ce71e30e51944461e6c42c5dd6409877a59b0e4f0352954ec62ac1258498b9f8aa9b229bab64b9bb4150f793a7000fb02c0cb052017dd6f55cbb83146e274d5e38be0782d008e43699763c98b0d0663706d5b69a93f8c090f612cdf50ff110ec11cd4069461fd95f1929e5dabe31933e7a4c8692b09185634e552732521320e8577678bea50bcde8df6bd4f4583fa0ac82c3cf42cfbd77255d13d7ab25849080711bea05c4731ce295d59e90f39de96858e6559c32918d83a8589ed81778a06c6b7b4853d019ed9a6ce90ac018cef54757bdcc5d7820768dcf697dd7030856087b63bd471caef47012112d87951557c7a192992fcd4a264d063f5637e03aaec37a938571bd4fab2576c7f8e82477dd14665cd5d4be76421c155ad577cf06b88152d02081d8d1a1953be47f57396a06c14786896c0dea95c5649cee9482b1803026049b4cf9b8022409b18f90814207ee6c0043d177bf3d7a4ecaa44752a5afbbd65aa35174330fae8fd990a2704a5b33714f303dc1a2a4dd09864a9f52731ab45609a559f563974cec7dc25b88eb606c487c13bc8ca093a76bb84fcaaee60826d7e766c1dbc3d6ebfe00d84ccde5842100eb3f2be0da02c9bb0cffa88354d2eb46082f0a1e5f7c9deb2047501f6032b4a2293928e20b023140d2fde95b86a035525ed300b314ad0dc8addf55751f30c5d8b2572b48595ce0a92591db5cf28539469f460a799f1868d6051a5de432bc0d627331cfb566fab73bc811694f85ebfa0669e27be072f0267229b1adeed1e265f90644129ae648f7ad29dc7115eda305db8a86be0b20a0b4cd0ae4127c2c1ccef2305af4ca635456592add0428784b9a1a231172107b42b8f9b3b93d50f6cdad00ca7d0d41a8beb11c5485e3d088f2396d167d9337153fde2eb536741864bd9f06b53771a7991ea3b6d729a690a5493cdf41daa323cba86313c04ceb946c96b5f10d36198fb7eebcfde95568ef630a74c1e333a631a977e419ebf42962c1ec85277a12bc1cc7b8f5c285adf8b48261f346d86e9e62ab3d18c002124995889aca5cefc73cd871df681d9725294f9d94e0b5fca8ad07e655711eea983020e21c57cc29df43b277b646233ca68d7f15a2ff0d5335bcf09d8903fc0ab9c71b9f9f72abea2654354b5575fee1a7f26e428d37a4075c15bf97b7f958f98ef0a20edf7e334f1cff657813fda5f8599a6101b26478d210b953d89e4de13e92e0e1ffeef33d8e3d016ffff29d57f732dc31f608b8779dbcaf4e3849928d432f8f7d10c2bf651614686caf10d2fc3cafca6a97535757e1c25721c7b819f64083ed978b43160fe2c8ccf1d7cc0d27816a5ebfcf431e9bf042095692169d02e6a0edf4b495737cf2a5add518b6b7e25ac7747caa60ea735178c025a8201fbd379119e18d171182485cf578d74d6ee3e83c521d546fcd55eefe6ad664715325b899ad7a50095c09a888d198e643aefd59abb4098a5e6a0a61893d04308d08ae16614d07f080d47abbb95fc415a5e32d33113c3e1ecbd7191062ec07895fbb46b2cbbbf860a364651693fd30a75062cad1e4fc0e87e2ede2ce9e002114f65fc4507d94f97336f3c6427647a404b2a83bfcf1dcf48f8d4390a27f5a905710dd6d61add9a25c3bc1141d99f1891ea43eeb5c6eb847c713faabea8c64b7dc0fb79517e535963a278d7ba7bd4ed9e083c465b0133df2b1d2f96cd6edff26f3457b26282530faa891650936dbe8df7499e7e4d70fc0dc802d59d825bbe7509855da0a48d7d1012020fa79abeef5b34d9bed916aca74cc1b798882f2926be57a41cc8dc6b137c8a8c695008f0d60b44271963c7efa25b4c5aec5ded446a8457c06b994de51e3023199ec283f6a1a59cfee1f0df77bcf28ca295f3e67f3fc9e6fecc45beffc845fefb79145ef8722438e2f1f97f3e320e87404479f423d02974861a13b3ecd2a531bb99ef221f8d9b42cccf543492715f34a1eb88cff6250e4b5f2a83288998ad58c607ebb34223bdfe2050a2f29445ce0c42423910e9900d4fde44391c8e182da823d102c5bfedc12924430000042fab476ac5c2829b31d81e8f8b965884ccd3eb05cf6125817474f2e07a16509f3053006727c09a5bd0c0519bfc2d08871621acb8400ceb789e8f247026f02d64e5088ca9e4acb4e9d98f113554e5da703e2d6fe2ce4f1e347cb53e8b7966498b47b54f32efe7e55ee44d85f43a1e2207b56f659158c746853d46e3d9b7e10541c1acbf9985c302c262312f26874484cd4f034489e14e61a1a44cb037dcb16439cd3c30f8924c1a0f63d677977af99386ece1a5f8c3e4a621564b78a2a9980e351e7b16d687057036dd38530aa0b55e6b56bd363799ae9a06f350fb1b542209da6ef635de3bff3fd6de5b097a35c9117d201ad4caa4d65ad3a32c6aad9ffec639dd237aee44ecdf1beb94536e7d40220b483c3f64214fbee98d119fcf33497b2ddf5e9e84ce500346223d3ded6813b2da4ea4ada264a04029d1a1461694fe27171b218fbf919b2d8c67741940565ccad77c5209a50f416e26564bc93b6e4a03e3b9c285c5e579d98f1320c35ff4001d36cf67dfea9b47671eb8397a58a0720244022d9225fdc95ef88826ba2ab79eeccec66c9c96e496dcfc96137c0481f57ef9fadc86be786e7c3d99a1c907eea131692aa94643f5ced844dcd6710bfe1a0e6dbdf181f161ebed965818158b0d19d8c29c763dab8623948588abcd39839a67caf94e5b655432818d22e4df8d800cea8c700d91f513599c368c47ba684c231974bc45007c63656ae40c8c53bd51d2dcd0c61c730f38b9f8444d43880532fdfd0a874d5c35272e35547b1fc693d8829109a73a40b756be8e83324fd362a1c545eae1760dfc4b1614d1c42788b0ffc45e5c40b05e7e57639c89806045109b1f224b63e0a0485bd8f860b64be8d40abb04e88b2fc3b3841187845bcd8efe42946cde2782b3f73f79d640fd3a36771e282ded2522241b2d852833a3704e308b105028f2ad2c8be3902b6924014675736f0ab86e7f550ef3fb19216aa7b45ab9611e068f165dfbbfd5650a91b17ec86d5567664eed96377a5bfbe769ce569dfafe5416627062513ad85a057c3d229c2a405de79e56551b95a91bd47750aa23efeffb7a7d2fc0e9e58ec21cced96bfdc3ec5d0c5a2cdaf14e13ec6f8bd12ff06faec019ff935589699008ec8335db70c275e5f8c99ea81692e08ab847e728b4610f5b696528f4f781aaea8084c04587c2756b3c7ba6ae17849fc714a12f88ac60ffaa5e5ce5c28945f72e7665c373c38350e3c769c99da4ab3cbbcd673baf260ca03870f51eb2b92825a40da4d2c61e23a92da41807d79eb9d047c71ed4de6141bd68492858af5907e026b882c484046709c17b9ca4035092b1d6cfc47e78ad12ce88c2f653d72f4317f0c6ffce028e40159766ac19d4167c8dd0a6525bd41de2a90778905037e4cc310a519fb8d7e11669cd3aa5589bb0017b4586cd1e1ba201e5c1ab55f6cd0347cea9af235b06a160ddb26bad7f3cd8b71c2d557a74902933b92518565ca518ab06aa584ffdb25098d3fa5e7e656d2bf1941675288b23adb1ca893f08a2e527b5bf3c53f19572b0a9d696ade33ec393b837d6079f7b8e656905d58ff260fd432b6731a33e2067ea98314f9ca1a7d13cfe87d4fb0c5901abec9c0523b16d7786d9f8b339ca6d95430e0646d32fc644c8ff6db79de75d7dbba0ed84b70c24b76cd4e485954877712b058ce6d088e0e7dbf56b53ce4698afacd09d3c84f3e3341742bdb3850e215c28529434bbc792322621ed55d1d3e0f887a453b5db3656b59099569691bf315ef4e35be6074735f886f72f8648b1059a1dbb3b226c50c92ba5e4431f6354a75a3a94cf5837975ab09c41a694eca91d5bbed479051d776ed422bbf8eebb34794b2a0373ff708f85acb36abd4e60cd22337cab2e8f4904beb453573d8fa8f8dd607cff3d084fe038ce739e9f50de2d56e25e8460ccb646c8085392407d4b98500d711508e5961eda4a2b9266a3ed07ce384b100398a2dd2de95b8fa7abead37aaea9f84dd2035c0da20a883870cbfc6c3322f3e09365297e753d6901d33e84a8d8a5c1b6f83d6759b3b284e5513a72ad389a896b141fbbc6efd31d3ae8273c5c51fe2ad46ff7b1425949dec5cf2fced0d0e60ae4c0ea239575955a31303f3d66ace360bcb02a4e29b64ce6172c69ffae97f105ce7984e38ba81767b383789a803a516523f2e58d944716e8609b192839b0e3fb1a2806a620da3eebe9d6d1370366f8057f278df5f315f53c699aaf065db57c97d081d1e5c75a202f87806eb2d085252912ef6a6d0ad201fd42ececcf33103fda43c253bf9e02dceadcf4afdbb0c1b2a5d2a7eca2d88fae07ea15ba5ef443b432a022119f2197f8f40fea53eb979037d97cdfcf0461f1b58ddc78b0a14d7a33b4c6c5b540360715ec01e58fac208ad596e04765c16a6b4f84d1c0d8941eaa3f98356cfccbcdda03d31220fcc08bb270a4a53f7e23803634f2ac5d5cd16441c000824a2424f0f2c8f7a2bf92992cc9d850a1570b355313f543d019deb0ece3490af6ac898bc18fbea81204997e41b9fa37d11ce0d27feb9f06bdb7e9a36486e12bfef747fa07f933fdf3cfca8cf0bf5774994a12e17dfedfeef84c6198468f194b3261b34cce9d9a343b411ccc0da304ae04b3d214266b60b658d606fa6e60e9cf503bbb4b39ddf92a6223c3f0a20d5da7ba979e374859fcc7be2ac0ceaeb352554648b60ab7a4da3a70f4aa4870006d52de488ab514f432a5dbb7a4886c73be916ca9e7b5ca046845fbc853c2a01f2a8b9751f10a4d1e335569b911f3d68ea42e64d63fa1dca194c6e0fbdd180fcba5d4722794b566c9372e88fd85abd5cd131b3f31294e8b7b4359697aad3fb213acfb7dc627b442436af226039bae6d793c8aefaee75ae0e2bcd3fad88cac41cb2031944222d05cb59c38d317c43c0d97ef1f141c7caa27d5cd68c746287742a175b1c01bfe708a435c62206dd71e438b1ececbb699c142ca1d83a1a94d47f1677f26b0825bfdd1d06666b39d7ce333c201bf81067a0563a27b6c4698eb6d8cf424e756490f49b5a41e1e8181b2eed7edfa57bc393fa41d8c2b0a00cb1a86ada402ba3d05b3beb7d138ea41d8ed343e3d499bc1b1fdc0a563feecdab740a536eff09efa659fae04abce5a11d20a72e0e9305b7ae10d183e228b2741e4f04bf5a5fad27189ce2b50b8e7ae8b01cdf3f4b0bdf530e3804646d270e3722fab69723b8428c2462a84a83b1166fda8f5ce53348630f765033a6c8c0477cea86daca3fa4e334a5b5e7d9ca2fe08b69a69e0e67a824573316a7296e1df55d2995d58f92574d5453bed8c5ac7818cb03b447c29eb0c09444bdb112c10c11a6ecff495e28700b8b5c77c15ff392b15877417ba92a0615afa585498f2e668feb92ad0c8a1b0d4c3249bceed4ffaf11a5e4287ce3470ad2b4a97b0ba9d2bb0791a1bb26724f39b8cbc3b567ab2ed1acd9564a32c98bcb5d288dd495ebd47f0fcca324996b4a0f8ac8bf6d7941a2516d9152d85a7197fd2c427f4f13d07f9de16d0777e31ea6f3c846911fe0672d158a120eb679913743dd94c34e5673867087d507f1c62af99b1f411a79c2b6bcb5ab7a859f7317eb5060b4891e2aebbe4dc4638bde060d5ca3800e2be37fafc16cfb3ad2230b91a502a4257952ca9ac8a5d8b56c6efd21a9e7b3ca2dbb88333d4655827e0da8573b9762266e89c77a65ebdf9c5d637a3954c1f738209e59262bbaf05e59098c2ac0bf31efc6238e56b5bbc68ffe86774a8257d47de569bdff5634f96514213776de527b23cbe76a17f0f3e6a68654e3773b0e814a7f37ee4fbd0a50714698853b412041a8a84390843b489d0c0b1a1ff0c2d4512059da3178ed977937d3b821762cf80b4724f1b542d58dbcdd2e1a15d4c531939acb612e11c40c0b71b0720ee4e00394578321e99e5ade2ed613950573f164dbc6c28ab722adfb9c19c11a3bf0fb8e66858d9f8ec6ef7cd64c24232b43759a8c76c5d93e076aa203ecfe4626b005687ea8606fd5f4af974843486d56577636d9948aeeb30b15935a3f8c50325a3293d90b313c8b6845d5ae1533edece8179a89fac37c745808128d2fc38407edde7a48f42242615035d3963d0a0bf4ae46273a74817e0777ae7aff4cec572d6f35e37d6cf6213e649a020e06df48502a3180bba76e65b8d9ac25c55f139355d71592a8be799cea2cf531f6b5d7b0a5fbe6639a250964d07eb8fe3244eee8907c23b492aef8ef691e2c94aaa64c956d689e961805e874d4d89d75c639543b79492bc624ca8686f9a22d1457fb50cb874b6277c2d34b5b2ba40a380b889c139a0384886b4208f834d01b6b3583918a8e87835ffa25a19af5101aef6eb37c486c609e064207a68e029ffe6c3ea567f7af51318868fb9ff5f7fc0ffca87df9ff1e17f7a75f81cc1c72c2ae1e29f153dffe9db49fd3a788e50342a5084140f9a2381d556e528d515293c490f34289a67d3f396c3795495a1b6d960cbe4a6b37ba4a7f2167d507569c8dd338b07211ed48ce2a3d1d2d1f5c2b69da642891aa007f23bf31a04719c4318f1733b49b2b5082d536c78809230e7c5a64d932cbf11cdf033434f4017a7f183323245ed7837ee44f9bd4b08be46f6c0e7b1c504e65df42b458916e668db51100fafb0bbc910b6b21e82844a4880efb8e2c768c1322fdac13749385191afdf037682ab4d929f5844f42569418184a1dab78b8e8aa546a2d65b4586eb15fea2ab321d49c2d5175c169ed9aec9b6637f3ffb123cc55f057dbe7d9efb149e65fb003e3fc94d6ff6cd873e79e3a36d80967038931ff6434cb7ab7105ab8a2ec22a4a71003a9e815e6a809c9ccf51c8c85fce9fea3a9c581b6c9241ff62919a2d6644fbebe7a07770134873222f500e1f1d1ae2510b1f9c9768f8f99654011b9c514f55bee1cde2a050a8a554b8717e68aff5f59038014a75456f8c605805b0dd982a28aa52d24f5b3aee30d9975bb4a43b0dc0a135901c329f9cd6ed1a20178b02310bfcae12d88f8c00f3647199e5e9b817c42093762d9dd083bbc3af15b56f1de5f528c9658e0810578a32f65ebd2c1cf2a46fa461214c010815f3d9198eeb2cf005f47e47c9ede16f6690a4881d5456c61940540102910cdc935e478dcbf6bd803a786931fd9d3208e578efcd936429ffb8c25e0d2bc58ecf20a4116c73735d94262095cec3332b38f42ca6e09ba7817c363f1a6cb0691264bebbdde55b79f79037a4afc94030ac6ca0e0368ad9a6f7f061b2f14fed249b0b7cb55d04b8e9bab4756492bde099fa6e5a0a5ac20b406f9efa57a0bad43170dce87b9ad0cf16078f1e0c52c0dd340778aeef8c7d8a77f32ab105ce2327a8cb89eacb02f0841860a09373b7f465c5f10a30cd0d78039a7c981fa1314a9265b763827b5e2b87b387a56e1ae811644f837b0da0d48d863e667f0a2efc339c2ef314bff201e7cad1974add8fe82d51a00bb1032577e028a71c3aa53b51476fe28899ec0aa7576a20e411c523481067ec2485bba41527cd3985017a45007b45389a9e8f562db999d15998f668839fea039c225083a20694ed649c826c2293a60bbec90ac40be23cf21715452ce7d4ecd4b76c3c4af8a73935dbf63e1f8582c72ee4ed4922ac3983cf2b43e3f5daaf4cb9c40cd6282559e13732e618fdd65772dcc5ebd5b948f9c0a016758d5a93497f9673365e2f30391eff36af578ce06e1930d8615b81f89159f8eb52d712bcc5bfb1f4fc096092fe788661e63fc4d2f3dfc452b192c2ae8cddebbff6cf61ccc5bb0f3f01cda04adf22826f8e5c144a82ba6fefbc70eeb0d018635269a44b66cb69619745b7ddfbf19a29ce730853b64888379c780eb5e991892b0193ee0fca7f6a1c8c39391da09f03158d247d57380c56db6856e2644197df47a21f68e6603cedfc2de794893522376aa3994e0e352c84d7d34686d4502ce91274a9381acc4581e3740a8610e46787c2285ab87cd137b6eaa666b9cfbce644e7fe316b117a91c12bb3204d4b2eb8ca6c0055320b614383555e5d185d72cf2d03c7f82041e959f434b7e4c8a88fdc56c57be0c1392c9873a83354f2f858b53db384e4e7aa86e1ae91523695f1bad2adf9f3c25ffc83cf2de2b69137a99aecd7d2572099adaffa79d96ac6159c6ec56dee226407103f7c11cea856dfaa61eb5da4cb84a91daa280cdf2d09481b03436845e36007534c353455ee9a58494dc36afdf55118bccfa3ded0ab5c09bbba9bf9ba12326756a5977b143cbaa53fc5301cb2b05402987d0294f4f7ec3168b5a61810e8e29a790ab2ae6f6ab488a426579289136d6670ca1a4392b724d8c1dd4168a425773f854efbc44e1adba596d94a9293039033c4339247e3304a9cadb38ff74a9aa3f5e5f1ea7d7b079d1941bf251850eb982159107d1f873dc9083747ef1f4813f7327329e3d74a3ae8ff62b2e6d058049508525e0ffe9992df50bb3f831b3cff3091819b658bf7554ad2e4a42a6ecb308a3b9217d530840b378213df1aeac49394fcb33aa6b700b8ce6e30413f54429a9d9b8a8a3cf8b63aaafd6a20034bf168ee58ca9116d6d114d468864f04de12714712d44a0debdd8e72ce1e19a054ac67cdeb3b92f56c38f3367f83696452de6f656717ea9dafcbeda9c56206927e391ac69f01cdef091405492767bfafdd67cb3a3d169594dc41f719b357ba65ba48855d235c3756da1437dc204f8d3aa2491a306ad1b60f95afd3c0fdcca2365fb2123e726c67f871b4d6f8174cf2b8517856c1ef4b1f48d64b85f3e2abe640002a40950cd89e6e09ef5cddd0e02d199fc73f48d4100b86765d57d2c7a3627c26cd4d8da661daf858ac1531eac5cc659c280a0cc49c040480ee1299201d1bfd5b08465183253cc4aa5479eccbd71a126d61d7f06c1188fad8f24990b257b0652005f46db473377c3f569e13c7ad7176f491dce093cff1edc33ec4bfcfc3ba56e049a5acf6a7355b63d191b99a6a79e1f7b3180ed4d5d28e68247eedefad3db0724f8df94de90fe0019dff3492d80ecd919518190491782a7aacb9798f418be9be11e0e002693cae0a73be7af12fc80d32fa86a46759a40a4141bdcb6818567c50eddf78914b131bdcf4039ba00a3812686740c1d943d59585ede643a5e52994ef2a2618d1f1dad78e0a722219ed2df643c11ec02ba2b849a6b19d8720eea95c80b26cdd929bc6344d844286cf53b5c3ef8bcdcd79c9cefa9136fdb0d4e1aea28bc2afc6fc7c8aa881b7d5d478d389051ba20635eed1f450b2158539d0ba42e845ea84eff73928306484a3b5c09b3d5973e34159ffd49230174852ebdb2e249b842bf2585e803097081479b103d90e1e10a7f32d403b9d4741820b234a16349cdc1543e671e367881625855097e4840ec79fb812c5a983ad61bb4ac1031fc30d06e64af42bdbb3f177228f85820e4150b613c2de600bc9ee1ac0158b7a05a2adb0742671a447aa2f2684e45074118aba2843e4fdce445fadf8ce1fee8e72727caa2703ef8c4c9571e992a29d378be5c8f77b2ee50a2f2a4a1c1321d1b4d6f4b8882f4a3ea29de3106ecb3165c8659954a5fd4d703dcc718e35c11b1a03f8c02cf87aa4cede85f238f519a1428be57a5812bf710b63b410708be8d43cc86a4859521ccbeddaa030138441adfa65a666be220e3da436cd18b8eec56d2c1663b21fe499934541fa4187d63069037b5bdfce2eeb720693a3747ee3575dddd47e6b6690c2922773bcc7fd6bc8ddaa40573f0774435eb2a9b172bc709908531a105abd510a1672e1bbc3712ee4ec690a31d11a3ef47af871114ef7ecc95601e01766a4f062eac87e5e2bf18e96f895d92b1c5be25967d5a3154a892129804860537205cf58887a2eddaaf9ed14c03b237c92f438bfb606d8dd6ef5943f897c5a956456baa3caaeadac39a397d8296014ebea9388de84ad165692477db63ef8b4e82f788ce5e150a12e8f7bb588cebd554ba75cc5822ea7194f026caf5a4208ba554c1c1113fbe9d643393a691641b68fc01de68deaa2e4409d4103d397ca552be5e9c02a3478c2e6aa725f62737c756b2fc8dcb07c7b18aba830fd6172e301a11b05211952f90c8a1cf34afdc49d53e36f06c650bad8a07e72137b7718b7f1fc2b6f8a232c77d5a913eff0e94c29c10a74452f62c7ef5d129a9f62828a427f05799529fdb39427a6745ec894cab77d825bde5012df306b875bcddad7d330394fcef5b87d0b122c66d1b19a02ddae66db8e2ec289ebe49bcf3981f86ec8d97b0068dd54eddf3d998c72aa6a5584c6a08af1615be1e4745a98dd9cc4e823c24e58d39bcee5283c735344096857d0855ffdd97350a5f1a660f06bc95ec61bf7523749f665dc5281424645dfae19fc113fa7c658e39ad64cc4328a5846a4625aa22b34aa88e0e76b3b8cba39089fa76e57c824bab8b5e051afaf5410f4a0c08e55134706d26f3b391cd0a1d3db00b746aa88deaf009ad65c459c8787d4696145397ecb43257c6c3df3f7b98fd3dc1b9d0b1aeb4c1622126dd92d9e6b627c5c3c3949f6ca7a8d3e7ef2bca95f56ff677a2f06fc86f882e4197ef7d82e6653aca21a43035bee69d5807b49cf7e4116d76d2599e8ac5987ea73360abf6746aba932ad56af7ea8c0b39e1231420e08363450424d79b5caf42dc0db807340b700fe36c715208c88553f626cf46e97447fccc4bdc205e4840642d976d97f609bd71c641119d24a162c7b74a2f2aa75e8bf0742219379608aace9adc7588a14d74b8443a636cd52ff055b2e16a7f6b4a3bb3f93ed25e5fd84b184a1533087131017a4e75635c26b8f4caf78b8f72756a01c2fdf3c95a3bc708b0d6b862ac197de50519a87cd95fafc80c3bd7360006510e0fff69874d8431878effc1886bbfd3febb883fec8639220cf9f7624feaf592afbcfb2545d2ef59713a95f29ab4d82ba7c8ec04712e1bd2f0d671a98573ea54331b9ffdde31212109639ee8f56b06bf636281422745bc232b9cb3043de2d80cd361b4576535a79b96e7213cd9a71965424a00b8aaabbf6cdb5e7694eceaecdd4fb28d033052c5bb2ae65db020accb8010ab4518c8d8c54e264c8c89e885c6d63356f428ccf5cbe0fd5ce45e2e0861df5d60c88b21f6e7655b1052bfe6908bf49a3ba250bac4b8f8c70c2cc6ba60caadda64658482780a82002a6d4cea7cb85483b66471840329cc36e307edbfa2fbf0f012e7033273173d7309224a42318bd54dca868d7a4ea4f32e8881749ada0cf804252a7704853ea0da2024e02fa7dee4bb5131c83738e50f6484d03d49c82ec6b142718d4b4c1778e959e2a14449fc3ab16c11e8a52b06b068f0627476335f042a7d285f43181848d95a134afd8647ac8ad7f206335a880d0a9c71ea3b2b9422d17000ec872a3e4a6e452925dd9a389b626f7a2e88de3febe910b89f502f428f69710d04bb07a18efad5f6162804e29b187e5f6b7ed787a020a92d94ea521a020f3868f2b9bce32969b3cb6458e4fba83b0a63cc473c65c1b85211c46e9d21ee3fc9c7934c52b1fc31bbaca60481a74f3c97948970543f2d4fe41367ce27545dfbb22a5b3b45ebeacc4340724a54685b16b4a2b0c36267db7089246e721a3a781eaefcc5dcb353065bdf970dbee19f6788bc4fcf4b02eb6b2dc1d8448a908c8c8cb257461be9ae2cd50f43792903bad808f97550a0495bf498c0cb3c04c29414f5f3a19f1a679f6d33ecee58f84ad1be238d1cec93b978ba4ce76b56292e4716c745e8c3ea1c744230f8ee6122c1c05bced03976ef55d5836c79b27f055d7009c4ebb64bd2fbd63683f4d9e8f6fcbfac433bac7276952d71424345a70f23dfc68c6ab39c102e7736c46323dcd2b343bace0e1b7659474b42809d9bbe66d1b43478b4c8612cc662f1fdeb69e0eb536c50e549dc7e6cdac4e70f00a1a827a18881e360030bc6065868dbf2610d4955b14989c327441532557558c9ab0a6d0c44edac1516086848697f97be76ae43d0e3fd15379483d8d99c211e5f011d5f4c98f326b6769a75bd02c7589b5e22213ecfd8a36bffe8179772a8a08e8280c23fef5f107be3ae1cf6e7cfe8d7990d816a8fb26910905b27a1552f896d230149079e511dce4a36b64113e38087d96e35fdffdd7ffa95b986ed17388a24cc8b9f9eb7373777ec9dc36e1b2e60b13110aec888a9cc132f7c01c73644b3970c1e9a37188de549cf3a0bcd02819eac0c8db57bea428c05f5040eff7c8a69ac9e8f2988c2984e3d4474edd307dd7f7c0047031e22777af9e4952626838e0f9e19406832956411d06e419e5eaba0ea1a245e342a071b247b114e98a35ca0202a7d8d3066582eecb7a7e4d47f03db20ebf96c50a62e1f9d04f91b68665df1c23fd762303674759424496a73861be131a697e4751af62108bd5e1822ae144919232b0a89f6eef01760d07138b94eade6cd32e015c909e9db162250760e7383f3de1c005341c4854026ee094f9b746b10c5d0ed5d629e14a65e8d28946fc523ec60d38222568dda35f72b679b4e1bd90480f21d3bc7da79097a7bbd34c7a5b3523c7972d37cbcd3cfbdf69b0f2e5ea5c6d3b27dad8eef3b1ef31403d6d19de94aa6ee3df715da9b0737e01c41d96a714776b9762cc63fca4ac63c3ed49b270482a5fd9bb54da7a92ce9ad05204f10ca548827f12995338fda38a3f4ba01102c267f39a2544d549dfac52deacad6a6fa6201b0e9890b6f399ca7274cbb9e8565bf9f27e35c2e0b25ecfd5d9d443ae17c3f22a2f32f8ade84987be00e95d0cf129cfb6805c02dcf2d7741caf295e1b95929a5aadf4c644913cf2d94ba7486273ded36e1ca748ab8cfeb632ddd203bcba66f66e7fe03d5d8389af5f5134a811c9ca9a5a5ee3d89e4aa0f22750967c5155ff85c699769fb22689db5c6e0872b285bb982999a36ae86a1a7be6a0c4953899e5a194a742c94aa705ed156c42878b432bfda01adaad3b1b821e28cb3521fc278976ce6dfbe221c337a49ab90c74d9853f64a420b68e0f38163da7be5b452ef94cd02da7df0045e5a2d240611d15fd243fd39334589b4b18174e6eb868afd1c142b4f6848d948277b9d279442e1685c9b32d3347d331788c67855bbd8339297f9146d4b8525e35df468951c06f2b872046c747fb376d240a501411263902d757e6e78ba4f822f43ec51d59a11a5f98d2250e617d3d8767daa28da20e97209f71c0795ecaca0d69c40d402fa37792d62c24d992f82987352d79d024f6d2fee01045a94a42737ef9b418000c29cf99b1aeec83f48a76543d8d30f9572148958448d9e7db51954569b3bf7ee86791e4ccf6c5809802cd5d911c9e4a2f593b194a01828dc6c648e7340d079315def358002a6220ac3c25738c0afeb6863ecd05a516bc57a676cb0ea7cf723285131f2c51ef004e75a0b9f7e20e8fbec24fb2405b357ef9d8832e7e24dffc1ed229385d409f46abaf82cd3c6dabec98cb8bde1eba1c36bf9e04c4a7529ea4cc49bd0e8adc7c0164264da1db999aa2dc20d56c723890dd53dc16a95175c2662b22f9f4889c10d23931710e163ccac9019e3dc10f8d5e08e9e0abc95327ac2d719920e2dd2a3ad8fd814c163b172f543a0e04307880147eef53f35a333b5ded4dfd34fa8dc4fa2029a3cabb5cffeec321a0bd3083a35940a05ee25e93a1f3dd4f819b7f1ef0b470116985223daa6fb2731b259580d856a23e8e90655949a78e638ac3e12425bb0ab522f43e8af3a566433ba2f90dac37dfeaead97dd8429d547d4736df37c91e7660f6e3da2a0cffb684acdd8e7a44c8c98414e8037948bb44fb459114ef20b16b600c4ec741c7728df2f6dfdcd6acf8cb4adbcf61180333feac7792fa37b8ed7f7058ac4e65040ff9e48a95640e85fc2f9988b21744fbee98e001691191bd5661164998d182555eddc58cc6081cbfa7225eb0f0c1d4cc91c0d3932181487d14bbfe31e0a00b25ab401e0fe6ce75d5040980744c53607c504c6ce98eab903f6df12adfb3577ff99510d7fb74ff799aa47be5049f34a5fc6649df0b433c17b5907cce43bf97d08506d30474e480c62a83e39ceecda8035cbe7f1a7a72c9b3e953e7a9595b592140d4ad8653fc662a8104881891360ebc8ba1c43821ef4d2ee92586dfff149c7207f671969a70de15ff965aac79bd31025906f21ae76721ddf9768c8fbc1bbe93839bcd46df956f9d674266287305da815c2be09cf9f4235bdc343214868e36d4e03c0193e8f6b4165b0a6218c871cb625b5e1df6a2190dcb34ac02a274d79d7e80542f4760418b7575a1257dc84ccb7e7bd81e9daa312912848af179f315d5d5fa03f0e638b6a9003eba6191cd7d8b94949d26a264430d1e19f83a4517b30f2643fb6ffd661f87b9b801e3304c7a2b7fa4dfcc7f47bf21f49147e2990acf928f219f233892fe8f5ef16080fffe2d5d29cab03a785b20c6d32b170aac393486f753db543715f98ef7141ec6af0cf61c3ac0e9c783ac2c05fbe369bebb27d57845353ac9764e81324eff30a6f45be4f654a74342262a742a251cf7857947a4468fe562d88130b2709dc7a83dec16b0dd589cc56b768dd5e66ee884cc6864a7a104054c3d862c404011b9adf2c1fb8a96e6f7b0e5035e25f66833aa93c4a83994381af9fbf34eea58f161177a67912de01e83f3bb1d5d85155566d7fd60b3550efd37887fc7804c306c00639feb2f46980efe4de260660689e4e3554f8b421bdd24618646a740a4c2528bd631d95f381c165b7f5317aebdef4ef93ce87f664d3491c73b9da9c240bb1868fc6bebfcebe64cc18c2846736949d9dc0fb39720f31788bd9fa36c860c69c4168884208847b786220f97593b4f4e904b470f29e29e217ef2b39e759116b66caa8fbd0eac26ecf896be896086bfb32cb4a50281cf080ca3ef7f9665e19dff6b5cf251f65fbc195318e6e163c6a28d59e25b095ec10667d86e91e0f2caee9161cf6db31a78379b084e26586fd427be947b6fe1ea0074650d89a731facce73d9f04bc9475ad3519184eb404406081f7af8ac0d950479f3a7cdf41d6e80156e837e11840d7f56ddeec41cf192b24470a1bf7fecbd700495f76b49734c4b0a6c32fd9f1d6ec4d47ddfdacc2d45408d6bfb32c2132810e6680f267b4bbc08f765e5381043ac658114df3caf55f03a9395acee3310af7e5c9ae3d473cf30da710c95e7f47fa4e4eebc3e8796b65512c6d87ca9bf863185e7194a0984e3d49aec43dee50d638aac1d3d1d519559c8e69260e9249bc4e2348a720fee6b875d74d689f7419e3b27f071e79b1b48312275a9660cd27d6f40b6fbd75fc813ebd5c6f8d86bc4dc8c28278fa34ea7ed0c5155e4efadeb0105fae9e08c46b4a78f9734bb0e6dc39d895f98db02d3181f28936128f2bd8e84c263cc37e5bb66714efa2a271632c73321a90aac722bb54eb599d38f83b3ad4c323bbd05fc3a430378bd58f4b5777ab24b886324adb89cc38e3a31eb6f6b60f5e4ba24278131ab6a2f79bb9cd98e077d6ada6b4c7392522641b646479932bf0eeedf1fcc84301cb2cab885ec735485ca83d6c94fa0e19e2acd0dfbdf6dbdcced8d38926394269f3cd97a9add8ca86da595071d14c4e2406e7c07cc790aa85f1fc5d11259ba8ef2d306dabe5b7b365396f2dc6ac7b8ca674e9493396d3bd4da70aedfedc6dfb4ea45c6b088ebdb55c57193f7882b5c2b3226afc16be43dfa67a5a439711f962288978747b24634f4e1a4f9885b7710931adea427990dde7d7b4ad38e1cca9975b6c87baefe231ddaf78c0ded0b3ae93526716af120464179939a787ed71957a12a9771026e306874d5a0dfeeb6238a45cbff24c43a06f1e4264a299895d48cf2e7194e51745c3800ab0bdd2e6ea10f31cdf73d1f5e4d9b90163177fbd5e6a1b5d2c919ce6d792b53ffe561f2e25137444a70237fa3d2378b9f8cfda484e66003cc38b7b4c8c8ea382fda43330855829a1ad296b713fbc4cc21c77708d1a161359bc483325edb06dfd327e881fbcdbe0d1d4875d04deb6c735d49743a66ae6cc5ae7f7e1252fb72210eec86ad86ede2a0d2c8324867f019cda5e9f27afa94e6a7a2ff63af2244b29178962c9494d28de32ba872de5dc1209fd0a549b64502284c9068ca0a2bb1043a1f7a4d341a937f882033df312d20293ab624c50fab75b537c9a05876738a0ca4c098214ed1a4dd4c92cfd0876bd70bf2b787ff207615dd34a85227761faf5ccfd6083463ef427ffea3ceeacc3d2fb2231d563e5bc8c5c636e3afc5ad4312e3d87d4061f6107b00ce2496f1d641231b98c8eb24e1e1b6f650ffb6c5809efc6111c6a558eb296725afc6e20b8136deae74a5c68cdbfb90b8c1c3bd849f279cb282807431fb713270370bb4805e2d91bf0d30398b7062832ce3488cb721933cf24c766d0cf0a8d27b8311d82f34c0ad16f0cb6b55203ac7d1e67a762f901416f901b2a4e4bd1f9471257190636b90b305855cff4ef928f1f0b4c43c5791dbdf8ee7915ae11a3b94b03ed4663088e4ffbad117d35471c5bef7562012462f74079cd7385225cece2cd5a001fc65ac9ec2c2390621d8d8efbce24b697899c5f6f0133b4fc0f53e52f82ab05ddcd325cc6a9228fc0abcb0db65cd87bd9b8ce48b9cd6527257c1c69ae8a9e887dc5619e5832f125507212523cd56c6150e63eedeb7156a88d51d421902ad3aa607467363fc45f1ec64b7b05cf7d992f801d963d4f0f5b9a19e31e91308dec7027a72c349e8dae74249a577cac2ab8acc17f72281292ac2efc3576a998feff7e6ff5af1c1a48e25b20e1ab0ae2584ae1eb8ec35ba0ae5f46ea7feed8ff835fbf30cdfdc774059b1875efde5f38c22b9d0ef516b93111d13c0e4557680c1ba3e6f72517cbad4ef58bd5418602925565555f02c69aeb3ad9ce983d881257f0657ac653203748f9fe0a24b7d01db8d09b31923e657f2a7ba3aa73eebb9a18606420bc7bd4c51e22d9b7107d9e418d69a9adbdc3fea49b03a599484560f52fff5067d2f97a52fd326a4745540a0df3214b8f0afa25ed362a94b358b882ea61fed8c211a718b6490ca27edc6ee38713c113c8e924027c270a983e008a562524e0be6d58dd5a875e771644d2066fe334b5fa614ae6ac0675e89c1bf9721922caf0e54d86370fbfa895905103ddbba397f003626fc83132b11423453175f7f3b3a284b323eb8b86fb0ad49793aeb2008e36009a25c96a68b1caac6c97e83ba7874049b616a62c79b7ac08069625e47a7a2173402531e00ce3a6bee19e2de1b4c0827e9c5f1e3751b4503112fecaed94a4dfb917dd6b70bc5f3eedc31aa34b34fbe740ed7b6dcb291fd2bb0c5ade750c6c3406b39d429bd2cfe5c1609922c7f9be90b111a4a93bbfdfbede67ebd26edf9062a86d06fd52e90543d347c23e64c925cdb3390a9c14bdbbd1ae01bff1319ef0539264053ae6e7500f7ccaeb7aa216b2922648a569e0ca625d5f0c1bd45a31d27f3d52002e7a79bb5ee27acfc8c94195c5b2b4a75f5297152a5fe8df3862680dd5731a5331269824481103ac4fa6143608eace5a56f26971e3ef8d73cda6d1f639bc4297991692e7ab7a18dde0ab382cbe579adab1a6452c8b2715f7fbb90d2d8113bf5627d353db161b628f79cd4e17ad0f04dd89915dd4f4b6486048bd2c6e809b947f316babb094df71e03095fea596afeeea34cb071e59222c3dcb28e3fb778d5941e0a8a1a92484d4171d452fc973d66e2325bf0b509e9bff2c6658f5f0001ed0e5fdca723ad8a0670244b8f516a90740c4aba167240831ab58bdefd71db37c90222d0e5584c57571b9f1982f757d7115bdcbdbe62abfcf33d36561350a6a7ddbc4cb5713f907c104aae46d4941716b7eb65b37648af16d21ba39e7a156ab6945c8f2c77eae0ae0760a320cd2fd35ab84a4f8aa062744120897cb15198f6da9b406ab9fa197f72bae6544e8939d4d2d0fc428b4364bfc39ee1be9934dd3adff717f34035f643f989b615467ff237de9fcd9fdd1ff4d5f3a49ac7e69acf44e944269acdaffd85be0df7fe0d9928687ff98ac60d460f12247cceca2e838b5e08a8bf6bc0ad0ab94da2f86b628cc5f535054aef0a4a7e457070c1810402f38035438f6ad14ef7710e552feb8d3f762d422adef7a90744a111ae0ed8fa6187c622e2eb16e4cff851eed8a597064662e74431e6fedb494e7902dd970eafe5f00aa0f3f8dec5b5449211527689af0c9e524d36e9c7bc12ba896f929e310da95aa395a835a0292e82aa9522faae845223995f4db10f4304615d0b2e53e8453d3fd61cc5a4e0add465deec5f40dae966eaaa9047bf30941e27a53cc5efa84fd6a3cdb025a59b44530d5150eaf29228ce693f2cbf7e6145c5888f30352bfdd65fcf8ab06eb95893be4ee830db0c44e84300d576585896d44d6f6e9cdfbf76061061908e2373c2ecb81b897010bfd841cb60b0e5d5a426d316f68d506a643013f89d54c472518c0c88a5ba12895f997ac03143ca69b2780fe6660dcb0f6e9518bfb62247140fb36f9192111a5d94946dbbaa73046ede29dc6a86ea3e1ea13852df6d4aeda9cef47a72d72b70605708448d98f9f8bdb560aa7e1d38cdc691dc7e9e504447b7d91775609b9980fad40d09f781bfa4ed68f003596a607ed69f398a25e60e47d98d7e734ddae087b29255011427382bd9f00b0f2cf83d83a2cbfed9749febda895dca2cf6b31c89099f4a84f5409fa0755b24c738134b2f81124d89ba18d0a9326260bcc49caf1d4b4275e0d94b73dfb150ea79b940b979fe611132190a1dce34d31cefbf91dd3a7dc339e08a4e0533dca50ee93281fa3d90d1d35785b008589dd2f9afd9119d973aac318c3efaf0044b7a3ece44b60b3a67818b5e450b4ed401d7577cbb0accbd5b4e7c7d573cf267f54f8903715d5f13af80eb0aa9b71a754662771f07bcee23b2dcba0ed1bd1475d2f51ec5ae0714fa9d8a41788fce9d4fb8f2ca3f41cb98a1b1cc3f02c7bff89df98fdbb1aeeffe83746cc3df3e87ff505846c534ce650b42e9746e9558ca194c5ea578a269cf4ff310739ffdc3dd96678c2be80140e88c06f21ff70b554b9250872dd99fb86b334fde186e4e76e5dc0e44b822269427699dfe6282fc52de8d6440a3a399a8d72f4a6e146c34f0bd2ddb795ead7f7a368e0076fd3bd75d3009a91170d93e502d21478d68cac63611f198589c2da9ce149b86df7daa63c1676b9bc8dcf9cdfbc76acd21da161679547a61fad14fbeb7d5c80ba61df150bbf130dc150edcc94db02a6fb041f3af2ba4508ea39c68164b47a1cf5bb2bc16d29651ceb7d36ebaae2fdc828cef71a4e7f5d90c17517023d321c7eb681e64f73bc11cb00c5e198be8cab2e128cb291bd85e074d8cb72d18d9eb892630b7ea709164354df3422995ad46642cb7d5d2552fa248f7f89a448f2b16e58741744cf2965d900d70fc8d0553053b9bd41a32152d74c112da8151a21a6defa862ea8cceb8c80ad8249b1c27cea57bed0ef60ee9f20a9e0750a470c8b75cefd4a58ad209f138477b584376bad527f945013e4c37a5d1d0226ce36dc888cf73021f81238a5ad36bbf8e6968fdbb1d63a319660bbc3c01cac891b81c2a09bd4a173e693ba27bb6349b53ee970d3e5dc4473e1456601096fd37b9ae6b6447c2a10b0201790e381afa92efcacea36c08fad6cec78809e5f4bdb4985fe1aa96c40577e226ccaec0a35e52346d272784462c67cbcab3692c2375a9bb9a2aa414af0fca8a04fe187497563b379291ffbba6a79b5f4ec8cc72e9006bc687a3a9968eef69e9ade520dee721056ee609be888072ce33c1e340e71968ec63462fed24cd28a4f3d07a8a39512eb5db6e83e1cc8e7805b578961ebf195206f38be878f27ab21cd134beb08248ff22ed4fd33109c10fddeb0804df92a4572a0124530a689e5be8b9941dedc9a6d49b56065c6afafcd2eb115ddef58790bb7fb695c882ae9b487cf29fd8c126fac97653ec42f0a375ec5153e4f2ec4ff3fdede63077aed0eee7c202e98d3923993cd1c76cc39673efde0937425c0b007d71e8db76cf48ee7b07e55ff2003be56ec328c7be26c5f79bb02aaf8d0101932ed537110bdeb9ba56cf7feb1237e464b874cf10b90992ab6a16551166cbc5a91d3d53c77ea91d37803b6d05b50c3a4d053d50761377f571dd1c947cab9e2811d542752d9b6ae6bcf0d4c8e7cc61974220b7ecae38f626965eca09043636072d1c52704c853cf09952c1c95871049332576ff9e09e45fa72de3d191a4c003ec9514e56b77aae25286cea44c53db27f484ba7478d13b1a78f85e1fd21a1ebc4beec39f90b7f5173f407c73722619847ee6ed4d6c37ff9482a883326fbf461cd016f15ef357ba9f97f13f6a0d92faa38c883744931f76a0ca979fe13a374f16366ebabf1db8117115fa3b21a2fa74a45053ee203966bd045ad8450b435c692f26a9aac828f0b987a5fbedf5d475a761e5cc61919e651a016ec7d7c8a6c1692396615f30ca5544516ad30fe701264bff555bb18bbfad426de31f11c0df6254f1ffdce7fd0fa39a4d8e046a36994336994b210d4812fc634ed799fcf94fc436f9284219faef3ce1f0e1e32740820f8e295a68c1be6429d30e89ed472b2f06b43e2ef5a8f650aa72d302c09c648c368950cf4920e0f3033d51841ecae0497222df1c296066669beede7ffb99df38fa4d9595196035a1343b323febc6f6663619fe83007c363e2c46b180ebae19c8babde0cb5b2d4aeb69cd93df16b7f5add3264474dc3e5f767c4db467e5eb83cb6f7433756fa3c8296e73795ef8359300e0386ac0348fe51376b038c7eb3bab922a2e43577a60cdf90201afae46d106e94235d08d5b0e8321c37063a751de9932579e90c976033e314cdda27eb1f5efa0b7357c7c241fadc5686e4446b3ab87a4e461335132497f43dba17791e443037ec7079d5f632b4a5555cd44e4c05e91d58c18e0be8111c3a53e2531b96e1fb4e5ed884d74d40774f2838fb3128d473e811fa196b8505a9dbdd35b34fbb7a11267935a8c939f004b01816916c3da04fdc29f75d0350a08bd758ad007d9fa1b25b3b9e510472e9dd1a289c93fa9a586b90ca0e00a522989e050e5ceab84c9692864d74ef14234cf06710328984b7c06dc367eb5ea6126980cecf5bd53d8a686ada72bd4a0e8870b28bf321199fdacb29ff44658eb916bc65a0c30f4fdbb630204246e6bbcae4ee7b1d8aee8abbeaf9f400968ea87a02db3423747c2519df301705acc4fea7eaa1768067d1716e637e200b5df7ae7fe9719cc7969563a229329bb6adb535f441cb4931e1c7eff7e099d670b2e193fdc91a30199560d57c3778ab6622547644d989944a5a2bdb755d58d27b6d63996e17fe6c15dbdfc0e59fb23a1344af87b9ed1fe5f388fc799a1c5f9570ef3d7731f759a42f2ffd25547680da828fa214822bdfd452683181d14b3fa6a4bee7768752b29b77d7b42ca34f528b99c81b4c309dd9a05074710f9dca99099ce2d67eecaedb777b32599b5a7e4715e00d6741af20fdc2bc008415b47d0755bbf42b66ee1a3094b76693aaa2eb040872b29af0add2ee666372a1b3963968ee180229856d379007e3cd2f267d357fb1640e156756d623b28729bbcd48cfb01dd7482a464d9205f8c8c66e89dae7e4a493577534a8e44bd70cc72680db73042c285269d2dc89c252aca9a007ed760899a4c7d509622c0d7b3290ec1d1eda37a35920b94614f0b25d8b6127508e93e01678d46ae20bcb42e9d8529819e5dd09dc2a511c3fe2522372a2ed9284d5058acd91e8f86177e4b571160e28cf4eef3f630c7df09a1933ac34bc0b7046592e6b38e58162b4a78e8a8775f0e9ead97a8d2a643c970e4ab0d9f646e0435ac4104167b399cb1387a26f8ef3bd2ee18ae0677288da27f6c9258405605c7e6f3a4652bc1c972e2143ab63c1c91936f79260b71fb35f0eabb62d0315be2bbdcaee7618b3c022b9eb0dfef7563632d16a00993104574a2f072b6beb222e1dd1f701a25ec55f2b7c3c8ddce21fe092d51c7cc63ab8548b8a1899d40d013c561b0c7db147d947f0aba786fb9d39f22dcb90b79452945f8a6a6ae1da66c2c9f51613de25770a12aeafd868e3b45bda642538ae7365c23e4f361f72ce07073a1060d0ef10be0908c821cf60f9babdd5c90ded35f62b482c8c3f070a31923cdac31ec5ea6bb54c5eb65fb9342de87b4dd5f6f3a694b9c118428ba18eddcca156137a4fa10c662ffdcdb11772ee486a85070feb7240b9891a41c887b0607c6907a815fb9fa2e53473adbf8da2d23bc4142b7ba890f05ac35c5a9b30821ce9c9892bd0ef471782414936b8b1c924c5a107e8b4293c65b08db71f74f8e3cf24c2c917964e9580438a3347a40f982ad73ae589c76b31cc7d99068beb0ad3e3b33c0fdee1e1a82d4537fc9ad0af1220c87a785fb2c63b74581ead466e07d480a16e243c566b9927193b35b8884e1bc7b752f4743af117314544ce375731668bbd02aa6d2ec37ce1f90fd60b488736cec3909e7af5b23e4cffb61b0eb183af7635ece8158644a5694d9bae9ed5f3a721ce564831f7bab13b794acd26f9cbd5c56918faa9c2b3e1e724ee37e50fce1ccce86b3807c8d90d9a3bc42ba62d8b81b48febd48ac1d9b70ce701182dd6ce250932d06cf396f01bc13143a4907ea1e9fd86602357d5566bc53345bdf0f87a8988699e265d009a306a7419d4c27040475ab27a09f1f134ad8b922f8d0c2b6e95bcb31723921d736ff1e58abdbe7a4469804e296a90ebec178d69a42db265506da51837c0aefa5d4d4c45b62ee009e6539413d9126966cbccadf0de5bae57c2c8a2a7d0e44a625247670b643c8155cafc7c938c45ed27eafa5968a2ee00b07e5bce544cd3a3406d99b95b4cd827c7b527d523ce7f80d47d0b15c4078c938109911a82a6a931da74bc809d391f2b54670e178582ac125ccb210efef1a6090d8ed39d7df3f46bdf85244eb4b7d2bde2f4cf6781c937708ff2245e620e226bad2cc201b6ac74197fc54bd1ec9a1a3923b02efe80e2e9cc01703422280a5c8109a3edf58fa05c335592a85a7f4fcaf7f2e419d1d90a53beec08253dece075f047112343dbff6dd7872206117fd293eb40abef5f6a0f5924a055221f0c284d13a93529d33a30000d624a71b9cf3f34ca0b0e9c939a027ca44c8b5e6fa36b58ccb5cc6715b692bf5717ea89cf5d4ed805fb56937b8e429c81aa2a6695767a4757c6863f29b5105201cd8cdad415dbfaf9f7b52fa07ad1747d1f6d8c161619f36120c6a0618970a0f19c79bbaf62b77cc93340679804ef49fdcc6bef930e33efa591c16d7cfb2498631ec79fcc086bbda88198be9794ac2efc86dea71362aeac757117c4fa0e07a8c561e851b91e07444194a65809533f27d7a8317a96c0410946ae90a4a79b93934bccc67db4bacd9a8280d7016f1e26e2a0297a21de4d1cdd4880dbf87af4080b1c2c2d2b5a48e963c35ef5335ac7c88f84790bf7852af32e81a33cb028019e181e0d25a4e4d5cc3e38f015458b39439ad282998872e65c56bee110a0f061bf7af5f4873ac77de236a7b40abee9c9c1d6a09c9d5e0ba833a9fe74d3463e95858187070d8bdeae5c106b9229d01f9575cfd448ba8dd19e645ce07725a11b83c562b5f91ecf77b1b9baf6d6a8acbe4967e0248fae0c4022041e4fda85c42def720d508f29eada9b3111b176afb966ac05b3600ac5e1958a2a82b328d7e94189dd950f20d2c6a94a77e62ec9bdc1bc4cb866f672ac831b750cce84056bde183ebef9c6fa3fbc77e9c0e05584b0f57efd417d7f9ce36c3eeaec9136d3ea379a587dc73622785f66e8c9ee1a041fc3e8435f0335a573023df0a2d23231f56994b0106acb14542a87a7c0697e5a2d46677268bb38187fe413f570316feb768e83d5d7b8662cd45293a09976248fb3fe8c1745f543fceea296f57ec2de2ec55d9fbc58e372802b495ad34ed36111de6633498cb55cbfdbb9c80f0126c00fd7e07f85e17cdb0a06b02f170f39ce343e9d52022c5ff08fde91880ab64b37cdaaa9e81258eeeb0bd6eee1fbebd90909a9758eccd309e63ff2ddfdeadffbffbf65e387c39f287ede8bb90862bebc537814d288e9ce1dfb5f44990798fc98a460542781aeac37e726b3db7f51673a4de9ab6280ab9106b385ba7a79e1dc2a78d079a2453ca8ebfb6dd502c905fc771e5ef66c0b6e9a40219e0b5d62158857008ef5113a068fa4b2b90022b3fbbd9bb4c16b62e2d6939773fbbf4f8d0d5eae2c6e9d00a7ce6a42890cd23a587377a09e4d5735f0a48dcee117a47c962a832c841543cf7afc8ac99bcad1f8faf94b24f99a9930ab5e424078b4ecc16de61a95dc82633e12043ce89dda8faa5b81dfbf551c21767b32aad76ca2d2538c2f384f5295a8342f60faa6f1e198fe321208d4e9248ce37e9ccd40883085183af8c0a8515d113ba39024b47f0ccf03777367630a883441bda5fff01ae8e82f5493fefa93dd98849edae445c895950b7ac582d495274ec60dee36f5014ae07f937ce3f78a75f45735ce372e25b123239fc69d87b717b88a72a173c93c13fea57c332c1e1c527973b95b5842a11a9649843d3e1bf6d9a5e4d1032d2d12b3488ba53f2db8e986e31ed768b206c26f0e94a05ba970d71278e0ce2c9c0b24ebbbc4b8f30ede66e3b0f95402258a2098b98c760846886b026493788ecfe46ed1dc5704a31f2dec19adc8d1d8797b94cae154b1ac27448ff0a52dd9abdb795e9c5546e4291c6c899553dc1ad7d7469953bd814061c3957e661c2da03a247a6fe41a459369f20fc7244b85b5f20240ccd0ddf611afe3493cac63b4088ad86e6212a72193f05cc684a79e885735335bd668e7277ea7de69226b380ae27ad341067c89a8ddcce90cf9f4cb312763d022c743d9ceb7bb6443678089b5b3da26d547f44b934df6972035c85fa7327678d946652bdcfcfdac8b38374ae659120d07f05df919e82be6aee267d68093366186e27f663f77a7eae58466682f67c7b4e5b7124f26187ccc970276971e54ca54d13f399dc3f22944b06fbf97b0cfeb3df6f65d71348ff20a66be77fef5ef83faf17fdcfbdf02fdeb4a3a2c9fffd5cf50a498412f75ffd7f6410443ee5d98e4d43741c0e8b1fb2867dd9dac3b948d800c2e0d8cf7cab35e2c2bccb1ec080e8c295a2618270e0e2814c44608a31ce7dec561803be533be97aa0ae144a50859e586059e600909f514590d5196d3717522e2709862529c42e6528fb794f03572dbb6330ff3afd9f97ea499c8358607228b4a045102b73454fc70f4b4cba0d065e2d047dd0c55444530ced96166b638cfb4d7e2064b85854e55b680f3629c9c2cf47c85f8e8b6a958979c16dc7882419da1b52cedfb3158eedfab0bc6a3dfec329e9678d4a0cb1ac1419792dd4efaf6e327b753547a313470e733b89db6dd5e0f172bfde8089b34fdf8ecdabfe70b468d874fa8b6bb73bc507325cdac264df333dfc2595da45e7c9b0bf8ec202bada3953dacacd39246f185073896258bbd2b6ebcf3861db1b357fb5a1164110ee51bd6dc29ee539f039f7f9541b0ab413e6aee7e3f1face767b38f97d9ea0670fe7abf452d4eb9f14dcb8a02527eafd3cae917fe84babc18a6190d8d76bb66c5c5645847bb28057a252ae1a8d0c73035d9665af9e61a1c3ed0ebca4193af5aa13837d90144d096ab902b4d6664f4cd52ffe230482f0b64841ca6fb85658cf1369822d30a62d2c2ccecb8153281c341f79d274b2a7b3e6f4f5a0629a2b113d7481678023487a7fb4a3f173b7256d8aa28ef9f38ba07524674b8d1fc2363c374e4d5ff701f7932c44105c318145e6d70761cdb161e472546efbc09ff7c64a30eca63642fcf9257853db6f59b927cdbd84ff09ac00d81d6f640b4740d7e09ac264e50fe15957bf22ed7c8e624776f7b14391ead1f13e1b1372a62ad66967afd20d7718c0f7e1cf4a343b509b522bad5270415fb67ddcc30baf452daebc2e14e545ed0377259523410120f938aab566bf77215465c61f17bc53d9bd4021de9227e42dba3b46b398353f8b3aa16d4bfc1132ceb973b31b5e04e0af5943344337ebcc310c37fdcdec4ffc2f647f7fe5fe7f7ebfe3486d0a89fe772fde1238ffa9694a5f3f6fa11a63fc201df6338a57c55d243d48ac94ed9fd5fd79872f905a3fa52852a02d0a72326529ba24f4c60762d54c62318edca8c241da13979f811448b2934641627884d234582b7517e62933dbc1fb92cbdcae9a056b57cbc30b71d2879fc25af80221efc15be06e1c6a60d932dd472654a9f01c014cb2c63194a21e7c3adc302d6d11da2f95a226985c934c90a4900348c0624abb61f8edb6052404ba8d78d37c06bbe31c947385fd48119eb394afaea188fb41abf90b53dc3fd28c724224500983ce9c402e453d6de80d7b700b8bf95138409c3213a649a1e278a0516fa1735a4b4f3b80b6f862df7e5649627a693ecc596922ae145c5a3b24b2a3afde7eab7bf9ec6c4e78d7124438e796924f9ba1271a3735e2e2b10f54f3286b7bdfdffd256f8a4b7972a0a6703b4d47f5af3c188d29174ec446c5d395836df42497be2a380dc658390461f0545c79924da93b661f226137d729d04e4cbef522e3fd238f33d948d3f94a29160bf57aaa9a6c1bc31da9bfe26e1161ad07dc10004dad24531fc34437f6aa3fb6877459730c8168752b26ef9eab7286d58c0fa3a123fae3bd0827f8228319c696d71900eaeeb741edc68e8c327977cca6c72802816e7fd0cf8610470b7c6d4ecd7a10be063e5cec028fecb6112a1ce7e00c03494d94cf0b87e9a5d467d1cce68c037c7b0a43d24f4614bedde95a8c020d99272dc35fd848224140b13d3fa64e923fc84557860101ece66ee88473790e45936191c039ee60b78018b41c5af7ec6e10608cc97ffb68a949bbc2bce6405d05f201ac88bf872efb1142f499e325b8a300a361b0fb8ce837ecf28805574bfbc1cc24e3c4429191019e9336429296022eeb62c493884e279b5d1a13e64e51794ac8a59992671d8005ff039bcb6ad3895fa442dd22a6ccd08fcc94953abf9c7dbbfde4e467a8a54ab4cb290634a0418518a2c9ba0f7ec9c60bf9e21d86f789dc7809f9120d86b1c3dd0f93fec9263b373495f94783d47f538338ff0d36f97ff5bcade10f6d43106357a585b9e5299902d254a651dac242ac4618048d6fd73ea721fdc25a119f9d9c896ae8716c5e29fe28e647d4a3ca7c0023c3fe4340f1da8ab8161c0b4d41e997a165891fd5d0e114138d1ad9c4fc7d6eecb2096b30c95abea2064239e5f62eea314936213709beed9feab23b106c490b80ef5ce8f31d20de3e584668f73aeaa9c86689c6d8c5c098e037664f66250190c52928100b8ad250beea204dbdc4d06032c3165dce3df460520dbad73123ed27d29c69da4e4f6fc99bc8b2d5cde560179063a0adc5af0037e81b8095b4cc2e0f9e1c724ed4e6ccbe330793e5743340cec0993935b9420871102ca022116a075194616d3201c7848769b23b968c5e7e4423f1ddfa6c2c94c16364867ad155095030b89d24c1d6d3d151e92d87e9ba6ecd8a796243a349a5685f6508dd8fd340007d498e68a81d555349bab8adcdb9dff4e3c25d6c6d562d906bfce1f6ac307e00f56eb54a413c65c11d7205c04d2766c1d276c41b29c99db35dc0f445014d642d49d9bc95b5e357ea2c1802114efd2891bbd5476e8484108404d3b23972b27fee7cd166357207466018cdff7b7d3282f05fc86bfec5d1c3bf32d3f75f5a9908bc3f5ad97718da87576493ce85b537acb53757dfecad3a5919b6f3476d63c154ebb4fa69efe50efab15d2639ebcf02d67aa50682bb6aea8fe2c044f0a66cc885761ea586268a12c9ac4f1d7108a1c989a4b851304d1b5b6c0ab346b5d8b86829421779d40f9db3564e3276c90eeb48391499d58d94e7f2a7e19ca0241e47a00a55a1c1aa335432a7d0ec51cd51bb437b52cb1652472b1fadc94c759b36fbaf93210cb9846aa347039418aaf8e6be148840bd228e76b7e6e77228ce1367cbc72ea743f03b051af6ab79765614134812e89935a912d2004b330b56672b8a77247067f8e2c8fc64faaa103ea6d8bcbdc14ab9e5e28cf1ca3035a6ad6d2438bac4ddd5738c8cb80d3d165eb4383158cb1a6bee3dfd1a2a8dbc4aba852057cea6511565aeac402030d78981c4ab56b43146195aaddfb39c0692686cc70c55d0711968afc0d64abbb40c723bc05c51d63087679d2db7ede207c6e231c6277141af90e0f6692aa7488413b3fdac0d6037d124ea70400db472eeb3d06f679b06f9144305724587e6e945af9c3df70d1c93fa254a2b5cd9d6c3d2756e3823c1b1a9be83a8d104c32cee2ef8d13f2ecdb15509e5afba2c90de7d6edc12c45de7a02caea613cfe90711289ce1cba9485f80e4c658203d6f4e05ce57deda6ac3997d2c4e93de6f556546e43be18152a7933896cdd6fa138776f5e365af4c6efa9ad50a329aa41af16936c5fac84f0658c7da9a4c2c2249b8514af459c0ff694636939c0c6124919e8c0e3ff66a647b2230e914b8eb9280620874e6c0d26e8d9718971389fe61ca907b54e7e962086f6aff6d927a021f57a89fe02b5433e58e850a87ee57bd1f56a9dd5e173052168d5406d9f113088fb21dd184fc57fd7eb8b09d57fc91b4522cfedfcb62ff87b3fdbfa8870804f82740425c8d29918441a299541b0e2c9b7203c2c66f2434babb6ac3726baee448343f668e7e6c3f936c1290c35faacc9848c7d939ee3e72c6be2be376a5499831e90c92a44b8afabedf6711174ad3002376fc594f16652abf74c6e7765c0aab861f558d3ec3e1cda57ef3f5cc0927031dc15a6b92dbf0a0761b9e4dd01197b7159afd535b24248d15c7b265b57e25c8371f957d7eabba7e274acd2b2ea94c9ca996b96a9101e0ab94c788ec0612023d2aaf273f3bed089656b8bb37108f7d9a571a68fa59cc2a192881dc4b5c6d2eeb899a2c9f98a122d19471e002b1b128c22f9a990db50b10ed17bef8f4b2a96825a980f62d9c8c06e7b7f9a03393fb9a6bf20c6443f847d896fb0b279652de1051e5cade0e9c1fb84d48f4d1de6f808618ca8f0cb75ae6d5c0b8e02d87b6d7468b1f8d23af11cfb7408dbf05be5c96d69a671ab0091ee5827fb5357e40c03a8f28b0e0bc87d4cbd12ecd30aa7b1929c4c4df5ddd85fb91d80014137b48e9bc8a90b1a4b3c97452e98e97cc7fd59588cfbb747ead8617c40e973f3dd005bded879a50a67be024b579a54a067cc94a2ecb55dabc838f1ff77339675181d336f31f7cf45ea14cbdf1cddf88e775b6694f9f9b1b24172a97495c96918d53b3dc988e1e0992a772c1a28ba20651c4c787b1e60fe339eb39aaf5a2295591292b357ac2c62d146abdf4d77b5e8a7ef2372d7063f655405419fe4c96c047b7add00f37d674d3169742b1d24e39360288b541c8c304bd589de56817dbcf2b61a0822d5e724bc62ee837249e4352f312e1e55c552802b8f82f879f52800ab4b1990af6043a694c7b7aa3920037d28c97b88bc62acae647aee38da5e29cb939518f4d6340d79ef4260b3bed78379cdb47ffce02b4cd7fb0ad49785319517fd85665ffd61c5d96f92fb0edffdcfb2242ef0b49cf665df183d0dc9a02afafe3f49d80a682fa2ede8441745951e144314b033fccb8ccd27ec2e021d633620e49b912efd77bc9302537c932bf30109238f1b80d1f19ede0f45929504d1b70538c8eb2bd021598548e8d46659c04f5a82816eee900b0a40043b1a14c411f8ec4cc30f16bb4a9ee0b9744a226c45a619c7865b1af470d6e869024729c407b9ad5b88ae20025df76e12e38da85f581cc453128785ee2db5d9b4466a601112b62fa39fceb36d0dc5342e50a740f0165d80fca478db25c011122e9741cb53e4cbfcbf2f3f25295db8d0d08f0f6501f81362c3d80bae0ee18f8fa5a59f51f8eef805cf3eb8c1c63b2270d2ca242a8c64adec6a1b41b2f08417c9bd88f81289ddfc5bac3dc8caa9a5f586261756c50b5aaa20a56d38bbcbfd1059e7359130d4d7b168b825d0a4b0a57b4db99241c5a3d14ffba529ebd2d8279c7e28c0875fba9e07b3b7fe94efa9db2b91fc788e1bc7db1a3b8f3938c1548f5ae77712ca15c565d3b261773e648f2e202b6350f6d0382aea3ea5df26965fbe14e916b2c467c5eeb0374c0ac6687a125a59e1879239f0d3672013a8223679ccfeb92b47ea20ef0813d845257d5a3303ef87026e0a11d15c050f745431e9031bdc4f79b98c35cf1ea825a653cd25d1a86f73660c44454b7713ef776991bcf846b68d9b6bc8a97f54fcddb918568f1e43f7ac399bf59a3f4bf3183ee7ff55d14833345f0ab40f0bf7ca0fff999a1822084fe68601e58862216db46d100c514b3a0e0eaabd43147e1b859b51d0de249ac4016eb454e0c415ef4262ef0b11de56c6d10607e181b353845e57e04da3fc92a763360d6b49dfb1f9a0cdfb7dfa841838655a03855c5452dcb79eb9a4269b9981398be23e3c938868f32c21fec84413b796665f4ef82c36f58b4a2959f214769873b55f358a16e316487fa44bffcfc087455a61f3bc8cd8fab9d8c19454183c225f7f2176ecd94cf55cc15c3d783be0db2354ad9b9ec98f5693d13a7c257ce0249688f0114ca6532b2050562e3c60ab368f41ab15a92eb09b118f79236915be126d9b46f3a092b64bfb693433bec2e81eb58ceeef25b5acd34d30822905558f4d4efdaa66d4270fac1d4a24313b40efde2e625da3b6e3f45c279d414a21cc8137099752c93e70fbc4c467eb4fc9c2cd0b222d6a02bc3e07432281a474839b9af68c493195da2191c732c6fe0d36c1fd4cf6d79e2d4a5db516950cda0a64605a477a511506edf151b1152763b151592c55c9d09d41c14cce0056dd2586784bb27c2057779e67ee2a93350916efa41e0f3c34fd3133038f3bd82c151f2b03a1fd51f2ad57adce323b6d3d694abd63df30ff46cdd35084613a3d7ea95484ea9ec9c6ab252353fb28436acab96018e68ff75babede7fd43857ce0a60434aa2eb77ad6ef67eba24681a4f661b2e8649f048a11b5b0814fa4646e8f22b916dc34b6f5bda848c3977bf510b5bff0ea5dfaeb910e4c23465da1426fa6725be5d319a7d33d71a73fd0a2c3d27563e350a6595435fed36fbfb0681dbbd654b5b9e85dac943471b4e49a7e27e165b60e32c4eb0d9718097cb934e419650a11307b6fec9520312cd9a555ed764add9c646bee3f0551ff6d9443106d5235aef7188c421e6c17d4dbeeffd752ad51941bc8342972b0d0e0bc14c4872b9c205499d26116927373d3a59e8453ce2c20478caa009cce0e73fcfa431928d7e3258c1ad1267ba448bb0fefeb02f85a67fcec2f9fdaccd796e85614c5ffeff7be6c45ff7ca7ffce359af442f182b1a7c43effc2c5b53924e51845a505ab99fdd76766d966714c4ae159863303d57f94abd257bfcfa970164a286dac5de9c9083f71531b7201593501899350cdbeb2cb6924443bc40fd72214732d82204238f2d682aa4b2d0a27c5dc6007e679203148e820785823485dff8254f17ae289c9e6880a40ba268988e934676b625f09824e5f3da8f9fd5588216f0b8ea7a4012e7cea1092cc51292640473e68ad2e488cdce799d61d6f3a61d246192f59efe21515fd84aecbef357cbdd19c7a167a6b462352bc6f7beef3acddd2fa287ba10731d1510a09b1987b0c7a45e331f4e96814b44872922dd3bc21b4fb291b826df30c81bc0ac4c429fecd3b33913eb7abda36eaba68d6976fece1116101660a4fbc2187693ce56ce6acdd11519fbc8ed68d3dd3198036ad2b2992a2cd3f82168c856f8dda73a8adcde292db36730d1e8828abe8cb87f723347a6893c3f721da79f14bb4288060077b04e2b1b4213c223c2e62f822c9db2ec6d275cb1b0e9291f8bd1f33458c0f24b2c99bf00db93734897c594f57a45a48af01d6a1dd0925693f8191bccfbd847ede817dd5bd4831ce730a07355cf539484d5d92c8f9ed8e5c0efc7fa5cc346bdd50363e1e9839a6895b4a646ec568afee3787af1779728c7f24c349e40aa356d34293384c181650d721dafa18babe27cf36bd3b270abce9e07cb07f9a6f83687518b24b6c9d1b7cb405339a7a45bd91bee74697881d6f7a52ea3584bdb137ae56e33e22e11476ed28821d0596c51e019363fbc29b3ec98b2e1b4193ceac30ce9e1191ba7ba185e20ed89e8b956c2ea5f0617b0eb2ea2589324e4a8c7b091663e0e8d684c22d9891f09fb6e630062006ef3787aa1401aa8ba479c20dd8b90d03a6e285e5d18da55cae740268a6e03f02d1e22b2d7528559c205b642b69ec604219866f4a79a4c1c8f9d53070982fe99d4c75e283737e07a335d45386481c0879dcf13b0213cc07b1b951fdfc297c08916c3db7258064ed74b4482553d1d535bce615513df91ceaf1f41eedde188a3e3419c124fa4e7a32e78bc512b8d7d16621c1ff883e31a0d34e446b8059adf2d778ce23579a01ccce50270c3e4d639f6678b9f01ebd89840b616a68b5bdb57f1385f2dd8bc3e389be65aa0f9047ab4775d2dbe68948e59e3106e9884ca7b952ded66c57d460f5f5831eaecf06c3ded34c8bce659c018a06138ff1daf17680ec3ebbdb6b77f1aa4beae33c7e10973ddcb6d9779f3bf2fdb10452dd5d5c1630c6c788cae5b2702d31a423962fe4c5d42a6527a3e08fa65bb766853700aa85ba97264fdd8d0353d838ff4869fd530dae01ecd0068c7aba0b04e3c540a8be89866688e28ff79dbf944e86e520aad871229bdfdbc26146ecdea0a91448b112736d1c131e59adacae5d8469de450e2dc107adb8369ee8c9fecd510c98a65beba771151165f7712a261b0112f58555ffd2015679269821e01b99af4051df5e1c25d0a5af02f17d92fa5d3ec980d53f92d4bd35a57e02f80063e785081d1529358d10113a636c404494c5dec8c1aac9e4e79d607dc3d578f3eb24559a3c3deb98943746d691b1826ca99bd5a54a295c9c22c4aae4c49b0af59fc0583021d0436f5d58a733fb9a27f0169466f25f0a80bcd3efd9b804c8af446cad25c37da89d2eeb53f0bcbd7e74dcc7d4076c1da89821a220406a1a6f76005ac4e97550d35b0ab0503da0fc530136cc1d4d03f38b9d0dffddca9470e53a181f79d92b6a5f996d24f261e0c59e504e1f1116db2f43b79056b87afdcac8e7165a1c30a5e2f8bc873223f4507af0c4f4e816dca6f936d56be188143f8c5a6ec97beb1a21ea7ed54a03be05a5a572f14d44e7a8239120f757d7bc1e56507fccede6e5e688f9fac2a8636935c7b603fb59d44816dd7f9d23dd37308d89ce3babda91c79ec9cc5e71d5962e2eadd430836282e75cb823a4888aa942975fd0a00c8dc8bf3b5f27c338651d530e792a9c33bf15c82ea3c1dd3c993ea403b212bddf82dc5e06924832ea022b3db0c47a0fccdb736e1d4e96f03456beab65ec45c9e95c7cd26815ff5cada4aa366f656d0e614d2a79ae608a5bfc6de2d0dbd57f046379164ea1bbc2d221a143429462f5167c249cc8ace40415041cb9abd8e53b526afb0c730413c72735399e40a304158aca1220909b0006d17540d90fc19b1fb22e0c7389b7154fd4504929c3dc4ea011b659017ed549f9de344341f82e27819df532ce6c59eddbb280fa771822ec2bdbd2aa0db789ee79efe6b65ef995824826aec9dcd303d45fd7dc9455cbdd3713e4f72657dd0051862c66cedfc3132cac578ad443a15e71e86207cf8d3c7adfd8da66e2a905b0186b635dd2a9e069305a46d7034e1c4df660e508e7e99176da637545ff2e1e616d000278fdc4c4dd8cddd5cf2188860a1211c03a0b3f4576d2444ad67ce2c4f7ff16b3444a21d063c3ac987baea65705a71369ece165e9c845f2307634182a176f96e34c65bf19446bf30ce6cb4fbb0ef2f49c45710ae84ef6efd29a69b5a1cd233941b82b37a893fa888951a132ec4f152c18ae4c3206fe55e2463f7c22f3e88bf43ac95be5ef67cc77f7951fe6abf44dc971c96a75ced619ccb3b50ba5175cf1f76170747365d00e9e2e32f02eed301d0b8eb4dbc939c801ed9787588a72c67bc075542cf06ac1dcf4a45b8375a3f117117208ebab81d0ea8132da0027876120386a2353817ee5ae4c227592d5219975cb89cb3d358b12a979dd662f1c75047d14c86d15a1262418fc6518ee524af0b42ba3479e32a486be32f66c62f710b785d09d7a07eb59814de2c7bf4e8b3e5d0cc5a02816bdfd46e522513617efb87140dc1effdc6c2ecc29dc1f7db7c626a79f7f55a1fcfc06558e8a6d48e29c4c98c7677138007a437f0b96fcafef10a04f6d893730bb8754316ac5c3d5927dd2713a253bd119e484d1fde2ae77c132d1b7074da3251b74ff72078edb4b6bf41ee079cddd8b77c36b78d07c55f4b29771b919d422985311308ba2a4820f27ca61df5f36290b6961d813b3d1b301bd43ee04f1b04fa1c1f37808f5f68a2c3bd1e54ef139120a71b313f8cc2d60b76899e28bcefabb1625d34468a7b52dca2a967a6ad54fa5f6ac953aae068877b87312cd917b19875c92836df2043c1f9e4f08cb7d9487e4b5dd56a4a9b9c45a93f716e458bdb90b058809e68ddea912c7aa5cd9dde7c624048582b5f701d33c9de91b1467be6ee2e650fee4291561f10ea42f3de617a2dcbaf1a3a16136032cc6fcfc16c534a6667811cf3dcf9d8336cba0fa8917a9dc8313de0b5fdf1fc8ccb82b3f16a61b51cac9b6ca788e6fb397fc1accbb07b1453a989a47d0b0251730b18b0b3853e2978c4107b4c57f12dd297bd1220fbc19ef5dba7fd06ef17fe593109c366c5d12cf46440bca41b28e6fb6267f97625ed787a5de7083b39652e95d90cf1c212f554e60f1b6a3f02813c80e4cd3af284a29ddde8f982054b5da43fa997e29dcae7c7fbc1e61bfc00f3c57316b700163f5b59010fd1339ba94d3ae582087d61b629ec7e3542d818f0ddd86686cf925b31fabbb9a57edb9265062e4c7f4fa629615364cc65cf5698361f9b04e97c12d3aaf864eab976e27891147d0a47a61d3d5097e6e070cb8fe45e0e5c36e10b939eb849afee766afbb91f401c3852965074ea75f9b862fd8dfb39814839b5f56596e1a193d227ea858c7bc7b7a54f0eda1503e7f9b253adcbae12db7c117e5c653dcba468ec6e43c5efd31f3cfc6d18e271a15903dd9c4d909adfe53de9aca261d9a3e659b349e3993906bb49485ec4363c98a9b70114b14389bd5d7550b59b6c05e573335c5529c5f61aa031b36695d7d9d3a3667b96e133e1f8685a280ff0d6afbffba5281d03e30e866e42bcb2091664182e57fad2a8dbf5c710d4199b9825e15fdb0c8c3b201abc992bda17ac4fcae57ca1bea79b2a6da1ba967d7a300fc5961ff079dccfd96b11c5093fb7aee9007749483e0d9d347fd1f50ae2a00456e083d35ad860738ad762af928d67311216553be8d9a1ed6f0d8fa03e52a340c1c907d21c0bcc5c5bc914aba7c713e29546b01357f3e05006d41321b350a4d38a1961799e38edca4c74325bf5265319a8d0683f4fd6b7f69e66c7b70eb586b617cf5e79559146ee8693802101976d2c3d4448ebcc171b5b6090cef44a4df786c8dabec8149725ee5aec2b0c5973a38103227359cd422457b6a155f32d3cdbdc11ce3e4a1fb362239b20ca592d4f45cdca0f29b3d7cd48a0f0827ccbe9d7ed32d92b2a3f82c9a65793a850ed2df7a9df4170f46feed329d6d9a26d69efa3a7dbcc160d3ec529c49e647908742f43c28b8efbe401c1427214555109ad183ac3bd29d7200bf36ebc199f4f022bc59217ae2b45bebca1dfab44bf57f8eeb6a2e273bddfd20ffb63a222ad16e8080b0b03b8a757bfb0b4a27ec2f42617565658082eb95a5d7701d6e2fbea827f2d247212bd07ff6e1eac83e9c1a72f9df12e2217fa5ca752054bd0562da0f106c8ea1ca5ba3bfcf3884231609cd0e0ecba1639b92cd52342cc3c7d524b7f3ec85896f761cbd3a5a19c013b1c9e20a68247218efc0a076c4a04d695753011aae74c71f06aed685eba8c70ea0c9c9c6523c90e366075ab234b133d1279676222d0ed83cd2d5fbfdd2ff79f0b228d52421f65fe8dc3d480dfa8a05f193e90d87132a8ddebd254c69c0230cddd0f0328888201a0e005a111c6d3530ece6ff84109c07a167850339940dc9b85a433d695f8655f309f6f59750ef68b64268fae62633259c0bbb67003176d601370e5c7176c503d86ad0fc4cd5d740d3c7fbf3240bba4bc59c92f5558c46dbc1289a82fcf7523f892e2602e799ed284fb5e999244f6d24e2dc68f421f6bcefa9f155ec6c06f0f3969a17930092459eb8ef02ce050c23823302c8b466ba98b7b49caea6b479cf69fa4a18740add20b04dd50da68f21ec1d1c4e68d2a6ae56d7ba70ff0d4e29d8c0590b5ae94a75cc4005bdc147e379ecc541e9a88d8230a73218f7d017ae33d2458269b00f22fad256fa0955d58e059f7ca70d4964946fc92eae68e53147f4a1bb9fa58898c894d910126d40876a1903f36f80801c93e9f07582a169837a1770da87bfa3de65f7dded6f1feb288a4e22c6f5cf3e569c21fbe0995266ccc48a60f2afdc04c5967953d221d21247c6d9ce0a31cbc2579440f7e2feb0dd5cc268ff17509bc77bb65c66dbeecd733bed7eb594ce70b520bb680600df30d899d6b7c3f251c932314fb93a723dbc7a1b1d3ba270594d9df9fe64bb5e21453cb0b56c2c3338ddb8720897a0df753347a744f1b881a5ed77dd9ce231da6d4a7bee52d0f6ffad1cb3665d20bad1b1b8172f146f2b26b4f9b74396a59d90f687b483dda176a6558c74d6c91b4b54a9dd072b3abce8e1d9eb93d0a02e95233986807b2aa5fa8234153f76c771491265dcc196f35b78c6b28c66a18c8dd99c31a75893cdaee16cf09dd052b6ef7de35fc1877c881d71e0ee760e8e78ca1f84c3c374165d5c90fb4a310f8026c69668e6cf77c6e75d315cc4439aa07e44a127c55f28168484c7ac7d72daf49ab08bd5f008799810e487d6bb2715d31cd10fa44f759ab254858182ce1103ea5492fa8e5b2caaa15da3d6d199e88c7e137c9a300d63140062726a4f190b93849ad896b5ba0b5c3a6511411a63bd0f818201fdf1debf50eba2d525062811ec9d0b7dce1bd2593f276d61d3dc8d74ec9a47203c88f96e08e940aecc5a9be71df6b6a50d8cdd1b040038b7b217eb6f77c80fb2434c23235922141a77eb906b139d5f685efe4330d0025e94fa9c36c20f6dc8df42d523369c912853c01a27543843657cb7bdc1753faa1bbfaafb3f701237dbfb9ae5537e3abdc2e34d382f86eba85b5379c25a61020c497cf5cd4f01e0de6c1b5f7fa9570a90930114fb50b590725facef16a8102aae365e779924e2715fddcd26f92d0fb356999a506f093ac0e1580f72765930ce4d8f3bb41fe9f7391cca223415db119868334e66fed6185fe37f2e37f665ee1ffb037e9df79311ca6ffd8c71a00db93e9aff263bb4e98393fa96f5db3f52cb563f6448fd9e257a7d4d600f2a0d1b5d969543656eafad8fa0e1fcd48e98c74d9a9083b075483f666d59d5e32073c70afc611c4a570aa4a24ef5d3ac638cfa94c39c769fa432f2ba71db0a826901cb29bb130857258c62374ef8ce0f9209243547460d29d56a6070d8a5a2c2dbed333ff1ff6feb44759657b1887bfca9d7eeb75b60ca2b293fb05a0208828f3f0cb2f270c3620638ba878e77cf72755e06cf7d57b3ccf3fd93be97d8942d5aa556baeb51624930762943b0b7357aa2a9908638c99ea2c6faf24f6dd485744df60c40d7aea7fcc155f963153b7663bea23451cc3399e6c71e9128bf947ddd83d4fd3f1f2a87393c95648b6c3e9c89142d91ce6eb999006411d0e38a1375e607c337cc7199b1cc9a6e74a094b1ff10f435e398173702521d8f784d3de12126be654efbeb64c9df762530c30f4d878d274af22bd01aaf6ea811b150d33b44fa248a1bab9380c94187bdf10fbc9ca5b32fa6930928fa414a23d7a1abd17da74eb22b2a2f06b4e0bc2783a3d21a7c43c182ebd63d70361ef29fce86355280b9f63a466cbdb4dc62c897dc508ac1e9c72b3c6e58a9a29cccc9ee3a2f42199a2d72b3e16abc1c7c01d055e387025318845859249aac6a48399178a310f3147391d473cbb8c96a4641d97eb653d11f5385a0de6bdb85c0f2d192d47dc3b4f9b8e58cc5771a1bbebf038f5fb9326954e94733039fa80fb9b431c2e0b753567f29d7c4016837934913877177bf34ad4fd8f236d2fd5a2e1e88da57b53f964a14eb12d8fce987517ca46529cc500718f7bea3045912a1998b3698124d27c345830a633dbbd1f98e98057680f45b6729cae0b623eae795e1f5ae978e09151e6ac32678354dba2a7e581545bbe79381071e36df0596f46fb8738364223d96cc771a118045d8eb7fb1557451339aeb71ce7f72789b7df8abd632c8676268fbd777d79d2fd0952cec7fa7cb196deb51c3bd974b345326b4bac89c8a5dcd3ce5f6cfc86e995843a4771bfa91527dd38236d4cc73dc51cd4a98acf38264d34b4c86a3d1f90c30d170ff94114fbc870b259e16c73183166606f32d79d2863525cb146cfa81b713ceb6d153def2d9464a9ee5c22983598dd73c94871a499b2999ab4cc14b570f4d1159f8c7dbdc61834a35751dfdf78c1605485c758e149249244ef387a2f6747b1f9e093c0283183c6397483aefcd102f176456a8659f631cc13e75d161708555609b55def4671d41f56da8a3f719977d82e6801ef6fea8fb04c8e78b93e8cde8f33bb38da47ddc71dc5a8c7663e1c6fb84299e52ac7a5d4c6343fb88cb251bba79df6a5e16cb1deba4fa83dba62f041b8ecadc52db5eceb2771989e0cff187e7806399a6bca5654b623379eec495d0e93fd299c62f6e91d5951199ecd3547f02d6cb99f85c1b88f6c2aa6c68ae664ee9af596500bdfdf3b8786ad8e497fbadb647631c2474c8e1ea9da9c8ec72e4bc40b6f36d6bdde221f47fd1e6ee9d3c33ca0386c1a58fde5d275fba3495f582ff2ca63776b05d76d3243f535d157c698b9a14f7d466466a325818aa42b63fd7455f0485a847be6b89b1bf972be290758f87ecc3d6fd24756d49e5c1dd6a343c82114b624845c186c9666a68fec41e355698a4bd1699762cc31218af9788ff88ab81b8bd6d41ca80de5542342fcd82ecdd326ef0dfda1d7d3eb6c9e4b33b1da7a9e4a25fc18595ae3de5a59e102d7dbf8bd69b64bd1d966b11a2da5636f6620fe7193fb8182073d8c8836e3096238a7a21e1824b5ef53a19b7bcb8516d00787f950aa811f56132a9424633425d15a716674c50bfdded4640e3e43e28c3198dbe9693fa3ddd198ec2d7a1e3e21f9a3a5d0b3fe28569ac5a2d2703c76aae308b7430db72377551ce3081b1c8f39db4fd17a65fbd34d240cc7521246b3d025c229ca857364701acfd96c7d50736e597c4c7a937289f42a62b1e1c4c5e9749c18e5c76e26ee8853a85645bf494727d923566e3cf2f7d1aa371f4cf943a33243af1615cc36e5d9cc13074effd8e3d7737590fb3b7d5c2af3d17bcdfb05bfeaa71fdb639eaefa7d5fd2a6a35eee35c2bcc7a0cbc876defdf09d36667ccc7ef454769792b42499ebfac09e563bb3574e86477d81544ba6d9b176bfef841fd5840c0eb5d37797533a9d31ea361a6fd6b6c98f0f3b6ec22d27279f97ab8dc5eee3b4d9f979366c6aa3b458c197f295a51459519c229aaceab1dd04a76a7aa8e593e1abfb3a6785a05a1f87d6f4743006a2bfabd7632e2f879632114de2301f18b1beff089b65420847da5d692b836111df99e6295bef0795f5912a3d6d94f6237721ef4728d2cbb1f4f481188132f4d472aea627825aced41dbf7556e16efd3199991feeb41785bd8f414ec6a3e59288242630c84c0d48c38ec8d53c360e591862549a4d69099d897b493657efb8b146199331e861d20bf31d2953f4cc29e77d65e579f56a17bddbef51a9d6649218b8afaefa04e1a6c67c14d7c151ddebc2263798e6e330694c334d7d3d26143cec4db0b1d5b372eaa0275b9ba2abb019a1bd0235862bcb97ac23eb9db6ca3b77484f3b6996d9faea8086fd8f05ea5ab5baacf65639c5b6bdddec303fe8726f62f4067852ad97f9c7472da5e6c79619a94c9f500cf2e314794640997bc4ca86c27c28f4d2e18734d24ab3743f04d61bbb781508739567dffbc5ec18f495d6768b99592e2f2b8ea2e8e1f47bb6dbf00fdb6e7a97ef7b7ddfa576a977259c7aaed734959abd928a1873246fe3bdb961756b1acd6525210a774def5dd5db25358661e651ebc7dad0eb2de713212ee9e9de72669839ae463512d9b665e10e36da1d47a32d7c971cd1eb2df29036ab799f3a6e25771757b6b76765c32c9077869546de3bcbc968e4360183b2e4f123de0bdcdef036ce26db67d87c64af77a88e70946dc5ef337c220d3887c5c891c736a6c75b1b6ae3380592e6eba57972ea8f594aba6ee0acc3fd903635ac41c505d3f8cbf1285da2218b91a2a4e6aea4163c8107da4e929d3e9fa609c39df4a6e117ab836390ccb2b2f928da514bc44bf3b13e9fb3539f0d57c7389eef0bd9a163f524f47037df33eb2ac7270c2f9f8240c499a8518960241ee3c3c7a93c9e7a5a5f39ce636e58f07513b2361d89c26c3763a265aa2a8696cd3d7f9e91c35ad3fc6dc16f27e23288637c32a58d9ae58e753c467061cd210cc32e5573385a8b499de5dcc9abd6dbe364b23cf9cb418123c30d9dfae9fb76b1181cf2759224f1613988629d8d0f8d528dd6215f4c932698e8f8e803d92582ed949b6619899bf51c4db1d97632e58627272d63dc609428b159491c5575a093755d2fb6fcdc580c9c63e350a516eb1bdc5de6596e8e9ced345ff3ac45e731b1e708c3dc1811568a86a558b82f90b6fedef8d36898130c1150fd605e32c6d067aca57c34b6e38ad7f75eeab8643c9b2c59666f9ac6712205ebcc1b529b3a11944d365c78242985bca57d28466160ab42298e437536d47654a2aef5a319065a84d29a838455be9c0eccb1dd5b0bc986e4f141cd2cf801654759181404fe81eea89ad8ab836851adad6a3569866acfeef1249d8c0fd57119ac7cd1df928ab5a18f9bd01c11e13158e6b6471e479bfa80f5fdbe74aab978b93e50ea31af64becc39f6245894c7bee39ab81f894193cdf375cfb0d7ac92720ed2bc2bcb214d0ba7cd3b1d8816bd4d27beb59e9684b64b8e59b35e2536a790eb602df34b2c1053213df89c506f0b7fd33f0ec2e148cdd19e1d119bc35037d693d962319aaf862b86927bf97a89e10b7d87d51ed62cd2619f6a65ca60824432e9c312b66fe613f3bf45a6f819f9e1fc8e7757960e2b698d404f79ef7d1a2ad3fe540882b514edf9a9a04d4ea3448d320d93d38315eda35c2816a705e92ac5a28f942b211a8da9f741618f7bd471cb6896b3dac923dc48dfd7a5969be47e83f5a9c9863935bcc9d0c1bc371cf2911684d251d96c76c791b89edbbb75c522355a04fe7a5d99fc56d9cf0fa52fc8ca0ac336629c16dbe9ae8a07b1866dc89d4f121e16233dd6dfc8353b5576737f6acdd15e8844382a9062bc9c957261ea2a5309efa3f7623499f5d22d42c58e8e8d0bed60e3f2629bafe23c3925d315e3bceffbd1a9cabcd5666c3ba57fd4dd8f58a48d8fd1fbfec8c683d08ec63bac4636abd366bab1799499557d9df5ab68da0c6603c11c28f3d50c236c4dcf46dc7a101143d335b6cc2645d574809cc2a3206dfde10e29064e252dbcc69dec352acb8f09d61f6af270a06ac7dc76b54a8e388b1bab4d8aa04834ea2755b29a59c4b6c7d90d1f122139982504876624466f9080f03f30051dbf5342a9af3d714e577633dd7999e81cabad6ecff4f468ac8f52b1f016a7c8b2ac9e2de3eb5e21a6ab9df0417bd570d323f22208bda17d1c90cd9412ea61ba1d1d5148a72344d8458390a6280aa5be57d33dfb0d74aaad2d09714c14d0ebc1b104c4358dd337de239626fe6ec99da67ab4272772c433a24337e5605f8a1f99be11cbf8a01b4c6cc4a12fb0aab326175abcae9dcade6c8e4b7dd7145b81b6c7323d9e0f948491eb84e70353f4fbabfeec7d6fbf1ffbfbd961323eb0038719285a69a1d671c17b9552cf19fdbdde28cef1246d51aaceb1b2c8a3315b6ccd13a326237b2e1fa7527d12e35d5164bb2a1e6e9879d437871e82b0f16e3559f406085faa0b47b524662ec9debb3e3f6e6dc75764569ca3d134f6187718f767037b826aa7299fb193ed3c194fdf5d36cdaade5cd1966aeca11a3922f365a356bdfeb119f552c39bab7386dea3ca7e8d6754884f85d99e2c1a33b148fba07dd0cb420bde07e1926ba69359ea1e64235a56c5d2ab1c5dded72e3f45faa2383f86193e91edde62bc400663fdb4fd4831891b09275c240ec35dbf31915e3345700d5f0ac7a53299644ab193476e7624f7d1a22cfa6a6f118fb796fcf1ceaf48ca55b72eb31a8d77aee9ad1d5723edfdfb969c1081cd31c3c835c71f73493d7a759fafaa15a145799f1b86c7fa54d38cb7c65733718bd231362eb6ba4f2eaa715df644af7643b3bf2c92c1420d36a2318adafa8c2dee7d544502e834ebe894a622997af10ef4ebfbcba9e4c9706bf3d251d6984e77aa4e70224a8b94ccebd485e6298a9769b10890e3071cad0273eacf39a8f09d2d926228b4a8a74b252625592704253134832124257d356ef76c781965f5342eb3a01fc63df396ac1ea60c0b6181b5d1d4b5369abf3cce3df36b4cc914a5e9862eaba8a025f6a556da35c775c0b15bdb12cad7787882377f82775e7d066fe93504629bbbc8cf92f39cbb9bfaec97ebd14485a2b5025c11e07fd2b3ed0db7fba7eb39e7035bd77c609f2377624e371e4ea77eae948e257d0ba7f43308ef00062803bf8737f1690869c13ce5307f6f2ce5692c6a30f9341ffa7b633a4f434ec79f8f799363ddf1e1e42e5f5b12edfec26180dd635305454d16f7638b329d518befd4f0331e4622f03ddd162dd9665aebb812f9b992fa67bfe9bcbee39dce4247d3653c05974b7d425154f3b07f08a555c277d6a77046665b46154c957d80119587b18963f1c942fd6afe89c8a1e33923f3143583b532dad3fc2e22fe91f9753c3d059cb1bbb3ff5040db11215b06e272461d70e9c6b694fdd7b8a22792adae7c205439dba628f0e11157fef20fc0dae9f433af2dee7a3b44b3193edd8279261bf0fff903bfefa829cb1dbe616f20df9f9370598f260f2b8a62f8d981a2e6d4d39c8bd9776c1c24ad7d5c893ceef8137a64a642b3dff401297008a0c7f419c783ea3b38d63832776eea175ef21fcd1efc111a30078a6a8e214531e327fedba883eff09f04d79c9ee717200f7e3df7717f42b211d03901e0f1c9e0696ee5547c676ed9b69442b6a49363a2b1c7198d303dee6d8cad142e3d0533a1b473e3eefda12fe1e183f19c18f7e90345e1e180a298c3133cdee6f0bbe0f972de59c5d80c5e40c3fa9050d4c47e9a9746e4efccfbd2865639b6767e4e77434a2323286b9950a028eaf4447786f42d39689ce149a4bd9739a5831b8d6dddbe47fa35aff516ebcdd29902bd534d0f1425868fbcc62e34f91bbc865e68905d73c6267825d7bed67101f5f8df2435bf5d47f45ace1f1c96c5fa40ceb3e07f54ff09bfb6f3fd39103686bace94909ffb48aff1edd67ea87c0ca61435590241a33ec9d3d9c1fc0ebe5bff8db67309f1337613b07776d3432c53da7bb993fe5c2f4f469ee6ea0694833ef3125f8af1fed7bce7fc35be565afc9e4e0f34453123a0f9a4c313be4cfbf7d6797f1b2fd4c33b23dbdc807b3a0ae23feb3dcb2fe5d5e3bbdda6c993bcea65fe9ff52eb72fdee3f47a9f1edf3b253fd135b776bf63277c5d8f4f3b60af922e369f2fbe8469446b439c84fa1c9624aa4fb28d0bbdf0ef78f7d56bf806736da434b05fdf1ee821837aa26dd4ffe3f04d6c4b4a559338392671722da50c324303fad9cb82973dfb5ed2df638f62d853e59efe0a4bffc3f4a77ea796fc358fce4377bbcfe065323bbfd7ec8e47cd88fce37d60d0d2c72580bb338cb49f05df808f1921138cfb80ef10f1017ce2137cd6c79fd7a7266171db12d2d7fdd35ed3a37a989bec1801f408795879e6e120fce33cfc65bfc897b4477d846930d781cd5aca0b8a9a3edb6a38708dfed29e73af71c67ec83682dbe03203fef4b3dc9ba5f19fd763b3e35bff4b981e7ba5a8cf3a731eff79fbf8db65c96a87e8835505f613feefb185a028d387e25bfecf97fbf95bf6513b9d3e101fd83c1303cab8673fd74fbe6f977d8633c3cbbef34e9f4ff6f52187517ad217ec3afdc3b4f6a50ce3f975400d0f3645cd0af9a51d64cdd3df60b3c3399de9bd2cfbda0ea2485e5f59eda54e5193e28976f6c36ff98b90763afc270f34b4fa8e6dfa7836a33eedc7acb7fd3e9ffdee33c397789a93d8703b17007b09219099fe139efae2f4fb787a15cffa1e6c2cddda5d7b8a195374c453d4eaa3f373ffefff7dfbf156badb75be7bfbf5ffbdad92f0edd7b7b71f6f929badc1a7fffce7c75b92bbbb78bffe2558effb49feaf32adc338ffd77b9dfbbff677ebac4cddddbaea7fd4ee36a9ab7eb4db95fd5fb27dde3f6cddb25c6ffb99bb5fe7ffeaae7e29b745b9deeee27505268cf3f702fc1bac776e9cc2aff276ea4f9ffaf156c5a7f5dbaf183afef19615c1faedd70186c08fffdec5f0590cc1d07fa1d8bf90b18692bfe2835f07835fc6d86888a1036cfc2f84f81541de7ebcc5d5bf8378fbf6ebbb9b56eb1f6f5503a79facf76fbf0e07044afc78e3f3e2ed57141d23a3d17880ff7893d2384fde7e457fbc2de0bc388e8ec73fdef43878fb154510f4c71b77fd68fdfbdfa51b206fbf223fde94008c8afc7853afa0d369d22e648090437059f849f5f6ebf8c71bb58b33008abaf6df7e4581058d22289cbf02df1063021920048efde7c7dbe2c5adc87870bef5b2e8fffc7863be7fabf5ef7fd7795dad83b75fff07f981fc40fef73f8010a2f516620820edad1f15d9babf59e7499c57fd43b14daad2f5d77d3fee7704f3af3c0ea35ddafccb8fff754f37973b2a370fbce2f84056fda0f0c13ef359596c772b7717dd1165f7eba4f0dbaf35771bae77ed67a528ba4f0b77e7476fbfe6759afe7853776ebabeec34bc52d66e55e4edbd5cc1c62920c8f6ee76decbe5645d5e3e6beb6af77037f8eae1894511d460befff7d601ff390b4148e3fcedd7ddb65efff8eb710b57bb2882bf7807c3e297ac08e064c67a5bc510d3e82fe8104a941262e52c6ebe444eb7e77f4cd0fce7c75be0eedcb75fdf9c87c8a86109d5ca8c9060469f96f118789107af213a0d419ca572dd6a90568b2e62f2b576bd6818b47b7e7c123776bdb84af7ddf9946fd10c3071b3d8d9595a8b7959fa5479d146bf13a6d26bc82f4e13c70771a3d7d2e5f411bd6a3f8daa257580895919f961f1d76804654a4d16d35fb2e06ba97fbded2ce6512879ff0e398f6038828cf1c19f27e75bd8ff11f4ff08fa7f04fd1f14f457c17015e67c437381496cda3461fa7036df99b0b41cf3b8f13034e567ca9e9fa5fbc0e2432f33709e6551db12b681b5089ddca86d1cba19a13f13f66e666c02663a6752a570ad45e863eccee78e293fa31b0f2b531b97431b98d81c5b7af922b455fae49a44ee71faed58439ea3b30b5cf9a256aebfd537f7157393aa985c291cf5e6fe98fe082c09e167421acc8c06cce35aca89e7d8c6c18d9d631288181673be59841a476e6cf3103a5694da78abd098048d5c4c0f7ddc681c95465c8e45788e9edb9613f193e99167a5a98a5121589f6b12a780632b8f331230a6c18d431fa60fc8217089812bc173ed91a2374b423f376a9ea36a1143312ff743df32223fdba1fea94c1ccb09c5b0d45d4e07386a5d398606e337c16c11ba3305f119fae45802e6587c08dc5e9e63d180030a4929cf7304188b00a5ea3774e6e17c686351e46501b8de3b317df270a3b1313847e2a883b96adaa18f91a89f4929cf497b07ce7f7906716faef959507adc21b4331deeb7cfb1b96d29a9c3d088d7d04d601235d84f7e26a57eeea47e3c08554b0e6df378f21a1ab85db5dfd089630aa88305a597f9a1cf914dc0d0a1a45107c9a4e63e360e1dce880333c8e13a31b6e63921e5391609a0e236129e4b339e2352c704730f00bdedf999807a318d3860efbfc079c019a780a36a262c367c43b7f8e61cd4cba4909f4a0b552ee6aa25e77e43378e09ddc3d4cb2e6b3c39603d53c7d012e95d4f8c996a48ba9ea621cf197590a58d871190c6f89913f9591ad9d93115c332b439fae47246e531f4c9c685d29fc9731ecc61d1956d4a293f1becc54c887c2c6aec868ed72a4d80bde26752e198c78a9f091b9e734a8fd3ef9fe394bd8ded523f268001f3e16151ed7024dcab800bc3b549a27e0cd612943eae346bb94cd7337a0f6854498da58c92aaa207828e2aaaa9a18987495bc7e26bd71cefdd8c2cbc4cd93b7299da58b4e719e1b73fabf2e16a3308dfe3716d67ecc905eba0003ea839132fc01e308199560e97d6ce01f05054fa0dbd398776784e405df398f80dbd929124744d3472303d7432b2e1678fbc3f9833191dda179c491b3f4b0f0155c27bce63f10c8c813cff35740c6161e80fdbe2e750d65cbea376a2d93eef4059c822aee5a43cb308eddc283d4ebe7ec709a597b100d7b7eb54cffcc1403e4f4f80dfba631648a7677eebe6ad3c4c8a3cee48f05c5af3dcf42a3b33a36172e3d4f21ac441e9996ceea8f4c6cf8c28803cc2c61eee7c4a7bdd1c4d600ee63647872d3f2c4285330e1e4712afe1544e1719d0adb9dd2325f5b9e37eaddec0dfe905d72400df6cbc19e03ba3017212cce763510ac6f131a9712d1a6132c0830bc0fb707e88d7566e207e96c29414ffbc17b7f43385bc0b6537c05390919b2e6d60ce24ca9ee7887dc0005928e480770320a33103c874434f8ee12d9fb6ba0ee2b3f17003715428335b3ee4aef38035982689f25c90064cbb663f23d100c8923c01b459791c89c3fdb9ee71fd356da6b5938deff6c2460d55a33ec1576aa8da042d829972004e8e0775d9b1f07009596ec2c37242ed994c42fdec108a961d0ab31d582fc9b38739cf503b95a16218ee02728b41f5b545a74be8d01c812e69d78995270f1bc4e7671c868ad7e821f64ce3e4636cee18877819d33e1fcb4580457bdb44cbb97188df8d43cc83354c49b5851389a1fe9a147b116b65b3cb91a760520c1693f0209ec89d634927db0cd2957a3396cacf6ddc683c86da053195ac013e664808f148411dbee1a7916eb074e9c87f044fc059a45ee0897e0d97fce7acadd5e9776bebf6ff2f0a2b66fbfcf093a821b8e3e23a22c890bcf88e24fed7fb8ec42bdf111ba2bfc7776c81ffc479c406ff788fff788fff788fdff41ea158b8751ca77b1879c3a5828917a1a822bbbffc0f0a5da09c8cdac78ce44659d35d442fd431320b6641e4677aa86424ea654ad41a8654211b12375769f05deac7f4decba021bdf7637ae7e102747ebc5c695c53004e1570dcbab9f4d03683c6315be7d16f0621cf4aa9d3193b5a42eaaa2eb137c679e25af01d3b71d03a47b86b29058015388d014636eed9393395c485c60a11790c5d7a99b3f733b4851928d099903a18db40e3181851384d0063c89dc9a18707b5630927974b0f624c850617a5fc94d59498ae5c534abd5cea1c3860c05d6003c618e1e17a189804346483f6b92ef24a2fcecf8a0c6dc2f1816135e1eb054315e05eb0df7c72c14d3cd72ae864f01c1aad55baf670390c2ce0d0b4eb75b2b472543a6df3e5e4d03507d0c1858686496c1cb0af9db3d2c27219bbe619da01b07a264bf01c1943e337a623b057fe2c093dcc7e7c26b42d79ce1f8a0d34e839a8d8876243e201eed797887306cf0c6ff0442ec01e6aa9c48a1a5f2fa86203d6699844059437d807df324a3f0386b540f0dcc5508a3d4e0f3d8ec57948336cee67c6d95904b0e27e9622c0101429b04e69efe40acc6be139053a642dbd017a366a8733ce4ecd651f78b87f0ff772c0d865eb762f588d9fa61a1fd38c6c4882de1c42034975754a1a06435bb221a8b24ee8aa6e68c068e1a7d24a4b14c198a62b2d5d841a6287b24e38602c1549970a73081d33455c000b670c7cb0767c11027a754df4e0712970baef79804b378e499c803306ee3bd3898fd3a98da5996b2e008e6a07375ae70d2331c712ba60019dfa599793841127b02e8701348c9601d71aa23ed8cf4ff023023e61fe06f9a322f3bf57d6b527133c2b21b625203c6b1cf8a910059c545c9d87964ef5cc380666da38a61c2a3a6142a7265f0cbf8217d20e43cf65c3a12d245a69ba1e8a6aeb74768134e0fc44fcb49caa0d5dc06020a0c3b09df39cff619b87db39e77c437dbe26860a354d7857a7a4a4a8d4ae0bd474ce1b990119d29ec60427e0109d6b1f1ce67e7e388ece9a8a4ebc6b28adeb0db5e367f05d663bc752523f5f843ec79e1ef4441bc4631d899f0585630ea0d3edc1f71cd26d1d423736cfd0a998f9357c9653523b37f2cb7e7029e26346e5c40728e75a3cb60104e8584e51da488ca58590b2c12e48d188da805743edcc99807a59990438350c6642e4e5d2c1c30564652a88854b30901330c773908f5cabc753604907c72492959554405ff89971f24fc86031a10edd1e4ab2e1b05a4a6a2a92ca162a4c7806099dec1839adbc07faa8757001be4d0506de80ec6c4fb988c66ee8cc358f29e4b3bf8b97b234e3d92a14ad22e463e5790d311df0930aca122f2c8033563a31edf10c9af10c9906dc627f03ffedbd702fc498da3b96b2399ff0f9d9028c91b9f2e3587cd2d2e3b8be8ec787964a8d20dd988379bbbf030027af21282b9e4f137361c383f938a764c2b21dbba1577a439f7cced8b8a653da0d7d0a2c1aee33d0d302e093987ef72ce314b0e336980ae806d29a518235f8318df8b991b63ac589bc199073e5666d06b86b0e4827632b1fd3474ca6447e1e94de06cd6cf37872b46aee9969ede0fef99eb98db12747a5627b66d4b689a63603e43858133d31f5c052f5c1c75ca52f6307330175546ab43c14213f45052d09ac799c84e771e1ef5a3562622a5438b609b0b406bf3bdde795a53481a977385b8406b0051812f5717eef71690c83ed0df90178d1c2a2bd67eaa16bda21b876cd631b3065e83dc4431e943e0cf6b195c7d0b16d4a5b8827865cb8a6d0d8964088481905d974af72e4ce918b73204f73c0b8c0c19e2d80fe4f1cb05f1c7980f50d603f60ae1ab913b16369e742e4e7f0d47723e26c04fe16da145f30e4bb0beda4b07667cacea3daf101bc6643edd631150bd3923612b693697c6869f77478436b039ee1f781253570cecc1838e662ef662c661b642bdf623a58429bcda8017ecf72c5b122483ffced5c1a12db5fe2d508f92b0c29a0a1ef8c2922577ca8003695e4216cd7b1009db7636449bbcf936ac464c6c936178f7c7dab5f629e45c2dbf59df1e85f783548bd5cd97b0dda38e631b501ed3c3cf3a0b3489b83fbbfb331b276b23407f2cbcd8554345b1c8067009ce0ef51e62c5212f2f383ac01740b6d6f1f23ab2003f65d5abb38d0a554b260e89d6d25906f6d15d829444b939dee12f045e89e6991a555e584c4c2848a9976dcd0ebecc3ce2edfb7c1f923d0b998a3d2a7b589c2317dc07fb3a0007219c26c860066594ffc331e13efd0ee83375b9036773cf10c5a390c150b60de46083b7cc1f156269dae677403e49d375bc4fca4088566f0216a83d062c27a9e1e4a8109cecf009abdde0fd6dff0e132a672b1197c080dd5e319c053f6decb8dca9b3cd13c8093e463a5c54ff7bd036494fc704f06f493006513984b6785199f517b813b965e56c51d3c2dcd710af4dbc0773e066435f09f78d29ed1b80303c237f68586860e97361eb009d42b4ec466505ff6c264b78e4a970143678179acd62a7d0c4cb60272db316520232f34b232e90dc4ed14692ef4ccd8197f33b78dc9608f4e403738c0568979c01f1b1ee8026e0c6461ab7b351ef829e1cd582d7dc60be0b736fc54221c3c28bd18d8e2c42900fec28c8e022e6a0f3255e85b185a92da908680cfc8d0715bc701fc558208b808ce057d4e8e4481dfe35065e9c45462e3690e64f51dcd431a1b3cf3056367dd1edce1626d06071bf8b50cb20b4ca25c3fe0c6a6eec67c9203426cb7b2e34efea02180cd07763f43ed44cba85d2b7c7afe61ec893665351da569631a3e8c2d2d6443d2f429abab93c7b1013ec3505451d4cb52209b131939d23a2ac9b2a1f07c463dec095a7a59808b4096e6120af00cc79a2dc2d69f4b6b9e3596aa11c2c329cf64119e1352f0d951e9c8cb814f056dcd12f8e51e6ec0c34c28931865077ca1a0b9b539a0cea8015c579b19da2599d0f1d395d6812e889ee873d9d08700934b9be1efc65313d6948d977b7c275bf98c2a3a9abec3ffedb82fe4eae35edfae09ea27a53b70b74da17200ec50ce49050f6539bbe9e03deb4d0833d4933ad099121a70d0ef3eef75c8abe03e01ea341f1e4828cff3188756e6a187c24407a1a596fe5c0d423ea6489e116aaf79a1bbe12130dbc9bff03857e1dec118c7adbdc273ec899f49886d12896d09ad7fce4a7b8f631bc07f0b8d3aeb2e389e06c63ba1618045a58d85a19f199103e5ddee56fe7a3c330d6de883f300afd7673b596c319167c57400653746852b958abd6cfc8073ea62b3085c672fc68fb62d9c13e20cda51604f80fcca8808d867d64bfc1b3e9f51f1ad4df1628f807cdf38cc754fe0f8602fceb293a1763a47b57690b9b88ec719d07e7d84ef997684d4363b3d03ec79f6100b2d1d9deb78e11e598c10beb261fef0badbb9a08d74ab63dbe7a07d7ba13b31063447c6ae39c86dea32ff3dcfdde249e5e75fda6b7776185853eb83bcb04f279a2e7f6a7f792fecd81776d7ad1d7b274344ac6c1c953cb94c6b7f3edb53700d1b7e9a329a1a9cba98c2de8b691ac84be047fbc04f023e7116a4b7718173220b8cf37177fb70baecc1758de483fcd9435b10970a118376e2d99eb8b787bf781ec6b9ef9fed6c911bfabc7d3ea371974b376e47579d2c7bdc9be80e8fba2429cca3cf499f932e583f17f6fea608efe436b41fe1e176e2984ee9c1d8a4b4f77321b571a55aab83989f0cb205f44f5bfb838fa9d080c93f6ced652472c5a71eded1c9f5b9816bc9e1e273babad54baf60b7ec2eceb78cef634d8e4960ae25ecbd0c4dbd5c0e838c6d5cb38da7029909e19b4969c00c622683fe75a7e783959e1ca73a4a2e64c358ca48c4ea1b74efc39a323271cc280aac45ed73c7743d334ee73a8e00231b8f534e62768c029300bab71193eb6778e83e531a60bbf96dec1cd8a500977b3f4f421f077ead84405b8c731a0f436012948d1927bfa1710f17b6303e95199b80239bb50a632f6d5ca5ab3de167c2dec361e24f066b6d99fb39022c05b649ed594ecdcf24d4ceeec6eb126388936b2a298c45df26d665c0cfbf1b6fee6469edb05dc6724ac6c09f0236f19c49c2f5e12e0e3204b4b800fb0868fb56379c69276deda56e5f0e8e29954e969e63dd19f093ad2ed6626142e46306b0cde38bdeb314d4cf06e1423ec74bc0bf97fb483e968f503ecf82c7eb8b0fc4c70a0ee0e7632a5aa9c017f15bbae394fd838c4ac07a020cdae07b314331efa54ca22f3859a9edd857b92e007dbbbde3f9d626807b6d5bc23e80c92fd0879bcb8941eb0c32586a0b9c672220db340f3b467e969ef8c9f420a2d2c1b684cd5cbe8f21409b6db68373bfbf8e1fc0df2efe478b9fbd180f3a3b4c095fc0987a99dc9e8f6064e3626ce3e146ed50571feacaa37cb2beec9740f26149425ee0a4bd974951c019b56d29801f228f3b405fd801fc89d9c0ff85f4cd64ddbd2c09f470ea3761c9cfaaa738dbe2c5fa1c532abc868a052642fc98daf90d955bdc20e7193f141a6adc3d575ee26c3932671281d611e35d99a6eacafc94f6423e960b7f16247355081f6c54463624d64214418f1f603acb3cad3adbff1b9868f277ff1d8a0d3f350600ff3e06e3f180cf228f3bee83868e024bd9031fc335cf4962d7fe44378961cfd50a5919f9319df919b93bc7b4457896a234b67998b7499140b7b03089c96f68d4c7a0df02cf7abaca88f05a19017dd14bf2707be6c822ad6c8a4a3b4b119e930ac794b66d42545a5f12e4543ab12d2512db84a7ffc6dffc2606150bd32b5d890db10bb2bb3ac24f70f94cd3dd98b130454d2d0dde8dc450e584d4809e5ca95d6cf7858d7ee685f6ec5a0e5bb9755b67f9d473ae7633b6b9c457b2647e1b63f9a370c818897a9c520bb81c425dd2e9a6db3ad8e74a19e2c3b6f8ea891eb914e199412dc69d4d0b78f95e66b7beaee12c0d945415835e1986b0781913e5cac84f8dc69b2097b5e989216ba8a16acc9f54c97381f3de0f01f8861546aa0093cafc53b1177121f5b9f3f9c1e0f19cb99d67c3ef5d73bcffaa7fe08219a0e2c67e0133d2c10c711b3fca7be04702bb49d51d6da502ddd9fa993cb74bd72a8dd9e61175b42a74b8f1651de7730101de03cf04c2f9ecd203c9f0b3437987e79913793323e5375568031bd3acc2e5a9baf14fa4c8eee2910e47d68edaca6e396135c520a7aa71d6c35fd3b37f5b9fdb9cf7a095dd7cac4846425816eab07a22ac7404f85648d89e59bca293ce76491e6911da6f439e01be165ceb334e2ffda8000ea0ed43deeb8df1777921bed2f935f6f604eb15f773db12602fb0c738db357615945ea6ec037c016da2333ed58c6d74788f706b135c717893702c5ac03608d280f9592cf70fe0bf3b7be87c010eda20c09ec18c4e165c744bfbdddd9c67f940bd3873e9e49921b17a42d0e798e2fbecf0748f7ef119e4977191f35f870b183b8034cff0a1a88f3fc12f7f1b97783a5be9f613261c8b6a9b7c2a5ac6c9b178f205ec37f7d0918f4bc0be4c56ea19d734ada392a5a1c2b48b2b40f9c3c7d44e6ba03df84437aff148a7de0b1ae8126cff6e1ad804600df734d07ef75fa48173b2b1f7195ee307fa30ed9fd301d72561ab28ea6346c33367fc199a62084b5947d965fc6aaf51689bbf9043f1231d388f387b79def2e7eda16d1eab568e0a918d5530a93ee8ce36da33c336efc0c383dae3c8c8b9e7979bd8db257e36813d3b4ec8cf6cb0c77e91d3cb1c9d3d768dd35c8a3a380fe743b993bb22439f809f0de3ae5dfc1ec06f001a6cedddccc3859d6d019fdac8606e20ccdb20daf394364e79bb9eafe5fa4d8c5186bd3816a4cd4984835fce1faee7281718a8730cb3c5cbe52c8fba3f77bd3f5f4eaf71c736e6f1d979f21d2da8547b3ef687f0fe8df9ee60bdd879a662088c864a2c8cc3cf60eec00b1ff8699cb3ef1a8a2a0dfbf6b8e611ee8fd6e670586799ad7024ee6530efa5d3c74e7467873efe3dc89c9bbf0d3f95f69e45971e77f5873a7a6f7bce1c5ec33b7f8a970aa517b7b152bb81b1fd5bfa88e7f2e3380f3cf362dfbfb4b390d6cebaf6d87cd5cb76f1a56c6cff16a17ecd996a8b7d6ef1fbc97efd5e3fe4f1efec97f00c720bc777644228c6839aff04be7b7ebafd0b1fe29c3076df9e55a840fe4b079e79e495afe181b4dfe5aee9acb052136362b4bc07f6eee77b7fd5e7e798f27fcd77e61b9a3dc7991c2b42607f3e93acff8b3193f9f59ca4cbc3436955434a56465bdb1dc68c546574de03c837ba22e89b62776fdf0be43966f45bf46547a35fed318c2bdde52f02bdc7441b0f2336b6a5bc9f636c377971b29e90734597f40bbc67ff032b314f25c0b3996bfaf15cbdcedde646f22ff30a7c3c28db5cd22eaf60a6ec79f6ea57bc38c3be16f8b63937f3f64cb11b73f3e7e4127ce2e35cc7c9a8df7596fd2d9d7bc7ebadcebd9e8fdde41230f7e7f0b77903df5ccf5dcec2433ec3177bfe70feff398d7d73bd9ff3c86dfe833e13f64196268e4a473c239c02d81b1ad6250c1d538ef9591075e71d8d63298d6b1ad839375c468e425b7c0fecac280a181a77cd6305c6ed6a21dafa084ed803586fec30e8a37819598bc60d5dde14ebfbcde0c24732824e2de4286889f12e1bc20cf2d42517575a698923280d95c80cff2c231049525872a1ea046b21acaaa08b399306aa6cd0b26208efda9435b444e215832761d798ec5c2f71e92a73d5b5c9a3ae4523d71ccc9936dfef921f01e0e563da073426dce70c87163c1b465b9ba2dbc36fc9826fc422ba62ce58d49533ec30f710cac4733e8985001f63a774396d6286a2de4c2935934c02f398eae7660fd39bf3290d49d6c8e7f404cf36e0ba9491810ab4ced2ac9ede9ce1e548f862bf62614ac57f6941e42ffecf9aea5cee3a17460e87c8e86fad8b1cfe7975912dec9f9445a2c37fca22ff298bfca72cf237944542c1702d8d945981d5d44f4a60fee43f26a1554547aee55766dbdfe0a1a44ff3300709309836da86dfbab22a9e89681db1cb4b691547d68e5c527a62486de901daa69362647d6efae6e17ce85dcbbd22071752a76d897f12632ad43123ed8e1e971aaa0832a2b7258097711fcbde2ea57fe5358d021ea9470ea794b0142963abb63f426b92b67d7adab5fb9991db96909c7b2df8b3b471cda008181ab8b8a99f4b856b5135cfb4bd5e6443e2aea59dc6e9ae4cf10ce3b9e7d1b55cb43565ba639d9b72c38a6761ba08ec75b18807079e89c0bdf38e0ee26b691c5f2ebbd2cbb69c11a6eea03ea69fd70e8fd279ce18d89871081878acbaf1305872177999949ed7dca6893c96de0d429e8530c3f4740f1310dbbcf40d39acdb5e168fe57a5140b56b3e8f0dddf5733f033cc083e6b161de157722721464c458ea88be036befc6e8d64e1b5e7684a583fe4d799a9d27615b7e916e600a9f4a57b6e5876d392c2cb36d4bb6b8b4e6674103cb6333bfbaecf74d89ef6d334248fb7725add79250b8bf0ff782fdb2cdc1659f646311aac622e6a1099d6a22435baaa1f01a6ae83c1bd07a2ad05aaa088ab10835940f65845c2ad354577572a937f44a89695a4b93f3da455527a62243a7c0b40530c1d4d40ca60aede191b94557ae69240f3c7353f60979e08696ee4a8a2adb24f2a0edf9927bb893fa5d781298a09e999e60ca40bee8fab31c4bcf4c91b62f0a71bad0d16b7c5d78eb6f2a759cff57646697c6a077fdba0c8b0ae58c6dc3c2e7de21f7f4ac3a168bba96903a0ccd6aa90d53d6fcd319fedf534a79cf7b9f955476e35f5d600609611f93b6cfcd4d29dfa081e527377dc978ae2db182a94de779aea10f5d46a2774597780d96504ab09f8dd750b9870df2ae24adeef8b40df79952e1b5c7351779627778bbf42d9b5d61ee5c1646369489ca92b26c181a2cfd7c35d72c885c4b6e7b3b71d3d0c50c02e80a0fdba5376188d4cba04c789c63a5b38a0670e3736c639b681a70b067d0c186af54bad58d6d48d048802c8d522fbe096d742931b7f290e7f4da6906f0f9b637997fa11fd7524e8e79ccc456965f78d5b1e4f021c4b333cfa5a40c6afbb951bb9982fb9312f133b6f671d8578b7466cabb8f911b173310f1dc476d8312e24c427d1ca675916bf5087463e358d269a58587c5847ac4c59f500adae9c2bfab1cb4c3b79c19396c11601e2bbe5d539752d68509988012dad2fa0d2c0fbbb88c026d4c25de428c893a1d43992f60642d1c4aaa0dc9d17b27b3eff627e0520496ef63f66dcf3ddc3589c4c3fdf9f97741bbe037f5b23645f5860fe2351c4f413afa79090fa09d333cae69877c6c3cf2062b23d14a50f970a521219f91357f0d27a6af79569f5ff5a281f08c01e583d0866260cb8220632bd88f8e23339e69cb57db92133e6dc35c309449f20c1ff34c04f1c2276dc84cd0c1bfc6544f525351f5f67e0386ac523e4e2e739f53f2617868068fb9019f6460df9c6bcfb19be3b4d6e6f2302285b0405b888a05fd1c3e9044d5a0dff56491f23145ae542ae663a0e7808c90b6ae45ab364a37579bb24d2feb74e60196e674325c64e83db09dce76a6c719b96d4a04cf10b10d648d4974b623dcfbbb7bc54cda39cc55de807d73aca8f47119ec5f8b6be3782905b670ba7154386ecc73124c97fcd97dedfa8d816b49c8754f0cffc28f2809d653db189af080e6015ffcecbeb018fad8aef45961a3cf8494094b0ad047dbfbea306772287b593d15567a4a4e344461571a75d94f8303fc03cb5710586a962b292c896068ccb68412ea03d8ff53d87b2a7df070e9e4b63a027c462eed09668b8a9f0529a409958ebc8c6cdb4a00d9dff5686412c83b6daf3bea620b902b0d217956d26543d079d6a1b5693a950d45d09001e00f722597a513b7a5387c6cdceade679a99925b35817a70ce643025a8eefe0d154b683c9c1fde9555746d4c9c2e0d0fc8a3ae8f62eae54ee96764ed99461d30837015dbcd792c9deb4a563bdd068f076fc3d3b7bde6a07ddbf6557d4a85e7c6401e439d0af5154cc7ef7a303eb64ce8c6e88e214b2f97104023e757e7dd3e2b86658b0fa01733b261c262a861bb795b3a5db6259fc04e86bc788b0fc3b7b3b4b6dab07fed58517ac12d97d6ae257f17afc0cf399dfbf0d926ec0f88d9e6b174ee53e1efe0be1f832221fddfe015caccff4fef4327c72608a07b60fb4d5fd37c315f661dbecfb217a665763d082f3d78dbb4766863c687d05589548ccfc7b5c00f93100f17082087619ac34d4fdeb6ccc6d97b1cf07ba9b83d4ae6ebeb7cc0aebca67dd8385803e085d6776f65e97dd9c2994f3b7eaa99b0bcb38f5e1d5f5c740172f92e659294e3a7c4cab8d315cfa16641e5c995cac73c17eca1cd661289c201bf4f42e48c3d393a6c23326fdb7518b6a24b6d2ab96a4c14466fbf67830e8eebef825c0c611aec14a6984f5d8b9fabba1d2a4624e8289443563bbfe0772507dd3e9fefefd29fa872e330542d86a5a0c4542c1870ae94df20241f43182eb0db677813621f4c1d5872d0c96feb166607232f6518b76b5c664f73ff1cf71d3c4c262580d714236265946c61bcd26eed4c1560636f821b7c309b12d29ec2a58d96914897ca3cbf6b8df2f248d660cda931698f5ef5795b767af75d0ce4d5677b09f6414b481deca76a483a80fb8b35a6163cb6277c37777662d6bd72b4e1c30e8f40e7ab8ec926f26d8bae6977dfa198cb373a8c9f763e927e93ae9f2f42c524a08c5138a3b2ad3475a6c6c0e7d8f6f7b084656d2262877c6e9c1c13f0d4eec8734aea71e9ce3f2131cfe82994253155dcd88b2f8e7f8c96ded2e3479021f5a515026ccbd1f53b9d96a666005d4f70aa1ebcdfe246671724af7ff97b046191812d4d249d1d110a712bcbd5d4912e473628790ba7ac9f90f4cbdf810dbb297f8a6f1d31f4ab6dddea0340972bf5411718c7d83509bf4dd120d235a7c7677ed11356d6a7860a9ed737c8d732c438c02335eb9a06e87f9adefb34fe91367462a24e0d7565928d731b43eb52c46fc678f90ae4b38c54a6a4a525c795ac2bef86212cfeab69e761c969e8996695bd8b19b57f428ee204dafb956ba2a795d6d2adacd282f67dbabd1c9f5adc4f53c24b7eaaac7826ec4a2f530ef0baa04f6330f705f62e45b3a51b656520c44243d8a985c29eada9a0f3f3f925f644b3eb99927a5d1cb7b54d8e9587fba16d198887c1967cd0f65eab37698ddc5359cc236d9c6d64a92b35d8c01682195b5d6d6d18fb6dcb7af0c5258db2d5c35dcba90b0db669fa173d3fbb1ca91ffc8c2c5c53280386deb89cb1715bdf14f8c9801f223f872d7a105b1ddcf93182713de65613561554aab84957073cf290b275f61785366d2b3edf7f9ba2d59d3330547a73d43b97814e69ef2d19209bcce3c9b99bef62cf77e93602ab4f49434f0e3736fdfd7c9fecef05ee6b5988fe27975f50e59f80a789871b95c30df280697537cf18f7722ad63f2fa5b94bfbedecee6b3a1ea423487f5a110afa038e9873494b32efd671f0f0009e97c0fed40c7a79bd1ecff0d9ba11d64c9808b004d314361e97421b79a5d2b563f93b0f1360f917cf4a848f2ba9a7124bc7926b033362193b9680ee97e73160fc21dcc1525226f2daf32022b7b462a85ad232308f95860bac67d1c85a0df30b6eafa9dea9d024a1d8c66bbefdfc4d1a3878be9cabf4884f0773464e626116a47626552ef4eb88899f190980d935d9ca6f2892e7883468d0bd9db5e5b6e7d7c9890991060c58ab02ed5f1917528733ea804b238ff90cf6432834c653cab7a0fae5054739125b612130aae069998188298c05963666c81e96d6c1148dbc8ccd1d4b08969b52734c09f5b314591b7403ec331b232b7e82842602e17bf9bb314b0f8e810c97a952f9a769b36ca824c08cd8eef64bbc491355601b4fb09e273aca4586ca9fe5885f9e71fbaede94f100bbec21f5f712f3ca61fa6f7c91edb7a9be53a7f4b2f4d4beffe1811f9e79e642dbf3738c680acb0ef66d5ba38bacbff8517f498ad3e5bcee8fa739ddb7167c4a572205b59833575ddbc5430c5b51f550f8dab64b79c6b88ba10bea35dea84c0dc600cfc054423d14cd36d5bb4b6b7b92efbf236de84b3b9d8fefe6b8a60bc5605d8fe9427a08f000f49b6208aa860a0b05ac8ba18e175fb08d4bccaf76be0ced4fd862e16c73b5cfbecb08395534e478f63b9804fa056dac8aa1b22ebe701f47538dbb6ba16b9bd0caba1b9f04d9093a4baa7273137fed60bcc4ee38f2743e9f7d8c71dec5d99843e861c4c651cf34764c1d8cddac55aab6331681be5a6babb4b4767b2f436c3cf31a07fd4e3c12cc2d66421430f0fd2c9507fdf136f676b6dffc4c7af701fcccf7e39cedb8d2cef9deb800ee98d99427174b0f7a26c9e0f94b2c654647e736c48e7a8d4183bd788ca5eb53d6d091f69cf8d28a9109f65edcc67c5fc4eabb73ac8b8edf7b311ffa1c0bcf80cef1f5f33cc6d450353d5dca86c242de65ee9f03b658c050e91ddda93056094bd145840f05dd50f5845401ad2b533dfdcb52e2ca22fbe598a55f67c49d6f3a27c40df09b84b8bfe32573a33fef25732decff24c4fd9310f74f42dc1f4d883bcb856b3edc6a420e3cf3100699d1c0b8d7068917eae0c06fc63d6673bcb48de067d1c9d5ca938d45a967b28b4beec4e6f6fd2a67bbe2927e0d5f24aa4f49493cc9f582191cda96efed8b3f3f898b0c7c4cbef878123338881baa5ecfa4848fe981671e6bfff41be7ecfcb03587565ebe18ae6752798ed30038023cc0c5dc3fb5f38f9bc5843a8a682469ac047cf59dada2dd7901d0cb7c0ff8632b0edd3b9c511917bc0d1000e76272d87b269938e6f1d29e7f05e69f1c733f23517f9a26abac8d39d9189aae18f2fa7d7b5fe4e74ae964ec2680f75edf6bb462c8fbdfdafbb1cb3c9b295caf68484bd9a035754aea2b86c41ee0007b7a702c01714de3b4ea70b3e2cea57346235a74159841e9c5c4cdd88b7ac90c8e2b86dc74e57ca91fa3076f06f301ea2bfd74e56193e3397dfde67e02bebedf330d048cbb6afd89f1750f6f60c8efda85f73adf7c7ca119f88a82b482f1a7eefd7860fd4b88ff2feeb9acf7d59c4ae467411a4c064771137e02d7e59ef33a2f3c2266edfbc7c45cda0796b0717403b6bc0276db2a35742546062b86fcdefd6738af2da46af8a25c5c685f5790916830a3d160fa9339722185eff083f625b10f2ce510580aeb65d21eda9ca7cb3a8e81c9362e6e9c5eef3f5f2fe2c1494c809fc7562b86fcfafe0bfc97f751d63e778c02d80e15a96d487f4e64e3f2ce35e5dee55d8b0d6cf709c7715434f630642ce2df1be34c23d7b188033c23cfc8c6538996cf18b4742644e935c405febbb5e474655b0a2c3116b3a0f170e3209a1daf7db19e1bfa6f4480ab86e05c9388bcc961ff093c2f7025a17e6664ae25a49ff120e46f1d41570c09dbce3a59da38eaa77c381671baf1703a8572c35a74b24b497de87318b58da7926d129183b5af4fb9f2c7cd3d589afaa76bd9e7fdf349ef366eb6e25a9ca9a6dc1366bb9fe2f55d3bec1d5cd807162d3893bbd2d2f1757f15f05bb2fe161d28e44b39791ef7565ec6cae8677b03e07b926d1d7cc12c3d381a71686954217c4ebfc7c54cda00dcafb274077910d00226edefee9b1c801e81af10704c62b3d6cefc78fffd45563fdeaf77712698e32d3fefefedde4d8e8963411f39f53289b8c1cbf8ba074fbc71af9f5eeecdf57ed174502f6709d1dcd5b6a59441a6ef606bf75c397db62f2bd8dae219ae4fe9ec4e97a67b31bfd0c558c4aef47773fffdbcd7fb773e86461e776cd6a6be733923f2664af1ff8f70bab951bb968c7e41dbe3336dc177a83ed3da58c45ec2397e497f0fbcec9a63a07f4e0183463e0ee554f24dda681c4b4244933dc177f69af258c458a08f32db949087f59f6c8c043c05df130b645c7bfd9a273a58efd775a5f771f70eccab5ee08ea883a5f59d2c9b7572f681b77f233f7cb977675bf63cffef934f2f647c0ee4cea5bee1410e9f5b87c2b3eede43cb84f16dfc72f55c763f763032f2664fcf9de9626f9b879e8319b5630951c0e93bd8da13c872f0dce4658b8076cc09913b2691fa198b382abaf1302515818d8743f9907b185bbd8007f212fcadb399beb817f0d6de368fa7c7df560c99762d879ff175f71b71fb2cd0a14f34f219dd3cd0feb985d92b9bf9733e80e35ff75598edbeb6b93fa3032003ce34772b279ebf7be1779ccfdf5ed8249bc3fe4137dfebc5abbe4cd6f8d736cd57faf59c2711401a7bfa1dca8bb525218e89ca679f666d5c73c76ef9fc4abb6d8e1cdc6786a83c2cc85b7bfa7c5ec3f7da12e232f670e92466c7bd835d7eab358ecc3593ad6d3348fdcda16b3541003eabda7be17bb36bef72cf2b18ce7e05cc7904fb7b57ea0b7072f661e0ab2ab4c7751ff6e796b5faf9ec7d969a37b99f8fb4ddb51f0850c0770f3cff4cdf37747396a522d6f1ddd5876cf3d04f777e10fcee766c60979fdfbbbc62c8f29656561cbb09b814b35ff1e3ec62b7124f7cccc1f6dfb7e3c2d753dcd3f3617fc94b9825773c01f8cdb59c279a5a71376bbcd258c76fc4b33c792d03ce6bbbe3edb30e7032b6f46652e464faf7f4c19fcb53dfd10dcff7bc18e35626bfe2b3475de19a04e29841d3edf5ee6ca37ca12fee9e07eb714d87f85247b4b4fe354c93e357bcf084f7dfc267cfb013dd6b6388eefddf046cf300f5fa251794e8de5f4edce4d7a6a4d8bcbc27833ee514d0bf418a166c7b05e5d09917c42cdd01b923e6b02dc14fe0fbefcbc25b5c3fc8bc648dddca4903f875f72d11bed83711eff21c8cab1c312e2dcc8d275efea6acbc932f3fb3a144ec6b1bec955d71f7fded33406edddbb39fc6f2badf6e7defc8c6769183e975e7b39e7db387d80abb713148a7c8daa2d3071df11447b87c8fc1d797b6be671b7bbae886db58d42a2cfe9a33b16aeb7f7d1e066e389f85e1c8f9240c4307a3c178800ed06f1c888d87183a40c9a703b1f620e2d3f3306c881308896197f3b0c1f93c0c1d8e47a3df711e06e0ffe4340cf9e4300cc5cec756c311890f86c868f89dc3b06ec9df390cbbdefa5f3e0c7b3c07fbce6909b8dac545fe9353b2bf16eaee00ee7fde7e79fbdfcb095c4b5cf7077015b8fa3fc1ba5ce7c13af79b5fff4f18efa2dafbc52fb27e58fc2b8c77e01f2f4ed3a6bf276ecfebfee7cd4fe375befb252cde7ebcf945fe1e87ede777704353edd65977dda1e4feeadfeb7c5f3d7c95bade3a7dfc328bc3ad0b3e3dfe5094afbedd17699dadbb6fcb245c07edc7edba2caa78576ce3f38f976f9af6ba2ab6bb7550adbb259de5c3fd157cf67f6f0e2aff07ac7db73eeede7ebcadb7db625b0168327079834bbfd8ae8b0ae0b25a67fbf5b6dffe737fd34b847ff97b3f5b67efd56777817f3e1fa3fdb55fed8aad1baec148c5b6b9bf3973b78907452440e4f6cb1fc1ffe33c04e33cdc17effc689da6119814903d10753fdec2a24cc25fe2bcdfb859facb1e0362b080ffebc745bd8bd3b71f6fc9b8fa252efa6e1967ae1fc5f97adb8069c017fdedba2aeaadbf7efb4acaf7c140003ff97ad7afb760cca27a6b4f41fb804ee171282085707d2cc1873a8792fbf2a91facbd3aeca803fcb3dbc67908c6a81ac86bf0f6ff3d1f55ffcf9b57bfc37578cd6e5d41cec8caedbaaafade292eb1db2fde013ddd7e119ee2f2f6fa94c65ecb5b3b172cbe9fc6d5aefba225387fdb94bbe2f2a1efb653b6177e5c4670d3baebe0f6c7a072af176bfffe32c00802259fbee8c7f96ebdcdddb4bf0e0eee36a81e6f4bd3b8dcc5fef59b28736fae2e8f6fdd3ce8b6f8f1a7aaf676e9fafa431610d70bf0dccd953fb8b9b85d4015b9e8dd15460cefae0914bbb97e987297dee0e94820e4fd55bf4ce22360f6dc2f82380f6f3ef6dd2a476faf3db75a0f0777dfc4b90bd9ecf24d5878b797d1fa76f0fea682bae472fdff63efdd9a1bd5dd44efef32d7fb9d0601dd9d8b7d61074c7047627004b2b46bd7940d6983901c4f6207a34fff96e4434e8eedeed57ff7ec296a55af24586010d273d2ef79b430d3eb7341f31f8f0fcb87399c54424fb7ed6d4fab65be7a7cbe7f3aa7ede3a49a2f1e1ec4196def27eb335aeddfad9e12dbd77eea9c877c7a4eabc5fd7c315b9cdf524f902ff57ddb3c4e7ee9ac47f9f0f80bedeff3a2fc95e662369193b3ba6577c6eefd9f7bc2fe1d4cc4ece1b15a96f2774ebecff3df3aed65a69c7bee6292d7f7e70ceddd094fa0fe0d8d7b2fabc7c5e4a9cabfcc1e8aa72f7b49fb74b49916c367b4f832797c9cb45b99fd79dbe5e3fdfb8979a8c5567294f7ef47eebbc63b8d7740e7e73f679f7ef0e5299fcce79f5924bac1f2a1be9f1ff9b85dbc7f8cdfb067ca7bb1b87ffc92978fda4e3eb3f5e241b43f2b21fe99b5b46ff5f07446a38f72ec17edae8dc57ca2d18bc6bc7fae9e366ec559ed37b6ceb1a60bb192d30f93f2d3665ff2495ede9fddf841bc17989f37d6769871a2cf6dfff02827cbf33af0fd4945f5f3e72f9e32ab96d56cfef0f8abf757156bfd64bf7ad6bcb85fffe2390f53fe1bdfa445ecef9c562f45353ffbac8729bfcf3f9dc9ef5b2fb488cf1f84b9b9c5ef9df5259f2c26d34a54cbf6372ff05415f7d38da979d6e98ff7cf1fa5fce7cdb5c7f5b9ebf7bef5f271327f5a6c9c8f5f3be1cbc641fff5f37e6554bc9c35ab7ee3abcae5f2ecd7fc72d65ecce50f529e148a072ef074ff78c4fb3e72de53799e3b7da6d3fd122af9e513be140fcbd35d7eccbbffd0d8980e2f1ecae9a66748d34dc3bd477fbaa9bc7facc5fdf2b13ad587ef9b9fdf991fce3c47e81e38693b087f3e4ee42fdfecfca1f83800a7ab9f3f27e2e14b79ff51dbcc1e36626abafab9f9e56d834a1693c7ea417fc5ecdd477c7a3fbf3737b30d1c7ca9deb5a8ef9fabf974f558dfeb11fe9f8734eb2f85823edefffb16fbce9393c5d33971a5b3624ff7727a5ffc6694ea70bba765f1f0fefe3e8967bdb478ba7f9c55fa533d3fcc249193655e2e4c54f64dcbf564ae5adde7ffdf64b615d50f62329ffdfbc3e3eccbfacbce25170fcdcf6a237a0e7c9c4f9e96de679f9593bc9c00ebb38f578fcff7bb28cef106afc67b752f8a4fdabf848e0e7dfa31ca73a89536e76dc7faec919e3eed88a7a7f2cbb17ed49fbf0423ccc1ff5c4cebe2e791f6f5fca199970f5b87ef75233da75e22711f3e7a7956b39e72a0c5e2f161ddbeffe0a97dfa72bfbecf27d30fe7e88f5e0cfcf9d3e4e77d793fd98a91f70d577313a4da4759abf9cf7f7fb65e1f69268ff36a3e7b7a77f8251c5b4e4c4feb1f5f2685b87f747647bfe48ff9e68fa5490cabe446e5999f7be37ff3d7fe8ecd9f5b35b0f9882feef5bc7e131f9a883787f2c5eaf59f3fe5721b87dd1f9adf2f978f131307de1f7b78320192d787160fc63f7c15827c7bcae3fd4f719f2f45b57c73f8a99acfc4fd4f51cdca37dffad43ee51321ccabba9f3f1ffa68fb06f6c797f74f4bf1f0e6e9debdc45dfcdbb89fbf1307ffa499beca4bc8e868aba7fbe5c936cf13511593ed22d7992df742e38c58fda693e42632af7f7c9956b3975fcd0d9adfb7e160b909d8eb1f5fe44a2cabc5c40c1173e0bf560fcbfb62f158cd9793a91139731357d213706b7cee7e35ffdb8da5fdc1ddcbda1ed3d37da77edf2d2a3c6c66eee6b7d59379a5dbf5858feb0d66b4bd597930bf7c796ae74b1355fdb812916f56addead4becfe7e89f02d1fa489c17ff864dba51f8e3fb54f6f1638f20733a23f2c75e81f2f97df8ef3dd12c8fffab7d5bcca376efcf6b72fabe54ffbebdbbfbf9b3ff5b0ffb7fff56fcff7f3e2e1f1cb09c57546ab572ae3586bf3434b9973dbed02fac71abf56a147da951b3d73a4c547ed78a4f18927d643b3983fe97ff2fee969239e3f6bb81ffcb395995c27dbed34d7b186e04ba9bde923adaa623ef9e463adc136a2ffd0a7c6867dbacf578ff75fa655513dae3eed2dd3d4f86f3f1f1ee5b146bb31aa2f784ebbb9bedeff7d9796fa7fde2e6fffe76a5e2dff530bfe830bdd9f7efcb2e4fd6993ede2f7a79f7f767cbb3cfef6f3fffb2e95f6ff9c17483f22cbf5953756fbeb465a312c968f3b81f9d268b788da65ef5e2a7bf7e9317fc9dcdda44eff4b58aa2fd2bca4a35beee8167ba2cabb2051f5cd05f6b76f7f10a7f2fe014ef5cd751cd7735da7c3a93a9caac3a93a9caac3a93a9caac3a93a9caac3a93a9caac3a93a9caac3a93a9caac3a93a9caac3a93a9caac3a93a9caac3a93a9caac3a93a9caac3a93a9caac3a93a9caac3a93a9caac3a93a9caac3a93a9caac3a92e8e536d48a78b31555ff8e479721cac322d766015702e0d567ddf8355ce3f05abf4cdff3658f5ddbe725cf7ebd5599bb6746055075675605507567560550756756055075675605507567560550756756055075675605507567560550756756055075675605507567560550756756055075675605507567560550756756055075675605507567560d59f07ab36b8d365e9aa2fbbd1f8749cb37a69b683adbeba1784adae1cf0fdbb63ef692bf04f692b7df7bf4f5b7d771dd7b5dcab8eb6ea68ab8eb6ea68ab8eb6ea68ab8eb6ea68ab8eb6ea68ab8eb6ea68ab8eb6ea68ab8eb6ea68ab8eb6ea68ab8eb6ea68ab8eb6ea68ab8eb6ea68ab8eb6ea68ab8eb6ea68ab8eb6ea68ab8eb6ea68ab8eb6ea68ab8eb6fa8bb4d52bfce96f71575f063b4ae474b5abb74d772496fd7d8f62b9c0fa070cd6cf89783a01613957de1ec2b2771096e3d8dfbfff0684656efc130aebfb271496ebec7829efbb67b996e7fc8fad79f5a578c89fdea3582fe370fbe931d8ea8588da0cea2d10b57dcf6f89a8d788d3a6f55e2a6efedc701e9bdfdfc8fe9743efcee884da5f166aef64cb5ec4fd5b1e0ef8040ce6ecae2f0be2f12214cfd339fc763d5b2ca6e3fe733e4f6613f27d958fb332974b3b6f3ddd6e7d7fe785fa67dc3cfcc86fb26a1a0a1e85e8898e918a02664f25b226e46a15dd3cfdb8ae7ab3e8badf1bcdb3559e3ccca2ebde6c7f4e706517377dbbb87ef5fd55399ccecdb1c5e6673dbb6f36e7997f374351dc64edb4eaafd8389f6127b3f29bccfa118a95fe792b0b5104b6c81d5432903efcb8abbf6defe1ea7ab6b8ba9efdeffffd6f9714ecd17cb15a9e21d55fb5db6f116b7fbda048fffae744bab9f14ea47722bd13e9ff2291fe4a5a9c25cf9b820c9f2604ce285897b9036777c46b8a71b297adf9cd7051c881c5eefab8b8192ea6329f4d49a6727d3dbc97e3fbeb6ccf7ff871d7fff63379f8b191cd7d9bcaf582b6fdad0c2f3f5eebeebd3c1f3d4cc670f5f279ef2a0af7f2fb95ec7ea73b06c8caa558b1b63f67e3116263a42829c48fcff5c572d726de7e7ee0bec114883aba416f7448ea8cda09f1e6afee6ba175dbfe3baefbd62414ea56ee3f9ffdc7dda1effb0bfa275e2dcf5340af1bbe68a0ab0b6aa06f7f52035d751aa8d3409d06fa9769a0d7e2e2f754d0ce74df8bd29b7e3b19b3b208d3d90191fbed830ad8bb0fb34574b3fca822f69f776ae8f26a68b7307722a5f0a5d95ee77cbd604aa1fdedab7b6579dfff5c4ea1f3b9eb733aa7f0caf31cd771dc6fff53154f9753d8e5147639855d4e619753d8e5147639855d4e619753d8e5147639855d4e619753d8e5149e3eafcb29ec720abb9cc22ea7b0cb29ec720abb9cc22ea7b0cb29ec720abb9cc22ea7b0cb29ec720abb9cc22ea7b0cb29ec720abb9cc22ea7f02f93722f4cd3e5d209f7dff965b258882a3763fddf178f0f8bfbc765758ac2fae49c1d92051cef2218f096c6bafa731cb0b9f38e03ee38e04ebafd71e9f699a479a181a3b6ef4f812727a4b07339d82405866c310dd31f51db7f64e37af61f777d40c9da66c9625d90413b7132752b993d9d0fbc5b99b97978d516befd4213cf5eb59bf74b0a962503e9aab8110dc3f6132345499d7a399183f67a3eb0e978f8588ce12a0776390dd7ed3d499793302ba737a387dbf9f079ea24cb3c1c5813df7ade1d3f799e5c2f0a99add818a9db71bf2cc2d9d5341480114fe40efcf12a61524dc9e0697a33f4d89dfdc0c8e0a90867ab5c66250bc59bf35f1ffb97d2b9da4438ae0d4c8b97bcf20be2b8c0fb6683efdf5e52119d7f8ae3eadbff551c772fff1dc77181f7edebff54f1dfd1b81d8ddbd1b81d8ddbd1b81d8ddbd1b81d8ddbd1b81d8ddbd1b81d8ddbd1b81d8d7bfabc8ec6ed68dc8ec6ed68dc8ec6ed68dc8ec6ed68dc8ec6ed68dc8ec6ed68dc8ec6ed68dc8ec6ed68dc8ec6ed68dc8ec6ed68dcbfc7ab1990e9220caefea62fa76becbe29ae0b9c0b92558e6b79f695fdfdcf9155faf67f9bacb2adef8e6b7f77bc0eadead0aa0eadead0aa0eadead0aa0eadead0aa0eadead0aa0eadead0aa0eadead0aa0eadead0aa0eadead0aa0eadead0aa0eadead0aa0eadead0aa0eadead0aa0eadead0aa0eadead0aa0eadead0aa0eadead0aa0eadfa3b68d597b79bff5e84af7ad981f83869f5d26c875b7db52e885bb9c005de95e3feb97d65f5edff3e6ef5f5bbe3dac0fd1f5bc8b0c3ad3adcaac3ad3adcaac3ad3adcaac3ad3adcaac3ad3adcaac3ad3adcaac3ad3adceaf4791d6ed5e1561d6ed5e1561d6ed5e1561d6ed5e1561d6ed5e1561d6ed5e1561d6ed5e1561d6ed5e1561d6ed5e1561d6ed5e156ff0d70ab57fcd3df02afbe0cb6bfe981f8efa78b5e7d6cbe43b2aeaccbec2bbba5b1bc3fb7afacb9f36e5fd96e5fd94ebafd6ba4db0121f3b2af6c1e0ef8040ce6ecaeffb22fec1c7ebb9e2d16d371ff399f27b309f9be7ab50fabc5c6c8ba950b7b2a85752b76fbbba2541f8f9b77e7c94c15e140e54ed63292ac52fd77b0fffbdbb5144bb32fed75ff3997f96a120e96d4198adc495609b86a596a9745881ed878a85e5f7bea0ce7fb7b900b3b0f85c5c6d18a8efb8bdb7aa07290b5fb6779ff1df36c351927fa6733198f445e79651ed6ab2ccc54e13ffd78d55edfbb352170fb7d653925a835cf5fbfdcd7adccd605193c65e1f76fbf7eaef75c049e3d0dd7c4ecdd8b9f7e5cd7fdd16e5f5e734fbd455390e193be1605eb3277e06c34cf56d4192da6c033fd1edd3cfdb8ae7ab3e8badfdb9cf3308bae7bb3425e2dd875dfbcb39773dc871f77fd6f9bf69b7fd8c9acfc26b3a2f0ca2e6efa7671ddbb8aaecb151be7b3b7e7d52bf6eaefa9cc9c28102b7dee8feb61c4c8fa69da06d58fbbfacdf59331526c3c34fb16e7ad57e60e12f97c34d0e36a7a031fa2ba14d370fd1cdd454f2ff7e0cdd97884d818294a0af1e3ba5ec4cde6b97e260f3fccb583be79feedb3effbe9f0737bc3e97c2498332ccdd8a8660bdd6fbb7b8caefb77babdbed7623c14ecda9b4fc64ce876b7123deb73a7f3517a3fee8b1fd7c332bfe93f4d08da5eebeabf7270b58aaafad5f55efff3aa2918793fae87dfc6d7c3e5ee99c6d7d1d768d0547761f6340daff2686e553f928703e7f766b7b21494e8f13aab284897139254b7d7bd0af9d1d9e7e44e5f5087897c8ef4fb33e7c33bb73972dfcdd441d68febe8f9481b6b1266ab1fd7f52a7746657193a9045cd5ec6ed642bfb7783d0e5efd5b517955dfdfcdaa29c9546e64907ef7fbb9f43226aab7effd67f2f0afddd3f9bd0045e64a3b311ae1332cb5c3a7ec7782beb22e69ad7dfd73d69ab9f37f60ad7dd5d61ae8acb5ce5aebacb55f11367fd062ab3dadb1004bc5526ba0bdd553f7633a1e2d0a990da7643067d9485b613ff29bac9a868247217aa263a4a260773eb3a712198d7e972533362e2d46bc3a6ffbe1febe84b9c6ecbed96aebebefcf5190b98c20bb08d359119622ba41e594e8df3355dcc0199d6b2b44aca270fb3d77fde5148cc4ed6c71f5afd8cd5f4ee6d54f6d19b713298e0bf5b74df7c2fcab731161fecd05f6b7ab3f28cabf7e5e76ba13e59d28ef44f919a2fcad487891d2749e2da6e148e473f855dbbf2ccc241d674f85ff30d392f9fece5b4cdbab6aea20ed3b484a06ea962cc0f4ceae0a229e5898b5f19c36b77cb642da970b17608a7ff7dcad243d76fe78e7c7c3e5540e2cedf7dc92a13d21eb9a8da3af05efade26bd7fa9312f871f5b43c2e704d8b9d9cf5beff4ed6a9637d05b673f5ab59a79e169fde776b2f6edd7f9a75aa6fffb7b34e8173e5b896e75a6748dbdd139f216d5f35edb24ebbacd32eebb4cb3aedb24ebbacd32eebb4cb3aedb24ebbacd32eebb4cb3aedb24ebbacd32eebb4cb3aedb24ebbacd32eebb4cb3aedb24ebbacd32eebb4cb3aedb24ebbacd32eebb4cb3aedb24ebbacd32eebb4cb3aedb24ebbacd30e0f7b8336fd2bb24af585bfe4e26155dc3fdfcf97274af7bf6eb8c3a8be7ffdade2fd575f81ed5abf8c515d81abafded50b46e5fc538ceafbd77f805139f677c7b9fae65d9d03ad6e9ff81c68f5a5698751751855875175185587517518558751751855875175185587517518558751751855875175185587517518558751751855875175185587517518558751751855875175185587517518558751751855875175185587517d4a3b5d02a9fa723d799c3dfcbb78c8ebe374d5ab763bb8cafdeed8eeaf5503fc0cac3a510d704b56d97fae1ee0f6de3f81abf4ef7fb224e0ff8b74555712b01356e70babd772e4a53060d4f6d349285414b2c5344c6793319cd171664d815d16a1e094ac9feeeffa3d06b2151b0fcb22ccea281c7a5180ca5c16cfb7b3071e05c28acc35bce7e2babf3085c9e548b0ebbe9c3ad16c4a06ab820c9ea230ab27e3d1622af3d5f57c5ff47bf61f773d753d5b4c89d32f2958960c64c53859ac28b145e45bb3480e78110af796a06716663c9a2d001b0fd5845cadcce7bcb782addb44b3859a3a594b41aaaf59e5329b4fc6c8cae7f5e3e46664e537f0eb6d7b359f8c470f058956145c2d6f9da19d3bc9721a0e56acbde2b91c586c0c5713f27d39215ecdc6b3ea5aa20746d063ee64cbcdf7e52ef303172a544135537138aa18ae3d188e240ce99af19943e540229e341450007102189e79b11f00240792e1a48178a66292ac29ef3590a43652bdea5a8e441e662b16662b0a84c8dbde553478fa115d0fabc97824a7e1609eb7d1d375d5abe85ce8fb9cc16bd7bee5b4baed3dcc22c9ece2266bd9182e29b86ad9dda62d9b6756311e8abcb5d584788f51d5e86b3e4d41be396fde5f4c2bbbc9e5d57f3182acc8efadd0b5dbc6d79bf38bf0ea7142be6fdb8e9e27403cdf8e336b429aeab6b728ce7d7753e909ea24d5bb775fc1ca6d6e79afba9ea3e7623ce4ecae77155d0f5b468a45ee8cdafbbbe54371336a72f5f07c0b8a45119636ad3c3e05d6733ecf54716d3f51e2cd6f016ae97824f2d65b4c5b7ba1c7e0fd75f483825250b05405b136df877327f6a14371d0c43e558c07369581cb7c54328c045541cbe48043dcf362f32f6d6392d590f79ad84725e48564211390270e54b335f3fb356da31f2ccc1aa6c70cf1f884644a3f3f691e3e8edf4dff97d4192deeafedb6d8f63325c89a8c674bb35984147cf7fe76c70b3d776ee0f65d8f442e0560d9d572ea0cc5f69a428f6d368e3e8c0773eef67bcc5cd8fe3e0dafe6db73ad6d5fd6d3395ce637c3e722dcbff3b61823eb968c56796bb76c8c9ea7374ce455f4742dac1fd76239dd9781ceece25a7aa684b2eeebddbd6fbff34721b33607e2795ae9771cb5b73c5ac1ebe8470eaeec5ca2cd98990f050342153743ef0728ade2a6afe2eafb3303c29adc6495d9fce0ee6a7b4feb722af3676a3651c8d4ad14cfb744e839e446b3059f84199f38c89e9a31155908476d8c8588fddc85b828194e0152d083b82f10461cf244217f665110a8381c0aa866ad9edfb11f7894d306e2c0818a49aaa817fb437d1d2b9a2d6a36ee1b99379568a1e7e57fdcf5a7afdf1d05573523bb77f7714ebc393e1e5aefc68862e321981024de1db726374341c9a89982aba7779fd945289ef6f2420e14c3d4cc6d88a1eef3ed716131b92e99b3bbb7613b75464f13bc1b43434ff7ab9109772ed87e079f022d13d26d1bf49cdf882736466afb79cdc6c34521b39f53f24a0e11614dc2acdd8dd5a9d4f341ac987dd5eeee53df4b11a6bb36b2188fec5c66ea96a0074abc153332e72c59679e7f779dfbb02c7330db9e3bdb5ddfc895d7bfd3f150edaeb591ffe5928e7bdbf3843505c1f6773dee0a9b9242dc8e47affa6f5ddecfc54fb3f14428f807592bedc574d76ff3bed0637e3a4f965a664c81d18d9fc8e46005af5d677bbd9612afdefdce48a1e59cb9672d3b58b8bb3e12b91c89315828b3b9c6eb634ed64e8d9ed1e332d97df640efacf5f6ba6a1a0eaa9d6c981879de5bc1ca6dd12fccfb2919f05c5ea9833afbce5517d3d932d273daa5206d6018b5881725e325a720aba84c00f28b9ae17e8df840409f3a288c00c3740df1cca640eb8ad48392c9d89f39480d2b461280707a4c67af0b7265edc652ee8895eecb71f2f083d8cb8612f468365cc9ac1f5339586e75de5e274c9dccd272fc83aebc76db5b9e5f4e57ca410d79ed51421da8a8159374cd2474638c045450518064ec330955ee2095ae19893c44743fe536f37b1ec28182387550080133b2356d8febca8dbc296e862f73416a1db09b83eb67b695157aace877fd7a5cff4a1f171ff5d1fa96072b7877317db4463e9214c036c641abc71f242301e59033ae7f5207f27e0d65006008dbd8a73694830af9811363ea2212ac1949d7080b0143564130aa208f9c73f4d17e5e9ed6277ceaf4bd6998a9bd8c7e91b17c120e5653993d7d90d77bfbd0bc9ba5f6230ab9b77dac29582ea6edf97264631365ed473962e4a27539db3fb191df73186602f1bca52068919fbb281c9614538000b4990f5b46e81afa825330aae330b119ee57886415e542305e9688171285234979dec4e15139b27b375a3f08dabeb315e7ef6d0724f2395b5090be3baedfc75afd8a5e7d6d33beb213977b5f40ebb2d6b6d9de26f5ec6976c5f39b4c1dd0216a0ad0231b27ed2fccd117bbe7f07b07977befbd06e1c8822aab119ead29cf2a86670a91640d09b51889149548e8b949555932aefd8999c3c2918cc301d7fe21e3a540bc1008d776eccf5a2aa363effd93b974c4573b732e19f9aaedaef690fceb5d52fe5948452a26a8846ae6c4589494e7162329a0b82c633caa214122f65307fa8145f9b0a44aeb91c832b231d4be5b6eeb79c738f520499d180ff83f907f9ff8627b9bf5337bfc952f8d9e29588ac28fcef78dc7a3875c6625bbe93f4f417348e7ab5b0e2fa6f3991f3531a10d0a9306fa918bf0a88ac940321f3ac8870d5443ed0357d0a700e2d48d37fac8a6926a9daf109fb5284cd631197028118761aab48ff7b9ce3fe8cb1e9151a76cec0f7248dbf58f13e2cdc760fd5cece31a65cbc8a0cec3abe7e92fcd9ff5017b56fbb1978c41e9b933f3282f6aa42080044984d30682c086fe485099aea90a9ad8ef81d8aff5fc58335c0346501913edc3a60dc391827e6f4d092a910a6c765c1e1dd74367c52c0ee89673fb7c7b9dbf1e3b92a907fda86561c611a600aa610d49e2c438f7184eb59dbc46216d10ae1d8a2397e2998261e05135e00830415559410e5b04b22ad66d6564d3bb7f61ece8a37f7fc89fff346e4441594ea5277676c027b1c4c3baeab5ad1e8ad5edb8df4ec142502799699bed9647ee7b3be14cbbc061e4806fd46a39195d4e4e626a41925814070e94a9c3e4a084fe0c40ad9f48d0c2904964e2c1594979bfa4bce090e71ee3bd86aa618dfcd4452072904a5ca8120781c845d56f8f85d7b18cddb12525a89d3af07d7ce9b9301bcd9e654b7e6cf7d95c7fb12bde1d7f2767ab77b2f458dc6ad70e64d5f6b9e78cb8bbfb74e8d178f8e118e9c1b8d3393e0d41cfb94c8fdac96c5e3ed0317a3811f7391adbf983f19c57b68889e3ea7b986d6208117889ed78de2bdfcccee52fc4f5c785a0d546273090ad0ec579d025f5a28957308954dec4182aa8908061ea50c52493a98d426db7433bf687758c7b2ec54183c2d442fecc811c094620607ea298df7329ef391027ea845ed4ef91df12bba4cef0196ee74a3ece9e8b97f7e64dcf8a998d9e0ec67ceeb48ebba05ce31180bcb746bc67513573a889890d2ae6a33ac6a534feac2fca38649ccac88538137188040bb5dc63920254311259da1e8cb1b6ed33c9eea213cf5e3e6fe6d7404d087a3c388e5a771d5f6ead60cd307428603522a98378ea50322a919f49a49296f94cc458708a5327f66776ec6bff1eda908b9aaadc657220211e080a52c042e8403f02083379cc3799924cebdbb3fce3dc112bdada562e078b0371ace696072b842f681785911787a98bc26145f98853896ae6d70e0b83758cfb15c57d8e70594232ac60381250c2359323897851439c7a0c071e94598d140594649ce2bc85c774e15cdb1270ebc77ddff967bf15732d6e46dec1f874e5aed1c5c6dbb08e89f6858702e2998354bf8638b0201f7016466bca6b0ff9851e7f35f39184aa1031864d8c879c4aaa90ca01c4890b7959421578cccf2423a97b6cbc4dc2ac9d1261dd924135b9dbc57944b5d3a9051066037b13f76f5defacbe1c8f9e2960f34fe235ebcbe9015453de53908c6aa44a01f9cc816a50c77e5123cc3855a5643293280c5cc62130713c09551c3201e54820d56b9096fd98b6085097e204a030a84ee8446d8f1c58e3d4fd77b171549935699c7846eff13e67122aed6f50955ad0cf3dca7b16c4a88efd9e074126918f6a8847a5d1832a71a03f538c1792e2c4a15808c4ebf5efaf71be8edd9fbdbe59d13112881b3f616dd88eedf17b238b7acd2d4f576867970236bf25426eeda8e6e81ae42b3bef954df81beb73c3722a930f6b0fda9761e361cdb2dd06fc6f8ed9b95c6fedcfac3e633e997eb8d5e3fbe03ad0ec62f29de2c4867c202148b56da420d63a8d3a5a66511e58301c0aca21602113c89f3590444d4c061ca94240d5e788071ef20732c645cdb49dc5239756276c82dd9af521d98ca30bcea948213f5933de9708440de4b91b87a987fc5220bf90c84f1d0a820612ba667e21904c3c28218831aaa80a1494b085326ab4ec812ab020810d04da1638fdee113fc0cbece6c4c5624d7583c29164fa7de2be8400d5940c4bc84ba9ed6a840bc94254b3307210a1564cb21af140219f02a4588954c951c824c3a91dfbb913fbbd96c9e4842c1d2e8a903d51521c88b50546375f5097c8cdba1c1371081d44861ce2c4a6782811ceb55d58c7385d333e5b4395b8b12f2ae4e71e228996a700c9c04661605335b3904c408c03106378eaf99fa6003dde92a1cda4f1c10fd878f545d91988d316e20030990086454dc9a882bc5e5392aeb52f0049c6a14a1da4dfbf4c5c14c236c6d48232f1909a7930a416e5a312aa648d54e421901e6567b6cce182b67699cf87e5fddd193ed47cf85c84ebc5ed1879f9475ddcdc72b8d276e5c5d637fcc4666156c658db1ab0a53c5953301208179c2aa16db4162a56323caaa91c88d82feb8d5f35d263c886a65f871522898be4a06404d5477531d873280b2ae1197efc0bef7378dde1727e270c51057d08a84282eaf9a67a5eeceb7913d82c1c693b43509555900f390ab53c865eeca312a9dca2246a99596f4815c342503cb311a62e3b1a5bdd3efb9dadeec7bfdc6ff674dc2fa7e1f7437148e79231e998403b26da3fa50dc4438e54a0184f5b730c23c1b0d64fa947395cb37054c77eea327f54211cb4318e14e2bd96f1dc42dcc43c9a1853054ff9eb7361316d578587d7e4d1f505d91e1e585405aeee07089226c6330ff9a9a5fd7316b212818c534515c2d4a180aad89f01caa1824adbca414b715699582c490c038a6400a0f69d8fbfff4d1cfd509ce2ee92ebd27d81423d2fa8cb784f310e5b86132bc6667d482155dbb11f344c06360c0307fad0667ec9631307cb5d84670d2589c330e348f51493c312aad96f3efba57dbcc8817e9f339c28a46883fc414d41d2500c5b04580dfd9e8700b420ee7908e71604d0daaccdcfdcd8cf5bc4b50d379494d035c4bd86caa441fe79ef7dc7271d8ed55d70eee39e037d56511c780cd70ed5b69a9a01a6ff0e61c3fc4c4039a898b6c9fd9ecbfcda63fe88c3508f8341c94cdc2a75a0d463a8e0c8af2d7674ad76b77eb47dd7a77d187ec027369c01baa0ff82f4d897b045fad90993c8af1d8a730bc9c061782029373e70c5fc9e8bfca8d17a96e2bca1aa9490675aa6aea1a42d52b335e269cbfcdc45ed0919b9f34b0fb38feb8b72cf6a665339aa21811e92514bb1b645a396cac4a1003650a62e9211d0fd40255da33075184eb5df03a81a4984473cc65a36d035f49326f6a3f684ffc299cc971342fffa1ca17260ec77e44315e37cc32c84430e7dba8e49aa28d0bf072d0c3381f0ac65dade525a3fa20a8599a4923a310ed6080c6b284725f2fb52cf91e3efbe6ca7c07bfe643d641d5f8eb10148f54be65397aaba89fd9243197888a39212adff4baefdf61853370e9184807ac8a73605a9cdf0b046212a0d1b2fd306fab54bf180339caba371ec5731c4e93c5bea7b2bc26cfeb2beecd9d3bb6dec7ac706bc8da1bcf0c677ae057f3f1ec9a7e195b6bf01239e95b7b662e1d3213bd7ba284340a88b78cf4192d510242e558843955831a16d4c108f43b3ae6cc73e5c23dcb3623f6f108f1ae8e70e543d872aade78625c3426a590f092b8ff335afd7eab631b331f2a6122e8b9b613919efd67d87650e5280ae7bcd2d0fda5bbe67065e7cf1b771b81d2fb68dc36dc7fc2efe46d6828181c5eeecb2b8197d60fa77dcfdd441d6e69ded62d083aff7d9952ac281352107c7c7c118db540e64b1bd46311eeed66fed82881d2bef30122d7347a8b3c60ef05431b892d383be77b2badc5ad450c658cb536dc72536e2754339e28c97dae79650a2924ab37ee030425b285989b0fe3c1390500fcaa841386820a080f9596d5821993aa7e4f714785a76596380f4b8f8ebf306f1c8427a5e9040313c6b292e2455d11a0168c77ee4524c418c873595260e596919074368e41ef26b1bf168cd7851c51b5ea74161d09c5c970457cf13200ef0a7bd15c4c9ea72eb439161bb985f5490072ee4a2a2aaa8503894c8cf6d14061e52650979b2a6c4ac739708674657c57858512d3f7800184e2d6878b05115e3f4685c3f0fb50d9fad8a6bfb8599d8c9e250e871d298fcad1d6fb11f1fdecfcdbb7b3ac38f7e953b74d84eb22fe74f042d0ba987785f9a780b171594c65f5690e71e04acd6be0623918dfcc8a10009cacdba910779ed20bf2821a72ed4ba95f7856e07153de14fa0a6204cd09d4c3cdc0797e3db65566b9f0af182539ed5da67643eb5284e2cc659c9fc08205ed6941702a954411faecd1a1b4682e2dca312d5286415f4a3962a6a69bb896a7ff2737ee2694286fc1c799c4ba8b46ccb0fe590deb9ed2d0f2ee777f9c11a612699e1934725e5acd4fa9b1256531e343141028281403877184e5a3d4e209f59c81f081666758c45c5fcdc615cfb14b50d41b43ece0122c95a7bc1aaadce3d839d6461f6c448511661baa4e3917538861cad2e678b0e05c38540202b6138aa284e1aa4923626890b31137198aa381cd5140f4ae4538782c4417eae90ca5bed7b51a06da3ac6458fbfa91a7db4130a88ecab09be1336db71c9cda7150037beabcd812f786273b25a7deb16407e6698c6bad132ea70f09e208441e0599842455080700f1be4038b1a0aa5b14a616e389a2246a116115d5731ba41ec599847eaa659d423c77589855284c00e5b03d6e47a2e7a99977a39f140cf679927fb08f170ce87ef8db6b1dc31a82518d78bf86b8e7c230b011081a440615f4610b55ee403ff118eed9310e2c88b31aca4841c3c8e70de4338530d37eb4a240db22c8b0f27f7aad838542513068d9c13cb6de256d9316e2610d436a23955a14689f937a31860ee3890dfd01a7aa2f36394fd442fe4c5155d65042c5f040c4386a19493d464615c35a968e3802b039619fd65360727f9753a26d944fd67a2ec75d4846020b926145316c995f8358eb7f0cbd18e70ec29103550aa09f36088f2aaafa359381b6cd2daa5240a5c935f5181f0a88738bcad4d42738d1077b6efb803e0497d4870ce72ef347126a99140e0454a8a2927188538791c4667e5622edab802187bc6e21cf15f451bdc985a26b2d8320872e3371c8918871629f8aafbd3019c5cf7c7e2037e0da750d637eb158fcac61216d201f492aa14d097461485d04469211da305f4884a32626418bf050421958312e2402d482bcb6508824e391c5fc59abfd374a6083f8d1dcc05d8c6db68ba99d96b1d9aa20d6928ea17e8ed52739c617cd3732399366dd8995311ed490078d610289b6af8772e3c742cbb0843e74e3305823d517d0c4ee0c875152023dc37485c38af1d443476da99d6ff2473942319db39fd3f06acec0a135b10dbf7ac13c550b61a8a8d4be1fd2ffb88913e1a2d6762ac32301555951392c199fa918b38ae2590b71ada81a71ca0715d2d72089037160213fab8d2f73243fc87094bb5a0ac42ea71bdefc44deb6b6ab6c3e05ebe773ea89eceb431c5e7b6a2f682370532fc6ac398e04c47d69f2abfca28e4368239e69dfd0617cc891a90714d908072ec5434155a2ed7ddbf88e38f290d6919c9554a6cdf1b5fd839cdb1bbfe8ed1af6966793e2eb185cb91372567ebc9cce3f8bd95fb0ee00a01e23198fb1a9cb23214f1ac445cd0832b98810a7360a51c9fc82c7feac617858531c59148b92c9c48dc301a7b8d740edbb934115fb437e6a4d9bc9ab76fa9ed1fbdb6b9c3c93544536c53387c9c0623269a15f5b543249790fc438b2633f6da10f2de6d70dc57accf56b48b49d11780824568c53c07c68239c6a3b641de3e0d83cd6bea21eebfbdc49a6df37f1ac5bb2c92f99106f7ece382a087ac881286fc78b45aee7d941fff392365ad4325c3b88ebff84a072a07d4905c3a1c9514086dd2a6bca1380486ac5246d111615c5036daf096662213dc0f8a834354278606b5d7d74ce7ec8bf633605a59a9060792f454bc1d56acb2a9d967df38c4f6ed082ded95f27e3219f027713cb3e5c0fed82fc05aa291894311908edab9b9c78c35fcf6ccaf51cad3d8a1385c2518554bf42662daae7e9f9057121a01fb4cc30191987b8b786217528ce4fc4cd983d95c832cf7c3866765c967e9af3f66a8d04ac9f0b321285b6996ee03207a3c77d0ed96b5dff3107fc5d9ed6299b6c9f4bf6892d165c2e06cafb0281d4822070b57d4e49da32192804e09a71561a3e1e476b86071281a18c716ac56164b19071a8e5900c2c28a9427e6021322acd71ad37cea973f0eb359ec47d98f1623c7adee528befa6c535fe4ac9cd55199efecc1dfc8513e983b78784eaed105636d88cf5a8aa94b79e4513c73a11c49e8a71622708df4bb5510209fd5946492e15943656021252a0a468285a987c2c4a6386f8c7dc3670e24e95159f7095bffaa9fd1622acf5913f8f0de0feb0d9c5ece1ef193064a2df3b33a0e03d7f870bc67411019de1772c619461c19263e69112f25d536358f5a0a12872a56529278b10f2d18a66ba4447dd21e393cceff7a5f5039a8290900c5751313565225045291423231ebd41b2eba904851807c6a41630fa70e22910349e020ac65cab046bcac1919484a22273eeaaf9d9403161da323b9e8e78fb70939c0735e5a06cb01a72af16232124c468a7268c52175995f4a0828403c5923537b26f02086ebd84f01d3635305968923851bb98bc28ca370586fe6ffa9dca5973ed8fac2ff0dfa21b0a84a1ac86b1769fb008c24c2434e55afa12001cca75eece7ae59dfc469032574104f01c57a6c26eb180fcb18d71e94d19a02245898ac213f6afbbee4af6d6ddfd7b9bdb7a42cff0571830ff2f1bf41bfdb080c052549434126b53f81e4a866b894c8a73623a88e31e331862af683d6f0e92a5f239028868bcac4ccfdd443666ce60d55491bfbd1d9e3af08076af219bb7f413967e24c7228181792aa4189c251cdc2c8a63213080f788c671ec34852392c21a736e2825319350c6b5b29aba0ea29aa021785a96261a2201895a778830ff52bffbe1d2119896caa221587498b40da52493d93cf13b2dad40192b08d897e466a197b43e9b9872acaa90579ae623f694d8d3a399410d7eb18d3e335ea4cfd6924d91fa8cdf052abeca37c7b7f3c076235f9f89daf75cb92119b4f6ea283751c6ec97a5184bbfa0af4759b37352ddeac97b5f683960b87e58d27726724d8be16c4baa4e7c4c87635283ec969be9c1c810a9208303fb72119082d9f190fd650450df27b2df3a1c570b2862af18c6cf603c078599bbc29ed7f87d0327cbe842ee2914d09b561088fd6c9be1f8fc4d419d61bd6f094de2fc45466ed84c0251d0f5b3aae0fe6daa18bd6174c1b88138064c6a92a4ba8fa352489a2bc9054d52de4a282386a291f72864b61ea1090c4833c529bbe2d6b538b50462dc248201cb8101ff5bfac7b3d0fe7d9723b06f763660c36f776860e9bb3f1c8d4a49d02eb601fdef2e0823911a5f64039e5a33ad67e2a4615c2bd35c259c5422499affb8a9528842ad6e312d72026b0a5247511ae5d6d2f983c36dce714a092f14c52f0abeb30efe2b0f3a2cc41ad658377cb7b8f0518a8c99dada672d0e4a07c2eaeb51cc9c084640e3c67ed1764562e072b165e2d3f99e7178cff149282c48b716d210e6dc8471ce108205cdb101792e1216724f0623ff1a096eb38714d8cc84f012226475d52de7358a8edb8a2647ee4207c749e7fd2df0bb58fa57da865a0fbdb70adcd2d8f4ef7fff69ce99dbda9030db2736cb907f80963832e17e3b4194e1cc84bc9fca0457ebd46e1a0863c13b1d6c120591bbf41d135c5332726da9f881ac6a9a220b291592feab98cd73625c32ac6458930b48feaebc37b11ac8a8f3199137181f36ad67fa8cb3d474f94446ff627785b67f64d2d703d6ff82e86fdfaef5bf212873bad3bca32076595cb2be7705cbbbe601dcd618dc040323c2a4dee0ad6732cf7b49d4571af89fddaa5267e37aa292f781c06566cc6005414479ea9471b0e6ba4580979aa989f71e6f7ac13ecc14637fcf5d833ab0dd74b5805397511471286a917e3c83231172dc741ea429edb0c670249536fcd466454213e924c06802a6a1b4638347568149447658f3d95c2d4bbba1d23c1802da6735387f2f99c1a4fef6aae1cacdb03f1e5f2a2a08a5a3d2e18ce1db34e64589ca461da9f56430e55ea51dc9710470e0474cd782161983831194a8a5115874c52091d6da720c02a0aa07dbcbef7b9f9b5e573ee8c367f7fe2035d707d832305d754210171cf86fe48db6682f9d0a6800928e99a857abcd52d52230e41a2106125f2678061544135a8194f00e33d108799842075d1f198f89e89ddafc70daeb4cedbd9120badb736fa0caee233ec854ff6dfd8e8a6cb716236e4858843e851021de41702f2998dfc08c45894314ed708070e25814731f5909f958ca70d92a8868659185408a312e11c501538946bad151caf4db3d34dc64e083ee8a6c978f44ccfedbf70d01ecc83b873ad8bb2561c95b15f54c8f0fcd06186d9885a26a3754c869cf9d04592365052a57d26637b85418b3075a0b60542c6f57cdfc4f511472405f1897cb6c94db6a4c4dbe4651d5a13bf643d12b38ed1b34cd5679c3626e7054085f8cc86e1a0a424b06332a837b1c2bc617e5fc4b8d7221f7108a0831474281ed5a64e7ba87f471c8547d9967541049fb4b6c8e7c3b338950919ade841f97ed1ba3516c46509c3003039a8623f5a233fb7f5ac41612619469c026821021b88d1a6ae1d6102fac8e43c305cd650411b91c4a6207211ee0b0ae8d19a625332b0f478ddd9e005f116a62e94b1a3478b5d4ed65e8712ef399776390dc557aaedbdb3d64b37cf3b2583e660ed81ca6d2fc8fcb5c89f5988040d95d4d5f6728c7b16e4d0856a66c5246aa0846b2a610bb1e09be3b903a5f629139b2a26639c6bafa84461e44232108c1fb53fdec7a84dacc7d43d39b3ef7267544ee787eb0addf2fa82f95cc11af2916064b3074b4c2217e2ba41387559485bc8b39285d46178c42919681fbc617e6e4155af6392dacc6795f6dd118e14c4234155268edb1ebf9e43312157809183ebf2eb5b7e39d69ff26105415622a9c74b2620ce6de4e78a693f4fa680e24298fac27ebf867e6a419e3450456bca6796b681a19faef5394ca68aaa81805a0e1c5d733bd74e130d05572b26c5819a7f9bfd822ea717f458194a2df34c5e0ece9b18f73ce4a70e048167d85a9eb810408b716a5330d0fe92178769cb78511afb420db4276c337f6643c04ae61fb5d3deec69115d0f9d091909fdfe5ff997ce8478651e9ad88fd2f36b6fc369b97f06f7b3b5510ee6a05e2eae30ac991fd9d08700fa7a5cf56b86672ec5fd92490aa8d6bd7ecf863805104080700098dfaf98f627f90c4035f3a0b699c361159391400ab6484170c2c7fcafbcddd4e639bc26965ed00798292a4792ca01671895304c5d4802cbf8cb3c5794271ec3358061d420b337520d280ed6d00f5a0a8635f2451593c83179367858216e72ba8f8d2d878ed1f2960cb54cd8d6bc3e35179722979e98fab0fdbcfe5574c9fa570ec23d07f1c8a23cf2903f53c8d77e54bfa27858c7fe70334f43546a1b9fcac0836ad652c9a4596bf3fbda26f1a09f0218c20661dac4b83c5affea4d8d80ca75dfcdc1259d678b69989cd1971ff7773b5c83f172f5b128aed7cc9fb9288c00e2263f0e98da2f3c2b111725c57d1e1b5e71b6862458439c690fc08d7160339c3708334155cfd432d53e03c4b5474fac47becfc53fecfb5c2e079ce161494d8d6f24a98416949142aad7303e9490e75eec27160bb58d352c5968d64984e1644964727ba159c34e6daa4602e252cb7a0b9da843b98d231fce9dbce07a3452338f695bdeaf15e3da9ea78049666c014a1847181afe8ef9da3feea9d8a70d22c19a2aa8a01e173c7536ccb01e3bc62754673cfb6a02b2fa9698fd1397876d6e53f3ea826b6485a45c54d0d472aa5bc47b2ec44943f90c504e3da86883c2c863527b3aa90b79d222bf5f6a3b9df9034141622155db5a969bfc123c738dcd7d5c1e3c53b0fc6964cbe19a2e177c7efd6e2337f67b7afed75aff325327afb690621cf97a8c04eea64e44de6abf8e92c0a15c8f876185e4a84632e331ee2918b28af1de663f8d23760e05570d23854dc7c373ead61a16f670bd88e0926ba96b3d4ea8b68f55e230dfec5da8181e9431d1fa28f53635c058854268213fb0a0f193730f4a68437fc358c5daa656b4a52a724c5db83f9a8fb56e8b3b9b53821e0e738ec125f5b582246d5148d79424aef11f40d03053b73d6d28816b08680b01aa10a72ec34c22b3560d5be363286d63b3121164f200e33055941fdf8feba07c393dbedec4440ffb6617d44992558ca42ee2d0327b88fa590d79ea52822ae4272ed3be1919541030ce7051c230b010cf558cb31a8589f64b5ad3576a20a13f905a67a113f1b85771968363e682fb24385ace9abd0f1474914f3de68f6aedab425cd490538fc9c065245008072d255a16e72df20b0e55bf62feb066ba0da62e543d8f91a4a1b8e79ef00bf61cce81fda02e6a8f501e002a130b016dffc336c689422455d0171ce19985b8900cf7ccbe7450260df307da8e038cc026c6a9a9a94b7156323caca09fa8d82fcc5ee2c7dfbd587ece44d30bee8565f6257528484d8e3732710554c6261753cbcc4cdb286be4078a92d4833cab985f3bb1a95b10580cc386191da6edb3414909744fd5559b12b19a8c173fa74eb960e16735892e1897c1758b70e0325cbb54f59cd84f5d2487dcd48431ec6a59b21071baad9f8730aa910c3c8467eb18b3daec2189030786410349e2a230b5e8f13da0eae9cb1eda6f6281a764e6276c33b8e5d105d76b4725935a67509bf27a4d256de9b64e3ad3767d98b690a09291514955008c6f68f64fc9cdbe7648a576eca700f965c9f0ac31b141959ca793371c52b3e70f3ee6a7ed7885c379569bf3165387edf7bf9b80ac9dcaec09aae8759bd7eb776ff71670f67b14beda97e935bff07a6d2f5a9db3afe79488e7db71561fd605f49275ca4a26b56d507b8c442d928905156c113735265d6d7f1b565bc2352259c9a46e439b384c1aa87a16c269c3fcaca47820110f5a867b7a9c1ccde3dac5670fe6bd9e115bd37d57fcf538c9505099b8d09f5990276bc4a9827c58a3305071382a633f6f621f554c8e6ae6a392aa118718aea1821623898df0cc36b1749955da1fd03a18f9a3a371924fc6edea6d2c731fb7347b4d6cc7a782e2bb82d5ae66f629fb7633ce0fc74ea07339b9033d68723d9335941188fd5e03e540187b97a42e33f5bb60a3c72af26b80786ac37050c7feb0a60482d89f01262337c641439596dfd4a5e44c26f0addc792d1b0ec4864ff6a73dbdb317d3b9d96fed609d0178e75a97dcb7084ac411af5d8aa9a23cb5ccfea2a6be6aa2e5b662bef6b504a7206d11403524d0a1bc5fa250fba8c31afa6519fb3d05c990433e6b20191dade9f49e0f3735460d7f2aac73f268dfb53f3cf72f58c72926014061b46604da148c4aed3b2099b6b1ee3f1e59b1cfead8efb5d4f855d461e1b0a64afb61694bb5ed8d0b8178c64d6d56bfe7c538f24ed403b58b70c7939c31de767be91e5af7c7f0927b503408275e4ca8422a0588e76baa023bf66736939988714f213fb110af6d248d5722214f14f369835451c5d8d46303088c24c474cd780e908c8ed6b23dba47d6a971e6f4cb7c9c895b3212749e1d5e1fbbe83e2eb4d5734edba5544197aa4115fb7dc94cadfc9e6b6ac9ca5189c261897c24a03f73112e4bc67b2d22510b151308f73cca2940be90c666f3d3e371b379bfcce5d2d4e89986579fece5135c72cf71c0fcdc41beb62f7b6d4c4652eb5a0a0200f9cc62840914a66e8c67dea6164d29a0eab988681b94f118e7ada97108743f052d0281b6658ecaab09f154110e56c5cb5efa7c625f69b9bfcb1179d34763b0cb653931373f39ef701da40bee1f2e0387e2dc85bc5671983ac84f1dc49164987ad02f2455a6d60c8871a2df45cb78e231993a0c476b16a60d52233df6d6da778ab19094f7ccbe8fbfb4ae7fb0df5f78f05c66f5d4297f6adb8782c1d3749f636397d370fd6253fe066bf749ddd403fbc20517ad69874256a3cd9ec50dd4be360f5c8a23c542c3d249a6f506af5d26a945796ad614284035e3b91be35c511e591450b5e1083201d5509c88d33413e22ef39be1f34466fc708db664052fb80f406cf261ea96f28c235caf211635c20301435443531f7854235fd42c4c3d888336f6238bcac0813857880ba363a8aa1de6f71cb3ee0092861ddfa7f25d8e98a985de4ee5e0c9ecc17dedb6e7f878eff6cffeebf579a8d2feb8e054058dc98327d032714d53af6758325e948807363475ba32c1fcbe403c724dbd23a9f546c991c9539835486a8f6754a26373fc683fbeec9f7c2206f26e3c6eece85cf7f37f83b109c150404e1da86d61bf5f31ccea98242d541130311015ada1a9955a370ce7362291a9994271514212e9b1aaa0df6b114ed790443694c171c6e7cfe530ff4abf6e6a535e90818c43e821dc5b4315d9da8f46b8d7209c02ca0782c9c48126df3052ba5f211712cac881385dc761e221252405b0857e29206615f2230bf2e3fbf8feb17aa887f34b3fcbafbb20f318d90844c0e41691a089fda1446ab686386fa0d2beb3d1176dec077acc3a3119d6cce412e93e0f2c08461505496bead1f3da8161e02075a2decff97d61726f2f66eb84b0617820214f3d939f8973872ad898782f49d6a61e92cf040bcdbe4436e2650579ea2053eb3037f5a4a01a7266ea851896bb4127988c8d2ec8ac09597f562ffc823e4559c57ede6879aee78cb623a064558c3775b121866be4d33554a5847e56437f28981faca92a0402d0462175633f02940cb4cee031a1ebd83fb137e4bcdf1495fd34198f44ec1fa85567c64070c93de73952238e4ced4e564199b490500bf24c2295b690536de3b610cf5c68d8c2c2e4cd987ac13cb7a89ab50c2736c4869b6b284e5c74aafed55bd9bd9ce8b172309691ae20be1cd3cbc2a18421b4ccfe3a24f120860e22038108541424aea953ada2966d9ebfa280ba90040afa35805ab69a7a31490b3992080bc9705f9c9c0f6ff3e9576c8c2c463ee39b2f682349e8c6fec0d44730fb0260e8c01002e31b85a985c040c67866c13093b19fac631f3a54422ff6033d0794d64b0c07ae9619ccef73a87df413bcce7bdd73d84e8c2e177795d4c8064aa863eab848b8a638f5ccfe6b72505355bb7138ac10ae5d64b80bdd172389482610199408f75aa8f58c9f0986670d525ac71cdd4fe0557e5eb960e7d8d6e36c41c1d3928d87edd439d867ed25fd678a0735f4cd7ec9b5d6ad140f4bcad386ca74cd70ee314c1d889336d67e8a5f7016a64e1c6695d639d0cf2d537bd8ec89379288a70d0b998027d655f371f67c509f9af17239f94115aa6118794825360b61cbc2ac32396066fd48cb8db431356979043639ad3d807c2d5b59cda4d9a3b88e0dcf252a2d5fa01a96e8584ec0011bf884ad6bea1c7c52dff79279af2592d11af1dc637ee219df5c0eb5bce4b1df53667f04a2e5486e211363491be68b0a2aedbfeb7eeb8bd8c4f0a08d6464237f5443ff68dec9eb1a0fb37d4d878f6b1aa6cd18a0074ad003ddf91172b06283abd7f9dfdb76e5397b7fbcbfe6df5eaf9328842e235a4fd31629c1639c6bbdd620a96de1c8a6a60245ad36fbc850a0c7250283127151213cac184e6d4a741b51435c2be4f78ed6d6cb6ffa606bf3babb7defdff7e9997df8598cd0bee8fe29b85fb130b521af01d37a120f2a1822c178d052cc6ae8a3da70132a0050228140d4526278b335e2fd92f15a699b320e130b86238964b23e5e43ae10c5cdb09ccad1f3745307c2b032a77d3073cecf49f819ff7d41d608040a623dafa94379dd521c3810072df3538f92c48a71c991d4f65456329e00edef4265d6383ce8430fc944c5242b1108544c128078a08ee64b6d9f7d5f73ef941efd18533dcc4c5f904d437ee4402504f2075ccb49e40716d373480d04c5994038f1286195a96b85514955ee509eba3119722ab38ae1921b1d4c2285546021c08ef28c6febfd9e1c5b820173df1f73182fbae753d220a0edccc8832af5ccfe5692ae191e4aca0380ccfe613d0beab9a97a0e94818bc0b04426779b95d04f1ac4b31ae1c8463c5794400b9da8b33709bf9b5a8e748c16fb9a7ad21653821ef2ea4d9df865ee8855110edc73641c2385b8bfb6d53df12caa9ff530ef74c15a7ad4dac4425257dbb5860195da371c49661831241066350248cf6f1be241cd086db45d0cd5a044807a54fb913cb021481505d08dc9895a7af3a1c8c1d55351d97c0abc83fbcfa28bae3ba6664f6aa86a8bf95113fb5abe070d32f182c0a2dc70c212f291802a00663f3bd5e7ccd77d113550699b77c821d7f69c967fc312fa4739ec0f7b4abeb7f1cf989b76ee8cf8d8d98f9fcf1896cbc587317419460286034e39e3b1a97992ba94071e35f940914bc9b0461c71e8f780a931cb6736d47e13c94a88d335f2a98d7c6a31996a9dd01cdd736c8ec474ccc439f9eef95cd89fd4cabf60edea7ccd7cd868bf59db54cc3025838a997a254c2260ea303a90076b64d6165393870d0113080f36fd030615c591426458c72175913cb5be8df8d4e90be664652e0faecb5c964537767fd450c56a2d6b609889186bbf80028687756cf68ced354cfb46b828e330b11148d6540d6a08b4be9ca9d8ef4bcaa386ca418954c94f31b939c8965acf1fdc13eda2b1486d6367556cf64485ebd8a7c0c4f425e2c82f04c2d06666df4c2d7772971254439e5a2c0c1c48b4bf9c712829d0763cf34589fc9e75c227528cd8808da3e5a63648768efff8f19cbf2e9f377beab0909a9a8114044deca7360c878271c6918ad466ffd9d4c4b6636cea0c5b908c24c211884904e21055cc6792f152229c37149fc8a7daede7fbc9fe1af092317c021d847b362543410d7b0c1d140e04f273270e138ff9b532f5d47056229234c8d77675d4c2307011811623690379d442a5fde95adbd90d3c6a57eff607d8ee29788e6d0db29685d94f1666ed64ccfe5bf45b8ca9a2b8a83731cbdaa6242ba92a4aaaccfaa4c538b4283676218078d6c621750c6fa3326d5bd7c81f08887bebd8173554b306695fee176335bfb95ef976ffe8c37d092e5817c989b110b1ee4b252433fba7b11211e8525e9afd9d19169ce1a160587f8e04e4ff3f7befd69c38ae360aff955db97d7b4d6c19f73453b52f00836312c963625b48ab564d619bd89625e00d10b076adfffe9564202421243d6b86f7dbbb72d11d6c4b3e3c7ace7a0e1d53f719027d1b820840a75278baf531adfc30af294bedb33149fbba47e54e761ff7d5fe097cccc6c3e5ae0f1b3fd1877073c7d24bc6b870ead2028599d29b5bd4e10cea5afcdd42d979344c6bc8822d74ba02096840101810101b861d49c30ea06ed0222cd8f8615cf8d8ab090b747fb1b33d0f4ef50cdae509646ebbd8fbbaa6e3e84d1ff38f7074e2f657f0a4afab5aa3cbe504b6881c312afa96b2a151984b9dc7848945c5a0440e658a6f6abd430e8b26cf875684754b180e74df69c43857b0a5ae67d2901834ec9fed854974aeed724566b1a0e290ebf24ecdcf57fd9377bde72738e3cffdb0da1b321e98f4deac281e9a9fa9b99182a2380d7b72c978d71ae93a8eb949c5a84061a705c38e41596afa4e0a14cf854e6afb0ee2048f2a24fa8086b941dd40221c00aa7b1443003131a1ecd830a48284ddea83982d39c1d99ae0cd6ae2b69f26b579243f4ec5720417a56f140e389250c9e38ac85141649721801811a30282bee187a38a8afe0682918078c4a12006624ac6f46b0408802e047e880464c4f09dc044d83b9b5ff2d958df5d6deed3314417ec410a43ed7f91d41914cade21cc6b41a723290b36d48d3684c58cea9abc9e05c3aef0b16753174a2aa054fa327211d7f5ed1d5a42e001147ad647f892e0c132b9d1395127f0835cb20eaaa061574099315fe774208670df20210104070029be1e2286e4a82278c0745d5ca7cb90136c9b5e89c4249272242b1bbac312391e80cee8a31847998881c8dee315e1056d3f6dd30d2b08608dd8a0840c6e7c57d932f986480f50dd332e6a51a76f513c2c7c8523ee90fb61daf2c3ce163a03819c3e202cb07c175a3e46e7f7cec4e889d4264b80b9a2d836f63a44030fb3a2e3e122fb541c335a134ccd3b7cd087ffc76109c368e3bbb1203ade130228a21aca7c8b00b19140150dfbad46ee453612ba8fe3d6c7fd16d1fd1e29f7dd51092562d0812672500565df3c9bd7f917eab6879a54efd44dbd5cbf776f0b99e2d9e906867d491daf459dd482b20310a005619e0119013a9f40469232ca49586d51a8e41b3161a860ed01aaec76a5bfb1bc451d6dfbfc6c8fccff2ce76a860c82ed8a88f7626cbcb5aeb17fb11a38fd2d04b4448248bd1f0efab5c231e4287b2b0214434059bf85c4485027da12e06d7c27307cc7933ea61c81212338b220202d04a8d0b6ed59dcdcfbb4ec87e65d3ed1c36b860c7aa37be9bd13577b499f5847e9fd76b35feeb560080ddff54cadc78670a374565fd9f0b86f4110585066a5d61b70207d9772ea8c38d5b62bb1a1eec539a8cef7171e2d5280b43fb0d1f9dffa9277b6c00e46c7bcf2c5f9a338da5d4ccfbe8fe4e93175b6afd1bac3f59fae2176e29d4eef155f301e46e61609c98684c186ea58f1dc20221650f108060d84872511c39286de468d43782890ee5d14b560982a9b9821270594c50ceaf8df2eff2066ff635eaceddfe855bfc7237fce4ff0ebcc1d59147bab09b60d3a1e6addbb7976fb747c67d9b22fb877d3a2a26fea1a7f38d850a76a516720a8e8b708f0b6308c74ff2d2422a0f794656aeb9e02924865e741d1df12c92bc2821ae21183babffdd9bdc1928c11bf3bf487fe8bd662e7af98cc9ef3fc7736de7fbc56e92c5e67ee7b3539faebcbf56af26a1d63a86b8c408964c742cea82220d892b05ffb8a8674cdcbdc80c093d4212dc24615c470d3f8e95253d7af61710945cc75fcb2809b8ff4df293eb137d6e4a35cb0f6677f4bc3825177c8a9f02c5fd7108f0bc4620edd51e9bb9e8180674186b88eb1069e4564267c47c9056821d1df22996afb08cafe8634f592cfe1e98b5e4db03cec33ea38ba0617e3f504a327ea46aba9cb3f53374be1d48a80f6f29d38c4ed25eb0d421d4f17b4fc900be8c62574908072c8a98e33e96f88de5bf35a244c6d9d331f720e6500108b00c49441775051161934f40075f21691b1389fe3b3cfb57beed7f111bc262e9767e2363797ddeba705d23d4203130162ea7af62eb4288e4be446a6af61d9977e180bbd47c786823a830a391d8597050d5389400090d337a1843614914dcef7dc3ffefed5049b9bcff4abcddc62a1f8612adaf51de6abd4ddfccfc38e1505940a76056b6ad20d4ac2fa26c5a88061b7a2981690552664b4d4fb75b25b40a6e816d6047b06949524000912f60115de968470ebbb67ebc27c827e91fd999e1e995bd4140faad46d3f9dce77ca2fda0b063ad1862a5ecfa0a44eb025b26fc3b0d3220cd604c405944a0f0e3650a242dbfd8072083c030954522730941c40212fa98e65cc0a2a06c5591fd92c5e8d01da649fa907321b2d12fc5e0e5370b9f859810adfed9bd08d056410689c73069c626f43b1b2a588a5f7019cac68f2c2469cb0518942c4101e313fec0302fa5b2a021b299b4ad9b2e7e3d2ff431bf45db8d577ccbb606fb54e8b84052342d16860f96164c210d6dac67286150c0950b6938fbd1a399e24389228cc011403aefb52612289e81b84f52594d0f45d22913c2b6759026c990dda62afb7bdc8e3b646452246e5510fc5bd8eb6ef07a5e0f6ac4f9fe971f71faccb797dfdfe92bd6a2a1301253728878c0a180e1961b482eea8428032245340840710e85bd0211286438ea467fb78c0a9931a44161575e2128619d73d044154d3f3b17c677ae4be84cd5ed6fc2c4cdf95514d0cfa05fd2e31d339ba38aea8185488756a0420f0313191536d092006019e54f24afb1270cca8430bca5203b2b4e5bb1050415a44204e9d1c105688f3f1572773bcdef6107d27c7345378e30e8fd6e3b3f28cafa7e3f7fcf9de25f7bf4cc2a21ab2ae804e5c12965534cc0404c484005a447600c2d156d7b166708ba407fc900a1a0e2bc2b8f03134a85314d4e1257263ae7b33c9e06c9cfde1dbcdf691bfe513f83ae38062f4f0011fb8604e22aa4898ead8261a0e0ac48841596a233c2c21262d12e616c5d0800e1584e536093b350abd9a00026818e93eeed4e96c911854d4a11551ba00fe28a667d77bef9d3e1017b48301921d4942cf82b26a7add397da973e4c36e49c381d07daa1d6853a72b88cc5bc81d143a0f43c92a772488a273270294792d9db7e85467f1e69d1e8827fbd6bfaa59574c67fc41c9b1cce5ec84bffa65cfe17d5dbbf245ddbf8627bcac11b14a5c6ed043aec3a1d6e08202ed2b9c27a0fd78377e5e83c3fe8d3b28ff0379a87160df7bff9d5ee617ccc16cea7ffb4eb5a56c586a1d17931a897e4d9d8ceb1ae9615f42a06b189bc845ba6e290491e187418be27ecb0f87151201f09d402216d8e7f34c86b6c24f5ddbe3be053edba7fab8f774e2b60ffde75fd555d039cfbab7c17d6bbbb75932b7fdd8f4b9fe706d6a82d12279b766f245f5489b60a55317cc0f5303399584e1801110d4bedb3720cb84e2e584450082c8a22290100f0a2288ed87c1d677aa1692bcf2f148d9813672bd968f3f5907f4658fde27fa21fd78eb7dce5576a3e4295fd3a35ea61ff9289efb8bbe9b7ba5f498d6057d653615648b5c62fbaeb2954725543240921a39450195de2e070c0a5ac03050b62380ac02ba3fa6882bc4b28230cf2672c491abeb606d507856875f92f1c21e5bc820e3d1e233f11447703ed0ce3b72e5823e0a5df7c746ba6774cc210b4c12764c04608b86b981c24149b06713ed631c708809f0ddc826a25f13361244689fc486606842062ddf81263ddf03e615fd77f6b5535ee1e2a7e0a9bf97bab6d4386e8d4ecbe9b0ba646d962d01830ac941015db8d1fe68ec69faa6ce501046b9ef0c85efd2128aa88544a0ae9984553a860c31a59b740b82e3020aafa5fbdbe1fed9783d32467622e04ac16e32dec7879dae1f46b1aeb559a45abed83c7dd3cf782fcf75afbf1def7ed92fe50d8f1183357db7d6d8683e19a3e71e832f78bbf627d79ff2efbd58eb5d2ed03bf1f9175e6f1d7384c24a12062d18f62ddd87374405d436aa277d37ae20ab2cdfa505159e4d43ce7d3790bedeab18140404968e510ffb2dea920d01e76bef3dc703ec6466ef9d351c7775aed404a767f5b2e75ace2ffa36ecf3d56402b640f1f94490bdbeb52278abe0bfbfc70b9ff5a99ed53b3da74a6650d37ee67e4ab6db8a8764f844ff7df5dd17cd2768fa8afb610720a7aa499831aa697328483862944536c21e80cabe7028238036717c9297040c2b8889844e67034352ebfea5615142877c607b3cefb510c1abd3bd95e105f7e2869c62af454454438797840d981fd2120165a7660cc9a0866e5023116d901b3302068cb02ea778c091f06cdfe972286341744e0eb17ca7bf41203a1fab78dc7bf3231ef1dc97739d584385a38ba9503ceb543c7c433b978b1b1a56280c4c3fecd8507a36720685afe38a09a0acd3827258511c57be33e24444ba863cd5f5962243d7580a47159495a44ebf4559cc7d273294def829bbffe7602729ce74ecdbbe77e909dab32e6bef28bb7dc811187224061c82be4975be6ecca9130bc202b3a93b5429dbd64412e91e1dc8a90c282243f78e04030edd6149c3be4d646a7f5473e6081eadc9e9ba3b17ed93e6bb881196d7d4215bcaf20d0909802016caee473a9644e79d02dd374de969126e755f3e0ca5defb767200251728f4a4ef64259448c00f7a7264e3e1f22ddd7817ee7fd937a1eeab924bc2861594a844983228e30a86398058f7c20784c11604c11629be2a4605c2d116b93a07b2f41d54291d9f322aa81359be7b36ff4d28de31b6e23ad1d7da15c57b9d8a5789d8f7db368bcc45733adeeb395dae7848320b56bbdc116d93fe647e8499617eb20e8bdfbb24cc870c6124fcb0a87cdd73cb33743cb1abfb1d6c609809e846356229200c297e6e20966f10200031d222616551057b964a14f202026890f3bde15fd761d139c81feb076f63f84ed0a97dc9b82e84292760c448c80b147a36c488293d9eba48203062d0f10c1422417164f9e1a0802cdf50062de428faeed8d08985efe43514038e1c22157ce907b5c2323090a775836a0d7b2b8b8cd1e26e8cd664dc9513b76d285b898ee9828ed3cbede108c408185594c11a85914145cc88a405019ee9eb6f1e16baae911c72c88a123985f05d6810d96f69fa7529a7382e749f219655be1b99ba06dc59fcc88a1454277d130ac76e2d7d7d9502bb486fd03cb102a59bf24c709ec90beec188005031ac7cdcb7fc30af7d3caa201e54d0450cb20e802c2b291b705df39da526127d8bb2d4a2782428cb4ac4688964072097d87aaf8665ec43f9060632d1fdcbed8a82f8b47e54b6ac4bf65c40e188d370502137ae9093035da3d969f6996848240d830d625c10392808e30289fe56f7d271aa1a3a29a0ba466397211c9790553602f46cbf9077e2aa5fc797eef7aa3ec18f143e194a575f5337e34969ea3d5cfa4e6dadcbc2d7933a7682d1023ac4462e6254c4ba77931f8e2ac294dc8c2b88a1246151685e2f46951f4240585f2a784357d7856748d7441e947ed839abbb9359bc4addc1f2e0dbffc88ff0e91ab3f353b09613775037b2faa7d7695767f1741c3c9297eb9b019dbc054345c77d00c3404297728823d377bd16742a40a467f8616a42166d75cd83302b2126808a40cb1a1f07a68fbd0d7269e9636febbbc3ea7c7cda0bf8be87fbabd48a37a9dbaeb3cff86a5ef196c33efa1899e94df7293ddda7bfbe63e905eb032939e319308c0c28a88040f72c34a0b6cd9bf802ea746cc2a0a5fb27c81c505dd735da1219197e185988e592e81c8e8eed3b59e18767759ccfc76695a7603854b8cc9343fcfd5f8aff87b9fff3eb12580a9b7d27d5b104302c38c58185701f20810472788958cc75ce12cb1861d0446edf22b8bf45acb3d13924615c11412bc8e21239a312b91ff959746ec0ff3f7ab2ebbdbddc808aae656a53a67b156c6138a820e8d724e41c29fa97e906e91c7acf2632d85225f39d4eede398fb98564866028268e32bde713ee6f7d08ffe345e7d86de7945152cc4c99e1097ce176530242d3f0c36300c0cea0635c4bad7908158d5d2be2ad13790e84b0802930ad8426ecc89f46c8a894d5da56bc29a6068d3106e51e801c232f641bcf87e4ff91dfab960bdfd9058d48536d5fdd278e163af8594bd260313869e857064c370c0202006723c1385b90105dceade063a6316315d6bdfd17194367472eba37eea87fef4a773f32e98d71133df81360989855ccaa8e6c9b98dc221476125210b6a8afb0674ba0511910d656543961aca8e853892be430ca8744c1cd4beeb6da0ab8eab73b473e8c13f09490b95e686d4a63a57255626ef70b6ceeef7fcbc81d1dd386f21fe03a0de3b633fa6b5e63e78684ef0f6b45e79d1d8bca1ce03a538e6107812b90346c2c0f215ff12235dcf1582b852362d6294231100a86bea0d0be8420331684377207cc7b3754e13ab6c223e8ac939c4d42f10cbc1ddb8cbeec6eadce829b3e08a02fb44dd2edd97e4a2f5d321f014bf0150921a3a41adf569bd1738e008230e1da8f8b5a02c32101e3202862561d0a00c9534ecd8ba07baf000c19e09b16711f6a11c7b996b701a372e59bb6c43310404442d1da315462d5d4f1fa8ef8f4c22738bb2ca2461a1ebc4400137448e4ae874b690799232658b4089dc48121099d4553aefd978e43f11db738059cb77e80362c12a75e14ad11975db565a9bb364f65e4fdecbe57b22d9af69e8d548e6bad7110a330615cd615441414bc88682841947b86f22876c098e5a340c5a54f46b02fa96afec3667c8a8805b3f845b18e6927ee823e06b851b2769e9a23e60aff643a57fc7250af32d912341c3fe963052c3b0b27db76fd230925092add6d58567f8ca560dfb5b248b0abaa8527a1115b440ee88213160447e8aafff0c1ebde821fa4eff860be607473601b1a078584117b6fc50d75cd7718f54d1a1d203642aa1aec71e9950e8beee86ef70a6fb1838d024926c7d47e9d844d20ffbee9ce8f15b9e90578d0ffc7f5f7dbb5a4c1ea7b3d5d56fffe7eaf72abffaedeaeadb159a88a9faf5ef7f7fbbaa669355f934fd259b3e5d57b37f2cf83a2f67ff7858cfd2dfae5753b1e093d57479fdb85eaeae533e5f67d3a7e96cb5bcee4d1ef3f92fabb9e0eacee5ec61aefe66d3d5a4e44bf573d63ce368dcb7ab6529a757bf01607dbb12f36c7af55b0b18fae71fab528f060630ff61827f183f42b3fd9bd5faadd5fae507687f0766cb68ffc3b07f338cab6f57e5f28fac7cbcfaed61c297d36f57cb5a3fd0993e5dfdf6bd659bf6b72b6f36bffacd6e83f677bb0dbe5d215eceaaabdfcc6f57503fd6b2cc1f3fbe5d456576f59b6918e6b72bf7f9e7f88f3f1693ccb8facdf87635cad44d8d6f57f7cf6fdee555f31d2da3fd5d1dced36a79f5db8f6f579d5529d49bdc4fd3abdfccef56db300db3657dbb424b75c6fef1dd68193600fffe76054f0c357eb4f6430fdffcef6f57bdcf0f1dfff1c77ab65e4eb3abdffe697c33be19fffab75ae262faa801a46076755dccc5f49a4d6755395b5e6fe68fd5723149a7d76979bd43857fcccabc58f1fa1f69f98f97187118b19cccb264be7d8530d7d93c5d5e7dbbf2c462feb8fa7db22a5ea0dbeeaa334f9bd3e1e4319fae9adfa3f97cf70b4e566971f5db6ccdf9b7abfbd5844f0f0bad8f46d3c9723e6bc6baf341c9a7cbfde8e6b9874367ba38fc0ea7cbd5abd1ead4ab19709eadd5f3fecfd5eee5df270efda6e5eceab7d5e37afaedef87adfe5a38cffee615cce7bf8879a61f164f1f97a586b4f98bf95df38a8586ca9e919c05ce6ecd3fc942fefded2a9bac268a5ff023e3ef4533596a26029d0b32504a27a72e378e36513730ccb532f79aa18e83054bdcb649dd18506c1bca38a7ee32fffdbefbab77f35609f1ca4d4e455cec826eb5f355299f99cb5b1e37f2876051106bb498f64c8b62af99577bb704236332ce57e92cd86dea2b03fd38a1bc0966f3f2c53201e94ba547c4eb8cb79709c86674ecedaf354101f9fffefb98fbef8ff3f4a16c28e17dd67e187560eced4bf275eb2fe4ebed2fb6fec5d6bfd8fa5fc2d60f6ce199a967202efdb2f39481763db19062f0fc0e0c1749d91619b615137d4af2bf515b1df53b0eecff22b2f31ced79d891aefaeb25995aeb2f55567ffd626b5f6ced8badfd256ced99373cf335afeede67636478fdbd12d9758ff8d96d0ce22501ed15bdef1a49ddb5132bae3dd7e6d97e9e7ba4d4de1cb2870a6f309ad3fb6e9900bea4e3e1267107060d1649a34c16d9adfbbc93b35330d7e90c3eddde77b5f2a9144c1db5ef72e9b97cdde3ab3cb586ec0e98c504b7d6e90ce5e3fb7c7d67a19ad4ed15c17c7d371bcadbfb567e3f0e6669bd8f68cfcc54c49577337a52f7c944fb517dcbc48d72e2164522464b8a3bb77416af95f2ab14e6096ee51874652ae0d34467116f795ada750abad96daff5d4bcc76eeed853efbd50f7f66e863cb5ba4fc90cf1e679fd3ceab7c3b8b3a8e97860520d2ff494cc46c504db8b44a439b9ef0282b70bdaebe601d83e657834c894d2ec76d6de803f65f73a12cb4cdc204f6f62c3bbe14fd9d8cba91bcbc978c8696751525c1499e04f69d95d2433b4a06e94676e5164bd6ebe7f7fd2eb3ecba9b295dfe3564ec040d27bb5a6519e8898d39e5ee323b845b769b3f6351defbc51639853d1ae0feff10cb7a53e77df6504b772eafed8bfc322291b7863f0624df263dc395acb7d268286eb9dc241b7e09e3bd8a4bdae35c1dba5e7c6add46d4bbd8e37434eef7554c926017c9dddc0efbd7c9e7bbd794e7aeddc1b8cea0956c6c7507a371a27df8149572496a7d623084d1479aec933b778a29dc3bde6140f96999b3fa5222e7457fb3192a4d78dd4b729c32c75db8b641634f071fbf9f138cf2d38c15b63d2eb36bb909bb7f74d5cae6890a716ca77f4f3fc5dbdc3fb2d2763ca1311cbb4eeeee7e6bba8c6db1ed76bb022e32acfc648c16d3dbdef3ed1dd1a90312d26785b10b1e5de60d5187c9d85a078d0648498c6fcc823bb3308ed3aaddb550290bcabab3c737fa8755f52c19749afb96f2ae26d866399ddc09c8c03b5f64f29886e9fe132926a2dbd1ae6236db06e9f52d7e4c92cb8edf1d17c3286b9fa47eed59a6c97d3fbaea4782b743649432f0a3f8bf4a6bb9c6054346bb6c953f0239fe2b6e9b9a848ca6e45156cdcf6c673b9e1b903d99b69785889152fd5fc6456e589359a2b6334d2ded2b7f7a4f7f64cbd2b71bb790a0a9eb8ea39a89e8cbb464fa02215d993e7365ecac3f1cd88a756704bc0a0a6e0479ecee2754f7473d299df86c0668a86326caf7526e40e662f788efaf6e3b5710786e76cb5a757f1c8c46d3382b7bab38fcff28def74fe4bad2ded2cf4bd266e5c2437a3b9e7ee3ce275b74845a4d7e277cd6b3b6a3d97094045a2d6c60abefb4ea705dfc1ebdfcb6e9188e0f6b3739f7117fed75dd98d927a4f4783b5b77350689ea86830581cd1dd46adb9de859a8c47b677834c02f29c2878b8c84cc536f75cb398de774b7adf35531057fe6e6d0868af53d05ed260c174047acf045ecfacbc5ef6abd7ec4e289dbd0c44fb29bb41b6373366de6073ebf53aabfb5ea6f88ca1deeb6e3cb25337faae798cbb5d10d06482dc81854c40ebc51c7a6fcad48dd9217281cd7546edb0eea6bdb293df45f98c806835c1c177cfe9bf99bbdb05f9ee3dc3f59513c75e24759a8f35df31bd2140fcf9fd463c2bedc7440c0cc503ee44dc22d8dc246eb47b4ef71cbe6898f5f239f3ea6e9f8ebbcbc4e23a7ba3972fe2142879a8f971dec8ae67ba4b05ffdec809258f5fc1a8d7dd6478b89c8cd15cd3dc4eee1dedf0dcea8ea1ee88a7eef6697adf5d689aabbb85d75fadc978b4c84494475ade7345274a5e34cfeaaf4c22e23a11b1ae2e40c0d64cad114fd9fc56d3d68dc2f5edd2bb412c157c93751abc7a7e5667759ce1ff3b1e3d11b052b27c91d43f7ee0a81d47bcdd0d0cf47b1cd9d1eff922276e67cf43b51c4b80a9deb7e19d3d63f5fc5d3cf7dcf666273b4acdafc62343d1f75ece8c78ec0766fb7e1465c3c81cdd63a567601b4cc6c3a74468de976762504ff0a04cdc68edf5076bdaeb2e68d9c864254728888dbb9e3e9e293e444494a737c3a764dc35280ed6bd7ca1e54f62c586d60f5c5a27c0503425338c98a265c5ab8fe0ffac4f80e229ab9b6f8be321f45caa7408757c9b1ed6639367a058289a3ce2b34572839e3c37e359af0b26b8bfc31d984fb02d12d0597a6eb4a675ab59278d4be82971a35b62c575d2ebacb2b2b3a2bdce6c5a0f1b07299be75e357c4aac919cde0fdb2fe9a9bdcedc789df54c633aee72bf7ccdb39b4e26af6930b5ba9c3c579dfdde44efbea22dcc2bbfec6cdfccdd4520f9e5334d91463fe35a3fbbd13b91afe97bff7e151d93f504d8eafd00bdb7f9d41dac5277cbf7cf19f68a1daef235153ff23bfc23573cec36d8e160a574ba4646787fe72ed8f2313def515003f6be04fbfbde9300ccd6afad1f2db365fe070e85c6947bcf9ff0fd57d3344cf0e3e04f007b7f82f9fdc7afbffe097f82fdfd5d6f82f18e37c13c7813acb669596dc3faf5ff556fc26b47c267cc4d75b45246eb7937c3dffbd63b0fc63faf7eb9fad7c185d1e0d64b0fc6521dfdaf6cba98ceb2e92cad7ffb5f79b92ad6c92fe95c5ce7f37fe4e54afd494aceebeb27fbd8e1f1cfab9497d3d9ea977c7ef5ed2a9dcf1ecabcf9fda006d4cbd554ec8e77207979f4c774f6b47c758a4f92297f7d5294f9e344fd7a7d61be3875f669ced762ba3bbba8f269d6fc7c9c2ee6cb72357f2cf7170f67eae678397f5c4db3e574f7497b16f1f248cffdd791a7e79feadb57d3edeaeadbd5f4f171feb8546f23d4e1112cd3f9e374be54b05c4ec5d3f4f1baf9f372d049809fbd7e2da6e261f9de28f5e7fd7b3457af97abf9e3249faa3bcd1feb9783c5e4b14a349754807c3c7b51fd5fce72759f57e3ca555a4c392fd44315da2b4ef7ed2a9f2faafc9772765d4f04ffe509282e38d7ff5d97f3f5aae457dfaeaa1fcb5fcaf9f564518a495a94b3e963ad1ea34e5c3f4e97f3f5633abd3ac7e8afd58d147c66d3d5f5fa51dd73bebc6adc48d70a4fb53f49a1423edd2ed48ff54c33eec3afeb6c9aacf31d76a83fabc77296ab7b2c6b4d6b7af8bff6bebe7f5e25eb07fd1d49bd9a2e356588c5e374b9bc4e64b900c7271e143e1d9fc865b9383e96bc4c1ada5a4dd4c75ff372b9da9d68102e7dac17abf9e1c7f5a479647390968b422fdaee383bbe982d27cf07d3f4e561066cdb6cbf39715dce56d3c7d9845f4fb3cde4315bbe1ec679b95895e9f399424c8e8e0ed31f27b36cb7c4af2f2dd7c94a6f3fee2e88cc7e3e50f38e8ed2d6d1c1f1072c8b89f9e208d8df5f1cdb26383a7ef5c8153f82d3d636da2f8fae1755b955c43e4be75939cb8f7e5e4f9633f3f838992ca7df5b2fce94b38926b3c3997c9e1c1f16d3e39b5fb3a5962587e38526aff719cdef8ff3d57c06272557e4b67beda45ca5ebc7a7e9f233631f27e56c319ff34f8c9d4eb69f1875585b4512bb65ff68ce3c4d3e336a319d2df2c5e7472a02b9aea6f5e671f253b31ec5fcf127c64fd3acf899e13c9f88c9a7c0b29fb15fffcf4e38acc184e7f3c77255883f33799aa67f6ada33a57c76ee629256d3cfa0f67ec212547f42e24e45f9b8982ccbf43a9f67cbeb03a75d9e1da6d8f027465c4f1e1f27f58e67bf3f76f5387d4d98a746ec3847317d8db9af06ef25de09999f3ee4ef5eb85ea693d9ec3d8d440d58cdabe9eccce57af1fa33fe843e534cf962fa789d168f4a4ffee4e8c59cd70f25e7ff99b67418355f7e62d05b3ef6937a57a3317f30e859624e9fca6563567c6a7ca3eb9c1bbae06b91bc21ca77875da793b4987e7af09cbf6698ef0f567a98b6a13f3b7efe2826abcf01f0f5a4ac7c78f8c92979b92af3d9fcf167dfafccb6bb48aa9f9a35cba6db9f9c334fd89f789262b17f665ab5e2e5ecd3b3e6099ba6ef52f2ebd10bc5e2d339d72fb7f873b3aed3c9629294bc5cd57ff206cb329b268daaf9a9e98fd3a7b75cfefde1cae27adff47b3d7af538992d178df1f17313ae1b03fde7e7fd0c563ccfcacb3ff1a862b5faf4323fcf3ab0b9742ec4874cf1c40d96d3c733d6f79979cbe273e6f4278dee6757c94f4fb8cee6ab8f417eceba7f3358ab0ecf16cac7433fc14d9b81078bfee3a162fa58f1e9eab1fc0886af877f1e986f667e86e99e98b443c287c789f8e9979dcdb3b70898ac1f1e267c7e5d4cdf4a9b7cdeb0a964fdd0fc7839a014d9e4b19cab47e4af2eb1643a9bea97d9390eaecb5723aae953394bd68fd55461f81fa724eb4fb982debeffeb1107e089c962f919bfd2a77c4f53914cb33fe9a53a3d6eb9cae6afdfef1d7fd6f388e5f4312fd555451f9a48c46495160bed957d31723b99c95ac1fc1f937cc7aae77c32cb7f993fe6d7dbebbd49cee79b87b2613d272ea793e5ca7eef5a31498b0930debbbc7e7c9aeebd38e7071ce17b39e5d93be39f5d47a7aebef5f29c1aa5d479d332defba4e5bb80582e8beb737054d79f9d11fae41f8ba4ca1ece8caf66f3cdac98ef0cbee3418aa69e3d716f2e3d7fabde4f393162f138dfd6af2f2cebe5f5743b4d27c99b39ead2b3823f5b4e1ea6c574b26323af07ae67da4975f0b296b3875f9e8ce3339bc9e3ac9ce5cb57a79fddb1c544435afdb99e647cfa68edcf5ea78f6973b0d23960a568449efe7b50fe9ba3c31bebc39d18682eb1c554d1f50bffd084bf38952ed6c7870f62b5f3c31e4ecda6abd5e344fb810fe7e64bed20393eb5986bfbf0c805f972cae3f4814fd3152f572f4e2fcb59cea70fbccc8b174f5dd6cb74c2b95eaae9ece9d4a5dd0a1cceafa6cb159fbff8ba578bb8f77f6bf3f3cff8c1df19a6eef2ec323a3b6a395d7d38e669c2cb6cb2dbe4fae4c803d3f884afbe0192683cf3eacf7552e6cf3ff50beadf3b77b0681cf6eacfb558f355b9986814d127fe7b3d5f4db3c563395b4d12cd7266daafa40870a77cee7feafff6b87438b95facdd3945ee7bf1fb6a5361de506ef36bbdd44bbadb5f78bbdfa0b1edc5ce83fe71bdac672bed557dbb139136bb56aff625f6c7cf1ebed55c681ffc9b2b3b90be39bfac972f3638d2b9c6e8375b1deacff3ed7778bedf02f976b59e956963c6ef7e5daf570fe6f797c73ff4a142fbab6f574fd359367fbcfe40707d62d491c838375aff515ce6b3e3f60efd73838f45e89971452367ce8c782b1dcf0cfee08b156a66b3a5fa27a6cb65c39edf1b7840fe7cad89ebc3717bc9756e20b82e94357d665499cd26ef5c5612ac61fda7ae6a1d76394dd78fd3eba4cccac7f5bbd0d243b5fdf6307f14e706ed7154ddf033e366ea7eff7a15d7ffcf97dbdb7fac67e5ea0fc5f84f6e74bf7bf979cbfbdd21bbcdef77afbf777eb73dfef2fabf5ee522fcf3738ef433bc5cddb9d1da8f0729c1b0583dee19e6f3a0fd26ea57fac325d31f968fe973e243937ff2b78554eddcb5bf3c2ecf07573d0fdb8758b57f6d5d245b6b175dd5feebb2b5f49b7f256b7d256b7d71abbf865b1d3191a344d426a94367ed8fad8c1336ffae935337f3dbbbfac79337189a49d965d918193a1018b4d754f059361eee826575f0f5868c8786e7b6c52e58f955406db7cc305fea6480cdfce9aefea1838e0988655ab7f4737ae58fa7bbba1b4d7482d67112189aef922d74803dc17cedb98365d23bfb4e3ab9658adb665abe48ca79f55e2f9e9d13b7abcbfeed8e85faeea3e4a5390174e6971d918c63c3bb69607508348fd05322e882d6553edd7da3d7ebe49ebbe559af5b11deae740b7d5db5a0bb9ac6ed8a94f9c27f3116095adb15198f8a5b77548ec1a89e8c294f4b9b256e7b4deff3c56db86cd6e5c668feba3a2944dd63b75ea339c5ade3e06a5307e33fc388d3decb04acc96efc4b589d85cd26c35ebe6bff9353d13a2441dd768ebfa74942f0cb6e9384d6db34efa8aef5ba7b787cdfc372e40e0c126efba4da7d376b2d9be775165ecff82f6f30e4a9152f3367bbbf5fbe4b007cd038cb1603ddee87b55eae41bffd78bb4b48f4d942b7bfcef0d6b8ed558bddf7b47bb3ae49caff68cdf5b312b73df3d9629108fae4dde765f00c779da0f71c08efa9b5d773743968312a32b73fbfdf270856bb7bcbf977eac6828ce365d66bd6ff21d8d1665f27c3ec9336f204903cd3c96d47f4e3eeee63c5f5aead469e5aa33ac3482768dde50bbd96fb735e7f9f883874768973876f4b6fe2d2737522cc776fb02fbbb9d1efd3b44beff6f7b0dd05ff7bbab4be1bd77b387837cbdb0637e8da73479c8a8199dc04f3dbfbceeaf773e31b9cf9e07af34f97c70ce779648dea09b6d57a8854b457b7bda19558c325ed790b5d72743fe7c6b8ddff7df89b83e3af8bc92ce3d3c70f55b9a37187d47be3d7cba4de37ca9c65fc85a9f7fad5bfb4b92f6dee4b9bfb8bb4b92306f15a9d6b2af5f96cb1cf7dfeee576fd8faafbd592c95aaa67372076d8b62efbb3f53226e79bbbbcf32b1e226077636923e5bfcdafc0ebefb951657cb7d9eff5d6f27e2fb4d1e2b1d7b876bc12c5e24ee88a79c6ce18db17fee3201e9775fe87ca5fd3949c7c38ac64dfe957ede6cf894c46d99b84deed8fe38bbf1969ebb9009b0db3b5535bfd762305e35b9a16ff2c96769ad9e992d48dd9dd3f190ef447e915a7c4d1a756fde889768de2bb5b86972b39c793e6abe7bb93b7f80eb2bd5e58d78fabddcdcee44db3d1d2325ea7eeceff55aed1e355decfeeb59446ad814b7bde1e13da69651deeddfab57fddae4a62bb52336d4789db3e71879d3bd2ccf77ebb5a6eafdeef3c52b711a26c0e4b77dbd96dffd4aa928837a7a5f80dbfb2aff3d6ce52fe15f80dbf0c70e06cdbf48e7f3177da5b2fa6c1166375acd996765b5f01ce3bf9afc41f341a917b73764f17bbd39f37c9d1ffb3cf786ac33b7fd9058d99a62a522bc98eb27c0e6cd33f4bce2f666993fe7e91ed668dd54cbeeb60ff3150eeee0d6acc5a8d79827711db3fee6a02eecd4d7dbe04855e8d9fb9cdb7953804de7b5cff7ebee95d5b13ab2ce6eaafdb8351d174532ee2e95ea770cc3bdeae78993f9c26abd353d78f7c5af5e6fa8735493dafbbe5f6fbccf79e446fe705fbdba77438fb7bd97ef95e0c1660ce23a2d8b97f42fe23a15edfaa04a577c9db9719d88c132dad5d0d8e1e9a237336e7b254a94fa7adbe4ab2fc6c162958020cfdc26777faf3a6a7e7283ccd48d6b9fcdff5bd1ecb31ab857a3f346cdff90a6babf1e7fe34ef5dfe3e09a8ed38fd5e8dd9a2ad5b5b90fdad7127948157f9ba9ef19653b7a3fe6114d7d8d417b91ccbaa6bad72b9a5ad271906b73e1881e477bbe298e54def0c5bcddfd6c49c7a3871dbd9664dcdd28dadba9ee4f4d81bc3defd3385f36f8ed7df77ac332016d23b5aa52e1c1debc38324395d9b751ef7330d776ef78f7ccd3e6b7f7d59a8cb362320e5ec0998c91e2cf86775fe8fbdc092ec7a0fda8cca897cf6a3a9435f54b3aeb0cdb562a069bdb5ef50e1f3ac94b6e15cedfba6d33bb5170d9f39381d426d4a0cdd37b4533fb1c5f0593ddd8c1b29cb8f132717f94e3fbea05bfd2ff063f346f4bddc17a826171db7b39e6e1cfe3c63a31cfe3452a6299f63a6d6f5f2be6be18ec78fb0bfcfcbf763d66d9532a74b5dd430e39aef73c6b98bde4e1cdbf71dd69ff5e763704db0b52f75ff3f9f60eceed3dcff6ccd59e67d50a6e9ad70c76269c3b90539d07adf80a5f6762b09ce0d1c34e0ece6fef5ff18e13eeafa9a579d952f3a1729307e3eee6217c8fc6071bbd9e0dffd3facc643c7a7836f38b6e7ad3f9ee0b9b6775beb89b0d9fb2f188dff6bc2705a31defda241632d47a64ee8ff98136efabc59d18580473e3342df7f3dfefbb061d23c3678b48fd8df675539cf9f7d46d4b8d4bb3b89edce7e55ded2dee66a3a7b135e4e93856effb9a07bdc4d1c337a12271b747df948be76fdfe85a2db7f7769181c122735edcaf482dc4d35950dcee704f7700be89a5fad6c9183d10b05d2819ab659168d7c7b8fb102cda7f6b514fa5458b4939fbd016df0fda1be23fdae09276b8f9d7d9e1facdbfccf02f33fccb0cff8bccf03d6f38bfa532b59e65c95dafeb6537a34da4f8acdb5ea7205a7a7d5dbf2ea4e321a0e361dbdf2cb4db9e621b8cc1f689828ca7cd560bd72ee6cdfc36c1edeaa03bcbe5eef850474ed9380c8397ef91e0c122e1c6edb1eb5e9f2bf7ba3732a833ff3ec13fbefb7cef6edfcc6fc3d64197a778fba4f5e9c636e4c98cccf7e746d806af5ceceb835e33688b09de1a743c7c482c6fee35b6fff2d885fffb382b52d12a95ce33c1b66e7df06c2b68b9b749aca1e1975d1386446fa590f1884d7a5d99b94a56c5eb8ccdbf676250dff68641680e23af7c76cf1fb6036ec8c1c64cdd419d82687e7b6f9bc92cabc9b8f35a0719a4336f3eae1b9bb8a955f5d696bcab7fe48135e4643ce2bb6d302f1e8c02ef46c940cad3ddb8fb9b91910e76e7d49a88d8babdd9fe78a52fbed01bdee8b0bd9d0ee7be5e5f5e29dd2103839a86f3efa1db9e51a06caed7db1e6feef76adba3b1b59e7d48fafca979b5d2f368a35f2cf7b6dbb3ee317aba7dc6c9efbed8ebbd27dfe1e4bd28880fba5103bbe7ba883e5b203a1ecd1330f2136bd44ddced5306e2eaf6be7aa3671e74af63d7fff1bff2b9fed8d4fcf15de92c048f16ba369eb53daa93c7db4dd7c213f7f8dc3bff3ea94fd8257b1bfdc6d8c366adbba1f5f2b9c7fa35aa5b9b3b5dd85dc14677335cdc863f6ef7f89058c3473a1eca5ba77f989fcee2f5b3edbfd3d13a7f835ea5a341cf6f6834f1a23b0dea92957f7efd6eb4dab6651fd428eb3fadfcf3e33fa9fcd3b25b96a5bef8ff552deaabf2cf57e59fafca3f5f957fbe2aff7c55fef9aafcf355f9e7abf2cf57e59fafca3f5f957fbe2aff7c55fef978de57e59fafca3f5f957fbe2aff7c55fef9aafcf355f9e7abf2cf57e59fafca3f5f957fbe2aff7c55fef9aafcf355f9e7abf2cf57e59fafca3f5f957fbe2aff5c36ec53cbbcbfaddc8fe610bdc9633eff85cfd3ea7c20d5d1b87d3855ab6582cbd4f9d9c5527dffeb42d277effe5e50fa5754fa5754fa177bfa0c7b3a66202f3ab2ef8bea2c1237da75068e8d049845e672469aeec81d0ae235d50574e2ca7387b6d76f3a11dfe573e6f5b9d1744eb79f7407eed9882762c4e9ae8b748207eb0c0f969e1b5793f168918874dde3ab2475076c0206331a9b59afc9cccd7fbfef94bb0eed2b02da15c5b0eccd0e5d35f575d86bc93bd6297bb35d919afb4edbeb0d6b8ab3456a8deae9fd4a77d14ce5fce90e648bcc2d4c52da2c01c653aabb309b4b82edd91d6832e19b2eb8e642bdf3b4e7dd36ddad5732c3867e1e924505c35c42e049df812dea0eb91f561bea920d6503e13b59493001c8e932cac8163994fb4ed582210104538e9cced677a04d9d41099dce968691057bde2d75e30dc57645b1cd2638969e63e47833cf3d315c642e5d129cc9269278584ef57b7636772c5aa3d25bf6ca4e496771d345bb3659620df96eacc8c6233315b1bc1ba3452296a52e6622b64fb46ee6a52e5fdf8d0fddf373d86b1977cc6bede61b09582d92ddd8cc6d3f4ef08f55a6d6ade72d7bdcb8fde4daad1311b3ace7dd1eba17976a9dbc5a4729f7bcdb7dd753f5dddeecb973ee2d78eed64f01372637717927d05372dfd64586eef0b64844fa442c8d8ff24ef0a73bccd7d48d5b5ebe683a9e5bc84c345e785b24d316945901c34e0b3124601897242c2a08061c8298c1702808865be854b6fa8742cfa638a8a1d36941d0af11a01515518d9c54facea082ee8879f9a2a263dd319d27022de818e6bfdf771305b3d7f8dbc0bf89c4bf1b0f8d1d9c77ddce4d49c74330c188bf3aafbb54a7bb75a06eac8b1e8d81f9948a6877cf58e1364fdfe2839ebbbb9fa685ddef6502d266ee6cb483e5689dd6e626156de3b0e6374333b58215756d79a7ee07da4bb586ea1ee3607e8bcdd58660f44870c6c7b171db64186b1adcbf7bf3cc7c01e8782875a121b5c6cc5bc3b2a5ceefb3e435ce1c756f7e3cea063f9b8c47f30c7b6b02daab3bab79a7c41dac69dd66a9181874acbbe2ae268a86c679d913bb6ee456bc6a9e17989079b68fa31692f91681014721b1a0acb6d08d4c08608d1c68f8ce889110b68888a4ef782dea7a2d18f212b1ce1686a9448232c4aa1614ea3e41d913239ebab1c2b735015cd165db1b2c8fd78e2560c4c90e9e2768e2c5f97416bcc2119dfdb120207a757e34d75dd36fba4f09d8bcba161b13bc3df00b32461cb1fd7ddff213bdde6e559fe32f04b49f2680eff1922556d74edc58fe144e62c57715cfcf1ed2d99e16e852f15d78828f4ddc8182d1f20d2fc3e8e819d4cc6ee29a8ee1335fd2f729e6648ce67bbcdfdf5fe354efe87793d1b3bb57c337123cd8d3c82273dbc59e5e949cc8f06046ef4de3087e4b325ed8630b19643c5aecd73971dbb3ddf5d5049b7bb86da89251d836eeb0c29776a5bb76efae4d706b95de0c9f261a2f3a5bc51bd19e4f8bc19af6f6bfe399c2f18676114fc5687fff1755515e9d3353b155fce9892ab9bdbb3671fb2b78bfbb2fd816a4dcf37abea2f79fe7f1091eb054b4e55b3aeface17d4b5e8cce856710d06f11106da0ebd5886505650523202e89080072b28a86dd0ab101870eb190eb011a922d0c739300689130b2a1a0c277720bc96149710050189da3f36d86db06ddc3d0e2eb9fe08d4d16d3d83ba5d7d4772cbd985e03c5a082acb209563c91183e8eb654c0961f220e25940420e13b5440995a48465b8a3d1b6105a7d4a44ec746615fc230b2900b016581444e5493faac5e6337953f7415981dfd2959df79aba3bc83ef9f85f109bd637bc7fa6b787f41bdc341820058fb61bf56f807f18843316494a9bfc482ac5b41d107d085b5ef10138a41899cbee587a485707f4b71b44521e7d0a52504a31232cffa8cde71a0cb97fa84316932d63609682fdfe5e99fe1c55ad66cf66bb35236422662f6467ffc241f49779563def291fe5ae9a697d41790d3b168483962694d94eee7a42de40e0b1212800034a9036b8ac9163a9c1130aa7c373069d82d118e4bc238a7ac2810cb04724782b074e3bb67f9c8597de1f37ac10bd97f2c33e704db6bba5fab77e4e64bb9f56337d654bcc3a4377b996d9b49dc66e94dbc7f8e4cdc4179f80dd0231d073fa3233eebbda7d71d5c6edd3b1b147a06947185c27c4b585cd2309708075b888941b12789405cd12691454159bf459ddca2ee48f8ee80d1b0b2292b386219476165fa4e5e13e19d5bf77768a9bb484aad8bff37c5c8f09cce1af55ab5ff137697e6af2e5fd3fa14ffeb5c92ff19487ad2c7a88032b7fc901784a506c511206151f8e1a8821871df892ce8f40dc28605914a8e7886e68d2e9194a5a6a23bca880d7164f9e1e05376d73bfcaf7ea377eff9ce797becc866424f04ac78e678e55d47279f27d8ea1604ac0a0ae26c1c2c9a4a5b5a2739adb39ff665c08bc97cea781b1f930d72830d74bc160a47a58f07823ad0420edc40392c20cb4ae81000c3a8e537f2c8248228992f11cb6be4065b1f0f181488413792e77d1923ae0bf9c6edd5491fc51b1eb52da633fea02bc1b89cbd5983b77c6843c6c347a5538fc1f669bfc6995bd4140faad46d3ffd8cdf2273b727f4594ff1a30bdaad8a76729bb0ac42120288914061b481a06f4267c48988b644f637bed301be5329fad8d2b00214a3c2c77d0bca6843434f42a7b325181548f64d7a9e1f9d9743cf45895f9cd732e4201f4ec896cfc27c779f37b451ea8cf60beac3910d1dafa66ecc50480094c30ae2c0f2c3d4a661a4f4e42d72c90685954542af45c25c42b76f13396008504e645142066b04e2d25763856792fb73b4b1e31158db67ec73fcea681d0437a8d816d4daaf41a35f6bb971df02bbfb71858fcade78bd4e041445226cfe6c3f1f743f39c1f6e359bdeff3fec4839ef049bdc0a2f8846d542b3ee95d8e4f86c480383048d8b7a0882c2a0605747200957cc2fd1aba5420976c298b0bc2ba056119832cb529eb6c881c56c8895a08781692410bcac042c06ba1f24fe3c2b10f6f7f6e4530aa13eb8d7f5157b1d8fb5f3ed025df8e7b8fd69ff58a57e75ff1d9f2152f3de3d33c8c0371b9fbee19c5adfd7b5a073e34e38a672abc32ef18d95d3f295776be0ebea666bbfe299be6e7fd4b4732c95c24387a4787d3baacb59ba3f055e1dbcef712d7d48d5ed8b8e37d55cfe373565c276ee33ba23838a18b687feed13b8c16c98c8383ef7916d73fc58f5fadc7099dc5b8245f2638a8912016921d1b4a282150f22d63485041c3c8a078c8a18c5a500436748a02861d838681e13b690d41cc89a4157250059da2844edad8e5e76871a67819dce9913ff6fae19ff2f9e82aa3e53bba7879295d7c2820233574fa003a23e63b590971b48178584110d8be4b5ad4892b1ff75b54a092b07c8b70d42220ae080bb6545046c09013362a298b6c08fa1261cabdfcfcb74fdc1f2b02da3519a30501cb537864ddb17eeb727ad5804399312a94cd9e0214660575fb06c2c442ceb04222b295bd82c2b4e53b510bba9e496454fb78c4902c8492ff10c78c86b42232dd40464c854967f4aa15c5269bdc7cca5ed09529efc6a39a606ebce353352fb86fb621ac6ad13037881896c845a5f677845945c2be0ddd61015d68fa6e7f4b84b7a16e54133910d4250081a0f15b85554d716021460baaf550af3e67bfe9a62ff54eaec93d5f1b9889f5eceb9e6af9f0212c8deca67ac7bfdabf9c3f49043661d056fabaefa41674832d0c831a6254113628fdb0321050f837aa20201281c8868ac7095452062d24c9163979edbb7d09435e299aa3617e0edfe6743c5c4dc6c18ae0e1622fa72678b8d727ac09b68bd4adf2c6eeac3e034b3373db8c8af42d3cef957edebf9c1c00a3123a704bddc0f2dda8f69d54421cb410084c2410f35d2a282606090b01256524f40091b04545a4e4ac059d8e891cc411f32ceda77388a1f4f3b332719cb177ecc14bee6f48df1970e4544aee95d045824868513c64280c3648f2123ac11682a0059d4a2a184045836e5fc9410b39e9c67790408016c8c90a1f47c00ffb7fda1e3cde4ffbbcaf7258a42002a8774ea74382d6e68296cd3e18ec9ddb673cb663daf55e2eff893db89a60bb7ab16f767fac9fc50ffbaadac7e7b2f170b9dbdbe4f433ba9518487a6fb64ef2f5b275391928fa060abd2d658843106ca0ec4b243b40e310f0b6c8e996147b128991a0a1c2a741091d5e10995a34841b22c9d60f832d6595455da270adf65daf3ccf430e6bff5a0f52fce3a2b13cbed20d5dca098626748924605410d1af7d973224888900ad949c232c35290b6c8a0300436820462c24fa96ef42830aca5118b5745c893314b4f7010f39b2d34ff0d0fab23c946c95aca6226a11999a44c02d72e202aa6f974a1f0a6c140e84eff42572f2968f3d03c9caa48ee22304903032481833df090075880d4362c3faa3efdf3e11b05c91592ce8c97d9ecedabfbf685cc856d1000ca9a00ee53e1e15d4f56a3f1c1434543a30dc520c250a5353ad3f75728348cf462ca8a95359bee2c36c542257c1a86f41450be1d9b89019c5b6b257d91d1ed4a918d89fb01df6311aabd4e2a7f7d8eb567d419819c8892b8afb365232560e4be40c1875231301c47cad9b28be31e0c81d9504472ddf0db43d415d8543d146c19508cfa44e0e081e7002cec28c3dc755f0927c663f71367ccadced02beb5b736770c5ed0def23604781ba583401017d48d24d4f1803183615c51775810103384bd1a0a68506720a0ac5a10f42d2447056143c59f6a1a22eee3b8f09dc844ace067f73e76df7e374676fad3708b57a93b58266ff78ce41d4b2f19ab671319d954d965acb385025a304442c7e38559a16c7914668c86bc847250513768a1b0a890eb9930f46cc82050fc18c90034b67ec7460c6e3fb05375ec53620dab933119f72de392fb33301c3118e60a0e923a1ddb772a038581b24b2b2afa16c58821064dc43246196cf90e2db54f44781286c302297e1de626758a0a823e2021d9c28fe453a38b9db297b46e76b16f772343d3052b0474908072c89113d8900596ef40cb0fa3160cbb8284d18684e906cab8f25dd8a278c891cc4ddfe916d4c9385278e32041445ffa7ff6db2f6ddbb074035dc491032dc43a06c423469d6e01a56751116ca0535944065be8542692812472c47c57c9e9bc85a40750581950d082b2fe162a1dcee9189f5bf77da3c6777c5417a47de8a41b2486050c39f7c34ce96a96ef50ae6c5f22bb15c2514df0b0f29dce063a45e52b9bd8553a695c413ca8a0eb99344c6b8d43001a7e38aacef3cc9d0db25beb8f6d6174c2166c6215fccbc1c920ea1ba56720176ea920861f6685e27924cc38c4b46c6cbf61059ddc80accb958e8b6497f92ea911563cb55f53e659bed307281c5648e6d6073c52d9ffab0926a778c4f68ef52fa9bb59be1397d40db6445680b061a17451c2862575324664a7a6610e086b62a628533670c691d2e11dca904b4ce4421b8abe44acbf414ea705d947f6cbde2efd9fa6916149b0d6df0d28a1adfd4361de22026e10ebdb34444cfd86a1b7a138327d67c889f02c2d1f8167504c4bca521b867d8b88a0a66edf802ead3e5afb04d8321bb4457252af0ad697c3fda1f043858bfd0d15818958b5210c31ca0a06712ca0400511c3cac79ea5ec52c50f51a8aec71c626243e16d50d8df4040007514cf400289e843dc4f80ad68de1803a4ecd8fff1fd10c43c03e1c0f4715fd230af49980922bd2d02d0f41daf454202fc7058110101756989182aa00b5b44561ba4e40753f67f56facddef606b9fd0dfdc80fb68f053f658784c11a5dd02f0d41dfa44e5642d66f41c64b22b312b943819cd4446edf46b228200bb604472672e3028571819caec29d92306f03591fd03032a08e9d18957e186dcffaa55dc5d7e275d6339ff717eb5731d3eaf79e3678bb79e7cfe8dea0bd99e22d4f4ff906346f8d2ea78384c38ab20a4097681bcdc75edde8d8b046b292548c387210272c3220cb747c35d43ed6aaf6c3d440a05f2396d7100c4ae8c66a9c44e5077865754d2ae262e7cb7b0706c1e5f6fd71b0812e0408a012e16043c2ac426c54206724908e9726c077472502918542b881b2bfa56e602a3b0f495e12101854281c1b32c4021b8603e69f8d8fda2e88809fd13d6a22614dc5409e8e6df62e19dbd78261df44827202a216720725127d9bb26141c5a88461c72620929afe64c69133547852fb4e60401c57142b7b46e91d99d2a8945e2f091b14677535406777988bdd7efae613fe938a8e878b4cc40f09d6fee113b2abb22fba1fc462a678958f11a77a2f32da2246368a172107da908d387289a1e987c5828821a70ee23eee9b94754c2846024a622130e2848d2aa46c3e2577cef8505ecbae5d8cc25fb5bf5d4d70c6532b3845b7f62565227550451db2a14e7fa3ec4014660574e282b08e847a2fad63f838daa0b0da2247c98f6109e5a0a022b0a0e3b5a08c0075870202c4901831c23ae07cbc4ec61311d7130c57643cacc9f8337b69a345aad6419c8097b6412ec7e720ebd7d4e90a142a99894ac452e0879544801828ec6c09801b1a128bb291404ed08200b6a8336410445b1a56351431f7715c111119047b069119fbc8dea4981b13f7749c3f2a5bdbcbed814496ef0606650346e4a8a02194440c05917d1381b852ba1509634e192a89f46cc83c0bca8ea44e64a33007102bfaf3a4ef52463134685819284c3fb0219ef79dc6d6f0a43fd76f62bd2fc7c3dd91808e67503164080f98af742427aba8880574039bb2a8860e2f208b6ac5db915359946502399e8d9c11a382d4c80d5a9045928001830e31ff621ece9359bcbac303a9be237967ef00d617dc8b651943986c94ee48c26a4b1d6f0b9dbee9e39851a52f0962d270c0903b2a60984b5fc723a51b1a0e380488fb61d0220ad618b694ac248298fef95c33fdfcfd3e662adaec0e9b05b1864ffbfcc6741c3f65cf7164b6deabfc40ef7cd939ee946c4c2f9b2be044128261498427f53f391024ec5bd4e1028ac8a03a3f57dbbf2da8ec7ea174ffbe0d013408f0b68411bd3f81647f8b9cc0a40e046771713c32a6f7fb9cd07845b06d1ced171fc5fcab6f8e0fb9f1743c5c11d05e26d667627a0e79aea7fd06978ca103812438662844150d95fd1cd9e8ff63ef7f9b53c7957d71fcaddccad3bbf6c496f19ac554dd07101bc72492c744b691769dda0536b12d4bc00d106cdd3aeffd579221210921acd9b399f3fbd6d4d49a60231bbbd5ea7feafeb4082dea140c6162d244f98fa4219274101896084775e0b98d926f082b5bd8af951c08b0d20f3e20c9909fcefb3fbe974fac21837228c8181947f253d4ba5bce78f779e6f1ea9c5a542a6cf0494cceba9c4c402248624e6455075e28750d8b436ceac58c305e50e69a088f1849428bc8bc03bda8a19edb285f9524b452328200770b9d9ea96c12c2f28648f70b7d429f5361becf43f8ab6b7e4c2a608312b7a3734d3c5a41d6b3956fae7c22c4aa06e1dc84ac279117dad07315cf6da933e0d089ea40f95a4e6522114a8495ef10351057277df369323014afa72fb9e89ff8ea5ff1d13c66935bb4240fe6f7c958d9cd47f35e2f5aab03d51a9544fd67d3645890240250f64b82a149596a044eded17bab2ce6c8e11cb2c826c2ad89805b9a8c0a04c22d12c420b80774ac30093bf0a44dfb01274064095aa48017f7e3e532557c519a72363ec75fa52601859c24ee7a2678434077b3db9b3cbe37db5c8c4725f55041302f284e2dc8e20ae221a39edf41892f89f64d5d034a9d03b2252c048107b74132e2d4712d8a7b35146147d77648770b715f20e07e1543145962b3cc53ef7c340766735a967e8a1da26b2576b80b9b8c77575390cd5f6b3d76351a5ff3fe2e3ffe93b9c1978b41412fb2280e25c1f91602659b0f05c1d052f600126e878aa886ca774e884504b191b2a7d8a8a2026e11f61b82c3863268401c9ad41b545a1e9dac493fab1ee638be4ec29f4f63ee1cd411780339f9588ff082d3f2851d7cb45eeeb87c72cd0bfa5120708605624509192f02276fa8ae8f0ad5da30201831288981c4a8a009e581a364576805895a6f71a5fc26eac40552be559bcf59537c66ddec27f51a29e09b73e2ae1fe6f6b85f51a3cbe9ce2d727a0d652950729ae0dc26d807d00925613a0fab41027165ef2296dad4f141e0d102896109d990512763480c0aea541d28c32dc5ae1524e157b90f6f79f92fa7c1b0207adf965754ef63fa123985d079440c09c4880171d481322e028d3d919b485081645a2b1b03e27e4592912072c4891c953aa72b717f8206ad5ff53f810ec88306747c3b7094ae4195f2c509805be8a10a89100438b702a76a88704de80c1992c444c2ad91700d88ab86e0ca0ef0b084096234195510fb27eda816f34dd9ec3b3bea3017bf3117e43fe183beaf37fc9f40779c9554e712204e85b24d6945bda843590890f2f195df2f2b0965aef45049586a419c5510441661ba2657f9f38a372da8e690e5cdd9fc371e15e9f13a99cbca75561410d39226c4d6397b7854516f54a264c8298e6a22ab4e9044922a7f1cfb00616213302c752d78424cc2e016025807ce884330aaa0441549a2affc99f735777fb92d42455ca204365016156419876228023c12548c04757c8bb021838cab7714c873959da8d69e24c207c8f12d287343d9e4140f4bca5c1be20a9cb6455e6b2d7ea256f77cdb642fdffe80cd324d62f50ccd71dc2a7335198fb8efe85c767038e64d8df8db7d87f544c985e3f26643c7c838a8755c91e4ac784b67a29ef928ef5c727f6cc8a01c94488416d239c5438600a921860d74c22d54fead1719104323d0b2b95723d1d6e02147f97205430eaca118b2c0210d4a0602e1fe69ec8b393768d26da877164edfc77ce4bf7e5fdf848e6b20463901b04330dc52675041e05b54401b32df26cc6da0f095fcebe8bc6cccab00fb0d6c69dba1cea82489b28722a9e454e0b827f192b25baed6a139fd37f6ef29880d8dd3e675d79fd4ecd5e87279c71d2aa024c037a853d5944592b0680b716412316254848a56806065972bffd7b511e30c8a010f9cc80ef43e2d34918cb6042046126252814ee71d1f89e9bfaf392363b43c832717c7f3b6fd0dba5c6cc0a438b4202b0475dc0639558dbc410559cc03ace47c58a3c4b5a1243551f657a2a8e46f29238ae6a6b2c509eb7528ab4cc5873a2f0fc3d37b2247eba0e826fb4318afc7ebd6dfe01f6a9d5facc9b8f74eb6eabaf1e70978d11b3b1caf3758a28ad7d941edd4cbf17df2f2db67c8e9a2484151a6a26b1d8f87549794d515020341f1a8408ebfa518098a533bc0c422b8b70d9caa4300ac291b5584652cf05c23d03c0025c1beadeb08bd6185242db4dc71948dd833beb0f9da3d9dbf7c2f8b563a174cf95a8cb4d8b85e6407d83788a40591918540d4812c35298e39121acfc244c9a8444cd9412e2092983aafcc53768e2ba180a7fc77732ab88e55df8f11a7c0e4d3b9c6f9793ec75f987871334db8719f0ccac9d17c0e7703717eb95895f41bc51714a756802340b1dfd044f9ded1164a65034436c17d01b16f291d455926a0a7e31f826054061e1544400bca7e85002d0980e669fcc47373858ae7d41ab5c79ff85417dc1b6148c29a48c421ee99d01931220b4e1d6812403914a4a69ee2b7aa4172c42008254a68819c1c508cda3a0f1602ca7a20f0620141d4412c3dc5636ff693c878c42683039b7a9e2da762b09d3cf4b43f119cb1c7b4939fc775d325ed2396f1c0833649a0859c8c43969bc8f141807911e0a846d8b548e2da04131b39714159b445025530210dc58312618d6d0088742dc294d6724fc7043ee4c7bfd54d93f1e8999c4bbf1de6eef1fa9acbd55950868ac0c94aa47340a14595bfa6d6b1f06b1d9774600709b28582486dff24ae1d786ea371a3952de051a6f70dc08843c5db4904beaa3179b3bf7c6cafb2b960eda31809e8f40c8daa87a3adce93065022969bd01b142471cd201954080f1991e9963a7d1ee05e831cc420801692d0d2f1000736d4539f1143de490c8c3a4b389b34264fe7c3e7f41c399f8c36e4a87cf72fb94f64405c14d0730115833270fc1a39a9a9560df262a173ed01345002b7ba464d860d4d28870eaa0247f91f45052534752e11f03b08f73901a4f3337b9959622f35e6cf83a968b2c77378d5a189fd9c0ab3987afc3b51f61e38071be300effa781ed6056b4af30639b98112774b04e9287b39c03d0332d881323782c4df425d330a1b88396bcfa71614b120203489a422c029408216c8f33b301970ca4eda1f45a66416a07bfb55e339e9dac93369975aa3623a3f9aef58dfb3ea8235006e0dd988d3a4c5b80e12bf0371b54538ea508f3490c505f5884575dec14010106da9931a5056759044267568a9e351d897108f3891313f6d7b1cc9e7f8721d77c127fd3b2e9ad34dd8b0d4f9d942f14bcc214e4de4a4922a3f4f44ba6e4ae3b739fd0a3a910159b885d2af09cb0d65034327aad535544492c801874a0e9cc4f53bd74ee35b02ba1b2af8fc135c88cbad45a178652894cca309e2014eb701eed9c8892c085c9b32dfa04ce7811a9411938081f297ecc08b1acab242db1772a03c61933ab909012da873d24e7b8319dc62d38cb89aff03fff2085ecdce865372ff8cf8ccce46395ab774b9b8c2b0a28e6f420702e828beea5714e71d82fb05150410a57b9d9e097104208000611750a75f52e54fb21c4099db50d9ccdeb00c92114712364842f0858ff944c7c30d4db612ee72368ee3215d0e5311c9688b246990c65ad0b8881226704b84db50276f88c6d62a18c194516f58041876a0180aed6379e156e7bce09e89589f412702d0a93af454dec41b5bdfdf047b6c58c03764dc5fde27437392d4d519b1a98f7d20fef2f5eada30093b81a37c7102104015623d40846f2afb9f289d2a2b5be749e24101b16b520141e054354ab44c53b2791b78ae81446443e9da41f255ced93b6cde63f6c325717285ae072ea8e34b9dc3ac73fad32df4485bdf8a730379231638b021c9a88442f9e7fe16315e42311201763b948526d239dc6e87a8b5e790af68a065fbf1b5545d708f2eed04c9a84022b421204a5781160fd1b590d2f73292900d0be4851612700b650ea01317308152cdb5e21304744e9ee29d2250b6aefcfadda762cde98da9eda6fbc42c8efbc5d125fd628b0adf260c7648426cc8c836705c037a7e0709e51b2b993b2a8344495a5d1fa9f53bc1610779614d13542127b551322c08f0352e4ee011f9856c5d29dd35064ab67ca25b2e590f29f32670f2ad5affd4a30289b04609b491a37cfdb056c781436ce8f91664a901c5a040c057fc5012462bea504e64b585b22f88205b04e2f2643d2440cfa9172b79d89c837da531b98ec84b74d3a92f1a3f497c9b882147021a0884264ca8ae67219897010ecd001333c021206cc49013d6c8191684e55680870ce1de2eef24df52a5c785d2c1baeefdcfac7758a5f3684dc0804dbca375c6f525f53554b62e1b09980c2a254361820ae8451d82071c7a03a6fc5ec81023ba263202944506629441014d24611d2404101cb3b6cea6e010f8f557f1cd23f2e56bfe6afde647edd71ddf83bba04ea2828898070e91c8533e57682adb2ff0068cb0d008bcc8a2c9a0200c299fcc52362072744f32933aa32a4894efa668056bca7a35553a0b875fc865b3c83cb4f8bc7ef672317104a820326608431938ca2f0d0dea20ded672f8204868117871016554b7fd87424bfd2352d98161433d02343ea103b7411257d073b75fc5d75e72138ee0345ed61ef16b24861572b22a4894fead0c28630e65cf2632ea2087d854281bb8aa891c56d00b6b225c1b8998695c17c735a1704d92440d613d03cadca21efc6aee35eef327394317eca1322c945d8e00e2ba7e50a635c53d4930674102b73adeaf7c191cd6100c78807d9388d046923322b3027991845ea87498b2cf0a5d23e57dc9f7cba9e0dfc7a0db51bee3273ae68278afae0d5954075e64071edcb69844b42492b200eb7cbe0e49468c0057ef77101c49ead0a2c535aa00f5a28eae0996fd023a4ae68e38f24ef76dd8e14baf3ee4f07d29338fe77ba2b2d35c32c64a125a2146054a7c1b264301852b8980751b3fe873a87447125724813562ca371c31247b16d218dfa989706e2216764812755afc28689ca793dbdc0cf89a4ff5a1fe63bfa7fe491dc36e3fbdfb8ab32ed63c15369f3ab0398ac3f6019fb4bbc785df1cc4410efb2a1dc63f1a25c7bf8e29bdf66d3a2213c025750149a8b20dec20894bc868851c28212386c60b74c20ed2f9ab430671cc89de83a6023a45051db8454e64422f3449e2d694911a2ab9a9be3f5927c19f0ffa90bdab2bfb711eedac2338c7178e93d016e3aa8394afa2fb90f80d754605944545706e41279744d08a7aa1240934887425c450222fae342ea9ee6d38e444f9034a07e3d0381927f98c6f456cecf37bf731935d8edfbe1ed24ae5f0114abfc5a8fcdabe6df9fc78ec445e30cf4706d80550f62b88872562f9163ac342d7e8b298071eb1910c25748881646823464c84fb05d5f50d038658de4182968153d5d08375802310788333f3a4deca9d43d9f086c64de71c8cd04d96988fc4ea9b476a77ea4b63eb42273202cc0594a98918b1a092d938efb4b8e5cabf0c0d6503214c9595dcd64982104027b508ab745f6cc4b28a3217c0845888d1129ef4170a9e0a7399dd980511d5bee6e9ccd87b774bc603933e98154d86e611fcbb36dff872fe29806c54040e34a00765e0c19ab0bcc5b972aa6de0a41dc48615c1a392e05052dcd33d0a4842b69029f90a01c5d136487c8058a8f3b62108cd2fe218ef7b671dcba9a92fb93faf7366656890046e21e315657e433d5420e677da7dd791eead1eb4b5f71d8ae1367062651300222b4bf7d7743245a702b2acd0bae564cde3eb9edebe668e80f5a35e87c7fa8b0dba2f79785faccde3d71dc77db820963c2d1070adc0f1f59e82cee7924452118100f72c2aa0aead47ac32d45c40418c20a11c81a8d1fd4b9dd450bc0775ffabcad65847a77b12ecb103777924bd97becbefe8be5bb7bb9a7bafdb195bc84e012aa6dea7bd467fbe9fc1bccfd55a9ecec3f56b6fea233abf547ef325f16b46823a1140cea0828ef27d88aebf8760a4637554444d807d3bd07da77c53c7780162d42356e05416047e833c24a074ad56dec2e62b4cb7777dbb3ec1b5f32fd89fa5aa03c7b5a1aead8d6c885d9b3a514d719f51c76f742f4e27b4a937e201766ba87b110e0b245d0b4a626b1d03a0adeb9e25d9060eaae0e9dc94f7750ccbe97ca46ca1627ad3d3715c788ecdfdbee7d35f8d4720a0f28f6c02600d1db245ce8021a75f2047f9a661431262114c6a84a1c6256973164913388ac7680141d821323290f43bd0a13acf859cc6373f45c7d79ee65ff8a4eff851bd9f41c7c30d395eeb7a61de4425c53e40b2b785b2b7252202d4e195eef7c7944f0a1b8895cfeedad08b2c84e352d78803d72278502a5e55d741169950e7e20d0b949cc47df9d3eaec7e8aae5a465fae0739720a16e0680b316c10cedb7a05273291d079c91592830a397109a56b43c7b7291b9648ba26c445a5fb320ac420eb752876016161831c1fd0cbf4f63a5e03f5490dc805b1e71b84b3b2c51e8c0ba87c16967620762de840e5cbb4fa82e5759b47c04beac5256195a63972504504aa20430209e507f50b24d3aff00dcea74579c1bece62c4a017d594f96690401b32d742004ae8b90691bc821aff2104ba3ed67325c2a443986f221901822b4beb11061b0248870ab7edcfe47c51c7d8ea827d9fc34fb11e2e550f44586e414fc973d784890f281b0ac22aa9fb7ae91a6adddfa44359cfa44eafa1bae735b4747f3d3c12819337480c0aad33241710e75fd5366cd35bb29e7adca0383f82cda379a0be20667241646a109d77a271a22bc8060239be49596a42e60365e342e6760207029484166185a06c5050412ce4c10e149181b02b118b6ac53b81f32566f01bd97d9f14c527fdefcc7be6da175c0f25657d869ca224725005ea9d645c501c3308501538030e65da4031d2ef4f0412813328a0ecd988f51ae4f40072fa1564bea42cd27b19147fb91eded47c4e452c332fae3e919317b491862c70f2baade1f581ee7723fb4cf7f871fa1c39594159d5414e9f53961b10e71281210b705eab3500955ef2a23a7048878870dbf663fe227fe2bdee396e273617cc4b135a36808140d2b703873298b86680730b325a500fda81e21516d981135a011e6a5a5016738ae38228bdcd7ab6c65a49a20e7452a5634ee6381fe4347726babef72bdb7a604e12f4749fc44d2abac769565ed27f766beaf4da1e584ab70ab721896f426fc8758ffa240248ba0664b94dbdd02260c4912c38114ae7f42ce40d19d2f842a9cea384de4850dcfb826f763d108ff3cb05e50794d4e9971aeb39193128469c086242276381132ab9c1a1c6e0d358250c26648b586868bc6d8f5654c41a9f24f0884d947c51ba159fcc11fd68037f65eb8ac1e6080e5a8b6778b9f83220989610132b48424363b778c352c94b22f32d946113248302e2dc428e8eb198d0d3bd220194ae5474a338b7a98012615a221c1ad4e9c953ebea4d1df2c7fd0fdde36e0cd082246841f676ae1a7f10cf7a1d57b033ecdff7f73c5eaf71c11eb748f782093b081365d7b200a712497f8bc450c93793082211ab2452631801341954080c0ac4b8f2c74a8a2393246a8cb20d2b899cde17fd4afbe03ea99799177550799ca667d25063197d621f5cb0375ebfa45e644256012a6027507eab8738656e4330ada0832aea2146a40ba0401c01bf210915088735627da52f25941aafc750724de79d9dcc93cf78763b2ca662f43c3da38e6c47db05396a57fb97ecc3c1088635d4d88e5919e06101715a433cac10e60575423bf020a02caf69a26c4d22218b24920410566da1ac0075a04d13d72218dad42100627412dfe167f98a26a3e7d9a02b6763c44852affef2be932c35204b65904406d439979501f1a8a2cad648e2022591891c5e50e15b54d1130c18925989706e13814a9a0c79a06d71aaf486057168d1d3b5c6e5643c12536f304fcf893d8978ae9ffb633cc4bc68ff01a767119c03a8e414e69cb00868ac78a1f58909c5b0844ad7e221834eda109c5b44b82070220309ddcf46f9302664ca0e410591218027d7e060316db1058a1470f609decbae6fbd2967896d90f13931d11637f77e8cece97c54cc8eea64b28117ec6f41596823e977f49ea447241548501636c8a342633a81c84442d96c6a7d47354c465cf94b01ce254c5c8b2a3d91a8b51a495dff27739b7cd1df2215b19c821adc27e8792a8ef64fb22eda3b06eb9e6a32c0a30ab25e0789700b71cf444ad6e35189302a61a27ce548424c0c24230b7aa86a31cf7b1249cea1800d4c7ca9e41f11eef6744ec6412dfa4bacede7ea41f57b7ae8f1957ffef2dad01aea7cd648c9df12096853e137081725c4bc442c63841505112180006ea1a3edc0267094bfd83369e2d608bb06d2f9b2cafed7b9d727fb5fa4205eab773e47f6cfc647ebacb797ec2583e4a082b2575327ac038c2ae8c09a24c38a3aa94d75ad19529f1b885d1078ae8d70dad044ef439ab0a58f45926101193489083b94e5e0cbfdacb779e9c7f2212e6923547a7db03e4322945463f24636149423463914a11d24c4824e9f138dbded76a81359d41930988492687c5fd8811e2d21eb972471adc0435ff5ea923431c1d13e9617eec70193d0a2896fd3843444bacadeae03dc6b74cd34884c286311e8fee58312c9a220206c101e5504a73575a08512d850462cc8fa95c6e375c2edc95c9039e2d331e569696ec978285b0cdcaf74d4c76bfe6af90c65de21785051e69b10c48ce05e07e1684b442c745f4b066da8f416ce18943d5bc96ccac29a7ac4844cf9d5a443c0b0d2b5ae1e31752ee917fd99db9ee69fc90cb7b91c7ed59013999aba6f8b880b02065cc76e93c84032ed50875701864de0518e12d7d43d2e592421f3b704e72691234e71af81cc9741425980959d7dda6fdef773dff7983f43beb63de2e3eeaebfd0ff04baf93662a84060546a6c461c1734193004062cc07d8ee44840392a5abb90d481e377284b6dea118912655b87064ca21a3a6e27484219383d833ae169ba1de2f5c93d7ed42e4eb5cb639d2567d4d4cf114fc5888fc1521ec55cd7b42417ecd194da4112d9088c5890d08a249144c235892ccac0238de2c92041bced7f432b02a2063a5187c8c822b89214936da071e95c9b2a19affb1157a7fc9465e6758bbd9dad74f76e6f57d3e527f8d14c45bdc3bc3f1e5f4717c519892b2a5c13016537175590c09a3a3e809eabfc3cae63848ebb851e01448652f11b65550d1dc4a1432bea1425727a364a5c9bb061891cc4283e494731b586ebb1153753afedb5f3821f29b83105ee3eb7c8cef6f1af9ddc3b834717e4c1a83fe95b7fc11a8b82210f0982530326d00c1cd850bd3f910992f806d2fd2f63657730280605c55583c4a8849e5f438d8bd80341122bda5684c51cb11187f8647e4c39f5baca562fb3848a575cf9cf7a7bbcede5d78e1d2d29507a70e7575afd221dc7fc5ef913f3787e0e7f4f3cf728ed5179417ed6fbc2951d38b1a09e6b4227afa1331248461d244927c0baaea7d3f67b0f01c194078ec6c931a9432b885d134aa23119a153d548d0027e55df32474b0aec627a632ea6a0fb743f7ed51fff036aaf4d984416944a1f8f18f2060c7ad0220095d47325c1a18dbc9120b827a9a77bd636948540e918887d8b32b22592d8109006b1b0839cc824a77bd9bdc4b3bfe2175d3f71bc16e882fb44a46ee32fca77762d8d65a6f3cc91404ebfa2b85fa204710428872cada1de13e1159148100995bd6c10109754d93ec2978429fbee8b1e6387f9917f798f35caa1b22f00b4292e0404d024785420460bea1053e3680268216f54e81a86b6efa6a16be0242a298b19129115e06a4b846f4046b6c8fb6aaf193d13b0e69973d48e9717dd6bd758b5918964af86caff654585642aa1432c2a0625646183182d112316c24820a131ed4d2d4f5854235601a2fc44a97bbb88c0292a244ee68b7d92677b9857fbf3d8773a47578c4af2195e65d9a92fb85fcd217625153ea00c5514f72c82750d81a1ed5b4c39519e36cef57e23c2034658afa3fb17326853115944a082e25452965b5410e54b8893fbd57f001338b54655d6d6d01f9341cd4563108eb2b3142fb900b2bc8632ec101669bb01cabeb2116c8a7b35513471528980afe4b4491dd8a122ae901757da576095842c2e60129ec4b3a51e9704ec7001caa3b1bb5d8e5d4b236507a48283d7dcbbfd79bec9bcb8998ac16abffffbd2e3e9d898f1d09cce47ba1676c7eb450a8c35d17867193f2b4ff2e3331dc5b6b85c9c71c802272b10ebebfed544d7cd8d4aaaf7d5a306cad0d43df1c490433586f54c2288499d3ea338af91543e083490a442e3d401df845e7c92dfcff1ebb4bff1c6867eeb3fff84ef67d0db8c93f2305f78f7dbc7fb613717c558c38520381654ebac7e15e0a282091504178c30b74638b7a1924598d8d42196b20fa992e70c29bbba2178c082645422c7afa907953ea84fefc50c8b1444ebd9cd114cfc7f632e76fee1ff4d4177b33fa76dea7f7fae9aec535c4b9dcf75413c1cbfd6d83fc9b080125ad04935f60f750605c4be8d589f91c43502dd4f0755881525f2c29ac8be8e8b201973e88500257e4393c8a68e0b88fc2a2f47e75f1fedb987e4e5ea45091ef0c0431511b1202cb509e6054a5c8092684b3dbf43586811963610c43c503a93650c01d2d17a41a68060d74252d9a35042dc2f49e29fee1377460ef5cfe779299e32d914d4cf47fa91b6b1fb0be650538f72eae47690902d4dfc2d0444ea988f0701c1fd8224c38ab0a240b232346e4c1249e4108030a9a9805b928c04c2230e99eeefc850424ed6a5bf60928d6363926ccfa1d7623246fb3db44ffa8b5eb2578a0b74ef2a27b2288b6c845d83c88cd3c4372856eb29b72186364a684158bf84825630090de828be1c7024a1451ddddf49425935147376b2fff69bf73797d371ff9c3e6ac6c4e34a1e3653cb5f4f12737ba4cfccc5691778aed4fdb73db8a5622874ac06c79c00b786de8853e136018e1a248695b2d3a0e73650ad5b392c080b65a0b16869013115840d0a28dd2f70f1feb41a0863723be424196da7a07b24c7c4dd043797f439c32dc27d8e147f49542167c020ae6ae81425944346135742e602e4f42404ae0d1de54b4492b010e83d1347e981c8d4f8ec8258080c0449dc533ed761fdf597f665e6f1f5719bd2df40462e58a75d1481874ac56b1afb0c473594da57d84211d68811e503d88429bf5bf94bd00c1cd29044f9a269adfba2e35109319450461dcaa075baaf287a9ece9131067473243751666a8ebda1ce91dfc5be77b6c64e9768babdda85ed98bd6d683fb6efb7fac33eeefbfb1fc750ba641e5e6469f927d49a273514a84422dc524fe73c5948d2923062119c6e11833514910559659324ae901cb1c01b5548ef29c725617e8beb7acaee3cd197e91d6df632f36769fa99ac6deb612ed7eb832b1b8788a8a6c948902404d0f12ddd5f97454680078cb211238aa6ca36c4698b0f28061adf1bc9bc43241594152501711538b40c3c7a3a6fe3dfeba36790c4ae8838e89375ae5c4e6cfbb33820bc68dc3c2e11f61be8912d4a862502238e0091ba3791cc18748849b15b07989750ba1664c446827228466590109bc8511578832a5076441259c88312392731915ede7d0c0ee2065ff3eb6636a69c98dd2fe4c0257bb68f0a244715c11987ca9e672381646512e1d7941545e0649cc870db6291f0023abea97b8132ca11ee01c8fa15547e4c32aa9018954410dd5fe4341dba4f93e4c767183817f4e788051d54e89c511cda04575b88614d986fb7b5169423e06fa1e4ba2743e0e40649141f695db5a51e6544445b84a980ac60d4c9b7c1e9deb2e54ccf49afc52f3ddd7f6939b5287fc5741a7c9fc55da5c78cc90b16d441dc55987c9aa0c51ea76bfada9b6fad68902523f9655fbdb68674e7e7f3791b172b9ea760b53e9883233d9dfe883ed43c70ba0fe3e564764971de20c7ef047820a0f095adc629f301c1c30ae97e303d53d922440e19c29141740f195f521cdac82938d1719a105047f9bc1020a7b2ff404fae835e8cdd666f277fe861bab36fa660df6fe62d36c0ae5e20dfd914cddb5e5b67cccdadb293744ffbe3baf4a276242fa8179781076d244323c0b0d6fd661dbf4370d820a06579893091146782ea1cc04149596523c7ede81eb6496853edcf540661b97d1aa7eaf8bef301a6da397d290f7a96ed7b487fe96b372441cba948f773ff97f79e22980bca5c83b2aaa37c3e8da9ee7086986f049ebb850c3198c0860ab7468ef2814813606250755d1202040625649c212f32a8e71a04f7ccd336fc3becef336c9063bde18eeb950bfada38aba0539924896a94440d72e2023a914564c103273461a27c6a5e42107398443565a443312f091e96c8a32551beb5d32f888c940fde8132165fc4cade6283383b2c9023fdf4bea467fbbed5740e358f67de513d5d0797aca3d5f88ca10535de7cbf42ac28885edf830aaab52fa20e14a4d3e2d8e6803aeabbb80cb0ce3d0150d7de0f0a9ab80d61790732d724a7f37c0a650393c654b45beef34a3ee943c9a7f3787d9f0ca4d22fd35dfef461ffc4bd3ea79ebdcfc15a91f1d21e5bc820e3d1f2086ea3aed97ac16a4c06abe9edab2d9079c53205bb5ad5f7b25d7d3f1e9e15a77a33d7bb1a824ff2532f3cdf3a57c10c746fb6b4ed8be2f926046ea37c54c2740d5e13e0b443c54010c67990441ddd578b15254c068c3aa909415c405c5494f5194d4eda65affbdaadcedc7e3687a9879ea7822ee969bbecf9e5fbdba1799fa042c988973a97317a9ede92b5eecbf2626f99c5d4ab5f713edfc65e77f3dedacdbbef7776ce6893367aed1be7e9f6977eb47f39965fe0a43665c4860e31023c2c1040955e9bbad712120857266164ab7bf60ac4a868f37f8264c888086bcae0163abd1ab1614135a6a2bf455fd4ca7ce87775bc77e1e57c101173c28a92627f1b24c31226d046c2b788d4382296ee17eaf880e29e4113c448824ae8c59c241120acea402f924863a0a606d2182c3d4bd77a7fceeb6dbf422f3e074bf3641fb04f625817ac150f4de4443674aa16073b716d9d8fa8315e7309c588eb5a5d2f2e295636e190230fda148f0a282313793aae5d415c0894441da4f3dc4fea85d798c7cfd0ee631fd2236b2fbda8bf4394dfae735522409248121c0b82738b267185125a2227aa494245a07ddbc882206c10ab8c00870dc5e116e1509224daeabc00cc1992d557bd820ee8512c8fd7cf5fb296dbef1080cac01956880d44e0f40bc488d4fdf51262e99c085daf464b94b8264c2209a56b508716444280127f1b384406093121831d047c09c1973d3dcc541cc1c32a2f8bfd4b70b44500cac0412514a184c037350e40a27b78d414a716c5b4843297d471cdc0f31beab926c5aed1d64ef91d0846822623e52d5508a79dd33d17a8921d8fca2ed9e12172fad22b5af7615c1deb4d987a4a86c49becc6dce59c6b9ff46b1df7319fea78ffe74bf6fc1631a31e2a02c54bacaa09800d61454500b1a807b79085260494539cda30719bc0e90b285303025442a7daa2847402c76f749d0a43a51afb05afb53dd18fe7936fefacac4841b54e815da4b76831b54265eff34c709ec9cbed43b4f8922301a56f22ac780a3124068cb0a8a3de190a5742e15a50444de029bf9374881c318873c583151531a7c9a050720a81b0a37bf27f51c39781819c6afd6f5714c49b4f720eadcbf58d1956088f38c5039d0ba7fb12b3b41338ba9ebd43756c23dc22c6059103e53b0a24dc3af050819caa814e0aa8a06580fb0c691cf4ca4680567fa0a7bee299f57d3254f335a74967bf5f7346fce27d2e9ca9f339953cf8ebe9eb4bc2a0a48c16d02136f29485101708a32ac0a34ad95f50c4154ca024b82890073b488caa004340982b15bda1e7d6288919f25c43e98500f74ef7e599c7ebd41baca667fa09e7d73a1dcb3b34e5c41b34f4ac1c980fd7eef68d3ee93d2d2f874b009dbc0331b1097001c4a1849ed2c591d23f1da8f3887c23c0a909595423d9db529c953021808ad086096241129a41e26f9147cb20f1ebc01b56e8648ec21bfa7ec6fbebd48ab7a9d76db273f624dfc996177cb63132d3dbfe737abcaf6b73cfd20bf6101972c87c03e2c880820a0842dd7b1326c4a478c8da7e5d3d9b3068297b08c91c504fe99fa8263232028da19eebfa0bca7ab6b295829fc558fa0c67b43c46c3a1e2653e15e17f82ff5faefdebe725b41437074e0a082b04c485f25f2c9d672790400e2f118bb98e79ebfa7f68224ff763af11eb6d21a025c2714504ad208b4be48c4add37fb343d96d48b95cc3d8e51ad3170e1e5ec01e982c0a90cedf37b238da3489d7c8b1ca2f88c414c0be4d042e7de2494058ef2f1601324b1089291b225181403a67b23e97c26dffa723f72df13e12fc7af71415b13aafb69d8ba679cce758306c26e8364ac31a98954bc1036ba0f87336450632da7803228898c4ca87b2255db00f73a087cd16ff365efeef81e5c70319fd43789cc65a0785d8e0401a14570d50970d4501cd950fa06543adbe96d4932e4018676807d0b39c4426cc0a1cc01725c033a7105953e77fa0239eec93db8d71ead15081cb24e3db856e7a8d7b5d2c69c4fe7d1bbfd4db31338f411b1f093b15fca9efd7dca2ce1abe33ef0257355fc863a50d9355cd78ec95141806b20595944f781a025c48853a597190114d30a31b7413aefbccf90f27f71bfa02c6f02ac6c536207c9907de597ecf0f4d7134c3aa834b7a431d5b96a6a65f23ec936d927fd2e2f8be78a4a256f108300b29e01b54ee4a5ee09816346714f42c63915c4444eacfc9892085f228f4822a26d9068e49f128941a9f12780ff557ce4852e9fef89bb1b7439deb0a0173324100f740f4fd70c1cd784092a288e394a6047eba1c4ed505c5954c9210f1a44e921ec373a9719b812ca11870071948c38c4e969dcce9fef4df342b3999383b124c6fdb8cfeec76a9d8d9e330bae29b0cd4f6aa42e989f94d6ca7f55be5cdb7b21b2881c287f8f51672808f31b2a5c8b62e593840026031e78911178b480021548724e64d81025e1712521763b107cadd777fdcb8f63625d0e6f43f9a3ca9fe2caa7870934a8886a98f80032d70e94bf9544269410c0241614d312394501b1ee87dfd175460ee754d7c48c2a226941003c4baeff0c1fbde931f5490de225e3da4182381571a9de3f702a8d014bbd10502f320367a0f49fd5621fe526d2367b682027b7091809ca7a122510409c5b04f80002fa551f80233de016c7f495f67faebe5d2d274fb3f9faeab7ff77f57b955ffd7675f5ed0a4dc44c7dfaeffffe7655cd27ebf279f64b367bbeaee6ff58f24d5ecefff1b899a7bf5daf6762c927ebd9eafa69b35a5f17ebf5f2fa66f2942f7e592f0457b72ce78f0bf5379bad27255fa98ff3f6e607e3be5dad4a39bbfacdec7cff762516d9eceab70e30f4c77fad4b3d1a18c0fc8709fe61fcc066f737abf35ba7f3cb0fd0fd0ecc8ed1fd8761ff661857dfaecad5bfb2f2e9eab7c7095fcdbe5dad1afd83ceecf9eab7ef1ddbb4bf5df9f3c5d56fbf7e373a5ddbfaf5db15e2e5bcbafacdfc7605f5cf5a96f9e3c7b7aba8ccae7e330dc3fc76e5bd7e1cffeb5fcb49665cfd667cbb1a65eaa6c6b7ab87d727eff3aa7d8f8ed1d5878bb45a5dfdf6e3db556f5d0af5240fb3f4ea37f3bbd5354cc3ec58dfaed04a9db17f7c373a860dc07f7fbb8247861a3f3afba12feffcdfdfae6ece1f3afed7bf36f3cd6a965dfdf64fe39bf1cdf8afff56735bcc9e348114cdaeae8b85985db3d9bc2ae7abebede2a95a2d27e9ec3a2daf773cf08f7999176bdefc232dfff196155e46ac26f36cbaa8df71ca75b6485757dfae7cb15c3cad7f9fac8b377cb6fbd659a4ed693c79ca67ebf6f368b1d87d8293755a5cfd36df70feedea613de1b39789d647a3d964b598b763bdc5a0e4b3d57e74fbbb2f87ce6cf9f219cf56eb77a3d5a97757c045b651bff7ffae760ffff9aad04f5aceaf7e5b3f6d66dffef3b4d56f0b17d97f7806f3c52f6291e91f8b674fab5253dafcc5fcae85c45253652f414e126737e75fc98efffe76954dd6132528f881a87fd3928d9a53810c2dda3f6fe3cca9c78d8316bf6dfba97c397d1f4a1a87cb8258a3e5ecc6b468e2b72e73e3df9104199371be4ee7e10e62c8bfd3e91d6fcd0f3e9dd347759e82b83980d0a9fd7cf17ffe7c31fbfbd3227d2c5b9efc5cc8be8cda8b58d0bda484fdf1e74958f5e07f0bd8bf05ecdf02f6df11b02ff2e055bc66202e83b2f79c816e33b19012b5fc1e0c97d3b22bb2c4663acbe13f22c2466ecf81ee2f223b2dc35e87bdd8895dc3baa418ebfe8986a27ef4bf05d9df82ec6f41f6ef08b257a1f02ac9fca6ff908d91e1bb45140f7af9681e6f944137059dbb1b9ef1a9879ea7499467de8f7c9674cdb4ec6fe838cd23bdb7d17f957665ff35fffaa11f4dbc2827a2bb9c7a71937a759179d15d02066a6c67fc501cec99b4e7eee74379df54b9c6f4b9453c9d539e96fd65daf497d37c3925b7a8214d774d12be5163c9c058dc975d990af83c4d06cb69693769536d7c971b430be63ab754f079361e727ad337a6ea3e73fa3c01ea5d0aee7bfd760fc6ebddd1d777ce2749274f405fdf77a26b666b9eaa7b837e7677d3794ead21bb07453115a3151dfb9b740e97bec737feed90a756ff793a47dcbf1d3dfbdef039f3f2bb911147bebacf4d3fc4268af4b871cc536b24efcb3e9d5a519e82e2394beacabfed9bd94ddf9e5a71e37b239e02ded024cc898817644c9753cbcf27892d27c988dfcc470b320e73e2b57127f2662e3af943d2c9091848faa0ee17e55311efe9c0a6c0169324335311dda5a0bba60f7d9d93abf7b7c630a7a2dbf8b7fc391bfbf9016d56fadc439f91a49353ef87a26391ddf497d3b26fa8f94ec0e1bde3dcf75e9d8df143beb9b7f41ceec6a49a76f7f9e22ed6f331d8a6377d6b92d42bdf8b3ba9d755cfae6bdfe9838e736da7806fb25bf8fd265fe4fecd222737dddc1f8c9a4992cd9523e3df8e16f4a19fb771a5e2cdefdfdff485a21f4db831f1e2c677b3417cd37f4ecbddbc7826cfbce299dec23bffa6f77f7daff73cf1e2627a3b5adc5bbafe7e3915b14c412f6f9f37ded0dbfef324b10ddfa3ea3e857f7b30aee92f683258655e9eef6aa73fde17d4cb4cc41b3a4692dcb46b463957a9d75d4ee7613b0f9e9b4f3d0e6862f3d482f9fe5adf6b636637f952f3d03419d8fe6dac68564ce7553e0564c7e7034012be22c970451ffad39d6376f78a2189b23bef35deb9fb5ecdcd33f5ba2c6d7e2c5b7ea6e6d4a3cba9b76def7bc0c7be373014eda716e237e2952e69d3b9bb2921f3dd11cf44bc9a5afd354d6ce3265f46138f4b5fff73158fada6b7559e8278454b53f187a1d6b9e6fd717f3bf538dbe5dcaefc5bf4fc960f634093fa39bde92fb39b7e916e979adf33d035a75e9893c4b67dafdbcef940c7223fded38b36543dabe8e7e456d1b556bfc352c1b7596fc9c878389f36fd3606f87a6cd031326e042a52913dfbb743739a2f73e2f5ee6eaaee8680284fe7f1662af886363b9a1df063fbee6fe6a6c86e7a3f741cd55172b17e2660b09a785d99398b0e74f2edef65bf988af0aebd57c149521b939bfe2ede0c73321e723d174eade5ab9acfa9d76524a9d5dc1801cbb781f3095fcb8ea25575c3cebcf680777f2f3b79ecfdc823b78be39b7e45c6a342f34cbb1e0fe4d2f68e3cf475dfc6c97864fbb7c82420cfc918e6c443662aeadcf7cc62f6d02fe943df4c415c05f9e28e787d2dcf53d05dd170c9747dc78d59f937d9afbe28f8d4ab9f7da6e3b5cfa9a82b7f6eccfdc156adb7f5c34da6f949f1ddfd7864a75ef45dcb1aaf5e12306865438b8bbcbba67feafdf5b3dce40be6377d978efbaba9c5f73c1da720ca493bc779bb66d0f3743e2a266aed0afebd95c54ab6bffbfd9bfe364b86abc9182d7c8f1bedb56e7e105fbfd3f5304a2778f5f3ec61c7eb4dbff0ddf546f17126a23c02719309cee88396c9ed6fb96b9388b8998a58d75b12509ba935e2295b7cc6ef7abe5e7fabb73ec444fd3d1969fcc7b4b497d3e6c78f24eac611eff64303fd1e4776f4fb7e0df0d7353a05a67a5ead23c88d71504bcb73dfeb6e77f643397be84b3a1e19ba566b27cb473c0e42b3fb308ab261648e1e92a47747131b4cc6c3e7a930b992939918349364504ebd68e3bb5ad72e69d9ea3d254329888d7bad57a3b9925f4444797a3b7c9e8efb064dc24d2b8fa27c6ac5467a1b2b79de4c81919387becc12c4148f2b1975407f39f15af9a27577d3be5b1c0fe14e17a8e3bbf4653eb679068aa5e2756543f91e2aa66a2d2b59e6653cbbe98349e2ee78072afd25a6a0f7562e695e42cf532fba2356dc4c6f7ad5dde1f8a6b79e367d3315dba51edf5bdc3d7803d0aebf4e7193ff9fff8037ba7a4a4ffba16ac0de03b55f362a80d9f9b5f3a36376ccafdd50cbf80e4cabfbd10d6d1d80cfbcd01f1ddb347eed745ebc50b0f742cdef3f7efdf50f78a1f6e7bb15c6273ea8f9ea839adf2debd71f8679860fba7fe3337cd083a17fb10ffadefd3cc74951476be5ea9c764effb34fbdf37bff79f5cbd57fbd38be2d6fbdf57b57eae87f65b3e56c9ecde669f3dbffcacb75b199fe922ec475bef8475eaed59f69c97973fd6c1fbac9ffbc4a79399baf7fc91757dfaed2c5fcb1ccdbcf8f6a40b35acfc4ee784792b747ff9acd9f57ef4ef1c974c6df9f1465fe34519fde7fb1581e3bfbbce01b31db9d5d56f92c6b3f3ecd968b55b95e3c95fb2f5fce34edf16af1b49e65abd9ee95f6b2e1ed91bef6bf0ee203ff54efbe9ed5ebab6f57b3a7a7c5d34a3d8d508707b44c174fb3c54ad1723513cfb3a7ebf6cfdb4147097ef2fb6b31138fabcf46a93f9fdfa3fdf67ab55e3c4df299bad3e2a9793b584c9eaaa9168f8a904f27bf54ff2fe7b9bacfbb71e53a2d669c17ea4715db2b49f7ed2a5f2cabfc97727edd4c04ffe5192829b8d0ffbb2e179b75c9afbe5d553f56bf948bebc9b21493b428e7b3a746fd8c3a71fd345b2d364fe9ecea9484bf563752f499cfd6d79b2775cfc5eaaa0d3e5c2b3ed55108c50af9ac5eaa0f9bb916dc2f9faeb3d97493efb843fd593f95f35cdd63d5e8b5a687ffd73e42f4cfabe9e651bfc7b459cf567a6588e5d36cb5ba9eca72090e4f3c2a7e3a3c91cb7279782c79396dd7d67aa25efe9a97abf5ee44cb70e953b35c2f5e3e5c4fda9f6c0fd27259e849db1d67875f66abc9ebc12c7d7b9801db36bb1f4e5c97f3f5ec693ee1d7b36c3b79ca56ef87715e2ed765fa7aa6109383a397cb9f26f36c37c5efbf5a6da66bbd4db5fb4264f6eb81baeee028ed1c1c1cbec0aa98986f8e80fdfdcdb16d8283e3773fb9e60774aa6da3fbf6e87a5995b55aecf3749195f3fce0e3f56435370f8fa793d5ec7be7cd99723ed1cbece54cbe981e1e16b3c39b5fb395d6252fc74bbdbc3e1734bf3f2dd68b399c945c2db7dd634fcb75ba797a9eadce19fb3429e7cbc5829f317636a9cf18f532b76a49eca6fdab6b16e9f49c51cbd97c992fcf1fa916c875356bb64f939fbaea492c9e7e62fc2ccd8a9f19cef389989c4596fd15fbf93ff782973998f07cf154ae0bf1472e9ea5e91fbaec75a59c7bed729256b373587b7fc10a547f40e3ce44f9b49caccaf43a5f64abeb1749bb3a394c89e133465c4f9e9e26cd4e667f3e76fd347bbf308f8dd8498e62f69e73df0dde6bbc233a3f7dcc3ffde27a954ee6f3cf2c123560bda866f3135f37cbf7aff107ec9962c697b3a7ebb4785276f299a3970bde3c969cff7bd6d2cba8c5ea8c411fe5d84fda5dadc5fcc5a0578d397b2e57ad5b71d6f8d6d6393574c93762fa61517e3aec3a9da4c5ececc10bfe5e607e3e58d961da873e77fce2494cd6e711f0fd4559f9f8f89397e4e5bacce78ba79f7dbe32ab7719373f75d53c9bd53f79cd62cafec02f2911fb472eabd6bc9c9f7dd562ca66e9a72bf9fde8a512f1e982eb875bfeb1abaed3c972322d79b96efee00d5665369bb6a6e659973fcd9e3f4af9cf872b8feb73d7effde8f5d364be5ab6cec7cf5d70dd3ae83f7fddcf70c5eb5579f9077eaa58afcf9ee6d7ab5ec45cba10e24ba178e406abd9d309effbc475abe23c77fa4ca7fb3554f2d3175c678bf5d7243fe5dd7f18ac4d87570fe5eba16748d376e08b47fff550317baaf86cfd547e45c3f7c3cf27e6872bcf11ba472eda31e1e3d344fcf4c3ce17d947069c6e1e1f277c715dcc3e6a9b7cd18aa9e9e6b1fdf0764029b2c953b9503f91bffb8a4d67f3997e985de0e0ba7c37a29a3d97f3e9e6a99a290effd731cdfa53a1a08fcfff7ec40bf1c464b93a27ae7456ec6926a6b3ec0f46a98e8f5badb3c5fbe7fb249ef53a62357bca4bf5ad5a1f7a9188c93a2d963a2afb66643d99cb46d1fc1f937c27aa177c32cf7f593ce5d7f5f5de25e78bed63d98a9e235fa793d5dafeecbb62921613607cf6f5e6e979b68fe29c1e70c0efe58c679f8c7f0d1d1dfbf66394e7d82865ce9b96f1d92bad3e25c46a555c9fa2a3fafe3518a14ffe6b39adb2c713e3abf9623b2f163b87ef70905a53af91b80f5fbdbeabde4f393262f9b4a89bf75fac9ad5f5ac9ea593e9876bd457af06fe7c35799c15b3c94e8cbc1fb899eb20d54b94b59c3ffef26c1c9ed94e9ee6e53c5fbd3bfd1a8e2d269ad2eacff524e3b3276b7ff63a7d4adb83b5aeda2945abf2f4df17e3bf3d7a79627db85303ed576c3953ebfa4d7c68c2df9c4a979bc3c347b1dec5615f4ecd67ebf5d344c7815fce2d563a4072786ab9d0fee14108f2ed254fb3473e4bd7bc5cbf39bd2ae7399f3df2322fdefceaaa59a513cef554cde6cfc7bedacdc0cbf9f56cb5e68b376ff76e12f7f16fed7efe9138f827c3d45d5e43462747ad66eb2fc73c4f78994d769b5c678e7c111a67c4ea5b22893632affe5c4fcbfcf5a37e40fd79170e166dc05efdb9161bbe2e9713cd22fac4ffdd2cd6b36cf954ced793a91639731d57520b70677cee3feaffed79e9e5e47eb276e7d472dfabdf779b0a8b76e5b69f362b3da5bbfd858ffb0d9adbdeec3ce80fd7ab66bed651d58f3b1169bb6bf56e5f627ffc1ae15b2f848ec17ff86647d20fe757cdeacd0647bad01cfd61ab43fd79bdfd8ecff75b20dfae36f3326dddf8dda7ebcdfad1fcfef6f8873e546c7ff5edea7936cf164fd75f28ae33461da88c53a3f51f2565ce1db70fe89f1a7ca8424f8c2b5a3d7362c447ed7862f0176fac58339bafd43f315bad5af1fcd9c017e6cf377a717d396eafb94e0d04d785f2a64f8c2ab3f9e493af95066b45ffb16fb50dbb9aa59ba7d9f5b4cccaa7cda7d4d243b5fff6b87812a706ed7954ddf09c717375bfff7a970dfecfb7dbdbffdacccbf5bf94e03fbad1fde9d7af5bde9f0ed96d7e7ffafd67e777dbe36fbfffaf7719ecff3c2f907e4296ab3bb756fbe120a51896eba7bdc07c1db4df44fd3b69fe2249f3aba7f4355dbe2d57f8f393a87601da5f9e56a7d3a95e87ed93aaba3f8c8b54f5ecf2a9ec3fafaa473ff9df453d7f17f5fc2d9ffe4df974203d0e4a14c788fbdeaee0c6ca38618befba6c71bbb8bb6f7e3cfb83a1392dfb2c1b234327bbbe16ccec409a7582f1968c8786ef75c52e21b7486ffbab4982f663daa4788f6fe876f17cdffcd089b504c4326d3afa776eca1fcff74d7f97f07f9000af4157e315bde9bf24fcfbde6035bd39f94cba8863578874587cf4eeb9defc764ebcbe066ed91d0bf5de0745300b02e83c287b623a8e0dffb6a5d54b3275b407bcaff2d9ee1dfd9b5eee7b35cf6efa15e1dd4a37b21efbf9ef0ffdf52cee56a4cc97c19bb148d0c6d689f177dea81c83916e1e9c96369b7add0d7dc8977778d5cecbadd1fef57412afbac76ebe460b9a740e13884d9d70feb6d0e94d21cf6437fe2dad4ed2669b257e4ec6c89e0a9853d1d915d3e48bf6fb9e7e9f54c47550f6fdec76b48d445c67492cb39b6dfb9cea7d6ffa7b9a7cdfd373e40d0c826b9754bb77679dd5ee9e4bffc6f8dfbeab8b501ee8186da7c096f4a1ffebe16f3edc8e8c74f05a6415b065303574823d9fcec3c55dd8d2fb315cea7750cf7e489b3b350772910f856966377d8b26fef780eb42b32501b1b32b4a5afab7ba5047cdef33958bef6d72b5bbf0ab1d1f5871d326a8efaf8d4a35771fe6d9dd17890df7f7fe1e8811a762604e6fc3c5dd43f5ebcddcb8dbd1bd3f2dfb7ce60dd6a957f383f576c8e3073c3bd8af21239dc74c17f23c74ee7c735dd1f1709989681182fa792aa2e578478fd41a3559a20bfdde3f97e2eb765e6fe3d2f73430e0777f808cb42d5eb97b0c17776d73c1be4b135a6449bd2f7af2496257532f6ec21dad5fe94737be77f8bebdf5efa7c6b77cf3c5f7ed3f0d5c841779648df45c046c2952d15ddfdd0cada9355cd11b7fa9017cf6d7dc1a77fbbf8fe17fa22c5b49e16232cff8ece94b23ee60dc4b71b6d5013f65c67d9a157f9e19f7fd4f2cced68f7e113beeff2f13e3ffb6e3feb6e3ceb5e30e24c37b43ae458f0dd892bd2893ea8320fff566de56806a489e41b75572f316a136604b44c7a3c514842bad94cbedab52d5959ce1ea83121e1bfb7baea6402930bea1e2c7af37b952b6fde174dc5fd1a4adc2fa686864522b51c099ef155c571b6b053390335d61a614445bbd7c773be4295e7c7c9e7db721b9d095e1015bba4ab9fefe5189fdefbd82d9192532f5ba1b6520ed95db8b229fafbefbb2dbf5cbad36645e953717baaaf5c15eefe8a49456f7f787fe9e6edf834a570dff7a53be2aa32386c9ef93265fde8be133bdad1654749b693230fc87bc7cf0e2d5d4fb91cf2ca3187b9df2fea6ff520ddda2f155cbf6defdaeefc5abc3e7d7ffdecf0f5e7cc760b5b87bb0cb2918d9779eee34516437eec2e7a30549eca7b4e9fffaf83048a7a5ff4acfc6d69050770fd5a162540604a3225d649e32e8787623cc677ad356baaafbec9e4d1b9ea9156f958117948b37e7db0ae2e271375fbf12d1ad6678f13d547f1fb6b9ae70bdd9e6fa376e8d5fdb6aeede1b83edeea6caef71e7cb397f673cb4fc5e8d8acc73bf07c2e659537c302802b6acf646ccddcd2bbdf7cfe19bebfdfa693267f15d3fe7606740bce1dd8c6737f9f2dd33ace838d47ce53b46fb8ecee27baceff1c2d7df03d15e7b3f1f3d8f5bb4c9c7f4c590d6cec3eb9cb78e8632ecb7ea9e7b835c8d3fe01f65506ec8382b26e3f00d7f923192743c34c620aefd8742dfe77eae3baf99a9e2d37dc52b5be2cc1b18d9183953a065cdef0f4d75e25ef907c36c58699eff1e085d41f905eff7ca0c749ba91796770fd5eaf0775a9e546baab7d1fcf3a0d6d3408ead21a7a5a25bbcc9ac6191dee4cbc3eb5ed6f2ad32acf539f6823a610d8d802d352f8fc3c5fe7d5e1c9dd4ebca3f3c9ff3fe736a2979611b53b3abe9a99e75f7fde2e5b9dede53a637bdee1b19f8b03d5c03ea9d2d9270e32d3f0ca4ae2cbd7117ed3d6cd9ce1b54bfbf4ccdee4bd5aabac7d16b075d9e3eb88b0f34bfa1374a8ebc18d45fc9930383fbee61fb811f76cfd7caa61bc59f48f1b9509fb3c4b65231d8dedd5487d7bd3cef63b8ecfec7aa56afc5a49c7f69a9ef07edcdf41fdf7f2ed8fa6f5ae97f22d6a67ef2bf8df4bf8df4bf8df47fd748df0b85d3a1d699d55ad8e1b8bfbdbff96095ee2d6d4cc74340c7c36eb05d6aeb89263618036535673c6d43b07cea75e7c17671374dbad5ab45bcda1dbf6011294bea40dbb5cfa1b191b87177a8e95abca4bc0dbbdd22833a8bef93e4c7f7802b8d1baf3267bbb8c39d17cb93266d288cce87cfd3b8cba773b2d89f1b2536786751296d26c8385e6583ae9824b541c7c3c7a9e52ffcd67b50da7e3349ece5ced2b93bb072b653a5a5cbbe0931d1e154ddabf1a62f334f594df126638bef9918347737c3109bc3c82fab771672f7e9ee962c7d47bd1bd9a4dea04941a434a3399d670d19f7166f35557f90cefdc5b8a9f2df71270f9c5e07de6cf756c48b757adffcc8436bc89517b60bcdf9f16014be6055edc6b5dec0ee9ca2bf88adbbdbfac73baba29fdef67616ea5b0ba6fdb7d38cdefbb9e41555740283465bfe3be0d4e316ed9bfbbd0b77bf58c287e78f5dd74cadd8a00f7979dff8ab7d28978258cf73e6fd58bc6064311d2a5596e9f22e5cbcbb4f6f938aae9979d1c22f7f28af67e7991e584d4db1d85bea015beefaa31c7d97fd337db036da7ffe01becdfa31288b8626834a63b058e8c70196d2f2b1edbb77e41ebbe73bb0d2ef8e7b5e6fc38c3b0b66ef51ece9702f86cba9081777377e0d59aafb8ddd3357d141f3fbdd4375bd7b8e8d46940471933679fd72fd7c68aaf5ba1fb3b3f2fffc50a698cccbc7d96afd4b33f90a89fcedd05790c99f83cafda30692ad0c1efb87f967624c5e0a2bf76f03e96f03e9ff8b06d25b89f06a1d9179bc9c7a239ecee17725c15eac03679153801add3dc3ea1713101bd366d769e1ffc7de7b2db98e33eb820fa498432f921773217a4fd19b3b3ad13bd1f3e92754b56cf76ab3ffeef977c4097544f52a95482091482412c0971f848f5b3d4e0596a0c8dbebd017af41cb9de1cb23f25291c0ce55e4d3ea93858adc026f6e529e98bfd4f5417d9e1ce497c369f7d0db8f7764f18325719ff492ea02445c228f58139e7b86beb92ade675d1fb76421eafa4dee6af87887ce879f64d33f667c300f79b27a79ec9fda016b6bec4150dc3660f6e5d6907f732d3b0dcfb2cbe38f91f5a7f44bdf9ffbc6c244fc472c4ce8cb1361ff5316261241111247befb69f41fb33011ff8485898010048730f2efb8e92f2dfe3b6efafba36f16a6370bd39b85e9cdc2f466617ab330bd5998de2c4c6f16a6370bd39b85e9cdc2f466617ab330bd5998de2c4c6f16a6370bd39b85e9cdc2f466617ab330bd5998de2c4c6f16a6370bd39b85e9cdc2f466617ab330bd5998de2c4c6f16a6370bd31b57f60b98d3ff1f144cdf8b0792a65fd26ccdbaf9af18987e78f01bea15fecf3055d0158610e27f8aa982401801410221fe3d50d54703fe6354d5154511e48a21d7bf83aafad2e6bf83aafafee81b55f54655bd51556f54d51b55f54655bd51556f54d51b55f54655bd51556f54d51b55f54655bd51556f54d51b55f54655bd51556f54d51b55f54655bd51556f54d51b55f54655bd51556f54d51b55f54655bd51556f54d51b55f54655bd51557f017bfaef21ac80ff93a5e5dc3fbfac2fff146ff5f3a3dfef4bf9ef5c97f2156b45fe9bf7a5bcaf4b79130dbe5dd7bfe8ba7ee34fbe530f262db9a6f48d1405f3483d47a69b69f48d4f72d9b8331f09626231efe4778b3a139eabc21fbf839b6b68dd489111e5002e8aa4d39acfb25c302c4194eecc23f2a0472a4845e4ed43dca68f142e8694773fcb7abdcb87452c680ddd36cb17dafd36f2b022e6c825f4d329f2b04664c03c6cb929811df9dfa707fc594ddf8fb0fedce7fe78d4f5e9a71012fb6f3a5c14fcf71cee87e86f87fb76b86f87fbef39dcef1ee2bbb7b5585775686c0e6f0318f85217fac64a97ec12fbe1a220e911f8d416fae21a7b1c1c7ae8fc71818b403549898d812fcaa2d58f0aa21dc141ce81d72ccaf1fa6c16c9070d37f1e3f71f97b8fcf67bba542bf1a06c975373f1502bbac48a44301f21ec2ee1c70da26e4d7fdcb8c99d094215299fcb4a1b160162ae49d76c816ff674896d494b8ea1a78174899da16f82918775c9d62f09427ddc3668b46e1177aaac741a989cc61cc05c15f1ced7faa58f1b29f97db04a4a3259971269b512b77e893cb3098c7e54da0649b68f7fe7f8f6f1ef96e4bdfc925964b12665a526f0b0f3cb7b6bdc4adf64525e32f86191f2ce4a97e412b49fa4b5cad6af21df9c2f3d2830567efbfdc096a084baa4e5eaf8f5cef7e70bb9ecd704912a05868ac843d7d7e74fd2db8f7e1be5923c93565d3f2f83225e9f3f0970bfebda730eeae3b2a0af6d4c3bad7a7d56b67f8f9afc8f6cb05dbbbf98c75e4f7c9dc160e83fcad1f8a379ecaf72344814bd22c4f77503f24f73345ef2ffc7291a388821084622c8ffadb3d83b45e39da2f14ed178a768bc5334de291aef148d778ac63b45e39da2f14ed178a768bc5334de291a7ffdde3b45e39da2f14ed178a768bc5334de291aef148d778ac63b45e39da2f14ed178a768bc5334de291aef148d778ac63b45e39da2f14ed178a768fcafc3eedab5fbafe669b46b076ccf68183e613c7f0cb5fafad057b415f95f65c4850810c70914fd86b682ff29da8afc9f13e27ec70c23571844611cc1df84b86fb4d51b6df5465bbdd1566fb4d51b6df5465bbdd1566fb4d51b6df5465bbdd1566fb4d51b6df5465bbdd1566fb4d51b6df5465bbdd1566fb4d51b6df5465bbdd1566fb4d51b6df5465bbdd1566fb4d51b6df5465bbdd1566fb4d51b6df5bf89b6fa867efa5f425d016ab4669df7f981e9b7aee95f31d1ffa9a235fa7344d69fbdf815a58592e87f8947f70b420bfbf7681d3f65ff038c1674fd1bc48e38888218f47f2d25d69bd8f1edf3fe91cffb53dff39df651397a59a4fbdc80c92df3a521840b5064c44d65923911a42681dd25a52930e29d3c465edf374be06d79e0bb60c49387f8f1c341295fac49a72e74791b5f3f22bb0f01ec2e09ecd6a2e02e21ef1ea260f6a1455109ff41b998db7c53851e7686d696bbad7b2470b3c6e5ed50aa5b2e7f3c7b2bbf3f230efad6e772496131e2e4b1c761228fad294d4109ece4295f0cc941b591b73722efa201ec6e294d0d714955310c6d31df1471ab35a2900e299fbf9e6fbecbe87cc82d72cd9a5ad41cf8751ec3121878cd22f26c1ebc7463516b587eeae1bb4c5491defa5cce5f72dd7291bee5225f80a9409d7a49ac2992224acb6d81a7f5a185ad499bacf1d7777d75b5d986311dcc362df0d5e6573f7cf485eb6153e86ba7f8d2bfef0e49ebd6222f6122cf6d09ff92992be3577ff01cf245ff5dd2ba4d4853607c7cb41949dae683fa52a1a93386433085b923343ef45747be06266d53a6bef97a078a5bb3497edfb6973e7ffbec1a97541197b7d270d5dc72d5526425ca011b5bb97d94ed5bae29da90eb885c4a398d44d98d2999ae9adb90981b20a99b6ce3580ea93b0775374b8ab29b3ab7c04637e92d0fbd068c5e76c2bbe887ed216a1e23621e791ffdd78434faa11f07769b2fb6a4469ed6c49dd6887cb87e6d4382504d00376de4a92f1d2d21e21621ece4214cc2a12f2d2fbd8802d5242d34248836c430768aafe73edb30451e34a43c07461eb924c71fe9e74396956e9b39e1c923a5a931f0c34269b126a5d151df8621f6a935e98c3c6a3938b0b0213e7ef9f725f28825808b226eb12616d445ae26f9a3cd88048afc50a42dbba4be39c43466242db985be04469e7bea5b2f27825bbe6c4ae4b52978d90c0b1569eb2eee577ad6da5c53189b6298ab435fccb3ed6563b75c14be5191e6096216e94719e110b7dc24721f7dbe8407e53b356738ac6bf950c8398d26d9209adfad5ba9d228a45441f91a93aff294a37f8dfb8fdfe59262432f2c526f0745ceb5ec4fbbac63245d629e2cc2affee4d754b279d8496b6c6d79e40579dc12b9047f6f83eb4b93747cd8e696b4241c79e617bbf8a87b54bec89308d290b61c185ad4f9d9976a1eb69fbecb41cc0f2a58913539b3e65c9b331f264bfa76bddf0dc77cb8aea48a0c988bedf7b19cb4ee161fd81cf861139758f1c5872d3122750afca973b52487f820c1c09b8ba4ad7f41954b945f75f4a1a73fd0af7cdccaaf652afe37eadd592c6f4f914b2dc3a50cd3951e6eed5a0ed8dcedd7df6971895aee10ab49fe52c72a97fd37bd88dc07656e9ef2c4a7efe37f57fe9208d29af0ee91f24df3d5972a3485447c53453435475edaa7f4cb9f62df7c63c89348dcee6be0996ed26ef9b73284fa55d7f7fa05f7c3a7c49d06861e578b3cd97e19c3f5375be1c9e5735cfd277d09516eedea3ef45d3f0e27dd5fba75d9867320d2305c531419f06bf9df7f4a6c4e5b74fdde4fe4977e8690a47df95cf7503aea8811aa493a73087df565f75fca21c697fffffcbdcf9d977c1f3a738fd0fa733b4fe1668a69aa7cb5eb55dfa7fffef7da6fd59ce54314e5b2797e37fafc37ed2e951682e392fcdec6dfdbdc9fdb148b15b1e7e4311c7cda94f04d479828a47de469bd28687d8cb853f8d94ee8331e305791fff0c5c76bfcfede0ebe8f7751708f98a6dad73cf059c777d9befb1be27fe2d30ca7265ffa713c97d40d07e27ed4d9b7b1df7dad477ad9f5f7fe16282868f72138bef745da924348531fb4d7f2f77a8aa44d4f0f020751987eb039cacefcd71800971871c1975d451e06c63cda8b25989bdfc7d36bce79d571a4bc5b8b658dffe83bccb699428b2a035f6b4cbe39424f036344c25eb2c7ad8b886c38c4bcd307bed425d0b4f9d6cfef3b4873a6bc3b2b2d09a534b6bd644ef97d9169711639f7fcb0295e2a5eb155f843f97a792b457aca83963b43c77cc52655ca934766615de89b54d0696b2cb860e87ef89b5e7ed59bff687bc42ab2cdd7b1ff57e32c0ffd624810f35468eaf8f41b0df83157d35415f16e151dd41096d4f0a35f4a0eaa10790d4a10738d8ddfd42dfcd4af79c27347e0414dfaaafb47393ff5f765ec62fe57f99c6ffeade13f62cddfeafb777ad972dbe13cd3c11e2e24510e47714e437eb341cb71ed2f6374f83a977efc7cb723e825e7dda258d30929d7d91d1f34ef2e88a936c8b13ee45a36f3937d0d61597ceab5f9d6d66f7143e67cc8b97cd5ab4cd7bfb1cf1feccb69964470c1978f093d6efe3a677c8b2d9aefe3fd97cfbf74d3b953ccfcbefc5490b05fd5fb1943ff07f57ceb03578a3b0a4a3ff4e716b1f597baf859ef3ffc383fcf877f58ce2b16fb2603f793fdf6b2fd3f6ee3ebbd2f71d25fc9fedbb6fe3cc67fb089af36f4a76d50dab449bfcb8fc91c65d9d0cb5ecdd00731ca76dc1f6dd875ea6dfaf4cfbfa85700f300e6c000ce73996deea65f54a14f7dc4d422effcd2e6bed83d962066135bd89afac62b2619e2ce9ce2322f15eb55af74774aea636ef8f05174f2e18ffee618fb88ada443fc459f53e4d7b92216ea579cfc4b9bf853bbfddbe3efb7fd762bee16b5a4de3ec916f5077df89f8f0fa5d5a618d11af957fdf4c3cfe3f731c2e7df2daa0a7cb38ae85b6f392497f15a9308e610c3681e5a7facab1ffc7d17b7e4115ab74529d15feb4ef87d5cf6933c3f7dffb7e7d0216e93cff584dde71ff1f3577bfd95af475cf0a5b7cfb9f5468a3cd6a407f5e1e7e58fb9d065235f6a3eaf9ca897107641c393ce18dea194778dc0377b99aea7bf88c57eb63dbe69659a5b53dfdc52dffca8ebcb382c92d65dd22ff38a6c614dc637672aa8af39f5173a7fd95d5efcdc868f39d9087ca989bbcfb265ba5e626fae235ffa43dfff17e3f04f6cff6b3c0de6a62b59af357f80484de07ff6c357d944fec7f9f1d67df40b4f42a940415fdafba15b87e78ed0c3beb4251f3ef4c27265029353ea9bcd67ac9d0faff12f9649f92b5ffb6fd950ca135791165f6bb6dff7d52f64fa59160a4cba5ff6d9f735f1e7dcc5272d39bf6250f9c34eb7dfd8e42fc6ef9ff84bf3633df54b5ff7adedaf3820a5f3ed37f29222af1529aff5225d389120ade9973da75f8ff7bfd0a52f1daff83dfc59a7bfecafd0fa128b721a1878dad315a422809d5fcea3df6358178d7ca3577fa39faf7dff30fe64cf4308d7c8337e94eda35fcd97cf705dcba60b3b7de9f46503be347d5d6f29f4a75f1079b34990577b3ef78be4d79aefa52f44cd7f9af384dfc668b7febbfce92bfe5cd2322f6d37d45d88741dd0b5ec9ad34c4b1c449a7df92228e6b75c2a83fc4fde330c57b35d90b44cfaa7f77e39cebfad1d5f6b735f5a5e71f02b8ef9bb72fdc2aeaa88e70e0f025f71f59920e99ab4c62beef86e6fb00b861e06cbb4a4b935e6bf7ca20369be0d49ac58d64bca93ccab0cc3978ec0af7fd9efc6c7deb3bbbcfa2ff0cd35f9bceae7db9e93fce9b7a9d437fb97ff88bc972d93874cfff15c65b0dfd7a37f10436d494b82af7550e819af75fe97f699bfa9a759e392fae277b53385c923643ff6c75f3e7878c5441f76f227b27cdaaad4a42f1f50524be8277f515ff15a571f71cbcda1b5fda8fb3f8c6d7f3fd753e46f7dc08f7af858170b691374da907e5ebaf721d7375ff56dbdf29b7566eb1621fff21d2e9df966637cdde7a4a92368d59f9e4d5aa97ad99ff1c35ee82ba6fefe4e81849e7446bed928af78cac35e63b3093cf0739df9dbf5b1f3654ef91667516d8ca8df64fff533451dfa1a1879d817ddfe5c6ed8929f7132abf581872da1b7bde6663069b92581c326a9c32386c1fed51685be6d0a4da9318c754a0d511e477a86b3bba6f5ab327f1da37d94f3bbef2892ce0792ceffdfffc6354ddf4e94da68cdbaffe7cba7ff53457fc12af2fbc7bf9e5c63200e81ffd5a3ebebbf7774fd45f83f3abb06d1f7e1f5fbf0fa7d78fdcf0eaf7fef3bbe1f593becc45094717b79c8dbed76138ddb6fff935effb31dd7312c48b2eb60bd6d94616d89f8f9b5f8edc1bf5196f3dbb26c87d32d27e41cc8586c27722b9095b7ea66988f8c4268d6b7e4dc35e3f17c96bd984fde5cf0966c90536df3770e2667cf95f3674adc810d59891c0903c37c347c5430f829efceade94c738a2295e38420359a228f0fd67a660873d855cff6d2a5630ece9471bf8dd9b52d2bc498cfd2c21116dde3b55414b26061ffc2ebfc223ee9a433c4e0a931c4e0c75e7dec9334d3cf919fb5436b7583cd36168713b561d11ec22c19c860614e175790a4e6d2253a0430b0a97de8cdba0aa91ae52f553c6fc6dfd2dbfdb77afb720cf24ffa22fca332238f58529e7b06be34289bfa2a4ba03fdfa1bfbdcd51ca6d339cdbc7ccfafa86fdbde16cb7db8d8538976567cbc1f86f472270b32a9d5944307744d62f8e87fe419d9af11fd689506bfcb15cfabe852783d32c4fb87ae22a04327757bd68b242f4abf2a0d4294154e898a59345a7633165857e4a363bab4aceca58197943160f4d91345c61d55cc7522fd9a9ad5067f6c6e9afae67eadbedf6ea3b95e56eb75774f212bff85d835e0672a33ee00effa0af95d7ff3e8f57bf422808e653a6fcf389fceba37f43268afd2653e053450017cd373dff83bee35f72f3e4111ee4d723e16f36f9c3b1efdf93dbf885dc8cfac772ff702babd1926b2abc42586eb33d6e881b0d0c7c090c7d7109e0bd4810dd75a70666c1c459038fe74639a46e711dd05ab949a290fa37f1162cc116b0b958cc550ef20143c343ac78e632f84bfd644f09a3307f71ebd6f5e0c0bae305a51f270ad40a2613d1d39dac303ceda7dd8fdde0a6e9057f5eae4f70200100089c8ded889ebfc51b4e350a5c5ccd84f01737f61abc1cee310359bd1fc3a5afb0fd35df027369198d9e370fe11e794896e768e183074e2087fbc352670967007412984359a9ac6f13db7151b3f996034c7101c75b9e1fb88a06d270999aee9eac63d759c356d44fe1c8dac69b371023fbfde2d8464295c8b9a292ac1a46027b0eca0d8012b30622c227e3b395ab0451e3db9c7ca7fd8a86c8ec5c7559a54fdb31a90256b23d44c0961163527e0e5baeca0f8dd86973bc449c4491769c84d9a2cda30c31549004ccb36feb6d9da1ce6c57d9c0ed29b6e8539610631f09d8080a927ff6725a902de5082caf1eb7ee097556441438b26a2632b85a7117e78a5e87084cc5b15a74763ee03372177e9e9cbda7190a547c6a39ea0b17a881b88a8aaf1e932eca7e7b09823e8751b20597b89139a94ad78180ec6582343609a94e320e9ee7444dbc766cd27b96d8852a8b17b328fade6cc2135c9c6bc49466b817b0d4ae702103f1686ede451e3d48b5c2c6e4e825139fea9d5b78475ecb3da2055f98d1ada42405b44ca952eb0bad2c832b41f54078ee48744a7a23a6850bf7fa30357e1a59c37ab474d92fa829d63d1b96cad1dd88b569931693437ae11a67cc9f17d836e54e1daa721afd8973d9526e484fd1276770b728051defe8f080e713030ca9e80287327969cabe55d576cb31710fddd9715a99439d43d8ee28eeaa84b3153616b1188f544a6760796b793db691b62c5e312e79e683e9d34a1f5de694e9d17eb21fc3bce436e32d22bb803022d7817895e75a1f0a84159ed706153cc091ec8a3253b64cdcb337046a712e514ca703b1d6a6df42a120f2b734331caca8b5f8e972e64d830a23d19269c16c0c3ece13183838536cf570e0162daf7179310225c2e567218b2d1340610f15c30dbfa6185ffb9be03bc9e9911b209b8f406520179f618782d24b3137a2bf3ebcc863515018ef4fc88852a0bba47371de60bde610a53f49b6510ad774639ea5708967d854742b39ca787969a2265922a58ca30628120c744ae064b56bb3e823a46b5bbd5e847a5390baaf51f7c2a017f74e51d1c6a3d8152f4564572dde4d1d19b6f62ba6bb7ee36fd6fd981876f76d8f73b2f87982aad89db25a41abeb945ceb9592d7578628141a270c8b81edd213b98d7bb4675d80c68367ac2cc484876bd4e6f50416924e9b51ba3c2f37e9517771ab846b19cd9a4ee1100caad895b24f16c2156b9d5bbaf58f0cdb20cc58d870849fddc574115647c0a98c9bb4389a86bc099787665624765eca1e04c7a2816e01ef16dcd596a099d654e44a8df814e897a803a9d95e06c9e42aed8a44060202d52394792162d33a474398eab9c7d476172a875602ef9bee91dc903b2450609823a4661c2bfa6c4c601fb30a189e3ab54226741dd1c7de8b8c7871d57ba345e66a5e5160cb84c9d16d5e6e03c2390de365a03ad43c301a0ff11ee47b90e3a906f034b0aa349800d2aa937a3619348931f2a52c0861d84b09cffce589884eb4a22e7735d77e2b5a1dcdcdbbd8ef44932db31ab5a0bab0d60a950d6af2ee2a74ea9219892253ca20aafd36ea4935d0f58456d706a56c9d85e4901d8cee790493d7f83bd8448f0c5ddb79aa01d1c5f5c7d55c6b6d0425660a26173ec46a8a32e119e1fb8a5329d7f77c5ae79d7c0842db156b7a315aa687c0e402cdf70600dac78ae17960c78765a954041413e702e4e4630b45e4aeca1e750d56066a6016b09bbc2ff4bbbb3143ea0f43b35bd51cafdbd359eea83df9d7c70cdcdcd71c5c59f0fde48ddcb9ddf89bfcf7e660f16fcdc126efb681ef4e29fb13e4ae56ad2fb79663ae1d3b846d98d4a59983ac131f4ed4af28553fb9b9a5effc932c4039e676d9e08cc22d2f3ceda56d77f7852c5e2d987d5c9d0727ebd29db83dc2f0205d51bb89cd7e24b8769ee7790ff918c6aee47adf2887d06c8a57750b6ce0078394b8046c97fbce5877d224548a899ee84cdef35df34d4476eebc0ede5b393f4c06cf55005550671f09dd764891c52dcc09fb22f407aae188f69c62ce72931e47eafc86df65944a961aaa92b0ae3c974dd55ce7c7e298c5c52972b0d799683ba43c7755cd1007a87f90f74878100a64a8bc118d13c2c411ca643bcad5780816abd89077d5953bb89589adadae1233d853b7146c7fd8d44366e2cbbc0c04288e8ca0dea707c4548bea6c70ba6708d201f3d38367179b9fcf16ade249c72bba462f96715cf187de8fea5558d002581d965b42b7b1aeba27053263eaa8b8e9a19035191380d5b306ac6175dd76ee82ebbaa0a570304b0cb8c1b3100aacc8434b1d570f7db64fcdb29a50d671cfe74d7312d45ead8f878843f1846bbb078f3d7c91dc80ce0c9dbce7530d5774844be99897563bc920a4a614ecf1e0e477182f84cf49033da2237b6675d0d54a562db5e80654c647526ec5363ba8b250e0d2e14e646a60b4e6082fdb1883542a0aa343e0dd31152bd66478cda4b6c9f21eeb454fea812b235a192451c70bd3963acb75d901e0425a23b0d7aeb0d8aae0dad23b9aa0802038b0b1da18d598b02135bce28843585ecbc776b5875835e3ea7aafb58f3899f127e32a5aafe18219ea6fe364ea5771b2b3fd9d3899fcb685ff330ccafc727c00fd0457700469cd84e677dbfc4afb09857d86661aef12c589f1e3869bca4ce6a5dc9480b7ae8d528e4f7f6872fb566aa5d1457b394ad7d471cca63c4f8909fba4bcab638dccb3c00a17faae4ee84d7e3a35ee38086cd767425c090cabb109584f084f1e370aafca4065d1d0759e010579d15dcb37144769a597c9784e0a77228ccbc45dea1936333364e105ea1261caa254b03ccd4313427b42f71c1cee33de1941a00da379d4f4bdbde3e28dcb97352f4462bb1c9bd3fb986e09c3a50be9f12843a44ecc84aaf440b24ecf98b807793e715f819acbce76183f1e5b245e9d2b9b56476a2f05c2173a121591ecd3ce343fbb3410ee5913d5386a94b51861d8e3822febd5e11a0a4ba4034ed9c1e7b94963bca55947af2f10d54d96e728e4220b884c930ab662d1ac2ff210ceb1ad92f622d05341aa3fedc41cb860f0609b209b24d412d4069c15a4ac45856f763c4c83fb10ed2315bb72e168cc9b322cc72d1b03a507455581b684b1ab35aa3b84796123ddc59f5d8e1baef3e210bdadb6848bfb3e8a42c866f8f0f540c564331117089d1c2744dc43e48e1447cfa2686c740c9f73aa04ce8974a54587d9000616a09896275e426b5cd2d8ad4399703902c7a3a7d1a4dab24ec5c7c9a7855c7b458be7ea25d4dabde678619560caf026a6c87c863fa1e68156cb89fb3a1ab8888a24cf4c4fb2e4891778812c1c90f4899df49ee96b81cc11e9c11341bb972732e06a5d2c1726784c86949678682746ab5cd4cb3e7fac978f7d7ed079fd1a4e1bf5bbf532fbabf5f2f6fbf5f2d73d831f209ea0d9842d07c582c97e3b7a7efdfdcb9869dc5c08a8d5e51fd74c79743a5ad17ac714a6d1d722fde08d67389aac34df50c2a0f20bc81e7e34526c7527e6fa520b7e9b2a4ac53cc7bc0862cbc8d3a6e1a4c86cd6a82ec2bac699089c298d24311cc7919ec4b0da8b0397ce3b737df0c003c10180c4ef0380e1178ebdc599c8f165cfb6c58e68fca0b76abdcbe7b0d8cd73b84ae6d3aef720ee2c41f3a4d621513d3cc63499f6e220fd9cbd96e4296d607fd4e7dd7ca69a6f85cdc300dd5b9b24edb6ec994a6bf15c2dc4554913bfbae0d9e34e52481f303d57159705bbeb191f47fc69da5e345970b532b7298598e54c60d38f850b90c19023c5f2e6eaa240385d6c91fcd6215ea67b9b42755d93a203f61cc0045fb882d6da12e37d941da72b0ce221524d0c5f8c6ed78c28c8e44f74ae56c6cd69d7e3af39574eac5c4c11759d8a49536e44549a3d46532c74b351bed472536dcea091a4132a2b384c23fcf114a42a6b569f7f2aa60fb281d5b566feb4ccc4b3ccc462d533bb1c201426a9802bc9a353fb21d9c1ba0d47503067dd22a6cb73dbf54335ae7e07a3d96a4c01bbf3779d28d3401a53ecb67722038b05cf18a0722b96c7d955afc54fab31aad363a1101195d5ee013a071bc363c91279b97915107819917b799ce214216ab01218c458f4289e1cb1b925930014de3ea87667ef2863257dc681b93f3476fa3cfa7cee19e9906c43a62add714d8659288f98442b64042f311105661efe0a338485071d1267cf199c5562c653d4ab2e40c8a54b817a3b4fd87500eee18d22aee6a32a7cf13e24804ce54f83f0b15c7a5a98f12805c727260aeeab756e644fbc41a050cf11bbf32ebf6d576a596b9443121a16bb530bb72e90ac4c23698dc60a14ca591c855d875c0e7760403e9b3941010ba7b5d0541a5b69ed63be78880de1a10c77d40b8a257718c678a9611283b9c0b58febd5720543bc19d4c3cbdbe4ce3c07af98a4912b0a81d9a0989f489de3e43954f87a55e6688b892bbd552cd35c28eb16031da39a57abb0d518480cb424cb6d22f7eb74e815572e5abc3daf2054dfbd880a03ecc95352e05ae33365921b4ba847f5342f5ea295d8966dc2553b527487c2ee8a34225f2ef9363061b2ba127811fa0cac51ea3ee163eb459e8b46930fdb34001d1ca9c3424e3f29152275b3f362de2eaf8b1d400d1beb4eeb9aeac6e8c66ed94fee3afbea301d7767f23a1eae30badc569953a194da7399b65d1a9615f1e6a35727f21b39aab7a9e6fd3c6c1a964e4ea9f543aea9f5646cecf39ae4fabad1eb40c1f2ac4308c85fe7954e0b59ab9e442d90e82d6bd17648ed68a3d73d76a267cb2f0273d7b2e1349d60e550df410f799806304972d36fcad224896e248ce40e690a96e8379860edc488217dc14dd6f226fd722ed892658396890baf11648380b2cbc49bab41ecb2137b7f2708305d16d433980391413e1e74a4b22f6152c95e23104f951424700520cce238f77984bc3eb83b3ace86e86b80e93682532d9e9d41f28dc317eeb03b632197c50bc15a1d83a498fd23d36cef2104c4c8b2487e56493f210b56875e703254da67c26520e3598e7ae0466d4852819ada1b4e7f85c2dd5312f1093b05090b5793bc4abc5b0b4265193556ce526b97cc3d40573b52b6bdcfbcaea0c649e5ab852abc4c5f0e691c4e59deb09d148400c2537b1b13cdcbe298bfe04ffcdc723514f2e381901740bfee96a26cdb4e28faa07bfce9db81dd6693241102ead926e909773a21ddd5bedd0b7f6a58f5ce280abddc43cb9564a440ac4e39e5c2e6c309ba63db7cf4d35367c805a5557974f5b625e35d75c3720c840a2e498f6e2b54bf6bd51479a967cf5c5c8dd9a034d86a68e86db8385436e6952a778cbff3f7225245e7f948d9d0d7c726b341204fb628db9614b3da5069736ec9dce05e8aca8d99bab2dca28bc4eb65066297fa744acf555c92df0af42e4364e5303e91208b9adfe2fa121255d47b103542b4823df2f5013ea8f9d6e266d30b2bdaad583b0aed3df09008ce8706bb6221e9dce985ea4393b29e2122538640d00c6012fc9dee976dbf9d00776e39c82730dd17eba582d7635c569432a11bf990f4747486f554b608d85a869cb3f2c2d73d441ac5bc5ca474972ff1ea59e2a0575980391ab3d273ea8f2ef2a4610902442e9b66ab5ef75bc03c129ee01f849b680facbc5ed47ed3801b0448873291b279eace4a3595344c5752954a280557ee2e2de40d20aede045b1130afb707c03c1efa860f27ac2823b862a44476f653a127e9c040e6993f38e78ad1a9d0e269e08fad7642c594e63bed3678aa0a9748ab59066930f85cb142a03b2d61e1e8ee10f09e2b8d0d2d5cb458ca9c1bbe7d22f8a00cf3699aea851de07dc68b6ac843421af66deea642b599ce09994e9be1a9bda2c6c467d0c4f48dd29f0c649e0f7c6eed25022ac16f4371ce91a7e126101494cb3df71c3a33b130018be8e11daaaadf4f562a2be821d929cc216e9ffb37ebee9ff3d9a443b31c43e8c8e0d8970556672dea1c1bbc1b43e4c8e5500f5612068a60b1f2cc96acd862967744b069ea90c8cb374f98c44d24dbe25e9a772ce4d700a84f281c09f430a96718c3669500849fc8ca69e14efbb4c7fbea484b8bc84990425388b3724d0458cb0b0bd34204cd54f932dcd2943346c69aebcbfd2c4110dc9316b4baebb564e8a76e35cbbc04886d27d890aff09d9fe050166375e17926ac75d225abc3bd5db1d3643a1ad77b85e405e1919054dcb8614d27fc8e38a6ee5d610511a41b9b1323988f02f7f4fcd303eeda3cdc25f2f270ed310413739ac558459df0008911b85c4a57b3c6b9b674129af02b4e0ff551a50f12d8035d3af54606ba3bb3939e81def5c4f61ec9ee12f488f089e59e375008b74e4d9a1b48acb81c3f09e700f2009bc0c63e32401e8aced16c0728ef637b885ab0a7cd08746b26264e7d6a803bead2dadce487bd87732838111f1e7a36ec54eadca2dd889f89385cbd087382de89ac847501612addc266f1c61e6fc4c25ce174bf368223b06c2d7ab1a1f70b9c8535542e69db76aa779de905a32a2cd91c8c7b48806a9a285384e8332717b7daef748b9908d23728580ffda1513d1e7975ccba2372d3f50cedeb98bf88e2dda7f1c85c06ad12e047dcd896826136579bc735eee39555081f7b524f1bd2cef016ed992140350bccc45e3604dc89d4c3241932bd56171ebc85a399927db67237ece95f86e4ced9447564329a721d5c21da25332299b8e62b2c89e7cd6ea46bb239c563a47b6121111fa2cee34ce802091b58c90cc5ee3d509043662d8e25be272b0c55f8a45d1717267444d4c487477164eab7584d9101d3649a8b93d83c9b3cbe8fdc489a093c9f3dedd5eef5da9f0b7fad994b8d215415341ab49bd0fd7109b2270f22794b544152009cf0143b429d15272be6ccdec881d961868399b203d73e04306007254795703d98f601baf45d7e8b2ea5963e4c564440d30cc40d16e7730a806d090c92bcfa202660d6da97004e137b4199c004ed80e6841be3c421259e85d92a84d41cba877738339abb443e56f431903e03b0a4916140714bb80078ba419028535c250c9b15e8bab7aa3f639c26b5ad90e47e72c85d725c01b92ac03216804e22c12b51924095dc98756f20b53b0a680d274bd347a0b19f89759e20a8c408c12d5a0368ce6336b551217cfcb8fbf4dcd64d6d03f7dc235bc8ced4938fdaf6b1e5f1d593d0f6828a9998e7e9d12a3597adb4e9d99b47fb38484b984889808e529aa6d877d4bd5d1f67c62ad51d2434f652ca237d935ba33f657dac373be3ee1ac80f6be0b2a3afe92ec7b9f0b164a5753ef2c38e90fc6a878499b966e16f01866ba6a936b1db1f8c6d378416a42b59473442004541f00ff7bcd2f1c5df0e1c1309253d806e7a606827a31450f9fc89cc46b5b897781b901038a8c791e0eae1a47502b0890e1c0ad5edb880df215c9cf82e8b25bdd4e4ea61c1a520080fd6e5c391ba5f9aa22dee4ec0a59632896d68561a02368fb315528e254081bdf2fbec5ed8dcebd8742e6e24b7b3a6fa88c6002f2988490eb3252dbb6fcd7a0cdcce970c3d60108943e7db22a24903734a221a3ba90e4fbbe02081a9452275d1dc348f4ba9f5ee757643b912c348ea0531cbf09996e3c54b2e1dac0dc1e1a40fc528e3f1524ac214c6c30446bc668bcf6bd105f01a259e065bd5e5244fbbdbd7fbe437211cf381167b2ab9848947302647a7e7b58d1d1f824133d8634b8e31da7623109e587e920903b420bb861efd99394f66c7fa2cd0b44402b1c2cfe099dd57f41a4d360f3403497a92b976108436ed258247f6408e91f4a4488697db6433e483679f679b11e283201cd31de931035929bacb9c80f65d3416f165e2182e04fd7865fc67a36db8fc0052480717240f91e9ac120340562953b20d59fbd5f228de9a03ac4ead4eaee9e0429593d3846e9f5093db84731e916879e80fd99ed9664289e1eebbb3a03ba68375657d7515c92b15bd115af9a9b369daef7e6fdcb13bc5ca494930c0171c02a305d63db96db71b1f047f6bdf9eaeffe6befd8f7b8d5ff6ea414fdf0c9c32289a07aebc530f147abb25be52c5fa6ac9a6455bec05eebb59eed2b0f19fb0b911b998581e6a4a52a501404bb4c045c3964d0f7a1d2e8da2e893fd7634096fee4ed73e59b308a5f1605d2d1d595ba9455029485a0b2d8c1367977ade839ddadb82f551d3e82ee8e3bec82acea50a70dccba715985b87f73b42b510c8d84f4d1c715d9146010180f45414dfe4766dcb1cbf07685db5f0411739d3e4e686d5526b4e47e8c0f93320973d33b289fbd8d315cd9ddce58f3d2474fb1df6e1977bbaf2ed6fede94a71a78181b74f3f6011524f6872417721e08486c16de77dc8d4585c19e51663b5e0e63c6c19d5832d78c7a83db7f4766dc85532d231d5c37562ca9ad65a721eb4689d15ad84e71366d56f866d4f8a68065c4f47ee3dd2f486832b738ec267a6c4c8ba280492c1855f17774680065225011c59a10b8e2027125e48a0886e9cafa886d8e4f5cb733ca5129a6ed97234251eeb959d68bbbc47270a2233e8d816dd3fe6e5c6df837b3043d5f5297b3b5760238c2b3827d4b91c35cf586b811e4f4b78c43d3224578fec6112264724d591117932b35773eebe99a47d8a59995f673639038caeee91a2dce9319d94e389ca6532f36c5fb39bb48254ab1705f894e56ad6656d7cba75a95fb12480c2e3444376ebf16978caf4e025170882c423ba371178371d414efbfbda09746fa4cf28690047ba4b4bd2eb102347837aaa6662649d15faa0cb72564cc89ce5029ad64a79d16a8e59ce433a26c5a2e3b826e61ad49d5a5e3c962963cbc77410e46183c5b294960a2f26b33733b1216c6ccdc34cca6b3ece40d52164fbb8a8a747f532e52175c9764b1b8652871603dc9c32bf3d173c326ff6d2665bcd3c2621291f559be27b203137fc823faf290ccd5712b716dc670a70d960969a9d070e567464a593cdb2e5ded0623c0d14924a5049a4fc5356a4f57af4c915a2e6c09f4e13b1ef66ce4614eb8ca0e92992933e2a7883126b8012702cd3587fa6708be5920b029707c3bb74a5b2f48a1fe09e546d70c0633a2cadbbd5ed352425329b770f35468d942295e8ec86f467da05478b75b12628aeeb70bbbb97e6de650917e8873e627b3f6979e7daf93060919a134f7e98e2667749f9493d526fd3777346a88b3c9a636c2b5659059e9f32224de9c9d4a5112c35674139339e5953a50d349803386ddda770e798a474e229d26440c116f4515c1603cd287bab973b7fbfa476c118489c9872763d4d5d66aafe12ab02443d9f438d5edcd98ae0be7f34bb645bb37811d2f1016aaeda84100b535949fa9340fbbc6fdfbb4b97ac0f5b7543026288203da40be95c016a69792b66b16053ea60bc5fe333db0d5cdbd3b2dc457b9f2a2b3cb6ce3ea542c5535f6be3a78a58c58a5cbadb9916cbd60a54479de64888548e13d98a3fefd503ad1503f52e030fc2457e6cb28ca303b3ab38cb8ba52a6eb101701c47c8e260320205c0622be61dbd66b830d98eef268b0d9780234b41192eae1f9c878cc76575271b1643d832b2dab9e7537c9c686ad283289a542fe66abc27fbc1951ba540a358a8afd9e05d3de24ce2e9a9c3a5e0195c86b05d4a377acf0e007f37e2459a9633a2e38832ae9b32045e0847bb527452019e49495c36b3ad533cad5a5a0f55a77b86698ea80f2b5e5c8874ec68bc41054dd90ffa562640653c4429418115664fa2069a5ae8ea11d14c6aac3c37e3aa9d2cd83602783daef611ed57942d5abeae42fb8005a48b33b0665d9cac90f02ec60c555cbbb8d110db3c29f67a9223035bdd6d03604f39d1699df4081933df8554caee3c346bc615c3e0c938f9369f811b8cb3208a36b10151a4df62e0463cf1ebf3602dcd1da7d1042162cf4037bbee2c7775af84ebb4217f717aaab0810623bac713ad51ec91c57b8f961e716abb24271c7b8afd1996524b35a8d93173b191a1a351ad0cdf5c92687cea999f25755b698c23ad16aa4ae61ce0ad20a17a4529091b41a3e101ce44347e3f0e16452ef3c005544f0f087cebf9d58e4532bca9d539faa750b46c3c871a7110e6d3b2b58692f6eb7ed5a6e770a9779db81e3302da2e5ca93636a042a64dcfce82e767074791dcd8dd6aefdc844a6e694c92368b407893c73aedd3453741592a44d4040f73efb627ca993a50768f1ea8cd7ebd8030e1072b52f849464742f8809d9e9992c7c5b2b3604555f726d681dc56683bd80a4943feb32ae46bb8c7ce3c8ae7546ed83a7b9a1eced378cd8f845102db190fbaaa6f8fc27a30c395696a42452ef1a412c40d4f88316fb0f5165bcfda02c33273c5aa1559ad28e33e9f1ed3e131547473a10784ef17a68f0e14de80baeea022547c30d1391b2efaa8746dd5951e4bbd1a7232ec1b42241e0aa6410deffadd1b39e54ad09a23bb31310635b0a189d3ef653f901be12b6115ad0fac0c5ac0118f9ea1dd2841daf2f2687d6945e50708d94f8fdac0e1f0e5fdc283f6bd4f4b8142b00ecd60d7669d27a8024b8206860f804597cc661f544170a11fde71b314fc999f019d58b02bd0254214f8ed9c4abba014e0aaa94dfa783cbb912c88166854333e23259154378dc4e2524d4c6602c58a7b3b10903411e0434636c28521ec3ba10dd312926276f5128f7543c40dd05d379d5a432d6c3bc35475aa3d1a54efe0ea614917ee21f32998e944371eb377bd9fa1890b68e988eb83a501f7e89a6b000f1b28e2f116c130596bcc43d92d6c8da31ee79cba7cc66e699dcf780c86e930da640fbd06ba6d7c7b0984be87e51bc5d9728c0c378cbc0b56e4743d7372f5b390d38db442511d45d7b6fccc71b039ed3870b4465704c727696cb0e24970993f307ba39fc3b67af7654f9428c0cdc18d6476e0f0a1d24347bdaeae5178c8715832b64bb4920063afb8eb11279ee3557099404e27c28646a4376bc81228baf02c7e0ffa22316dd5514a93cd2cbd1652a94c5ce639ce12c02ab7a9c5fc65d0229f12c8967dda79a8e5859f06e92cc3fa9e3f9ef02817519751604a06090f449a7e54803ae29732117b5069f7c18b4b25c240f1202110c29684be5d8e993dc66b629d435ec8c1730ddd286b230f1fa5ee3834e2924a3d89b925a0d3e7d89ee749b212255203ec70930cb2116f06497463978db06261852ed68e07dbc55f7497b4b64022f9ded8f7757f2a66c34257ea8a3ba0ed2fa0ba4aa0310c353ca97078e0081c6df62238dae2465194ccab8d60f831710bd29f4d7d09c1924f31a900f5612fe6b2e4838b72f5ea9cb48315398a60bede76518e1f4f3badc7bb3f56551ecf6c0c8a36b23c07076fec5151346f5c49a9b3943343857aae6bde89385e2a99cb5ec04c65a8ad6db379d5798cef5bb2c16be2c8e3b48cd0f68496b6db7898764ffbb1e985547637bda51857a74682d673d67083a1059f612fb752d72251c3b09d583310d7dd26d1561a4e2235b973ce787b86599c831276d2932312305dac109d2e3cb0549ac9cb2da20f194f4bf8ec5ec6386f3855189bd1be9585797af68dac8b95199315af490db6ac259418aa93c8909bd8634dc8a4dd3c06930e0f9453257b5a8074d04b979025750c47831c518281c6864e295b0e3c9c08b57fdfd993cc5062a048439bcee2999ec3ae5f6601da2f82ad34fe8ac22e1318e9999a568ae330c5435af7683a9a1a98e524909a381ed7e931099cdea226a0b900e4d8c05a8b7ec7d6628aa158a167907e11c58b75fa74d2ec8bec2b4315200b9ef6d37a783a0f706241b189c254e052c0edadafe23b311d475a41bb253aa9531c329773626eccc32ace37e21a2352aaf5f33ec3eadcee7562168a093d2a4c9719b20a1d0b072e11697a267583af9a19d44c80d6741f105727316f7ee2dc06ea51f8f9293b04d1e5ced612a326df1b6ef7af562a036b7ac447d8127e02779b5c83be7e5ea7601b601c8bceb27bae287432eb2234782eacf76dc678c08eaadb601fd7bc146f8f4b109c938be5ca6ca999bcb8dc4d822e8feab6628f4348b27b03f7b77af21d861f45fbd22f4bce2a0b366637e0c9935290e6a65f8deaa08aa89b0781ed311e0fb9ce1c45c7ec4d9787c6447ae0eb1ddeb8e986c1fca94c76c4103c0e88e05249318c176e07868fb05fd71b0166c08c073e17234a725651932a990361fcc47a3d6e87de05c4f2a98f44148aab85e6936cd3aeda609acf510c1157c412e33e43b6e3cad6be92849b3a99292b2230e0d7162deda55f932779afa8477d395dd825e7d12b9f63583212f9245c17afaef4b82c9b18ce366a2f62b1796c02a58e9fddc0adbaf2c55e6d92b4dc63589badab3160752d8df2aca1724b2ebe8334fc6b2810bd4fb1a9fe202e8d7e0d41b38f966bbb128ee328ccde5dd162c2ee0fc5e2d0b36a517e44311471ccbe7f660496bb44b691e5b014c3e3eab489cc71dcbed2bcf30434bdcbaf1680cf566670907c41af518211c76dc116a0b155ad3d556e04c252769b438a489a66c693539a8de32f130a8c984017f3ae9f71a13422913341b2c3915a3f647ca122a0426282d7d2fd5c807ad0702e89b378bb3ca1a4bac247f904addbea3fb3d2bd67a5cddf8786621ee2dda8c480cc0b9fe0b4a4d870cc46125c8f9f39b12761032e3ede5c19922cdc11bfddef5bf418200cae59f6b89e32e623b2724da0b9b6371e291f9778f68b958e7dc92924fb51ccc08dc46762793c8af92111e1237c80e8ed9190ae0258008b3fb894aa1e04bf5e96e53ec9c2858122f47a6f6980151e5c2631d792b51e6db89a9723ab9f60bb610040d2f36a93c70168eef36919100a5426caee8052da917f2a4174d6eb4948b3640190bb7bf0b261c5aa8dc73891323e07bc405e78c98718ebb183bb020a8029ce5176c5b5cebe5fdb47a94274035d8c761e2788159c20af2058bc2b0b7715a6ff8fb2b3d6c2558b96f40311e016feb8bb67b8bbf3f43dcebe7646f70d76272444046bae5193afaacc7333b76a8481622b497863e09dc68806192cced7840dad2a4d471229015e09752fe7b3eda4c47f06b1c6b22f3d4c095ef16de9250c2d4904dabab60e26f15c82335b8f01ff027505095c01d80538cad266268d3868f2b9984a4bb0d47b36108195d0c793713b75f6ab42dc5fd2e552735536d931f778168365c7d737554f7a5819fc032f0d57725a0f7051510fbc48948cc1769327256f3af5467422fd45b89df432281c0cccb0bb5ab21bc55285f913dbe47787df9d303deb15e05013caf0c303116c88e928028cd9414dbe2af025e5bec577524f00508f3632b8e6b1ce06b91fe52a18c538f0387663a8013049a9cb5a43d08aaf70ab33667ceab16829e70a5cca1947d23dcd949d2867015989ea82a6a589fe4c4e9ab8ee50807241c02faf969f36459dc154d75baf67a01568a286d99bee761f04afe85a59dd8b78a4acc99b95ad1b649a507c554705af525ecafcc3837d4eae4baa75a198023fc8f8701bd504a69f003831f590b45c4b15d46c44c96bc06d7868bb4b29758597332538ed5c5417ad14f6edbe4be8086c754daa61c95b37a86af6520b5852fd053919b90c4e7fdd2cc43a9596ae6a18145876881f714627319527771f57820c04863771826461e5479be8acbceb6696bddd49ea5f52fb062cb055e59541cdf73e15a42a8e676b8621fd30d46be35cf3f90c277ffd752b4af6946e58e6784868ac7e92801664d7f8cab4d1fc8ac1cc3a1d0701c01681a975bc9fcc9500f995d8c0b464052c751ed66fa059ca7b75fdad753bf752558ff76f4a8699c83887c9aed57b20c1a59c7cd77c42c5a55bd4bc8de1ce9757dd4f2464003713e096761fa174d8a9261993abac9cf48ff8200e189e445d6b279c3c4fd8dbf9045c876a6025e01c2160bb41159f04e569417587728b845bebdd472983ea3866d0a57b858931445e30c8a78d868a76bc8473e619a31e1c7a159ab41603541060eea9e4674365f545a4b18e6bbd6cb5c086c0d096a2ad5a67a52497020546c949e4922230676e2a760076b1fc11218e54811ae4dc1fd1572b647142e3fc321f5d1975b96b34fbcc74c11b99441919f0e2f3ce76813daa5148894001226ddb55985a6c6acb588b05fca44c6235a07edbf789a3b460d04eec6e1990c36b1fef6081708db3c6480f236e51cc9fbdac1936e15de5dcfdfbb50cf5577b59e5af3c69b49e21c5f4af9dace023b005c1bfd88af22c852bf536057be964fb11a19576a387a5ec9875e39189ef4f2945ed4cafc83f549822e3824a2b4ca76cbe7340ea576133869a64d394d2ee0f6446d1df7458dfa4a5607581185bfe9c69ac679db33b2218a8db80b8b88a705ff6c2be74b93a6143291acb9e59548e33a54a6f8f5a2ecba3d8494124d9991bb20c26f762cb638423b8ebe4c5eaaca7ef69d52dcb38df5875b4de8b9e74b4845f49d54e3e849e9212af5031e944c1863e8172c90950789a477d5d3f6cbab7dbbb95b874df01071a7b09dd363292649b4123437f8a407f5665c5bb69e21ebd0c18509f35f9ed91d2bd6362291612ae7eb96ef18c3eeb101957ed8240e863bd5a4909b0607e329e4bdc5202e70e32541f2317c6b7420fedb6507a12583f37aed113d6456db94a12a180a7c4af8211ae6d76cc7eb638ee2945ce6783fb8079ca2b8e9804a9b36c91e2893d9f80bbc6c5ff54d02b997a56ed455b1f1c4b93f35512b3945d448e51b70db6a95bd69b9f1c248b0406d6048175ae56159b7e558a369a21b3e957832bc47ab11d321861fdbb5685ac892187ae86716f1e2186b9973e53089bb62d9ac2285b3809a6b2a16cd0ba86690be3199313534736c7dfe337b8aa1edf83742f67904f9e4e3a0b9eb4adc15c922d9bdc1461545f3361f51fd9b5f9d242ac568e0634c7173269158bc2471f32cda79d7628b43f12f89f6742b62715b0a89ffdfb657fc99f6b7fc79f1bff576c9b1187c3f96f36b6628e48ac0010d1841ecfb4de9cfb4f6c23631783ec1d3bd7e04729632f9e4abf039122171ebe7e2760ff1c0c73c16e935d835f1886975eaf83cf250b4baa731a18218b44975f65a50cb1cc6f8ec01337618db93ee00d891200009a42419a442f0a302c0bacefda84dbeede358699f5fc7b67e5f0e48649f5f5cd612bead480d195cf7e90b708ed1d68dc999cb5c1d6b46edd27386474382f392b2fcdf411b4580c3280e7e6dcac7eae50ccba71d3f956832857bcbb9a6f9ac91d9f60a12192f8124d4dbb96f299eaa21b91a32897df96213b5293c4a8b8cdae7f059bcfc3c3a1e5d4afde8fca5717454dc5a4beb16611864b968b1b543104db95abd7adc43def9268fa5cb823e8b02aba3594c46949a875c9e1171d786264602802d72995d796a216634ec0aed1609c93e70161b7ca38c5eb74d69695e456846c78e7625117083bd5c201103fc89024a7eb726ed0f16fd594b56822644cd52b41c719100e9f3320db4bb41ce4e76bf5cbe3ade38d687a917987a40b248b71e843ab8ad56df744340ad3e86c2d30dd02df7f4316194d2e681aa04383d6be57dc4e5baaaf7872a5194308cbc46899ffdd4f7853f7c181cf9cafe233aa28edf9fcf7abd5b3ff94db0af541631068104b5c3a763fd373b34e373a4c8fed25fa8fd033a1e0fd9b37a88603e030ff4d08a5b0fcca612bc4dd97486ac07e466790fd2c0018ae17fd01ecf0d811944969c7ce6c93b6edd5ad9db9a4c5bb001ea74bb0a83f5ea9e5adda3e7611eaef16d284cf0be1ea3804d1de8623186ce7205f7705239b06b98709c161575a99cb3f1fc40aded1424118dbfb3a7e5d80afc71d716474fa06ab688732250eec7a7972227b3af3de6d77e1442a6268d5039e2bd98f72f1497006b7239b2a146833320be28af95f59e0a3186781e0653dba8a8c7c4e85329c619db4e9323c874e1b3343470bf1895546ee7b4a8256adaa388c392b436706b1d27a2cd185ce1485f2088e487b02575f48c20e761e3fe41487c8768d5b0a2f76d0d9d11721efe03cc12c0b5ea404f6b77ad3d2bb391e33dbd37383a92c97daace22fc3cb54d6754592f2c6addf8027babadc5d19ee3d95dd230c5ba1cb2ca85b152257709a9a4d1bc7810a4d0895dbadf527e4d18c88ef3e94e7ad631c3045f5fe2a3c6fded2545c0b4441a5b40974f69f6f309a53a0c4fee83759cf3b8413818ed1733d57f7901f58d20e09c5ac13832d064d8d54b6c3dbe399ee1d65c3371fb2a7406be419c594a0d89b018907ca8a351ee725c9f278b1c2742ea6803af677e9c179e11052dc3cf99bdef33efc8f5195e2d4bad7c2c3274c3364351c4155361febb2e0016f5938a8b30f91cf93c2c4b0c636c28deb96db1ec772d128e5812a89e9b88fc978cd11ccd0b495cf11d95bba539337b8e468193317ebe5704461c570818562e0b9b70562c18400331223de6f8b65f94a93231a4922991967739c7e09e2a5874f86eea6baa663a4769c168f3cc8cc13468a78aef73c81f38eada55afbf9fd39407f891539032691ae81de7610d4d1eb5d7d1876e2df5c11c72f15621a6174de850e767d446b05d7f952acd84c507f92b8b271e2086d317b548ce82e8632ac688c1209a526afdbab23141b104847b439a68507a18822bf5958e34a723610837e1b4ca3b18985e73d596e6213808ba77dfa3bfc61570da03b177b5ae11ea87941a29c841e6804736279b84176529ea3587501b40a0502e888fafd80877165d3c4fcd4daab66077be8633f2ae29b2f5a6ce6b749974fca8cb04d42a7562763c6ef6b0e64a3c5f44511881c5afbd51f1e97a3d29800660463d60951a32e77fbfcd09ec9b64808b01133c1186361c3efac167efdd2c15971485c85c544c1d4c03aa66b718ffcfce1a9ae6e5f4ea59d28a6173a7a1fc22c96d6755a86d60da28f9830cb7cdd7432ab442423d8bb956cdab09140c53597ae5d25017cfbe54594e37a16211c1699b96a656f87291b2e5cf890ca6b221e3fc3d1a1e92695a91202f3d41292dd1c8caa4b00a70428dcb88749a1c7d8970bb326b23665f7dc7ff5830f668645ae21120539b5f6363423fcd58e96e61de080adc27ef4987d39bac46a858da58902b60e8d40fffd6a2f3b219dafc62bb1300dd457212215749461f14ec1474472b92f906f102a7b00d654283dddf153f07ee81cb02048d22c92bd08d9fa245c2b8d3b024f3d06209e52282138731a5e2a770b9b5c455afd03cc8bdf1aebbd88fbb6728e2792e73d87a43552107bfb081cf8fd8451c6222a07ea41cc1d3d6a84ab6894a1d102898efd35cc2ad6933fce7be8698ac7d38c43bf6ddd18c24a6c5b73fa199cb4545ea695f62adc08b002395a169e5f632353f48900fa95d6977de5858f9b69065c236ec4bf271e8576ad5d6d9ebb2ab807b4c58e9a2cbbc4b36786ec3e844fbbc6cf9d96481b0ddfb536770e6d179fd2471a19dc2c424908f32c3c6e109f886523412f39ad157a788acc3c7aab106501b44177b606f8f138490ef134fbb0e5d04a734c7db3853af87bae23bca0bc78f6db605e02afcfa0d4efb344157b08bc5543bf017153d6c33cf67733e87d3877654a092ea10e48c9a37b617bda107fa4a5e00e44c845bc62befa4c84184ac35e38acb79b5ba87293bc16905f96e829872352af4e68a35536d35eb5baac0bb9527cac3349cc64b78f0fec56ab1f42a9aeb510c9cf1823648e066b99829480bc096aaa30de726bf2c7776bd60b0fe8189b9faa95bc34468dec9bf4a5858041fa43f1385a81e82fdc74de8ccb32d63dba0c8bdc822294575f34397ec54e715da7b5f11eecfe05b4a9aaee8507f5f8534ea9d6d0d2082fa5f1da96c6305d560a36bbfa6e2e151919dcb93fd5f984325506ccb30adf57e8d657e06e4b1e6c4af1912e1cc32843dbb9480ce71e30e51944461e6c42c5dd6409877a59b0e4f0352954ec62ac1258498b9f8aa9b229bab64b9bb4150f793a7000fb02c0cb052017dd6f55cbb83146e274d5e38be0782d008e43699763c98b0d0663706d5b69a93f8c090f612cdf50ff110ec11cd4069461fd95f1929e5dabe31933e7a4c8692b09185634e552732521320e8577678bea50bcde8df6bd4f4583fa0ac82c3cf42cfbd77255d13d7ab25849080711bea05c4731ce295d59e90f39de96858e6559c32918d83a8589ed81778a06c6b7b4853d019ed9a6ce90ac018cef54757bdcc5d7820768dcf697dd7030856087b63bd471caef47012112d87951557c7a192992fcd4a264d063f5637e03aaec37a938571bd4fab2576c7f8e82477dd14665cd5d4be76421c155ad577cf06b88152d02081d8d1a1953be47f57396a06c14786896c0dea95c5649cee9482b1803026049b4cf9b8022409b18f90814207ee6c0043d177bf3d7a4ecaa44752a5afbbd65aa35174330fae8fd990a2704a5b33714f303dc1a2a4dd09864a9f52731ab45609a559f563974cec7dc25b88eb606c487c13bc8ca093a76bb84fcaaee60826d7e766c1dbc3d6ebfe00d84ccde5842100eb3f2be0da02c9bb0cffa88354d2eb46082f0a1e5f7c9deb2047501f6032b4a2293928e20b023140d2fde95b86a035525ed300b314ad0dc8addf55751f30c5d8b2572b48595ce0a92591db5cf28539469f460a799f1868d6051a5de432bc0d627331cfb566fab73bc811694f85ebfa0669e27be072f0267229b1adeed1e265f90644129ae648f7ad29dc7115eda305db8a86be0b20a0b4cd0ae4127c2c1ccef2305af4ca635456592add0428784b9a1a231172107b42b8f9b3b93d50f6cdad00ca7d0d41a8beb11c5485e3d088f2396d167d9337153fde2eb536741864bd9f06b53771a7991ea3b6d729a690a5493cdf41daa323cba86313c04ceb946c96b5f10d36198fb7eebcfde95568ef630a74c1e333a631a977e419e7f0e59b278204bdd85ae0433ef3d72a1687d2f22997cd0b419a69babcc4633028490646225b2963af3cf351f76d80766cb4951e6673b2d7c292b42fb955d45b8a70e0a388414f30977d2ef9cec9189cd28a35dc76bbdc057cf6c3d276043fe00af72c6e5e6dfabf88a960d51d55e7db96bfc9990a34ceb01d5056fe58f7f958f98ef0a20edf7e334f1effcabc05ff95761a629c486c95163c842654f22b9f744ba8bc387ff5755d59221d87fedb50c7f802d1ee66d2bd38f1366a250cbe0df4733acd8478519192ac737bc0c2bf39ba6d6d5d4f97194c871ec057e9221f864e3d1c680f9b3303e77f0014be35994aef3d3c7a4ff128054a685a441bba8397c2f255ddd3cab6875472daef995b0de1d299b3a9cd65c300a680906ec4fe745786244c76190143e5f35d259bbfb0c1687541bf1577bbd9bb79a1d55c86c256a5e970254026b2236663892e9bc576bee0261969a839a624c420f21402b869b5140ff21341cadee56f2076979c94cc74c0c87b3f7c6451ab800e355eed3aeb1ecfe1a2ad81845a5fd4c2bd419b0b47a3c01a3fbb978b3a4830b443c95f1171d643f5dcebcf1909d90e9012da90cfe3e773c23e153e7289cd4a716c435585b6b746b960cf34604657f6244aa0fb9d71aaf13f2c5fda8faa21a2ff501efe745f94d658d89e25debee51b77b22f0186d05cc7caf74bc5836bb7dcbbfd15cc98a094e3da8265a404db6f936de2779fa35c1f137200b54770a6ef9d6251476819236f64148083c9c6afabe6fd164fb665bb09e3205df6222bea498f85e91722073af4df02932a64121c05b2f109d648c1dbf8b6e3169b177b513a9115e01af6536957bc08c64780a0fda879672fa87c37f72bcf28ca295f3e67f3fc9e6fe8e45beff8a45fe131fce0b5f8e04473c3effc323e370084494473f029d4267a83131cb2e5d1ab39bf92ef2d1b829c4fc4c452319f74513ba8ef86c5fe2b0f4a532889288d98a657cb03e2b34d2eb0f02252a4f59e4cc20249403910ed9f0e44d94c3e188d1823a122d50fcdb1e9c4232040040f0b27aa4562c2cb81983edf1b8688945c83cbd5ef01c56124847270fae6701f5093305707602acb9050d1cb5c9df82706811c28a0bc4b08ee7f948026702df42568ec0984ace4a9b9efd18514355ae0de7d3f226eefce441c357ebb3986796b47854fb24f37e5eee45de5448afe3217250fb561689756c54d863349e7d1b5e1014ccfa9b59382c202c16f362724844d8fc34409418ee14164aca047bc31d4b96d3cc03832fc9a4f130667d77a9973f69c81e5e8a3f4c6e1a62b584279a8ae950e3b167617d580067d38d33a5005aebb566d56b7393e9aa69300fb5bf412592a0ed665fe3bdf3a991853cb9a6d7477c3ecf38e9d56c7b39123a03151889e474d5a38dc9723b91b60ce38102c558831a8997fb5aca37421aeb919d4d8cfb691280acb898add9a410721f80ec4caca69c75ec94f8fa73050b834bf3b21f27400675f8001d36cf67df6a9b4ba72eb8d95a90a3520c843c2d9005fd496ef00806bacab716eff6f6db5835ce4ca9a997137c789e71eb6c7d6e5d5b5c27ba9e5457a50377d18834e444a5a16aff5944d456510bd60d8bb6eef8c0f8b0f5564b2c3f058b7409d8828c765cb38243948188abcd589d9a67cafe4e4bf929640ceb79c0bd1b01e9d419e22a226927b2d86d108d74de187a3c68788b00f8c648d4c8ea18abb8a3a83a8185d9c6eeb352fe09aa8a100b6478fb150c9bb0aa7654a8a8fa3e3f5764f29f44d8e5013a95fc752c94baaa1af12d2e500fbbabe03fb2200f272e46f8bd167a6101c16aa9af463f631ec1723f323e441247df469136b7f0c16897c0ae6466f1d1175f866709421609b68a19bd852898ac8f797bef6b695641ed3a36671e2835e94522201b35812823a5709637f2009029f22d4d9365912b6e441e4635636f72b86aeb3283b9fd0c11a5935bb5d83017834793aebc7a757eb9f0336be436cb3335a676cb1aadadbcf33466b34a3c6f2a72c13fb130192cb504be1ee14f05a0ae734fcab20d8bc4f1abdb2f9491f3f67dbdbe1760b56247611667adb5aa316b17fc160b77bc5379ebdb22f4f3bd9bcdf19ff7498af86b9010ecfd35dd70c271a4e8499fb0e263ff0ad9476329b4610e4b6e2528f0f6812a2b9f84c0458382756b5c6ba6ae17849fc710a0cf0f4d7fffca5e58a5dc8e04e7ce7779c333dd8550bd66d5f88e93559a9de6b3ec57e5075018d86a0f984c1063d2021271638e9154175288fc6b4f1de8a323176aef20a75eb42064ac57cd0370625c46224284d398e05c56d400284e19b336b01aaf14c21e51d87aaaeafdd139bc71f599c321a8e0e28c3583d282af1e585462099a4d3cd5000f22ea04ac318601ea11f73adc02ad9aa718a9133660aff063d2c78268407ef072953ce3c09173eaabd09240c85fb7f45aab9a03fb96a5c5520b0f32f94d4e0106255bcafaaa820ad653751af07352dd4b5d54961c4d495e059230d22a239ff883206a7652fbcbfd4aae940f2651dba2b59d677862e7c67aff73ceb1284cbfac2917d63eb4b41723ec7d72a68e197385197a1ad5e56aa4da67c8f41979674d18892cabd38dc69b8d516acb0cb231309cea081320afde6e2bcbbaea7640cb0e6e09886f49afc80b2b90ee62570a188da111c0cfb3aad7a2ec8d305e49a63b6908e6c76e2e847a67131d023897c5306e769721254c44daaba4a7c1f60e51a32aa76dcc722153b528426ffbb961cdb5bf1a0e2bf00dee3a8248a1059a1dbb3b226850d12dc4f8431f7d54a64a3ce44f5f37875ab0ec874c09d9533bb67c89fdf21a6edfa84976d1dd7749fc16540a66dee11c0b59a5e57a9dc09a8646f0965d1691087ca9a7a6b82e5172bbfef3bcf7205c9e6559d77e6abeb85bacc0dd10c17edb1a22234c893cf52d414c35c495239453b8682bae48928e96e7dbe32c423fc010ac6e49de6a3c1d459bd6734d846f121fe06a10854784815de6679b1189039f344df0abeb491398f62140852ef1b7c5eb59d39ce525288ec2962ad9560d5ca5b8c8d1eb4fb369bf9ff06045b92b57beddc372792539073fbf2845038bcd9103ab8e44d2146ac5c0ec747f6315f9e38595514231453cbf60417b77b58c2f70ce231c5d44b5d89be547d30454b122e9a1276da4343240075bbf81927c2bbaaf81fac114445b6735dd1afaa6c00cbf607dd2583f5f61cf9186f1aad0554977011d185d7c8c097252006806035d589c20d1ae54062f1e501d60677f9ebef0d12e129cdaf5e4e056658677ddba05162d953c4517465e783d502fd3d5a21d8299022589783f72894eefa03ea57a0969938cf7fd0c10165e4bcff4071bdab83702735c1c13643250c61e50fac812a21875f16b2af5574b7d428c06c6a67051edc1cc61e35e76561f981601be062fcac49196feb88d00da40cfd27671048301011df04b8110c1cb25df8bfe8adf648afa86f2bd922ba9122b1f82cef086a51f4752b06b4e6c047ef4451520f8eb1794adea89660187fea37f1af4dea68f927e3faee4eabfd23fc8dfe99fffac7b09fe5d1766c87188f7d9bf727ca62048c2c7884489b0985fc69eaa38db7ee4cfcd4ff61d1166c4298857df68b1b4f5b55dc7925a573aab4b58cdfe4a622383e0a2754da3ba979e37485ebcc7ba4ac04aafb354941f1f6f256e8a9579e0e85592e0005aa4b4911463cae86588b7678a21d9665c235a62cfa9a501d0b2fa91a78841352a09975e72324d1e3355aa991e71e68e240e6454355fec504263f0fd6e3f17cbc4c47426943167d1d32f88a983d5ece689899e8814a6c5b9a1b430dcd61b9909d6bc3ee5625aa621257ee38149d6b6381ed973d673cd7161de696d6c4646a72590180a3ee669b65c4efcd7e7c43c0d97e71d14ec7f8a2b56cd68457a20757cae7611cfe9de700a435460206d55ee8f165c9c932c2385f9843d065d559a8ee2cefe8c611937fba3a18dd4623ae9c6678405ea81067a19fb85f7d88c30db5b18e98af6ad902e92a871353cfc0f4abbbadbb52f7f336e483a1897650096540c5b4919747a0a663c77a371d485b0db6e3c7a12379d65fa814dc6ecd9d56f810a75dee13df18a3e59094699d53ca065e4c0936136b5dc1d307c44165784c8a14eb4a5fc927109cfcb97d9e7aef201cdb2e4b0dcf530229f46465277a2622fca69723a84c88346ccf9b03b91dffa51eb9d25680461cecbf874d0e8316e9f61db9847f99d4698b49cf2d879f5114c39d3c0cdf604836642d864cc8f7b5751fbedfcca2d81a32cea69a5d43a0e6488dd01e28969a78b205a58366f8208d6b07baaad1437f8c0ad3ec62b7bcf592a38a439d015fbcdafa58f458129770ee7da5180460af8a51a26c9b06f6fd28e5777633ab0a7816d1d41bcf8d5e91c9ec99248975c3d9edf78e49cb1d4e26d5769b6201b79c1a4ad1547ec8eb3f23dfca72e8a385e929ce2d22edc5f436ce4486056b4e09f66acc5898be9e37b0ef2bd4da0efbc7cd4de6808923ca8077251193e27ab679963743d995430a4673867087d506f1c22b799b1e411a68c2d2ad35cb7b059f7317ad506f3498162afbb609d863f5dff6094523f00e2be37fafc16d7b5ccdc37d80a904b4253e4342ecd9259f356c2efc21c9e7b3cc25bbffd33d0245823e0ca8133a9b2c3dfd0d9ef4cbd5a5347e637a3a5441f738cf1c59260bba7fac5101bfcacf1f3eed7119c7095255cb477f4333a54a2b6236fabceeffa3127f3930303772cb916180e5fbbc0bb070fd5d522a39bd95f348ad5382ff43ce8d27c8ad485295c09020d04c218f821dc04686099c07b869622899cced00bc7acbb49bf1dc173a1ff81b47c4f1b542e58dbcde2e1a25d44532939ac961ce22c40c0b713f920ee4c003985783c1ea9e9aec2ed621950953583c66e3a14653115efdc60f688d1df075c7338ac4c7476b7f3a612612229da1b0cd46396a68a703b951097a552be3500a3415543835e9d501e1d228d6e76e9dd985b2a90eb3a4c4c5ace287e7140f153e51ec89809645ac22acce0291e7767c12cd04ec69da3dcc74014696a16905ee739e923178849c140474a7fa8df5f057231999d270b509fee5917eeb998f67adeebc6786964c01c09e404bc8d1e9f63d4cf84aefdf7ad7a45618e227bac92acb82416f9f34c67de678987b58e35052f57312c91cbcba681d5c7b2222bf5c403e19d281677477b48fea4055530642b69c4f4fc805e830d558ed64c65e44333e582bc228c2f69779a42c141eb4a021c3add63aee29b4a5e1da09141dcc0e00c906d24455a90c3c12607db59286d0c9435bc9cebb092c76b9481abfdfa0db1a071025809081f1a788a3ff761792bb556d6fcefc745ecffd31ff0bfde87dfdfdd87ffcdea7019828f6958c0f97f5671fd37b7937895ff1c81a097a000c92e34873ca3aef251282b92bba2e6ab5038cf86eb2e87fd28ca8fda669d29e29b4eef919e8a5bf040c5a121674f4d0e843850d5f38f460b5bd372cbb29b12252a801ec8efcc2a10c47116f9099fd389a2a586689160c3031484312f166d1864f18d688a9f297a029a308d1f9492096a45bb7ec772fd2e01f8eae9039fc71611987bd1af18c66a90a16d47411cbcc2ce2641d8cab80812c80101bee38a1fa3094b9c60f9df24e24449be5e0f5831ae3471766221d117a409f92286aadf2ed80a96e8b1526d2519ac5750875769d8a2882b2fb82cdc6fbb26cb8abcfdec0bf014ea12fa3ceb3cf729388bf6013c6e929adee89b0f7db2c6435b1f2de060263fac460ca7ab70192bf32ec44a4ab6013a9a815e6c808c9ccf914fc93ae34e651d4eacf53751a7eb48a066f337a2fd55dbe8eddf04d29cc80b14c34707ba7054fc0767051a7c9e2996c006a7d453166f703338c8e74a21e64e941dea6b7e3d244c805c5ee11b211856024c3726328a2a9458ab4bc71e06f3b28b1a77a70ed8b40a9243ea91d3ba5d03e460a12fa4bed7953cf39121609c0c2e311c1df5bce0a7e2ae26137ab077f0b582faada3b41e05b9cc2101e2725e44eeab15b94d9ef48d340c84c900a1601e33c35195fa1e8fdeef283a3dfccd3f24ce231b95e47106108587402405f7b8d750fdb23cd7a70e4e5c0c6fa774423ede7b734549cc3e36b756dd4cb0e3d3097104dbcc5817b9f149b973f1d4f40f2d8d28f8e668209b8d8f061b6c9a7889eb6e67f956ce39a40de92bd2e775331d28b80d23a6e95d7c982cfc533ad1627d4f69171e6eba2e696d89642e78a6be9b16fd96707dd09da7fee5a92eb1751cd7fb9e26b4b3c5c1a307fd047036d5069eeb3b238fe29cac8c2d9e75c909ea32a2fc521f3ca11f30d0f1b99bdab2e2780918c606bc3e4d3ebf9a507f729ca6b76d807b56c987bd078566e8e8e1a74f83bb0d20578d8a3e467ff20e5ceb7697bab2577a807d65e84b25ce47f4a6c0d3b9d081a233b0945d0c9ddc9da8ad3551f89bac12a7576a20a411c543881766ec24f9bba0653bc958f907f4320ff6327f343d17ae6a7cff467bf9b547ebd78a07b0324f0db2e253969db232b209bf2459f04d92218e17e691bba8306458bb62a6be65a251c43fd5ae98b6f7b830e05d66216f571460d51e3c4e1e1ab757eb226163c35fc38464f87afc196358afaf683b8bdb2b739e70be4e2dca1ab6c62fa94dfb6cdc9eff6578546f6e2febfeddfe407f872d19e2c6dfc25d97b216e02dfc99a567cd83715273bfdf6ffecb597afe7fce52a11483aef88f6abdffcaae8ed868f7e0c7a77fa8dcb708ef19231b0622afecdb3b2fac332c34f633a824d444a365d5a04bc3dbeabd684d65fb39f8295d44c41d4e3c83dae44885958049a786b25a89fc3123a703f432a0a491b8ef72fb8755169a163899d3c5f791e8071a19184d3b774b1965608dc08eea6824934d0d0be1f6b49e221514899a085d0a8efa739ee3389d80010479e921ff643558bef01b5b6553d2ccfbbdc64467de31ab217a91fe2b31204d8b0eb84a8c0f951203614383956e95eb5d7ccfed0f8ef041849233ef6976c990511bd9ad8c76df85339837e640fb51f1e361e5f6cc22929dab1204bb4a8ae95444eb4ab746ed067554c3e716b2dbc8195445f66be1c990c45457f5bc4c39e3324eb7c2367721b2038817bc08ab97ab6756b0f92ee265c0d40e951486efa608248d8e21b4acb2b08dc98612180a7b4d8ca82441b9d67d18f8eff32837f4ca57ccacce66bc8e88cca9596ac51efa8f666a4f3e0c87c42f250fa61f0fc5fd3dbb3fb45c130cf035614d5d1959d737d15b4454e22b4e858936523861f421ce5a12ece0ee2054d294ba5aa6933eb6e2c672a86536e3f86401e40cf094e4d02808637bebace3bde2e6683d69bc7acfda417b46d06ff107d43c6648e205cfc36157d483cdd6fa075285bd481d4aaf5b5103bd3a222b168d04500e21f975e1da10bd86dabd19dce0b9c6841fdc2c5bb4af629cc42755b25b8a51ec11bfa88a216cb011acf05650279ca4e89de531bd39c0765683f1daa110e26cdf549867feb75561e59503e99bb24bb3c7528c34bf8e06af84337c22f0160b3b12a366a29bef761473fa4800a5603d635cdf11af67c31ab7510f869e8a59bf159d952b77b62eb7abe48be18bda65ab1877fa34b7c750e8c79d94d65fbbcfa679ba0c2aca998dee3366ad74fbeb420576f460dd1871939d60835c25ec88266ec0b045db3e90bf4e05f7330ddb6c490bf8c8b0fdc78da3b946b53f49e346e16909bf2f7d20692fe6f68bafaa0d01280f951260b99ac9bf73794383bba45c16d590a022260ced9a26278f4b45f84c1a9b124ec3b4719150c942d80ba9f3b3c3d0d71163e21100ba0b6482346cf46ede1f051516f1002b13f9b12e4f6d48b4851dddb50420ec23d32341ca5ac1f607c9a067a19db3e1fbb172ac306e8dbda38fe8f89f748e6f1ff401fe7d2ed6b53c47ca45b93fadd1ea8b86cce554490bb79ff970a08e9a744423726b7f6fed81157ba2cf6f427f000768dca792c476a8b62447c8c00bc453d263c5ce7b049abfee1b0116ce91c665cb20e3ca17fffc4c27c36f887b8641ca00e495bb088761c507c5aac78b5c9a4867a71a6cfcd26749a09d0119670e459317a69b0f8596a640bacb88f809b6dbbe56989313f953df7c3f64ec01dc3c8c9a781adb79f0a39eca78284dd72dbe694c550528f87159a274f87d3199312fe9593de2a61da632dc657851f8d5189f471115f0b6aa126d1ab16043d8a0fa3d1a2e4ab6023ffb6a97f3bd409df0fd3e0705063ffe684df0664ec6d83850d23ea5208c051295eab672d122e1923c9617208c2504054ee840a68307c4ee3c13504ffb9111ffc2888201753b7384e0f738d133848b9c40a843b27c87e34f540ac2d4c1e6b05d05ef828feef8c3ef8ab52bddd3b13e91c744419b2028cb0e6077b0f8787774e08a04ad04d1965f3a83389223d11603423228bc085959e42174eb33d65633bab387bdc38c1c9ff249c13b2513795cba386fe7cd6458f2fd9e4bbe828b0a63db404834a9542dcaa38b928e70675984dd324c1e32492215717f635c0b329c650cf086461f3e3013be1eb1b376be384e6d46a8c064d81e16856fdc8208cd79dc243a25f3d30a929704c732abd229cc0061502debd4508d57c0a18754a71903d73dbff5c5fc19cc07b9c664529076d081394ceac0dce6b733cbba9cfe64cb9dd77865573595d71a292433e4f93bdee3ae1b72374bd0d1ce01dd90976c2aac182f5c22828406f8566be49c811cf8ee709c0d586b9a024c30870fbd1e6e5cf8d3397bb29501f8857f6270fdaad07a5e33768f96a88bf4e58f2d76cdb3ecd112a58480e441c4b728a984672c405d876e95ecb673e09d112e8e7b9c5b5b1dec6ea77c8a5a249f56217f2bdd5145d796e69cd24b64e7308a75d549846fcc940b234aa3369b1f7c9af4e73ffaf2b0285f15c7bd9a44e7dc8aa9518e6c4297dd8c2701b657252204ddca068e08b1f574eb211f9d380b20d387e00e737a795192afcca08e694be928a5fc746019e81c61b165b12f9131be9ab9e764a69b9e358c65981bde3039d180d08d8c903f52fe748a1cb352f9849d55a26f06c640bc18bf7a32037b7718b7f0ec2b6e8a254c67d5a813eff0e94c28def43559cb23dbeb1d129a9f7c82f25c7b79699528ed33e527a2348e4fe5d2b33c825dde4014de206d875b49dbd75531298bcff5b83d13e2cddfa26115053a5dc5b41d9d0713db493797b13cf1dd90bdf700d03a89d2bf7b3ce9c554568a008d7e19e1c3b6c2f169b730b3d9b1de87841533863b9dcb91bbc6260b22d0aea003bfdab367a042e34dfec3af257d7feeb8179a4132efcf296428f829e8db358337e2e7d4e86b54d1aa81987a1e4988984f4b78057a1912dc7c6d875e3507e171d4edf0a948e7b7ea3fcaf51532821e14d8314a6c4b40f26d278b031a74ba1be0544819d2fbe543d39a2988fd7090322d8c20456f71288487ad67f63ef7711a7ba3b17e639ef14284822539f9734d3f0f174e5694dca25ac38f9b5c77ea97d5ab0df7c5807a882e489ae1778fac7c368432ac30d4b7a49e5674b817b5b4f6d3a86a4bd14067d53c148fb550f83d535a49e469357be543798e71e5f0c767006f4103c557945b29bfbe05380bb00fe8e6c17ab31d1ec28848f1c29f85deed126b8f113b57b0802cdf4028d32e7b0db659c542269122ad68c2924bc70aa79887563f100a19bf07a6c88ade7a8ca14861bd0438f855865168b5bf65427eaa4f3b3afb33596e5cdc4f1089183af9733001514eba4e59219cfa48f48a077b7f6239ca72d2cd5119caf1b7d03046a0105ce10e25a5bad85c2a4f0d1cce9d0103288100f78731e9b087d0f1deae7f3ff6f6feaee30efa2bc624469ebfed48fc5fbd54d6df79a9ba4cec2f3b54be42529a1875b80c818f38c47b4f1ccec437ae6c4a867c72fecdb8040484a5b653d33276cdee06057c886e4b50c47711a4c8bbf9b0d1a6a3c06c722b2dd74d6e8251fdec251108e882c2f2ae3c63ed399a95d26b33b43ef4b554068b96ac2ac932811cd36f80022d1463423d115909d2d32724574b5f8d9b10a23393ee43b1328138d86147dd3505c2b4c68daecc377fc53f15e1367154b6788135f19110969f39d59040a5db94100be818106484c7e4cafe34291768dbe8081d888773d8f59fd7b6decbed838ff3eccc8abfb96b7ea2c8272318be54d42868d7244a2dea74c809a49ad3a74f21899ddba421f63a51022701d59ff352ed0447e09c21943552d30035272f792ac5f23a356df09d6185abf039d167f0aa86b08ba214ec18fea3c2f1d1980dbcd08978217d44204163a628cdc916991c52eb1dc8580e0ac077cab147a864ac50cbfa800d32ec283a09b9146457f468acaef1bdc85a633bf537b201b15e801646de12005a0196cfcf7dab979f7e402717d8c3b0fbdb761c3d0139f9db4eb921203f75878f2d9aced4979b3cb6458a4eba83b0a6388473c61c0b85211c46e9c21aa3ec9c3934c14b0fc31bba4c61481c34e3c9384893785d7495fe41367ce23459dbbb3ca1d3a45abeb4c0541b24c54681b16b4a4a0cd6276d37099246e721a5a781eaefd4598bd53724adf970cbea7fccf1e6b1f16941956f45b1db089150219092974368fc7c35f99ba2683d929033ad8087176502f8a5b7893f0966809992fd9ebe3432e40ce3eca77d9c8b9a84cd1b6259c1cac83b93f2b84a77a5fcc5f1635be8bce87d4c8fb14a1e2ccdc65830f278dbfb0edd6a3bbf6cb63b4fe0abac3e389d56c1b85f7247d07e1a1c17dda6f90967788f4fdc248ec18b68b8e0e47b78e18c97738cf9f6675b3fd170553757ada084877a4b29f1685112b276d5ddb61f1d2e1219883093be5c705b5a3254ea14d950791e9b3b331ac1c22ba8f3caa1235ad000c0f082a51134de1a4350576ca16fb0f2d0f94d195f653eaafc9a401333a9074b812912e86eeaed9da392f738d482ab709072ea338523f2e1218ae1911f6554f6d24e37af9aca12a9f945c6d8fbe56d76fdc7ccbb134140405bfefd847f1e7fc1d5f17f97f1f967e641429ba3ce1b8706e44bca958bc15b88c39043c6958570938d8e9e86f86023f4598cffbcfb9fffa95b906ce173088244489951f799b1db753cb74db0acd9f20b0919b605594a61897d60f677a44b31b0fee9a15180de549471a0b4d0281968c0c85957b62428c05d904feff7c824aaf1d3a4311e1308c7a98f9cba61faaeef8109e0fa099fd4bd5a2a8ab1aee280eb0553e20f8650fa55e093679829eb3a04b21a8e0b8146f11e4662a8c9e628f1089c604feb1731ba2febf9351dc1f5c83ad42d83e5c4c2718197206d054b9e3186daed843ace8c9288080c47b1fc7cc734d2d4475ead821f09e5e1800a6187a19cfc60413b9dde05ac0af627062994bdd9a65d04583f393b7dc50a16c0ce717e7ac28673683890b0001cdf2eb26f0d2309ba6caaad12c2118bc0a16395a8132ec27538244568ddc33a3edb2cdcf09e8fc5879068ceba13c8cd92dd6e26ad2d9b91e58a969da5669ebdefd419e97234b6b2ec136d2ce7f998f718a09e3675774a14a7f1eea82a15d83e3f1f620fd395f3bbb50a21e2306e92d7b161f7385e582491aef45d4a753d497b8de9ffc3db5f2c51af25e7a2e803a921a6a69899d5134c31b3f4f437fe5555de6187f73dcb3e15a7ab19b337c6c88f32538a209ea11449f04f22730aa77f54b1b6041a21207c36af5942549df4cd5fca9b95f5db9b29c8860326a4ed7ca6b21cdd722ebad556bebc5f8d30b8acd7737536f590ebc5b0fc971719fcfee84987be00e95d0cf129cfb6805c02dcb26e3a8ed714af8d4a494dad567a63a2481ef9eca55324b139ef69378e53a455467f5b996ee9015e5d337bb73ff09eaec1c4d7af281ad48864654d2daf716c4f2550f913284bbea85fff85c699769fb22689db5c6e0872b285bb982999a36ae86a1a7be6a0c43f7132cb43294f8592954e0bda2bd8840e178756aaa10adaad3b1b821e28cb3521fc278976ce6dfbe221c337a49ab90c74d9853f64a420b68a0f38163da7ba5b452ef94cd02da7df0045e5a2d240611d15fd243fd39334589b4b18174e6eb868afd1c142b4f2848d948277b9d279442e1685c9b32d3347d331788c67855bbd8339297f9146d4b8525e35df468951c06f7f0e418c8e8ff66fda4814a028224c7204aeaf4ced8ba4f822f43ec51df94335be30a54b1cc2ea7a0ecfb4451b451d2e413ee380f3bc94951bd2881b805e46ef24ad5948b225f1530e2b5af2a049eca5fdc1218a529584e6fcf269310018529e33635dd907e915ede8f734c2e45f8520fd2444ca3edf8e7e599436fbeb877e1649ce6c5f0c8829d0dc15c9e1a9f492b593a11420d8686c8c744ed37030f9c37b1e0b40450c8495a7648e51c17a6be8d35c506ac17b656ab7ec70fa2c275338f1c112f50ee054079a7b2feef0e82bfc240bb455a3cec71e74f123f9e6f7904ec1e902fa345a7d156ce6695b65c75c5ef4f6d0e5b0f9f524203e95f224654eea7550e4e60b2033690addced414e506a96693c381ec9ee2b6488daa12365b11c9a747e48490ce898973b0e0514e0ef0ec097e68f44248075f4d9e2a616d89cb0411ef56d1c1ee0f64b2d8b978e1a7e34000830748e1f73e35af35b3d3d5de54add16f2456074919bfbccbf5ef3e1c02da0b33389a0504aa25ee35193adffd14b8b9f680a7858b482b14e9517d939ddb28f909886d25eae30859969574ea38a6381c4e52b2ab502942efa3385f6a36b4239adfc07af3adae9edd872d54c9afefc8e6fb26d9c30ecc7e5c5b85e17a4bc8caeda847849c4c48813e9087b44bb43a8aa47807895d0363703a0e3a962b94b7ffaa6dcd8abfacb4d50ec31898f1f7f64e52ff83daf65f6a58ac4e65040ff9e48a3fc91c0af93ff54494bd20da77c7040f488b88ecb50ab348c28c16acf2ea2e663446e0f83d15f182850fa6668e049e9e0c0944eaa3d855cd80832e94ac02793c983bd755112400d2314d81f14131b1a53bae42d6dae2fd7ccf5efda52e21aef7e9fef33449f7ca093e694aa96749df0b433c17b5907cce43bf97d08506d30474e480c62a83e39ceecda8025cbe6b0d3db9e4d9f4a9f3d4acfd59214054ad8653fc662a8104881891360ebc8ba1c43821ef4d2ee92586dfd70a4eb903fb384b4538ef8a7f4b2556bcde18812c037985f3b390ee7c3bc647de0ddfc9c1cd66a3efcab7ce33213394b902ed40ae1570ce7cfa912d6e1a190a43471b6a709e8049747b5a892d05310ce4b865b12daf0e7bd18c86651afe02a274d79d7e80542f4760418b7575a1257dc84ccbea3d6c8f4ed598140942c5f8bcf98aaadf5a0378731cdb54001fddb0c8e6be454aca4e1351b2a1068f0c7c9da28bd90793a1fd177fb38fc35cdc80711826bd95bfc5dfccff097f43e8238fc433159e251f433e477024fd2f7bc58301feeb2c5d29cab03a785b20c6d32b170aac39348657ab6daa9b8a7cc77b0a0fe357067b0e1de054f3202b4bc1fe789aefeec96fbca20a9d643ba74019a76b8c29fd16b93dd5e99090890a9d4a09c77d61de11a9d163b91876208c2c5ce7312a0fbb056c371667f19a5d63b5b91b3a21331ad969284101538f210b1050446efbf9e07d454b533f6cf98057893dda8cea24316a0e258e46fed6de491d2b3eec42ef2cb205dc63707eb7a3abb0a2caecba1f6cb6caa1ff06717d0cc804c30630f6b9fe6284e9e0df240e666690483e5ed5b428b4d14d126668740a442a2cb5681593fd85c361b1f53775e1dafbee94cf83fe6756441379bcd3992a0cb48b81c6755be55f37670a6644319a4b4bcae67e98bd0499bf40ecd58eb21932a4115b201282201edd1a8a3c5c66ed3c39412e1d3da4887b86f8496d3deb222d6cd9fc3ef63ab08ab0e35bfa268219feea65a12d15087c4660187dff7bbd2cbcf3bf7e977c94fd4fd98c290cf3f03163d1c62cf1fd095ec10667d86e91e0f2caee9161cf6db31a78379b084e26586fd427be947b6fe1ea0074650d89a731facce73d9f04bc9455a53519184eb404406081f7af8ac0d950459f3a7cdf4156e801fed06fc23180aeaadbbcd9839e3356488e1436eebdced700495f76b49734c4b0a6c32fd9f1d6ec4d47ddfdacc2d45408d6bfb32c2132810e6680f267b4bbc08f765e5381043ac658114df3caf5ba81d41c2de7f11885fbf264d79e239ef986538864afbf237d27a7f561f4bcb5b22896b643e54dfc310caf384a504ca79e2457e21e77286b1cd5e0e9e8ea8c5f9c8e69260e9249bc4e2348a720d673dcbaeb26b44fba8c71d9bf038fbc58da4189132d4bb0e6136bfa85b7de3afe409f5eaeb74643de266461413c7d1a75357471859793be372cc497ab2702f19a125efedc12ac39770e76657e236c4b4ca07ca28dc4e30a363a9309cfb0df96ed19c5bba868dc18cb9c8c06a4eab1c82ed57a56270efe8e0ed5f0c82ef4074c0a73b358fdb87455b74a826b28a3b49dc88c333eea616b6ffbe0b5242a8437a1612b7abf99db8c097e67dd6a4a7b9c532242b641469637b902efde1ecf8f3c14b0ccb28ae8755c83c485dac346a9ef9021ce0afddd6bbfcded8c3d9d6892239436df7c99da8aad6ca89d051517cde44462700ecc770ca95a18cf5f2ba26413f5bd05a66db5fc76b62ce7adc598758fd1942e3d69c672bab7e954a1dddaddb6ef44cab582e0d85bcb7595f18327582b3c7f4485dfc277e8db544d6be832225f0c25118f6e8f64ecc949e309b3f0362e21a6fdba501e64f7a99bb615279c39f5728bed50f75d3ca6fb150fd81b7ad67552aacce2558280ec2233e7f4b03deea79e44ea1d84c9b8c161935683d75d0c8794ebff3cd310e89b87109968666217d2b34b1c65a9a368185001b657da5c1d629ee37b2eba9e3c3b3760ece2cfeda5b6d1c512c969ea96acfcb15e7db8944cd0119d1fb8d1ef19c1cbc57fd646723203e0195edc6362741c15ec279d8129c44a096d4d598bfbe16512e6b8836bd4b098c8e2459a2969876deb97f143fce0dd068fa63eec22f0b63daea1be1c32bf66ceac757e1f5ef2722b02e18efc0ddbcd5ba5816590c4f02f8053dbebf3e435554945efc55e459e6429e522512c39a909c55b46f7b0a59c5b22a15f816a930c4a8430d980115474176228f49e743a28f5065f70a0675e425a60f2af181394ae776b8a4fb3e0f00c075499294190a25da3893a99a51fc1ae16aebe82b7963f08eb9a562a14b90bd3af67ee071b34f2a13fb9aef2b8b30e4bef8bc4548f95f332728db9e9f02b51c7b8f41c521b7c841dc0328827bd759049c4e4323aca3a796cbc953decb36125bc1b4770a85439ca5aca69f1bb81e04eb4a9da95b8d09aebb90b8c1c3bd849f279cb282807431fb713270370bb4805e2d91bf0d30398b7022832ce3488cb721933cf24c766d0cf0a8d27b8311d82f34c0ad16f0cb6b55203ac7c1e67a762a981a037c80d15a7a5e8fc23897f190636b90b30d8af9ae9fa928f9a05a6e1c7791dbdf8ee7915ae11a3b94b03ed4663088e4ffbad11fd6f8e38b6daabc40248c4ee81f29ae71f8a70b18b376b017c186b25b3b38c408a75343aee3b93d85e26727eb505ccd0f235a6ca5f04ff167437cb7019a71f79045e556eb0e5c2decbc65546ca6d2e3b29e1e34873fde889d8571ce68925135f02252721c553cd160665eed3be1a6785da18451d02e9675a3f18dd99cd0ff19787f1d25ec1735fe60b608765cfd3c39666c6b847244c233bdcc9290b8d67a37f3a12cd2b3efe7e705981ffaca14848b2baf00776a998feefd7adfe730d0d24f12d90f05505712ca5f075c7e12d50d72f23f53f34f67fd5d72f4c73ff315dc12646ddbbf7178ef09f4e877a8bdc9888681e87a22b34868d51f1fb928be556a5fac5ea204301c9aab2aa2f0163c5759d6c67cc1e44892bf8323de329901ba47c7f05925be80e5ce8cd18499fb2b5cadea8ea9cfbae2606181908ef1e55b18748f62d449f6750635a6a6befb03fe9e6406926f223b0aace3fd49974be9a54bf8cda51119542c37cc8d2a3827e49bb8d0ae52c16aea07a983fb670c429866d1283a81eb7dbf8e144f004723a8900df8902a60f80a2550909b86f1b56b7d6a1d79d0591b4c1db384dfdd5989239ab411d3ae746be5c8688327c7993e1cdc32fea4fc8a881eeddd14bf801b137e41899588a91a298bafba9ad28e1ecc8faa2e1be02f5e5a4ab2c80a30d806649b20a5aac322bdb25facee9215092ad84294bde2d2b82816509b99a5ec81c50490c38c3b8a96fb8674b382db0a01fa7cee3268a162a46c2badc4e49aacfbde85e83e3fdf2691fd6185da2d93f076adf6b5b4ef990de65d0f2ae6360a33198ed14da947e2e0f06cb1439cef7858c8d204ddda9eb7dbdcfd6a5ddbe21c550db0cfaa5d20b86a68f847dc8924b9a67731438297a77a35d03eaf1319ef0539264053aa676a8073ee5753d510b594913a4d2347065b1aa2e860d2aad18e93f9714808b5edeae97b8de3372725065b12cede997d46585ca17ba1e470cada06a4e632ac6049304296280f5c994c20641dd59cb4a3e2d6efcbd71aed934da3e8757e832d342f27c550fa31b7c1587c5f74a533bd6b48865f1e4c7d5b5dbd01238f1ebef647a6adb6243ec31afd9e9a2f581a03b31b28b9ade16090ca996c50d7093f22f666d1596f23b0e1ca6d2bfd4f2d55d9d66f9c0234b84a56719657cffae302b081c3534958490faa2a3e82579ceca6da4a4be00e5b9f9cf6286550f0fe0015ddeff594e071bf44c8008b7de22f500887835f48c04216615abf7d5dd31cb0729d2e2f08bb0b82a2e371ef3a5aa2eee47eff2b6b94afd7966ba2cac4641ad6f9b78f96a22ff20984095bc2d29286ecdcf76eb864c31be2d4437e73cd46a35ad0859fed8cfbf02b89d820c83747fcd5f4252fcaf022744120897cb15198f6da9b406ab9fa197f77f5ccb88d0273b9b5a1e8851686d96f873dc37d2279ba65bfd63fe6806bec87e3037c3a8cefeb7f8a5f3f7e68ffe77fcd24962f54b63a577a2144a63d5fe876e817fff7acf96343cfcc76405a3028b173962661745c7a904575cb4e755805ea5d47e31b44561fea0a0a85ce1494fc9af0a183020805e7006a870ec5b29deef20caa5acb9d3f762d422adef7a90744a111ae0ed8fa6187c622e2eb16e4caf438f76c52c38323317ba218fb7765aca73c8966c3875ffcf03aa0fb546f62daaa4908a13344df8e472926937cebde01554cbd4ca3884f64fd51cad412d0149749554a91755f422919c9f546f087a18a30a68d9721fc2a9e9fe30662d27856ea32ef762fa06574937d5fc047bf30941e27a53cc5efa84fddf78b605b4b2688b60aa2b1c5e534418cd27e597efcd29b8b010e707a47ebbcbf8f1f71bac5726ee90bb0f36c0123b11c2345c951526b61159dba737effac1c20c3210c46f785c9603712f0316aa851cb60b0e5d5a426d316f68d506a643013f89d54c472518c0c88a5ba12895b94ed6010a1ed3cd13407f33306e58fbf4a8c57d319238a07d9bfc8c9088d2ec24a36ddd5318a376f14e6354b7d170f589c2167b6a576dcef7a3d316b95b83023842a4ecc7cfc56d2b85d3f06946eeb48ee3f47202a2bdbec83bab845ccc875620e84fbc0d7d27eb47801a4bd383f6b4794c512f30f23ecceb739a6e5784bd9412a808a139c1de4f0058b9f620b60acb6fab33c9bf17f527b7e8f35a0c3264263dea135582fe41952cd35c208d2c7e0409f66668a3c2a489c9027392723c35ed895701e56dcffe0f87d34dca85cb4ff3888910c850eef1a618e7fdfc8ee953ee194f0452f0a91a6528f749948fd1ec868e0abc2d80c2c4ae8e667f6446f69caa30c6f0fb2b00d1ed283bf912d8ac281e462d39146d3b5047dddd322ceb7235edf971f5dcb3c91f153ee44d4575bc0abe03fc55cdb8532ab39338f83d67f19d9665d0f68de8a3ae9728762df0b8a7546cd20b44d63af5fea397517a8e5cc50d8e617896bdff4ede98fd6b35dcff63de1831f7cca3ff732e20649b623287a275b9344aaf620ca52c56bf5234e1a4ff170e72fea93dd96678c2be80140e88c06f21d7b85aaadc1204b9eecc7dc3599afe704352bb5b1730f992a0489a905de6b739ca4b710bba1591824e8e66a31cbd69b8d1f0d38274f76da5faf5fd281af8c1db746fdd348066e445c364b98034059e1523eb58d8474661a2b0366778126edbbdb6298f855d2e6fe333e737af1dab744768d859e591e9472bc5fe7a1f17a06ed877c5427da22118aa9d99725bc0749fe043475eb508413dc738908c568da37e7725b82da58c63bdcf66ddaf783f328af3bd82d3ba0b32b8ea42a04786c3cf36d0ac35c71bb10c501c8ee9cbf8d745825136b2b7109c0e7b592ebad113ffe4d882df6982c510d5378d48a616b599d0725f5789943ec9e33a9114493ed60d8bee82e839a52c1be0aa810c5d053395db1b341a2275cd14d1824aa11162eaad6fe8829f799d11b0fd6052fc613e55972f541fcc5d0b920a5ea770c4b058e55c5dc2ea0ff2394178574b78b3d62af5470935413eacd7d52160e26cc38dc8780f13822f8153da2ab38b6f6ef9b81d6bad136309b63b0cccc19ab811280cba491d3a673ea97ab23b9654eb930e375dce4d34175e641690f036bda7696e4bc4a702010b7201391ef89aaac2cf7edd06f8b1958d1d0fd0f36b693ba9d05f23950de8ca4f844d99fd434df98891b41c1e9198311fef7e1b49e11badcd5cf1ab404af0fca8a04fa1c6a4aab1d9bc948f7d5db5fcb7f4ec8cc72e9006bc687a3a9968eef69e9ade520dee721056ee609be888072ce33c1e340e71968ec63462d6692669c5a79e03d4d14a89f52e5b741f0ee473c0adabc4b0d5f84a90371cdfc3c793d590e689a5550492477917eafe19084e887e6f58c0a67c3f4572a0124530a689e5be8b9941dedc8a6d49b56065c6afaecd2eb115ddef58790bb7ab352e449574dac3e7946aa3c41beb65990ff18bc28d577185cf930b711908b4729761dc1767e72ada1550c58786c888699f8a83e85ddf2c65bbf78f1df1335e3a644a5e80cc55b18d2c8bb260e3d5ca82aee6b9538f82c61bb085de921a26859eaa3e8cbaf9bbea984e3f522e141feca03a957e6deb79cedcc0e4c8e79c41a7b210643cfe2896f64b5c1472690c4c2fbafc841079ea39a5d285a38a082269e687ddf63381fcebb6bf64742529f401672545f9daddaabc94a13329d3d4f6093da12e1b5ef48e071ebed787b48607efd2fb0826e46d83250891c09cdc490621dbbcfd89ed665b29893afc15edd78803da22fe6bda3feff373dea6d630ad3fca88794334f96107aa62b10dcfbd79b27470d3b377e046c455e8ef9488ebd395224db9c3f498f51fd0c21e5a1ae24afb094955654e81cf3d2c9dbdd753d79d8655308745fa966984b8935c239b85a783588673c1285711e54f9b6c9c07983cfb67b66217edad421de32f0be06f7154f17faff3fe1f8e6a360512aaf9640ef9642ea5342069f8d79cae33fdf39f986d8a518472f43ffc8423800f5b8084001c33b4d4c27dc933a61d522788575e0c697d5cea51eda14ce5a6058039c9181d12a19e9340c0c7067d51841ecae0497222df02296166669beedeedfd2c6e1cfda6caca0db09a509a1d19dbbab1bd994d86ff20009f8d0f4b502ce4ba6b06f26e2ff9dfad963feb69cd93df16af0dacd3214474dcbe4076034d7466e5ebc32b687433f36ea32c286ef3785eb09b4900701c35609ac78a093b589ce3f59d55491597a12b3bb0e67c81905757a36cc36ca11ae8c62d97c19061b8b1d3f8ddb93257be90cb4e033e094cdda27eb1b57dd0db1a3d01528cd662343722a3f9d54352fab0b9289964b0a1edd07b48faa121bfe383ceaf891567aaaae6227260afc86a460270dfc088d1529f92985e77003af27624263aea033a05e1c759a9c6239fc08f504b5c28adcefee92f9a636fa8c439a496e0e427c05248609ac5b00e41bff0671d748d02426f9d22f4418efec6e96c6e05c4914b67b4686af24f66a951210328b882544622385479f32a61721609f9b553bc10cfb341dc000a16129f03b7835fad7a982926037b7def14b6a951ebeb0a3528fae1018afd4b45663fabdc96de186b7d72cd598b0186be7f774c8080d46b8dd7d3e92211db157dd5f70d5228054dfd10b46556e8e64839aa733f00cecaf9c9bc4ff543cda0efd2c282461ca0f65bef22f87283392fcdca466432654f6d7bea8b898376b383c36fdb4ee9225f70c9b071578e07645a355c8dde29deca951c913565661295caf6de5655379ec45ae74486ffe10777f5621fb2f607426994f0f734a3fddf701f8f3347cbf35f3eccbfbe07a8db9452f02f5c7544d6808a62108124d23b5f6c3288d14109abaf8ee47d8756b792723bb72f644c538f92c719483b9cd0ad5970788471c09d0a99ebdc72169edc7e7b375b9259fb4a911425604da721dbe05e0146043a3a82aedbfa95b2750b1f4d58b247d3717581253a5ce9efaad0ed626e76a3f2913366e9180e288669359b07c0e691963f9bbedab7108ab6aa6b53c74591dbe4a566dc0fe8a65324237f0df225c86846fee9e9a79456733765e448d40bc72c87d6700b23a45c64d2f982cc79aaa2ac09e0770dfe5093a90fca5204f87a36c52538ba7d54bf460a81329c69a104c751e20e21bd27e4acd128148497d6a5b33025d4f30bba33f86724707089c88d8a4b3e4a1314956bbe27a3e147dfd2550498ba23bd07bc33ccc97742e8a4cef012f22d4199a4f9ac2396278a121d3aeadf978be7eb25aab4e952321c076ac3a7b917430d6b10a1c55e2e672cae9e0bc1fb8eb43746abc11d4aa3e81f9ba6169057e1b1053c69394a78b29c3845ae230f47ec165b91cb42d27e0dbc069e1876cc96061eb7eb45d4228fc08a271cf47bdd38588b8568caa444199f28bc9c6da0ac4874f7079cc5297bfdf8db65e46ee790e08496b863e6b1d52224dad0d44921e8899328dc936d8a3f2a38055dbcb7c2ed4f11eebc85bce28c22025353d70e533696cfa9a81ef12bbc5015f5eda1e34e51afa9c89492b98dd618f902d83b4b38da3ca841c343fc423822e3b08083c3e16aaf10a4f70c9604ad20f2307cdc68c658336b0cbb97e9fea9e2f5b2fd4921ef433a9edd9b6ed612670c218a2ec63bb77265d40d993e4489d83ff776249d0779112a945cf02de902e6242987e29ec3a131647e18549ebecbd491cd0ebe76cb086f90d0ad5e1a40216b4d49e62e42843327a6e4af0b7d1c1e0be5e4392287a4931646dfa2d0a4f196c276dcfd53208f3c134b6c1e79369621ce288d1e5281e0e89c2796a7d32cc77136245a2c6cabcfee0c70f6dd434398f9aa9ddeaa902cc270f85ab4cf32765b14a84e6d0ede87a460113e546c5e283937b9bb854818ce7b57f77234f41a094741e5345e3767818e07ad6226cd41e3fe21b21f8c9649818d3d27e1fc756b84fcf936067baea17336f3722ec42253baa2ccd64d6fffd2b1eb2a271bdaecad4edcf263957ee39ce5b2ca6254e54209f088731bef83920f6776369a05e46b84dc19e515d215c3c1bd500aee45629dc4840b868b11ec6653979a1c317cce790be19da0d0493a50eff8c43617a8e9ab72e39de2d9fa6c1ca2121a66ca9741278c1adc0675739d1010d4ab9e907e6c2692b07345f0a1851d33b09663e40a42ae1dfe3db05677ce498d3109c42d531d0283f1ad3583b64daa0cb4a306f914de4ba9a989b7c4c2057ccb72c37a224d2cdd7895bf1bcaf37ef3b128aaf4b91099fd20b183f31d42aef07a7d4ec621f692f67bfd6999e801817050eefb9ba85987c6307ff31fedb020df9e549f96cf397ec311762c17127e3a0e446e84aa8a3a64c7e91272c274ac7cad115e381efd94f012665948f6770d3148ecf682eb6f9b512ffe27a2f5a5be151f94267b3caec9bb44709122731049135f596e900db5e3a0477eaa5e8fe4d051e91d83777c87174ee08b012131c05264044d5f602cfd82e19a2cfd84e7e7075fff5c823abb204b77dc8185a7bc9d0fbe08e224687a71edbbf11440ca2efa537e68157eebed43eb25fd144885c00b1346eb4c7fea9c1b2500b02639dde05c9c670a454d4fce213d512642ae35d7b799655ce6328edb4a5b5980f343e5aea7ee84fcaa4dbbc1a54f49d610354dbb3a23ad1b401b53dc8c2a00d1c06e5e0deafa7dd9de49e91fb45e1c453b630747a5733a4838a839605c2a3ce41c6fea9afddb315fd218e4013a31780a07fbe6c34cfad8b6382ca99f65930c63d88be4810d6f75103311b3f39404fb281cea71372aeec75711025fa0e07a8c571e851b91e07444197eca002b671c04f4062fd2af114050aaa52bfcc9cbcda1d1653edbfec39a8d8ab31067113fe9a632f428da451eddcc8cc4087af80a05182b2d2c5b7fd4d192a7e67faa86fd1e22b109d24e26f5fa855d63e6790830233c105c56cb99896b78f231800a6b963267152585f3d065ac78cd3d42e1e1e0e0c1654734c7fae73da28e0fb4eacec9f9a1fe20b91a3c6f50e7f3bc8966fcb91616851c1c75af7af9b041ae486740c19554b66811b537c3bcc80540412b0257246a152892f37e6fe3f0b5434dc92fbd255b00c9009c58002488a21f954b28fa1ea41a41def335733762e3226ddf320d787f0d00ab570efe50d41399463f7e189d3b50fa0d2c6afc4efdc4d837bd3788978dc0c95590636ea19cd181ac7a230057fb9c6fa3fb6b3f4e8702aca547ab7fea8be77e679b6377d714a9369ff1bcd243e1bb899b417b37c6cf70d0207e1fc21a0639ad2b98516ca596937100abcca50003d6382221543d3e83cb72516ab3bb93c539c043db90ed69c0c2db8b86ded3b5e728d65c94a293f04f8ce8c0861e4c0f44f5e3ac9ef277c5d962ce5995bd5f9c648362405bd94ad36e13d1613e41c3f9b76a4570ff2620ba0407403ffb00dfeba21916f44c20196e9e730328bb1a44a4789bd09f8e01b84a367f4f5bd533b024f11db5d7cdfda5db0b29a9f9a9c5de0ce3bbcedfd2edbdfaffbd6eef47c357207fb81d7d97d270e5bdf8a6b00925b13bfc47963e0d73ff3159d1a84008cf227dd84f6eade7b6de128ed45bd31145a110120d67ebecd4f343f8b4f140d374cad8d16edb0dc542f9755d4ffe6e066c9b4e2a91015e6b1d82550887f01e35018aa6bfac0229b00af29bbd7fe9c2d63f4b5ace3dc82f3d3974b5bab8713ab4129f39290e65f3c8e8e18d5f0279f522904212777a84de51b21caa1c7211152f822b366ba668ebc7e72be5d767ccd449a5fae324178b4fcc11de61a93dc82173e12023ce4dbcb8b233dc4982faf8c117e7b02aad76ca2da538c2f384f5295a83428e0dd5378f8cc7f1109046a7692c179b74e66a8c4184a8c1574e45c28ae829dd1ca1a523786e049b371b3b18d661aa0daddd7f80a7a3607dd2cf7b6a4f3e6252bb2b31f7c32ca85b56ac9624293e76b0e8f1372c4bcf87821be71fbcd3afb239ae7139f12d8d9802fe34ecbdb83dc233950b9fc9e01ff5ab6199e0f0f2937f3b95b7842a1199649843d3e1f6364daf260839e9ea151ac6dd29056d474cb79875bb45100e130674a502ddcb46b89bc406f1e4e0afcebaa2cb8e28ebe66e3b0f95406258a2098b98c770846886b026493788fcfe46ed1dc568ca30f2dec19adc8d1d8797f9975e2b963684e992c11566ba35fb6f2bd38ba9dc84228db13bab7a8a5bfbe8d12a77b0190cb872a1ccc384b507448f4c6d43a4f96b3e41b00b44b8db4020240c2d8cc0651afe34d3cac13b4048ac86e6212af6982003cc78ca78e8850b5335fd668e0b6fea03e69226b384ae27ab341067c89a8dbdce904f5ba65909bb1e0116ba1e2ef43d5f62073c84cdab1ed131aa3fa05c9aef2cbd01ae4283b993f346ca72a9dee7676de4d9453acfb24810e8bf92ef485f415fb5f0d23eb28419330caf13fbb17bfda0502c23374167be7db7ad3812f9b043e664b893b4a472a79f4313f399de3611c93f06b3833d01ffd1efb7b2eb09647f28a6e7147fef5df8dfe745ffcfbbf04fbee9c46553fcc777d52f25114abd7ff6ff9161180794efb80e0dd149342c41c41acee5680fe72151030883eb3cf3add68807f31e7b0003a20b57864629c2818b0f32318129c638f78957610cf84eeda4eba1ba522841957a6a81bf5f0100c5195704599df1767311e5719260589242ec528eb29fff3470d5b23b06f3afdbff39544fea1ec4029343a9852d8258b927fa3a7e5862da6d30f06a1118801ea6229a6268b7b4581b63dc6f6a8390e16171556c913338a4240b76809076818b6a958b45c96dc788a439da1b52c1dfb3158dedfab0bc6a3dc1c329d9678d4a02b1ac141b452dd4af5d37b9b37a9aabd1a92b47859326edb66af078795f6fc0c4d9676fc716557fb85a3c6c3afd25b5d79de203191e6d6172e09b3efe924aeda1f364385f4761215ded9c296dbfcd3d247f185073891358bbb2b6ebcf2465db1b35edda50cb308cf6b8de3661cf8b02f8dcfb7caa0d05da09f3d6f3f1797d67bb3d9a82be48d1b3878b557a29ea0d4e0a6e3cd09253f57e1ecf283ef4a5d570c53048eceb355f362eaf62c23b59c0ffa152a11a8d0c7303fdfbfd7af58c4a1d6e77e025cdc8ad579d189c83a4684a507f2b406b6dfe2454fde236211084bfc50af2fb866b85f5229526d80213dac2a2f2bc5c3883a2410b9027cb26673a6b4e5f0f2aa1b91fa2471ef00c700c49af4dbb1a3f775bda6628ea9a765086ad2bb95b66d808dbf0dc38357ddd879c2d59882078620a8b8cdd8751cdb151ec7154e104c09f7363a51876531b21dac10fbca9cd5e56eec90a3fe56d811500a7e38d7ce108e81a3c5398ace2217cebea57a49dcf51ecc8ee3e7628567d3ad9676342ce4cc53aedec55bae10e03f83efc598966076a536aa5550a2fe8cbb78f7b78e1b5a8c593d785a2fcb87de0ee471548580248318e6aad39ef5d0ad52fe78f0bdea9fc5ea0086fc913f217dd1be359cc1bdba24e68dbd260848c73eebcfc861701f8d7ac219aa19b75e618869bfea6f727fe1bbcbf7ff9fe7f7ebf93586d4a89fe8f5ebc2574ff4fa6297b83a2856a8c09c26cd8cf3859156f91f430b532b67f56cff68f4020b57eca50a4445b14e464ca527449e88d0fc4aa99c4121cb9518583b427f97d065222e94e1a2589e1314ad360add45d5464ccec84ef4b2e73bb6a16ac5d2d0f2fc4491f41066bd10b44bc0f6fa1b771a881e5cb741fb95065c2738430c91ac7f013f5f0d3e18669698bd0ec4c8a9b70f24c3245d2520e21014b28ed86e1b7db169010e836e64df3199c8e7351ce13f6234378ce52beba8662ce8656d38e323c38b29c722324540983cedd50fe897ad6d01bf6e01696f0a370803865a64c9341e5f140a3de42e7b4fe7ced00daf24b02e7592589e9a5f93067a589b99fe0d1da21911d7df5ce5bddcbe7e473ca7b9620c205b7fcf8ac197aa2f13223291fe740359fb2b6f7b5ef2f7d335c2ad2033585db6d3aaa7fe5c1684cb97463362e9fee3738464f72d9ab82d3608c954b10064f25952f3994ba63ce21124e739d02ed26e45b2f32de3ff238938d349daf94618950afa7aac98e31dcb16a97778b086b3de08600686a2599fa18a5bab157fdb13da4c79a6304c4ab573145f75c953bac6672180d1dd31fefc738c19739cc308ebcce005077f606b51b3b32cae4df099b1da30884baf341b60321ae1606da9c99f5207c0d7c78d8051ef9ed205434cee11985929a2a9f1f0dd34ba9cfa299cd9984f8f69486a49f8c287cbbdbb518051a324f5a46b0b0b1448280e2f841429d247f908bae0c030238cdddd029e7f11c8aa6c3228173d2c15e0931e86f68bdb3bb418031a6e0ede3a5269d0af39b03f5142800b032f91efad78f10a2cf1c2fc11d05180d83dd674cbf5157c42cb85a9a0d33938c130b45c606784eda08495a0678ac87114f2aba9d6c765942983b45151921ffcc8c3ceb102c791b6c2eabcd267e914a758b995f8e7e64aeacd4f915ecdbed27273f432d55a2f39b1240031a5448209aacfbd04e375e2816ff30fc4fe4c64b289678308c1dee6c4cfa0737d9b9a1a9cc3f18a4fe9b18c4fd777093ffbf9ab735fc61db10c438d5cfc2bcdf299902d254a6f1738485588d280c9bc0a9034e43fa85b5623e3f3913d5d0e3d8fc9f68538c4dd4a3ca7c0023c3c14340c9da8ab8161e0b4d41d997a3bf1f7e544387534c3c6a6493f0f7b9b1cb26ace1246bc58a1a08e5feb677518f497208b949f16dff548fdd81704b5b007ce7529fef10f1f7c13222a7d7515f45364b34c62e01c614bf3167322b09802c4e4181445094860a541769ea2581069319b6f872efa107d36ad0fd8e19e92095e65cd3767a7a7fbc892c5bdd5c2e760105063a5af20a7083be215849cbecf1e0c921e7446dee1cb87338596e3703e40c9cb95b932b841007c1022a12a34e18c739d6a613704c7894a5bb6bc9e815c43492dc6dc026c22f7c8cdc502fbafa01140c6e2749b0f574745476cb51b6ae5bb362bed8d0685a29da57194267731a08a02fc9110db5a36a264917b7b505674f3617ed62ebb06a895ca38d3bb3c20421d47bd52a85c9948777c49500379d98054bdb916ca42477ee7601d317873491b724e5f056de8edf4f67c1088871caa644ee561fb911524210524ccbe7d8cdffb1f3459bd5d81b188161b4e0eff5c908c2bfc1aff9278f1efee999beffc4ca44e8ffc1ca81cbd001bc229b742eacb361adb379fae66cd5c9cab0533c6a9b08a65a6795adbd9737e8c77699e4ac3f0b58eb951a0adeaaa936c581a9e04ff95008ed3c4a0d4d943f24b73e75c42184262792e246c1341d6c7128cc1ad572e3e2a58c3ce4513f74ce5b39cdd9253fac23e350645637529e7fb686738292fa1c812a548586abce50e99c41b34f3547ed0ded492d5b441dad7cb42633d56dd6ec762743187209d5468f06283154f9cdfd4f2042f58a39dadb1adbe3509c27ce964f3c4e87e0770a35ccae79765614134853e89935a912b210cb720b56672b4e7624f466f8e2c8e264faaa143ea6dcfcbdc17e72cb2539e3ffa2cc98b6b691e0f812774f2f3032e636f45878d1e2c470fdd55873efd9d75059ec57d22d848572368daa287365850281796e02a47eb5a28d31cad06ad9cf721a48aab11d335461c7e5a0b3025b2bedd232c8ed0073e5af86393cef1cb96d972034169f313e890b7b8504b74f53394522dc84ed676d00bb89265197036aa0958b8085ec9d6d1ae4530c1528141d9aa717bd0af6dc37704ceb97f859d1cab63e96ad73c319298e4df51dc68d2618667977a14ddb5c5660ab12c95f755920bd07dcb8a588b7cee1afbc9a4e3c271b225038c7975391be10298cb1447ade9c4a9caffcb5d58633ff589c267d7b556546e43be18132b7933896cdd7fa1387760d9265af4c6efa9ad50a739aa41af16936c5fac84f0658d7da9a5c2c6349b8514a0c5820b035239f494e863092c84e46871f6735f23d15986c0abd75494131023a736069afc67f185710a9fe61ca50f854e7eb62046f6aff6d927a021f57aa9f1028543315ae850a871e547d105599d35e173052168d5406d9f113088fb213d384fcaffc7eb4b09d5ffe81b45222fe7fe7c5fe97bbfd7fc94384026c0b9090546346a451986a26d54603cb66dc80b0c91b0b8deeaddab0dc9a27b912cd8fb9ab1f9b6d924d0a72f84bfd7226d671764eba8f9cb1efcab95d6952664c3b8324e91f457d9ffd59c485d234c0881d7fd69345998a9dcdf8dc8e4b69d5f0a3aaf167b8bcb9d46fb19e05e1e6a02b586b4d721b1ed65ec3b3293ae2f2b64273706a8b846489e25a8eacd6af0405e6a3b28fbdaaeb77a2d4bce292ca24b96a99ab161b00be4a4582c85e2821d0a3f27a6a3b5947b0b4c2ddbd81f8ecd3bcd240d3cf6256e94009e4fec3d5e6b29eb8c98b89192a12cd18172e11078b63fca299d950bb10d1ece8c5a797cd442bcd04b46fe17434b8a02d069d99bcd75cd367201b2238a2f6b7bf706a29bf1b22aa42d9db810b42af89883edefb0dd01043b1c968ab655e0d8d0bde0a687b1db4b4691c798d64be056ab417f8f2585a6b9e69c02678944bfed5d6e40101eb3ce2d0828b1e522f57bb34c3a8ee65a410137f777517ee476243504c9d21a38b2a46c61f9d4fa69b4977b2e4c1abae4472de3fd76e35bc2476f867eba12ee86d3fd48432dd0327a9cd2b55321048567a599ed2161d7cd89ced71eea202a76316367cf47ea94cbdf1cddf881775be694f5f981b24972a974b5c9e938d5bb3dc988d3e0992a772c1a287a2065126c787b1a68df19cf51cd57ad194aac89495193de1e0160ab57e66f7be9fa19ffc4d0bdc987d1512558e3f9325f0f1ed28f4c38d35ddb4e5a550acb453ae8300626d10f230412f56e705da25cef34a18a8608b9fde92b10bfa0d89e790d6bc44f80557958a002ec1cbe1a714a2026d6ca6823da14e1ad39edda824c08d34e33fdc431315658ba3d0f1c65271cedcdcb8c7a631a46b5f7ad3859d76bc1bceeda3edb3041df32f6e6b12fef48ba93fdc5665ffd61c5d96f93770dbff5efb2222ff8b48df613df183d0c29a42bfaf93ec9d80a682fa2ed98441f45851e14431cfc220cab9dcd26c61f011eb193197a43c890feafdc7303f6e92657e6120247593711b3e32dec1e9b332a09a36e0a6181d657b052a31e937361a957312d4a3a2587aa70bc092020ce58632257db81233c384dd6853dd971e89c44d84b5c238f1cae25c8f1ade0c2149e43881ce34ab491527214abeedc25d70bc0beb03998b6250f0bc24b7b736a9cc4c032256c464bbfceb35d0dc5342e509740f01bfa81f948f1a65b9026244d2e9246e03987e97c5f68b9f2ab71b1b12e0eda301026d58760075c9dd09f0f5b5b2ea368eef805cf3eb8c1c63baa70d2ca242a4264ad12691b41b2f08417c9b3a8f81285dd025bacbdc8caa9a5ff4c3a2ead8a06a554515aca61779edd1039e7359530dcd7a168bc35d8a7e14ae68b73b4938b4fa28fe753f79f6b718e65d8b3362d4eba792ef9de2a53bc93e65733f8e11c379e7624771e727192b91ea5deff25822f95775ed985ecc5920e98b0bd8d63cb40308ba8eaaf78fcf2a2788768a5c1331e68b5a1fa0036635278a2c29f3c5d81ff97c70900bd0111c3993625e97b40d5275800fec2194baaa1e8509c08733011feda81086ba2f1e8a904ce825b9dfd41ce68a5717d4fa2523dd6551746f03464c44751be7736f97b9f14cb44696e3c8ab7859ffc0bc1d598a164ffed51bcefccd8cd2ff6006ddffad2e8ae19921f85522f8bf74a0fffece506118417f30300f2c4399886da36880628a795872f5f5d33157e1b859755c0de249ac4416eb454e0c415ef4262ef0ffc7de7f353b8a2c6bc0f07fe95bcd3e780926e2bd00844720bcf9e28b1338e18df0f0c6f9ef6f20adee6937b37bbb73757644afbd58035559994f3e99595550aba60b53ae0127f28e526e86e17864b98076e7d478506cf219e46d7947fc6adf8705b911c04d8d110c7f7871caf3516e284ca21aa86e2b96ce637e5d3bab50433ba43b76de98cae3566e1d066d4e9cb36a3439342e8d46f368eb0762c455388aab7b8fa6fd8c3c85e64e557c76a7533d246b969140a78bcc68837225b846226ab0ce66827b0f6a122e0c7438b672f39c7cfd813d6915b880837742c088bfb81a23809497a94ee8d666c63e3a7f5e1dd4c34c3ff7f99c592e5450660587c6bc956afe288d5ae143a9c7874bb277b9a428810b9ee127d3c98155e4599e39407387f04e061bf059959d112548a91b65e332d398e2b030c2ab4d87ead835a6555df98b6bb9dd5d0f6d298c3d099c43140a9a1b4e60f085f797d9ad31bf453ab705ea088d326852f215b1228d6f68b12b0684ab44c54ef15a008841c818841e0641839980ea274104793612db33a254027abb325223517a0d15ab8b3146b7b66573c5275b848be60e02eb1d9b149341a1d0326312432ea35a5888bce2815462e6d5a50ae919d08fe7105a2332e5c6d3b66b05259e8f8dbbd0c2438bf02c4c4465bf24608f168fae825cc2daf4a24c873b5eb70ffd7942abe0823cf7f96984db2e738c245d2f618fb18e6faf9c63782a0c3ad62d3ccbfcc65df2ecca6d79a29d79545fca1eefa8f43e0a653fb731c3c78ac2130ad31077d5b7b40729690b393f3dba7c9eba92661f165e33c92302f7d4c8866db36da3d8929c504d15d1fc95707b0ce726c1d8552a46eb966d20a5a04f66c437320eaacc03696820b7260aaf60b795d4649e1bf519f6946be9faf5513a65d8e0e40d2f61a9346998a36165a4f72c1a86729e84c7e482571d016783ab740a8448e74247026dfb69e0bb17cd5f885a0f1dd3bdc2067406261e504e2db05bebda4824a7213b0f3ca05cf04299235848deeee81e80cdfb5b38f7bbdaebeb2290a462f1ffe96f4e7ce6953fe68f5bf9c19a76fd2080cd31a75dd524c12f0481491921e7cbd6c85b43a3aea4006ba900d1242a47e2f5212e9c56efe5469ef8730ae69dd6eb0e0d0d4f58e9ed80f51da6269f8e93cf53dc2717c4c162c44aba4b7db17b17462f636f670ff8a12271b219e4ed749ffce884630830e20840e0d882cd7c33638240cbbe74e26486656f8aae07ae16f63e54fb7eb26eda6a8529ea2331543f65d9be9ca781467c88f338d80fcfe414094216c11ad5466988aaeb1614208772ea36592387ef4ece51c3709d737a09691a994221671fad70dbb76d7b366d7177892a8dd9484618f854b4a47ed66a3f7d8616e47715edb33a19bbb2393a0be687f5796eacdbedb29c5035e49035dce5b00dd9347d2e6ed13f9a9ecc86eb12c1d489e94e3551c6b76a5088f049abb9521b2ca98d91e6f6b251dbad8d3752d8e2b1aadcee30e2500f6c290319811773e2bad6bc916e6d0082dcd59835d12d7d097cbe5df9d40b76ce331807b14ff448e9397f633207aa612ada60b82b846ec80b66f6985e0eae1eebae6b86dad4b5f338e56ea3833f5541d729bc9c3e61ee71b674fc59210921fade5a67a8b953ab58101b32e48809eafa7803a7a7384d2cc73cf55e358986ea466c59d5ddb86988f934018f594b3b3de74290e235ba0871b9d357a2b306e39cd4c9e44bd733fc780699c48537a6d2215e020dddcc88787ed096b2e741121b8f426b2bd502ae59bcf73a29c6bea75d6a4b4b6c49a4f584c879b35a822ebb32843c7469e27a52904fe0c617fdcd2b7cb6a61be95cd932857602d442ca8e6549188e4d584d1a89b9a513c225d4a27593c6d5760acab3bbcecfb35a6e24c6a0f312bb9ec471f098d64ec6b557cfb9b9b5eff2bab772e8bedcaa937782f2c86b36d0e62a3c2d61dd0e86d8394b055dc59bcc54f9938b5a9b3fc7457fc27aaf722fa5140864e77490ea506953fbf099cc6aab492fbe6e526da0c3b65dae8db86a1d6e443728ed154360469e3963d5708d7c203b9b2773cbc46bbdc516073404eb2caa4e9150f09c59d87e8a93ae48dd543d45dfd2b9692f6b80de06c8a509af621bdf6489764ce32b96890f895abb735dafd00e7929624bf002d31dd86e7da4dfe24db99e924ae9e6137653e867eb59ad7a6d4fead89336af7664e1e59a25625ef4542165dea1b0695386b8fae02a6dcfa77a8d33a1209f9e0365a48f47a548255af6c42c52763648b8a5e1686a725048a032b72d8392a78ca4adad9eb75336deccd2cc4bed2e81e266e8ade74c105d6c743f2bcbf5be873d2c8889f8d4310f05b22b4aa4b9ee02410a22f4b9dd1599839b845b7710bc8783344a8d3d3188f1107957bd538ea198b7ab2b67d75674dc1e2a91f0040ed8c38ed5097384583d17645665a31bddcd7e5a5d64507081901deec26d65fbf4714c6dc5277839e7e879421bc21e9b4812733ea973b7e0749c6db3b39c974010e9f5ce9b2978a1d8247a1a4bece2ea352d385842a19bd7a18f742e2b2e9efc506264f714897e19136ee974f42c20f175a35d6dc36582aac3aa49f6aecb7275b6adee24012b663f00b74b2f685c9c1a54ccce0dc891693c90a2fd3465dc54f7d352d2696dc1bd1b6632644e3d5bb9731fe4f64d4168a514e307ab863cd3b29cc1e31c6449ea75860086b06d0ddf53415fd6489077fba2b8db83b92206d85ac4bd39859c2b675c1844f22d6f7069799653ac5a72dbb39175e20d20d55d3b05cf0c09e3cd36520c9a06dd537424a048991b388cc24df1d10e151d6ba4f958de8669c057de09980c1a069cebbb6cef12cb6fae8043091300d52bab5d12abe09f40aa5f1f46987a98d011ce037aceea398aced1c4ead8e366f2c1a96fa245a1b2e735ae4f2373f714de4aacdb13316969c06d59079e893a974c8c0f179351eaf38acffb10d351529cee53a9651b38786bf888ab3ce40cada276316f5886ca9fed2c9b8aa99f21a5f5d27cc12378d5220a6b07b8f3ce73698c8cdd835e22ab2a58808cfb08c8449667fb042a433c6d6a14f5b7aa1625549f797c34272ce2c0340aeaa031b9d49626500dfa6b1fa050535fecc2c65da5e86f3a835bbda5f6cc24137b0fb06a53f4258b1a578aaf7bed72ba3f365e7a1288126e0fb0d7636e1715a506837ba60daa842c4f60417af642a60bb0a867b712103fae4d5f6ccfbaaf3c881060181150d5d62c6851caa207bade1400738d48111afe715200884dc1d877ce400c680620de80cbfde6191b0ceca4dedfc647399f6d8e0fd7f3d33cf5f8ed3213fa63d722ececb62323e866782d710a353d532b0de40a059e8f74ccd26fe249d6b0288a4cf99ef3e6da50b00ba6e8d62a4e30b1f2b65d3af6694ebabe9b9cc1cb95cc40205987cfc2aadd5bd2dd36d5e726415faaca76d6eb6461eab0b94dd1c4f0229caa3c578c87d7540a75e2fa4a979809dbb2d64668622337246b3647dc2e2bdde627e9a447ae118a3ed51bbd7119abb3dd1120869ec029b19e527d66a5929cc228b87bdb2d3bfbd278836adddf11439c6fb4144f992953b1e9f9ce9ef1761d5f00479a2dc3adbd3e5e935bd9917a7bcb876a18b6cbd99b6de779b68cbe9cd8a017e3915baba487314a4eb01561d144229dee3c6eb8fd84a3aae2fb6488fdbad8a00dabd8fbc8a6429976433460f7284eeea995c0c676a9ba35796a55dd268b2d14b5684c77748947fa92153628b3abd5319845d8a7cc782ee7ade17dc0bc6466ea600145dfb6114fc0b53f3d8b2bc5c5ce90496573f60a1bd6c5ce28b093d8100cc20053c19180c3aa953e63867ae9ae7e98b27848fb33c64754533f28910e27b553af6395ba6e7b71dc67726663a2be8d499d34fcb3832f067159301120a4faee91f5ee1b31f47c9e8d1b7e4f593f365bde246a8b4aaaac957c107896596af80fbf392bfbb0c37176be0e654f4154474ff67eefad73935f8dcdcc2d2c04baaa23b2441a1b07bb8484312827a882cb1bd6965952ae660c432635d1460ce58643010f43f69f8d6c5dfc73219a35d45c24b9da1e116d29489201b59e27bed8efb20942cf42cacb05a0efa7a9a8cbfc1ab6796682de9ee3c292bb9742c085f8d69e61e429c0367bbd86d298ae1b0a4acfa438637a49d9640fe62b70972a8698ead5b0a1f1ee2848b53c47bcb4ce2ec307fdb95d49814a3b74664d96d9b64da2d834ce6e0166725e8e04a612e45c62ed81ca3781802105668eb7aa0b779742d59947d07601481c8a1afd4a9abd06470b573c7249c8fd294ee4d58b54b733b20bc4c680c9aa8b38fa9dfc90da42ce76d63e7368cecf50ea91fe505c3c893095c1e8921218983878ec274766b26d7182b9ebee8faaa05006ba38d162eaa8a6707eab77a0ae4cc3d5336f1a51da788d6fbaab2be669d3ac7ada6fb30a85f59c436252a9cb256f5ce25ab6d1068445882e351b7099cb0dbd6db3921143272dec8809876a14d6eae0c96e71b051b37f0aef90a9de876658806583eeaa778120e5411314b88627af0b7a808d864e0ba37ef6f37a328b4267864b131a78a891e70de2f0f5a1dcd12ab55ce014d920dfab63e4e3843edcca6b4c0189cc123b5772de8047ed6ade2165b3ef2765c3220a534f1436e5bc008caca9644dee17c20c9ee58eec1ba7b8a7f059434ffb82f68ab37691ea21f785eed22d4f28b2a29de0be8692e0647148ce5aab3a41b653be1db4d3b9790ad625300dcdd74d97737781be040551e1b3a463507ead2f4352d16183756430610af134fa491aa6613c79b6ce853e4e046611d54fb45c302b3ac35c84f765128698a307c484980e692cdea2ca8d8e1471459b16af3f9edd209efb763e5bde232c2932403ca3af1ed7a139cac37b8fc226ed28e9a968c30614a325591a991224345cc528cc7aae9e42fd46f51c1cc59e06554a60f627fc3c80bed6cfa9fdc87b5eb5937521e9c74388fbed06dc5a4a794469b89688924f89b33618562b2a723d5dd57bb9945d9ce837941e492273b08776a60092a423a14c6e69febc93677cf21454e5b03dcf2ad2a86009ea952752c69475e19376462c53564442456429dc65bbade23e1aa1695cd6a9945c9c66ee469a1236665c407ebac917e5eece1bc35682adda16d03c630dc82676eeb427a761a1073bf123afe47094862d856a40aef19ac1217f07089a3ab574fee0714a0ec6d5c11ed2996ae8f40a54898daf2edc3271d03cd19b934c1346183ce94e64ffd8fc26b145b0d6d6352c736d08c2717f56a984e4f3959aa3c7e3728b0ca76150d8a6c39e222a17cef576a63c15b0839678e2cdd2c3bc34743c4e87bef18c872704aa6d260115ccd3614a81173ac91d35bde650abd1a3d35a0831b68206f70ccb8729dfc429c5af179e9a179203980db8e6b43c2f06196eac703f9361b3491cee88a56aace95631babcb765d0783215e73961ee44b32861274113db38e8ea77eb191912e76cbae3325d4f8c0a470822221cf2208910339b480255d45cb0ac5e770e78082adfd145c25e9305bc6f827bdf987dc91fb8373d972db19c726c70574a19c2459df8765a9a4d9ed1e081df9966f3673479a00ed045e2635e622065b74d66acb9bbc0d3b934a1fb720552bb59b1660f5aac702f1d313d9b4404124013d5536656a05ae8c26329b0dd3cc7c20dc2ce1214ce73c7fbb32a9a67075526eb2205770b2055d5dcd16e2d02870f4f03e44c002a0263ccd6d7276453c1d956e7b080ce8e38b5380d3dd50189128364269984fc29c9385e472b34cd65b8cbdc95bb2c21eb3344bea26d7e4db7e21e59eb0c5e6e0987ac427bafab2603f65a40f6c45941b6a079405a9e5df6b8b5c10922e865254f022ca02780316de7e678cd9a54fabdba83fe89325560c4db8b0fd25be85cf43a7db07bb8dbedb4258f4247ef2e4f46ee1cf764c8335891c7866d2019a49c0c7eb5180d10c7aa2f6db6373a5902a6fb3db191c24f168ab3121162310d7bb067b74ca6677fbe26380dd1feba260a549642e3fbbc1914625cef38b2aa6d58de5567be55d77ebd3492a38ca40f72ea7380afd449c799ba852188676fb92a76c6cc094f4b1abda0dc39091919fcc96d27bba8120df1b7d11e334f5910417c98fd50c815d4e458c1a336a83e9fb829cce70a52e9c6d917cc6ff1c85160b684057286576d3ec999b95e80c4ef19e0ba1192bfd95252383116161b0fb979e287e7bbff58e87162d9bb90bb865c3f5852411bf706f8780d140e13ad1ab032f6855a77f3a48aa8ad2c67b9c800d994973adad36951c7ed1eba17dc0ba3cc50b62b71b6aabd41b806adc30b59da0f7944155ea684c1bde88c73b6a4ba81c6a4323b7f654d689bd5cd1143ed32d69b71c64aa3e85a4cbb26e573f296e7bc768abedb810aa927fbe9443dece973bded8253fba3c396d39570350b03eb422ad6e024b4d6b0667b20c5131ba8a6fd3c9b5828d14365fb6e29615680b8ab6c4ad539859ecfa1eba731a89ac0c2f76e4b46b3b9135ddf84dc063e7bca05f87873f96e90d6dc2f224455c3fb292f4171cc3730e7211953d08e939e8f407754239cd3701ca0961e5cdbe6663184ce797579a41b585c00453635a366e12ce89416cb2523f152d04353e814192d8d6662e79a845674a6ee181d1a2fc63248d8580fa00e3d4bc869edaa6c4312bf86ecd433222536962d8d31738d819c205b5733a675117b59401584c6cb13ffe0184be4ac935bf90a3160cf3e4a2f6aec98771b72c21b52c1e922f1b779f608f22c374419e6920f3bf18d3aeb670b97b80d90225ea4c40752ac79e24cb04963cbe58a9cd0823c8590af80d215543add4f25f699c748aa5381ebba67c5a808acb6e1fd5a8ccf79ab648dc5415f05cc0b492c7c81952a7fe1fb292d888a9f079cbf08cb09be131c545cb818dd30bccc8c6d6e32043222c489115ba537f0da6a435441a5efdc9c24b8f9958f346537576c3689f9062dfeaedc4ec885d885d409abf31019aedcbb62c875a12f5ca6d339371c98509eaab91a1b2a945531977ba10d157ab1ac6c9e9fb2e2cd493f23a1647b4b567494d663d4b9714e6776bb860672335709ba02cfd22c9f67036f4e0a6c8a5acccb00472c11f6e8401b2faebcbeae7e215f0479ea83bde1906553089ec22b60e7d402614edb9d0b1bfe14a1eb7d01aeefef2229717101644123491a94c85f3a8715fc07d68fdf6b5ece77e7267d592f869ce0751eab7dead750de843b55144c4b5b7ebac892268781e6511332b6eaf5a927d2d3064db03634aaa9859ee28ad253f7d142c20b37b932af3fce5a74126f84d98a46b35da293090c8fba0630ce691e091c9506e1a1b4a93f143ec208624766352274207e34c0a50a175245055ca748f32c9b930bb5e3d91f59413e35b29ef34425816e8e06f13e990a4137b19c35fecd193bc3204a118769c66205efaeb00fbbba63804dcb05b4034f498f340d762c971fc96705fab6bfee9eac06d84d7a4e9b770a4d0be9568bbb5e7bb1eccfccc55752cd3937092f56713ca528279ef01b2c6ce707427bc44573c24029596a459eb676f7637f0914319e4fe23ebb62e9f2fef0884cb5f21f6dd1a230b46ea1c2cc06784221e334a141d66ef4d9db6599842ce7b6a07a0e3f0a6cbede4395b676f4a2ad849242278ac91eadc9f401a8e9ba9070669ce60cb3837be92c76408d6c828a73a80b97e7bdd56f11472b5b2f785b4dabd83cd0226bc57be34c883690bc4ef39e84c8ca5371e4f0d43e6f77f4890697384cd14091e35cd6498d202758599ca6d56d29857d7d5f2f02ab662aa1b8ab9aa8d355b6f2ec8e4aa7bc4bceae067517ee21508e2fb7d23d6fad2049572602ae5ba5eca4bf381cb52051b1e4a9da1a77896e466d016fa8945d152e18f3501a642b7aae94a71aedc651856b858cb6bb90dff6ddeae36c70d30b45f76f2818ac33b930103894a8c3332d582ad205bdd18ecf8f8f85665041a74208ecb5bc4a5a4cc22741b0ce6e85a32191d5febdf60b70e8db93d9c4cae446ceb260f91616087fe2a968c9733bb5cba2c7f356b731aac3fbf9ce0dd955cba79ee322e05a86732f9fd65c4ebd5ac3c387a5ee5674053b09b7a45ba23ccc06de3d6aebc1daedb104cb0232d8c7e856441b7dea30438290689b74bf2afc8b8953f94977d0a932109ea3abd284da7ab21a9438175c7e16d02c8fc0f3b5b823ecb65c6827f68a3a08ae3a4ec877d63ed9d326e3fca9d7ade674d34bd518032ce637d83b0544a6fb0aaf178c4369743b896b04dd85128fac09a6a19aba67405484317a19d235d70502cc14395c2f8f8e5fe5ed2994b1ddc13685705001dda3cb0d0cc7b672d2ba7e9e9bd27f68f20d24bba124fb64bce419701eccbbb07375b8f4374a4480627aa65db9225db25c1e2befb5abb75a11e2ebf6843bcd192fb856e71b83e32ab2709c2757931ee49dcc7dee6cbf874f098019276aa01134554f89dc932a60edf2b9daed684d9fa14d5c2453ef65bdbf04f975262c2d2de73d65606f7f8077b2466ac9f4c5c885d5994f631c008b819ee076db9d714b7acc68a368f6978d1dd61260c6a2f6da0b72a11b68252787c1f180c5f25bc8e35678ba3578069c10d7621629263998895d40558300b85c0131b93543c88e898e581e51435682013a0e3b05b503b44cf31715836422d060a0bab70258b5e94cafa36437aa5474289c3ed6260caf00782767e2be249725e540125631b111d142756aebe2a15b385415a264fb58c1f45a62ad84cf60a4cb232ebb8c831a1be90f174c7ef6aab317cde91c9dc39335d552a3f0f2d087a14196020eaa2e7e4af43b2272a7223a31f558417c71bb5f54653df13618ad4513c53a129f602c2bf02b68fb7b3ba13641ce0099064da8decc985a7cfaa90f68940e57325514fbc210d0a4fb3c35082270621c7a896802a16d54f2aa7de6a9e08213a7db2944ae84b0ba3ac503975cdf6eb7c14490dc1fd60be2a526e265c1bd5df30c46d7b561810a9aee5ec4149978c69532cdf834c05206e2520944775c62eb64311a4e6d9fd7d3b553c1d380dd0a4ebeedfb7ab5bbe7c8cb23b6a7c6d0025b75d9b510bb07f9259ab3fb49421961d90cfa1c4eb20e7b8ec6f3a18cfac07a1212c9409b68b4f04e972e8f49885ae10e54cf7e6daa3b00448ac95c4e4db889d28986d4ccf31f51faa06c5ec8d9e7c960c78aa014c549a685ddefa373eaaee7d5ba81834a6f23eb01809f3e872b112f930f042a43553c6df4195e249e23e0cbc85d39f5ba478236142e3be7d536464d7dde26bb735931529abbabb775dbee19450c13ee6df13e30cba4ed7664cc53c38af190ac6797d9171b95a3714a70aee9ceae7e951d6c91503bb7e667baa92526ae547037ef36cd8291cf34153bcde8e03e2bfd645e2a200b6eda7c81c0530357fb13b463fd1c1a9d64543b46aabc310abd7f4fc7e479e59d67c09cb2f4f4441b22bfa82a9629746c13b51113b697117729b7973a4d61b2aa194a8178795634e7fe40ec04a21ddaa6cee5296d46422329deef2440bf87e1741fb387f7c83a6322cad24622e30e605850d9d2259fe2d5982db1686c7a7b2ed7cd71aa2ab2724c47d2d315c6dd93db908b55f61e490de976814e2d649fef6ea4b82b1beebdfee0966a1f15bef6acfb02a5c0f30605ee64a8c3ec760cdc9f467e91164b3b5ded138a9443a236cfe7a454ceb3a72f060d60ba4d3cf72cb463d29941b73e8bd2593c55e7a772313ba70b9e221be20132c4a26408ec0368f93506f477ee96d37ca3a9034792d499f9b5dcedfc2fe76ed6c77edf3fcebb34bfbcef8af993644d145939a78ecc68e7a2f5f9ec14ace53299a4e925d606093507463896130cc3ce6a02b9790e4faa7415f38e6266d7e761071f2e1398799eeb223e7c19d7cba57f9d25879d4eb726a59c4102c8b55782311fbc706635db69c107cd2a97f0c1721a94055b4c432cb13ef359e4663b2cfca29e6b58ba78c9085920477a6efee091ab82723e0b139790dd9c50700bb2f0fd16ac9a4475767f7af2151104b19fa4f399724c7883e41bbd452a7ea95428656142568c26508c56c090d81c15cd0784aa2a696eb7b64db8dd17df266875f0842c1b49150cab06b72489652236bdaf792ecdade653b9b18b272468663a191ae44a0bda1ec73242679b81c51779cd97e7deadfbc904f455cab9732b4c5bca7a54268bfcc8d3995a19ba6dd652184935719e4c33ea5ba1bfca6a9ce7c895a1ec89e5d629c741444c3890a659d570ce97442ea7bae1f67048faf57a55f748455b043c175415558ffe7643972629cb325f5434cb2d365f367db824a9d032e5165f2de4f204c752f4fcaed8d44c2e1209aa60bebf32dc79f7ab2e476c5acf4a8f55e4cb30c516314dd3ad1724fb86faebe6939d995b0512a84ddd3817bf679a44605daac9b199c36ca7b033b8936d57779148243cebb1454c766e301a8b4920963ada3e47b4ab6aabdde38360cd61e50744ce5f55969e1dc75eaf4a9cd4e1992ca652d48bfa7c0b09424905d77cea766bc3f7566fd7b3c19fcd912c8dc45a9d34363388327d301d1a95411ddc3b2562591002824ef44d40492fabd3b8c59027349213361b68761b1277b85fb7b371f24e024195f832ac6a7c8fe4a82774b7a0d622752e58bac66ae385c47a29a605062240d9272e57938534d666d084aee1d85d74c9907d20a63c5fe478aba52639d95ec2ea15e783db4357cf1425eec5838a6597eaab6be4264c879963b9d65b722f3d4e279238d104158ee54aac968813a7be8d0a6045d3f3c568a0939761c572b6ece4cadf6e17e97ebed3a4766a1215466ed6084f21bcddaa3340be3905bd82994644af57d87e713fb1f08f704a54134fff9f38bbb2f359c5dc448a11c20793ea0cc088719c28d92c30a279dd2fa591d526ac558b9bcd5923b6b7fd46047a7b03c0ee2e66179c7ca0ad879fc8b5a74dd7bf8fda05b1ab47d2998d43cc050c90d782de37c1a1a9583a9dcf4266c6a9b2ea4531ae173991bc3119587082da384a92c1117a7d96962e1235fd0ec3859c576dcf8c438ee6265c10634460219c8327362ab48965f4518a1857824e2998219048c8b9ca775aeb58063d888fcba3bd5cf953d58364ee5b30de9a8b8768b7beb9e74db997cc9df61f3390ed431dde0bdcf3bb68b582672e53f6f3f298573647532fc34778028bfb5e30852740343f00161b0d19b3a13c2a3aa82edd7918f34cabbe70099a616727b07bbaa820a342c13d5d45a58fce23d8a2fea0dcc22db8ce2659376b090367533ba386b9365e600e5ac6b91c6e6c150881d9052887f2cebb587fe2bc4d48b19440f912e3a09a80a9028cb1e809eb10fe20c5ce4a4259a2066f63c6b096fd75e82d8fb7aad54e56a5bd85b73d735df7e46948726ae5ea3e8a4f2a1ccec5096bda380dcfde8a121b438ad3b9ea2f2bf4c2e90514c70c4d29922421f2d7dee9e6ff019c9a89ab80be031d785d7c570403c7de7fe11cb1aa8c4695db192b9b89ab9609b4ec535b87ce9dfcacad42eef2c5b2e9dcced348640d3f216e669e4cfee015c5aa5ae3d6f622e5e11a854ba85ed2da540a42ecc8117007f8c7ec3d5660e6972bbeb0a84fa3bad9b990bbde8470d02789b61e53a1fbebaef410393570d73619ceb6bdb3d34679f1246d65946997f3b16deb71c8cf052d6580730e4190cdc7fbf5764241a1336ebee12ab4a468e1c392d6def3235d636509ca983ca483730ef0a87785cc9d116af6da4b25ce3c02b6aa8793a49baa918790495c8846dd8ce104acdbe554d9a16448343543fa9c203599228cc8cf44bb39a54b788bf9a4d4d68c1f68aa721b73e5ab60d1ec4c1d5a351c7c4b9ba74060404096a535ad91abe69d6ef80d44716bef9f15ac70177147646c398fc0e680a78d01111351c555d5afd75a6f47ed12d42b3167b7ae058cd32dc77b577b3e843b4106461fd0f70b3e064e98f8814978f3a327ae58ec71f4390b1cfc2929c61a4e80300c77cccc1a803ba7ebb44f141d26c89d977b88ca61bcedad88b80df8d49de4700a520750db12bd197121db97ecfd7e468f84cfa12d0f9cd61f38a5c84c237f7206fa1fe79793e50f89db7b5f3ac4da0c331a16c6c91025939a60915f304f928246c96d0caecf576bc3d1a7f5e31ed4d7992d8a6eeb946c55aa9e138a6661a25edaa64d638a5efdacdd8f67d32faddc7f6897be51dfb5fbd9b734636168f625cbebdd68f28f77a3852f8f733ffa6b4e6a24695ab6a519906896de9777a503079f628eed3d57ec7eae871fe46d7e90571afe4cde2edc30d073c62caacbcf7d8e5fbd9ffdd3f198b24e52667b5c61c70fe5c7dcfb65eebf3b9ecffb81dd3ff603471c31ca0db5850855458ddef9aef24b3aa57e14e171c8f0e2c05fd39bfc4313ca8dfe610ff3afb5a5ffd016895eff743ff4afb5e9ffd02483ff799b5fedb1fef0c3eb37fbb515d9036e3e7de43d1ed992e4f5f66ddbb246d5e4ed57dee1a74398005fe774bb94e239d564217a16357a157dae9b3e8f6ffd2666411746cd99e352b5ae24496edfd90f24cd41fc95f1e99c5d7bae3dc48c3ec7303684305bfaae50de8cbfeaff2a73102ed19a4092fceb5d19f387fe0350fe57fab7906a8f397bfc26ff830e6c6798e6da60c0d953cc5585e7eaf35feb8aba2a9e718f0e52e53c8f248f5fbed755a4fe0bb27ec4f4cfbe76fbe6db0e19cf234c7ff4732d8e9fd277fe3e920ccb2dbf906f80bfde2716b021452c7792a4057e214989fca1cf1bff2b390e584d11a26721b7fe1d3cd28cb8cd05704081030f3c563fea181d7e45c7264734fe57ef2ffcd4ff2876892e504c2f24b9ad2949d2f80ffe5718e8aff89ff21a73f5b97ff1e5837fddf73aef607d39624e7cf8f815fda16f7d6f7fa56fcd73f5567395dd77a03ce4ec4d64d6d983d941e7aa3de6c5ce6bec6fce0ffda93c428c4b180e500b4922294a92f4f2833c61b1fc53f2fc65bffc407b34d2be12eba524c9abf743bf14a8fd4abf3fcda10d8e9dfcbf8fbb336912d98b6be954244972ff0177b6f24b3c687f96a754e6b0f63b1fb137cffdfa1ce99ffbdae99614aacf1c716760169294d3ef7d8dbd99da2ff81af405836cc2d945fc335efbeb181793dfffef5a39bffc1ed1cf797ef15916060e9e678f1f24f0837e3dffd7fb00d9fc15eb1c05fcfb35d2cff51d4c51aa3f518624afea4134c60f7cca2fceafe8fb5dbf515ea38051cd1631fb4ddef4dd5ca632878d5ffdfdb87cbd846660d92f1e8ce89fea4bb71fff9973ce7faeafbb993f2a66a14892be1c914f597ed097e3fdb3ef79ffb25ec8efce8c7cef0df8164771feef3a67f9a77cf5fdd96e4cf9035f9deae8df7596db5f9ce3f4733b7d7fee94f603aeb924f8953ce1afdfc7a7fcc356e5c7dc7c73fb4b992e94794688573c7fbd9268fcc06d5c1aa6ff1b675ffd5c3e54322ffaf6fa5edf7cc4219bfc01db50f4afcb77f55ca5321c6cf71d6c0f5cbd8b6bdb3ce27358c73ffd66df4ff1f7fd378a5fdf54f9167fad6bfdcbf8337ee55df29ffba89406fd5cbf2e4bfef3b966dff8a89311fffa7760a02e429443779f65a4a23afe05f9e80b7885b9e7eb0c91e8904ffe413ef7f9effb4e4dc9229e2b563fff7edacff1682c92c3e2e081c7970feb3ffa709cfeeb3efc97df8bfc29f6c8675ac59275e4ac9d762349e6c75c0d394aa3ffe837e77eae33f6a97920e21d97f5514fffc87b7c95fffbbeb1f9e1b7d15fcaf4fdb7528c1f63a694fffbecf88f73c97d042df43e1cf67cfdf8fe1382b2462ded2fd53f7f69cf7fc48ee6be3fc1e8c879aef68be37eac73a3f2d7f3b23fd3991dd6bf72a6cf9fd8f5bb3d8cca0ff1824daa7f196b7fc9618290c4e479f148926fb59fe641ae54fd0339fbab4f9ff996cbfe3a0f2209c1babbef4b8b24afed0fd899cfbf542fbeb0f3a1fff23b0cdd7f2537fd7e6dc6f8c11efca9ff753ffba7d70c7faa278980cfbd241eee25a60767463fe80990995fd7d3cfe6b37e4d36967ae75d3349e324950924797f7ed4b9ffcffff3e9b74f5dd027cdf8e9f7fff7d3bd4c3ffdfee9d36f9f94a04e8edffee77f7efb5436c198cfc97fc5c90c94cddfba6a4af3e66f8fa9897e07c6a4eeaa604c0660e8fabc49c3b61d81a86aa7389993661c80ffaae70658faa0eb921ea8833969fef671f55f5ddf76493fe6c970749d378ff6f8ff381983bc7afda9790bf1a74ffdf669c8f7e4d3ef3084fff6a96ee3e4d3ef280cbe7efdef317f3d0b8330f43708fe1b889b10f13b82fe8ea2ff8523d01986109cf81b88fd0e829f7efb940fff1de7fda7df1f413524bf7d1ab657f7d764fef4fb19c520ecb74f42d37efa1d8270f072c1d1cb6f9f942a6fca4fbf43bf7dbabdfa451008c77ffb64e5f1a7df2110847efbc4fdf1abfbdfffdd0531f8e977f0b74f7a7cb40afef6c9f84374aa2adf034141e27c5cb651397cfa1dffed1339e6f5218a91449f7e878e5c1a022114f9ed93321c7fc1f00b88821884fccf6f9f6e3fb915c4d1cfb77e19f4fffcf689fef55bddfffeefa9998624fef4fbff0ffc0dfc0dfcffffcf01892ce95f1a3a94f609c8da3a018aa429f3660096b62f872e881220ca810fe8fcadc9d36cacb6bf45f9dfbe45d0973b86a089c376fd0e6040dc46879d85ba6bfbf11e8cd937f0fcf8afd7367affd90cfa3419dfbfeb6dfbf1db2d18a3ecd3efcd5455bf7d32c6a04abe58fa75a527c1d036ef7bb996cdab0390efbbdffd7eb9bc26dd97dfcd6418bfbbfbf8d3774fdcda783afafb7f3f7d08ffe7cef492346f3efd3ef653f2db7f5eb7afd1dedaf83f6cc1b4fdafba8d5f9dd9493fe42f4d43ff059d5fdcd2bdb4f29978fe52391f36ff7751cefffcf6290ec6e0d3ef9ffcef664b6d571cee4e06c63cb5ab397e54964bb8611f5103fbccd4d33baabc23eb2d277e1e71bf441de8e3797c970b6fbafdc1f8e3e795bfdb86c272711bbdba9ae4a6eb22b2fb12a1fe4999ba7023fe6285115fe4c29a942f2b92d01f11d12427c54061b9eeb2286dffd3514267c8eb8df9af3afeeb48f0c76d9fa91fc161e87f87fb4118394812faf771ff5bf6ff23ffff23ffff23ff7f1bf9ff41117f10bcb0515cec60c57b3b31b57c4ef3e9b4737d672d4218aa045e9f05be9a635748c3da4604c687c25a79050481a7b610ee2a0fd1323aedac80ab768157b2d0a506dff8a33d8153e6b0d1b3c0c1768163d2d7d15ef05a09dc576d716276943b02474c02ab2cefcf9453d79023209ffe4acea24dbdaf9e8b36ec7dcf5772692eb584ef25ec57a914bf977f0acf552a89ae5299a69080ab8a80a636dfd5a1a8c67681d75bdfa0a05700a8952c82ad3484bd34e6b24ae08e129849a3a3fc3c64e4fdce333e64636cd8773030da5089ce6f85f0b1d4287036ea3b0af492396d25d3617bdfa0f6d8150f9db69eaba51ed36571cda43793492d50973d9aeaa28deac246013d671d7c479b0ebd861bb5c71cbbc534b5fbae08fb872d38a238ee490c6a8b1d34f568740e5d7f8a376a8fde5331a35713737cedb6d8c152f9651f2bf53e9793f4479bfc2d0d781d8cbe6afb28bd058e8562ee08807a778c27e4cb348659f008e2d146d52122a41e9c65611d1fd7b39f537b88d89b07bffa287d03950cc74b239880a25aa90e0cf8affebf3c03065f5d0b7cdc85dc927ab59546af528e6d3c57af7c9a02c3ed182336050ed608bc52458d5f45399a1a870e9d750f37ea28fda668a34adf11211f8e8ff1a711471c3a4b15935c14879422184f3de3cb3d5594538577e8aeb652cfd5c15742e26869e07807d62b9fb34b396d259bc3d3a8b12781d7ab08d177817bdbf8d0c9ebef1c39c93004874d94c69cbdc71c39d1695b081bf5d6f91bafa9c02837436b25c3d59a68a336df7995a955587f19e7eebf70e1db66a93cacd2e60d5bb1acaa4a05ce9ee2bada42181b0fbc09bc9f45759579f55a1d327a1c954670561d3a8c60650b5c0aa4f35bfa4a8838b6f00dea246f58eeb94a1bd5b7d46bca34710828caa93de0ec21a4a9cddba83a70d6eabbe7ca10567adf15a6c0c1e7a026dab0d667dfa090c0d5dbcfdc10d57613b80a1835a5e4bbd912222228fc308e92f039a2085edb10aa5986bb39e0b032842dc9779436dcc8fc9f783617aee849e0d159ae0f0ec9366fe9528f23dffeb85174ec5483cf5593bf1cb6cc0e1f2b3e4f31099c0805ce5a461b95853975d7c0320d1c28f3612bf56b62fbe085fa0f9e4453ad2953fff396157a3938e26813099c75f8dcdec1733a22669eb33aa6414dde6b79c3fadcf6e1d7a9c77dd1fdee216217f19ae437f6e46d54fe929926c7387fcdebfce4df6143bb0b392d0d6b160c5cbf12b86af49cb8a26b2af5c85692f24e0d11bd92f2f62c3055fdb2954121de0b3ffa2c707a17c16c1e72d607cf61d9eb687de373ffcb0b23028755875fc41c9efa8edec5f487efbe707d9b12871d438e4cfdba3a783f0b6b4d8a6a7b0c11bf12e86c3e3076e0faf57ccd0e116c759ff51ac2eb10226f7fd55ee3d1aba8b4a738a760cf153bcf1107df7ce39baedfbad51d0c8ef6561268723c640e1deb2c30a2e68218653395a3db84685a2caf6bed4b5771cd0ef1710f2d8251635742fa818f978fde52abb1a7b0fe137cf0221436b70ffdbcc6fb35f776614e655fc5b72a4a3be815df3ef8ed33963c44ac3ef82cf36a023ef8f16527fee09c751078a588ea6a89c9ee85b557bfe93738667c971a42a43a7425d195de06eeed6b3eff0e7fafbf95ef67caafe4ff1c6fabe9b08707af5084e8079ffeb53c875db8754e8c17260b813bec88a74781f8e2d2e60b1edfb67af3dfd7f9451736fec19baffee9b4333fe254aac1eb1c3b5aaa1fd8475e53f7fbd17ec81148b4515888582fec443501c59cf571bfce1ec5dc11bf5eff0da12a0faeeac0b9a5fed7edf0f6fe8e1b2fbca51a6c8d365f2dbe43be383faaab3c76f54a4e3bee88691fbe5c251c3b46dc5ac91f58ffa6cf779cde42c4063ffbc55bbf5fe70f76fab5bee59cf28f7178303b1dbaf40fbc19d4183b2b18bcf3a53f38a6b9a547ae1438fa2b5738ec7cc4c4a0b68b98ec0eff7af517e61474e4291f7d5f7d03b21297aa3c9aca625edf02477ce9eb6bddf95c55fbb5bdbd6208a30c216297fa51e436fafe9913fcdaafa2f738b9af649ae8f2c086d27fd6658488c55154070e7a14de1ff1dfde8fe23ee2d6eeb3adbfdb3a7be8a53b38e72b7efdda66c64bafae98befcea9b2d43d82ea72f4eebbcf7b8b3987ee3e3add70f4cba47be412d9eabb7b2f3ce2b3dfa6daf1716debeb1fb2fff7ef59f8507a7bff4a0a5f1810f83ca1383da23ce2e02c7c7bec250fd75cefcea83ecea9f6147cdc95c646dc3a489aff3cafc88d7fa1f63ff727fb451b9efac73bc2de971edbdc671e48b0a14d51f76846df0b3ce6c5bbc79f4573c69bc7288175e3fdbfbc8613fe2fcd7314ca2ab572c68debc9c55022fce871f089c88099c3f87dc3ac76f1efbc2857f9a67d46f5e0c1cac0e3fc7de129be3cf7185f7b390b72b81236a816e9fd64b367b57f3f62970fe16c2e007860928e629e888a9af717264f931c6635cddcbd7df5c7ef0c7c38574d16289879ab6af5cf315ab787b3f7413c058fad293837ec430e588effb1fe3b5b790a6f2c46cff84f7da42e0c6e923df7ce1cde7ec579c3ef2c5fb375cfa8a41a7cfb80a3802f9a2cfa31fb2ab129e9aa3467bd9ec6e686d00a3c718b7b8ae5e3996efbefacd7d832ca5772d34790e5409b4aed9a0d6093434c7ae3848da3731a138daa3d3cefe8839dfd524dff2dd1b13d5e4ef7f66c703674b2abb5e2ae4ba6d95cb2ce45444e7642a5b692a94af3877f8c8bb4db3cb229e1a0247c9deb8229e114c4cdf3d53c95655aa05930becf28ad9064de6875c1662e72f4ebb76f6d7fef1c37d1f35845abff94a76dee3931d1bf51c6809b91f9ff9900ffacb768f9881f855d428479d78be19e8f24576474b85668c84ba9a22de065d5a380bec928b7486041c91854ed9b9b448b8b4907fceb76c5779c5338b63c18086e8c37ffdaf7847fd939ccf430e2cbee2ea4ff9e25bb989293e6a01facdf56afd1dd7c2dd1ec2e80f63351ced7c3384d4258f9c0812045a3ce285193be2ab46572bfb35c1e9c1eceeffe4be8fdaeeecbd63f5f8c195a3ef661ff5fe0fcf7cc807619fedf5032e6c65f11d05f65d713f64570b66bad15fda29055abcb8b4d8850d05c5ec92ab391509b9d6c670367b0ed449f6923fec2517becd93049bd5b5c0b124bafa88fddfc7b96f63e5dfb5cfbb3efeda3ef8877ea96b0863e00b8bb68e459c75f6be9d7b98834639e2c46bdc7fd8e18feb3ff181b70e98978e0ebf2f7cb32bde732150f5ce41a02f71e3b32c5f74de7c6dcbaffbfa09dedfcfbe757c054b898fdb1066c7c0283ff2b82fdcf2dac62c5b1ff3346f7e3bf07efe93bcb18d797d1168081668e1c5e332f2138c31bfc8297f8c51f4afedfad5f59f60f8ab71ff7dfef84adf6f3b7e3d67f4755f473e10d7f616c1afb9a8552ec8f7b3dc9b270e6eff82cfafb99a5106df61a7d8258fdc7d1678b10a9da30e78c76b9f3bea6d023bf2c93f722134f51b710e8d23c7b137815386d85540df1586577d507c1bbb3ec7619fb307dfd53fd781ffe9458a7a6e96bfb3527ddcf179690202c10bf8656d8240fef36b13f0cfd626e033f44fac4d7c08ff278b1330fa7fab13ffb73af17fab13fff0eac48b20be5e9860e6d76a2fa2b4747e4b65031cffe3ffb4b610982391b2a777803b48fa5568511fabc8a9051375ccc7d9518ce9350185b5fe11a4c856b3154e32a8e36f55945373585b92b051739453638888d5c724d147514e6c02f7b92f2bf59c78f31d7bfc5848480556a93e0706b3242cc352d88fa2f968b37c4db47e4c5cbc267e5e13b1ef89821826b6e0f304bda397c1bb70cec223c8d7fe1cd550f6b128511c41c887d9ed35397a147a08854575d504bc9686483cbd1233ae5ae49c4ceda368625853cf5fc1b90a1be56312bfdabf92ed28d4de13360e56faaef02eb698cfabfdd4edf3b3324d399f133fe12a4c379a6c8f7b0f7b0be517dde492397c1470509618d41422dabbc0ff18efc7a463f57e6f434b03077d4d8abd9262072bfcc3ae7cdcc55cfa21cb97b627817e4fca840e8b091c91c71cfb65422fe2cb3f168098af6ce56a92b0b4c56b1296fb63e7418cc4885c7f1e27f6daf5702482be83edbe7b9b4da6baea1666ea06b8c905f96e83b5a790b3f7d76280cb42812b1ef6cc1383fa920479f55a09dc9ac56f2c653e227e998c3dc61a2362f72aeab6e5d0ff1ec23e181f36357ec0c9676cbe71f55936e33599f5fdbd47d29abd30428b94b551a2b509a956b2a661df06818d459bc9eeb6ada536c81a56c9aa3653b1d646ddad9cba9a20c618b62e9a20660a0cc1090cab3a2fff1a45b3d40681b3bb43af514e1d85f1e6bbca2ebc7ca27ad9cd77b4c336a6ef583fe8ffcba4d1cbaeaf02a2f3ebaa387414d631e439712570f17c2469e17b11f148e4c6c055f6f782e16b823a0db96a0cdc0fff6d6e87eefe443fa8246ce47f9e7f0c707c4d9ad2ff0b5c6780c778dfef68e694f9b1b8684734457bae5e045f153f6f9c8a55e4da5d54dba5c0d8aafd9e9cdfd5bf92577bfb8851b28e6613820942ac4083efc9f37771f4f22fcfa0249d19d28023c6376685779f9fdf17a8d9e1eb3eff221e1c764a0506dc5c30bb9b9695ca063584f0e742e2b548f9ded15308cd770baddff6ff6a07a2ecd2565d90d06cf6e8937aed210f9dd7e4e42ef0541621cae785bb17668c9a853d83724c834202ce9e5e497a8dbd2605ccf72ea377db3499fa06d6c8f9ebd9f782e41ff6e8625ea942ce1b5e93591f7a7cfde3952aa62945b37dd6ac88bbc5eae6dd803c9fb3f3d88952d9ceb6d8c19e3e1f2f6aa36f9e83edaf45d02b54c62cb1bf17f2b4e13df1646f77b71c22c4de23ce9efc2b84c91c5bfabc5845c88d50afe47223df7d9b16ebe816f6b0c051b458c2d0367214387ff09ce8bda8c355fbc704e4eb3deaf7242b511f9c7d14ab51fdc1d3eeed7fd197bacecfa950a0a1f35180fe380621750df2f23149281dc562e078a9b391a39f93b3efeac5e71d6387fc5fdffbb6079acab00d7adbc72eb1462c8e36fcbafcbead5c645e789ce5fa4b7bb9c082a9fac28d3dd1ef45bee990d360084537f0e9bd2b0ddbbc4d388acf3ad05ae9ddf62d35a1db370b1ed1abb026b698465381d661cf15521786a008d11f1f13c8076e0eac5547aef08acbbc08f9c62ba6d49eb3be78ce43aa2686abe9eef8d9ffc7de9b3539aa2bfbe25fe5c67a5dfbae6228ba8b7fc47d3094c1e0a16c3062d871e204830b3002d365631b7ffa7f488c9eaaaa7bf5eadee7841ebacb80c6542a954afd32e58d66f0e59027b6a5b2aef9c8d707775fc594cebd34609b34626db05052243fa59d630e62b419c69b6f1a8e00055fc67112b6655b5a199846f872daa27ecd74831b8172932b725d6ef5fdebcb016dc8b5c8cf82dc8bd1f7faf79ac6877835cdd01a7a72f4c13eb066e58439e6760a1e1d73ba77d15c04fc06835864982ab2c4d826dc567c7a083d16d141655d6c6477a20a7c20ad5dacc30cf64b19c67e2a952b9d1fdb96134da868ef99c6b8397c351800fbebbf2303c6318f18833ea98c727092cef69ece6f5d532d6d4be5103fd9257fb475fe682f87c7d969b0b718583832789ca411e59987aa7cd45e691b4eac4da8c4da78011ca19669886f2ef8b0e3b595388827683ec7b84eb892c17ac2e451904aaf957c53426bb9ad0e8fc24d77982c83c71a2cd1af8b57d2f7e96a8b4adb0607f1d0e21365c6fcb4a5078501307bbd6a5b57569ad47470f27a9cbfbe1c72e833d2fa725e9fad2fb11028cfbdfeb574549ab99a211ddb639e767e0ab68e890d45e7792ed6acb9297cc3e36fd68751487e9979e9e87445036cfc71723175f22b99b3545fabf9ac5cca8fb58275bed9de1b3948bfcbbd747742eba3fa3ca8f551b46718223da5a878b25ebbe2e0a4c80d2f0a0b23f179255e1c94705395db1ed6e3c328bc0f407d6d00083e0b77b84c768af2b3ae8cf567d4e60d6ab321a9a3868e8efc548fc3f1343785ad5f0e769ebc403c89ea8d71dfc541d5c6131d3a5674f091bc938f27251e7c5144bf18c7d49f8a74d84ce2dc1feb8bacc98378b6973ef7d26dac3c6f42b57c2ac6b11fce910c9601336138da930f573c8fda39d795a4a24fcd3b324032ea228d8ad6a712cb267d10ab92a06ba51a4e4a6deb9adc9b528f79c57342e2311c14d1bbd10cc9ea04e59d9bc22160b410bfeff40bde96b5dc4ff1e14f4713f1a998b46341472e6384ae858d7a1560c802912723b90d12c4db2d8f2ce9d066306d6753d8f0f32055e35eddf22c4163e433686d407b3b25c6f3a3446b41b447b2b05a7ba95291254a11bbb22afe447a958364fef3ca0c905c47ba78e1b300ed17f06126d28f7d0c54790c81c1a9a6887848dd61c05a0ad26a2f2b152b4bdb5475417c701c54e0a9311a57559e710e8be4769fe7318f1537e645aad66370460b16663e3e4819ec2616285c2b3ca74d3a382bf34a0e88765ac98e73f963e3b60911da0f4e749af652f87895ffa2ec0575140c7ab658004db928fb79399496062d0860185e968de989f4e3c0e472249bd5e16cba00b3a531940c5d54c38b3199217a06e52144fb8e0a2888ca8a4e8a8cf773686f0a9609b415b9dec78b425cf9781ba16d721c9af348d7c4760099a76d2682ce00c9a441e299b07058ff4ce7406b8687f59396a7b15ea2c67635877abcaea483cd157faeb7a13f0a92b13988cfcbcb05904837c7f84cb6ea6a38ae79fa8cfefd726fc8d5cbb1eef709af4f4603bec4e0265e495bc02796e53653b5b75937719b65bc4e363142aa7d773dd68a3844e9621bad692325b44425b9ae07f895cc0bfcb1b45b2912f5cd1293cc169570ae0f622f7dbab17663a05de454f26f33d5133c765eca53e7fa8a10f91508b470102f54fbf3a5c71c233f8527e5797898d4f4c5e5615fc12d6f8f828d6bce36ca4885b659c9bbbefc35cb41a4c8d51e1ccb952e6f258be9c3c6a41f434b47b23b0895672a54526e7f49f3566711b5465fbcd46dab3a31cdf0da85c624712db53ae4960e37e96f896aa89ce929d769100f21beecc604958fc7a2969d8b700284b0d683d65d7902c4faeb55fbae78a7744ca95e67903e2ff84aac613ed2ac08da2ca0f01881437ca60f353accdfee77c5b358475af6d7589c4fc1fa6dc377e223e2396c3b5599415bfff99cebd3c988bbf1bba9af9de961a84f780f925eeba70b8a1eded5bfccc76b3d56bcd6bbfa7aecb90ce1bff9a9b1f799b0d23faff5a9aa0fa5a02e120aededb14dc1631ec385016dbc8fb6d03e09ef8933a76f17c8a67d2012ec8f837f68c7a0ed23a25f9f9e1306e982fcc915793c4ead3e71a60fbf975fcdbdf8226fa58bf4f8b39f5f0d0326ca6d26acf8aa96bd9763a3e867747c5e1a8bab3d6703bad52cb5f458e58b7246736c17c4f6564706a96b72d01185b5c7aaa563ce286f94144a3cf8535de3fd69a57f884aa84801c4609b94db07624b4fa8887d3ee9f2ad644829cfc3bb7cd55f976eb51d305265e73b6dce6d4def00a6b1ce22e3f69d1c6b5128618ef7d7f53a6f2d6975aa49b3d7e55002cb64a66840e1b107593a433ae9c6b6c06992095bc78a68bfacfdd2d960efa7c7c42fb9ad6d810203e5636edafe463a6129507e2a61c003e247a45b625ab22aa78c66685fbb0e4658174bfd94df550e1633e8b3ad5d1fc90e68b3dadecf921a500bb78e35e37c56839e8ed2f318f8eda4b0f4f1d8f5eba8ece0939466bc583805a67a565e0d282d7c06264e658bee3971a8789fdf2f0fadcd5eaabdd6b68a573b954e8ea9e57e1ce6ca687b6607592199f53c44e388c6bdb73634bca3628041332e35f02e6f81c7688ca5dad602f918836b64582addba4705965a205e6aec258a28b4e9d0bc9be23da6c05e3e777b20250918d47e25549614da8b6435df25dee15c4639686e8d02ac834f4a6e17a48f3765524b93355595ddc9f518adb7ee6173b15ed4638df89a058523567b383d51a50518ec5e9e93d3ac1c6c906c33187e6b5b6aee9783e354e497be2c9576999cdb104cacb37dc57567d44dfb01feb66ef71f983e93f2b168f4b04667e8b7118327653e554688ef77918fcfc316dd1eaa3747d5d1ae1d87575d19bf2ef05c587b0cb7b62d0d7aa944a1f9606300338e7370aaec87c38abf177993f615adc38e35dd8c75e1eb959dade2aff3fe213e929f420c1c1a29e1c49a862a7d2cd4729029a21fcec52adf586fec6c392f86b9b80033c9a234d558d3f7794f5492f148601d3189edc1b98eba48a4a506f8a10e948b36b532ef6babff97d3dff10f8d81b41a69d0ab0041789ea131f0583fb42d40790c3e2b6cc0ee89c7068527f3517d5e886dded7deb3dc37db521ae04a6dd3a6d7f86c3395b64836d520fb08834c916cab81731508b4b2912aa3362607de8bb600680cf8c6c05f249b36aea9e68128ac5d34ce155009ed9362d7e4221f3b6a48948dcf707e0b8dd7dd9aa6a0b9d5f155fc54789673167be40e2d6ff074bdc6c7da0c249c65d18e6424eadca08c18e9e8b56df7868e5ecf85c4d90768fe8a586ef5636a5c7b3ca779e4c74aa707a63d1bcbdf6ec76c1f98c7c48b030a9f21a78b7a6deac720b98ac75cb8a9544ec42b7ecc0371504ce2c75aa7c56bc099ccaef6a6b4b984c1ab9180c59206fa52bc6513453ab70afcf4c0777d532563c86350ac6b3eeddf8b173d151fe9c9dabe319e54ed595e8d6bb3fe9ded43e43cf22128bd672ac6c0c3d1f4cba4e44bc712daf383ab73e6aa9e72c2c0fd84d522b476b8fa8db13cd5deebd76dded56dc6b43dd74307a182f79147a80ca16c9ca878ae2bd53e5314de1c2b6940d95f1559db77fda8cf05620da5c167028a189d79ee8ff5333a33b679a41d5df9aac848c794de94e7edd71ecf9c6c735af39db6f752a392dd43553028f0aa0da15eafc3eff3f39933c2b419835a762bc912382f80e64d0da8e2929e494a3ce09551756671834f1add6578c18b587f7b890768af85fb7a83a64d5cd2b16d55ba0fd2497aebc6feb37341e9ed9f5adbdbfaaaad6d397a2a9518a4fc7c69676b6d57ac6b72687e9db04ed4c67045bc89d3c47d9da047c3ce714aa41965146007838f6cb93f4effe6eca1dec7543a48183001ac6541b7b6e0774abfce563edc3873a9e73c586a407d5918b54d71747cba4e23347b86e14dbb487b765bd1a2b21d609e8f15919edfa36f3fffd5d94a3d9e0e032845a476154099a67d069473fd46dbbb3407db9a9d907ee93c530dad170b305b028ad735b1b22b60f9232ae1c478c2fae015dfdca1a3631eaf7940ae9c0a7e350fd4a0fa331ea8defd461ea8693131efd2f5923fd24ff0c13a40f245a4768135837e3c68e8070c0ae8cb449a69cbcdadb1de55baf9b51c52e20b3e30ed4b9add3c6ff97963286dbd4a8ec676e570b66f1df96aa7f90a77c0b35e7adcdbe6e27cbef46c6f8dfd6c81e3a54df98f74b00aa7c159cdd8686d1d5aad8f75769a662f849db986cd99c721f459b4cf9e6d5afb3d6abf14a0bd32d6779d942f3d53427b6a887e3b7acfc1bdb2ebadcfec92efcaf5be8db18a6d363785f5ca0cdaf3874ebe776d686c98355d5a79ae9c9fbb9eef79f5d6eef88c6d1ee59df3e4335e188693ea7cecefd07dfd717d676d6df53c90007d91f04b4d57c2b92e540ec037f6c097ff1a5e54442a5c603c21dc56fc57adc15d5cf3f3fb032afb645f0fbdfc772173faff4a01c7aa74cd63b71faaf9bd8af737bdd3def0d25e1abbe663652b35a7b1d2dac62bfe50e2e4aa9cf3397363dcdfd7b32ee3fdf7f4a12ee6debbb2b1fab756a40e335507dfe8d3f776ff7f741f72554e632b18ecfaedf8944c101f8b497caf7de7f3a9f76f7361e7ac70cff8ac6288e4ffda17079773e583f660deafb06bb4a02fa95c5ad0d5dc4363f7f1d8f7d6f3daa6fcdbf6cef134d41a3b930c1e031914d8f1e637da4cc4b43d276970780b23e1c79a3133b0ee6e68aab1a69215d5e007f1bc41fafc97c9b97e1fbf2ef2ef5f2f6b1e7d6f8cb15d2939c32ff24abcd8d80c5fd88c44594c6d63ebe3e22475ae27e0190cdbf636fb8f6f414a1528af93c24c8993aeeeaaecf826ae603463dd0a4bdae00a28af14ac765f71e30cdb6f023194d59a8d6d27a2b6aecbfc495882db7b9cae1c35fca1b3eccfadb967671a78cdedcec7fa58828b73f81e6ee0937bb633ccc2059ee19d31bfa8f73e8f7db2bff7e748dcc33fe03b229c1c0708d20731be1b27d5223fd5f2550a12251658db4aea400680f2530883b4c186cfa6ba2e447e1a9c9ac04a0103b7de00e3fef77eba45cf942b0ab1c76a9bbe1e560580e1f65e4cf7f8b217b809073d68787d36d3247eaa1b9c645192aed158976cfaf7bca4385937fc501d0ee21b32e2796968afcb217cd1002f1849b014c3dc321269610c816e51470118dcb33e04fadce44ba7ec452eac6c3b45cf2678f36e1d31ccf1595b8b8f306633ad75a6d5ce30c38d73701d43b81ec34fc9828f6d11b5b3ab12d3c3a6ed187bb84432b1c193001eed312686d6446aac026118f4de1981ad039ac062dab0773ec5aba3dd7d7ec2671bb85fc98a0ef40510161a507b67782adfa3433b5e4aac0d947f3e9263bacf0e7ff91f05726c5335ce925fbe50bf28866fed2bc9febc388e55dbefb84ad25f88ab24719524ae923fe42a894544e72eb9905469a9ff22b78a44d03583eadca3faf18f3a37bf65cf0d4dc6c7d872159f421123c1a0ec5c19a177a05464be7016f9c048c0ac7201a32b3823c3174df0618f5542af7357ab5de0f0754da7493ca8a0f8157ce765496bea82329a63e3ba5c2df7d9c6f512243d77401cb7cd63d537ac8ec642e4c85adeba1dc9b0684c35386655dd773f05996da9b59bcb6cef8f60e99ac1261005b455857e36dbb8d6a050c42afedf02cce4cedd139cce5c179b36367136f57337b4451d38b9e702b755a4368643388d1f0f8a18a1b4e39a0fe2ce754dc95f6a77cc0a528ea1154dcc280c0fc7c73a3278b4197008447c74baf618fae0c930f2d2196cfa5cab5097ae71a122e136ef907ae6312a855411451ea2f13bac74ec7275e96e180583aacf4dd9d8d4d01d75b101eb176dc0e8145f03d07339452ad84c5ac29934592ac5f4a22c60725bec4e38eab9ace198466d9c141cefce9325b6e23729f353d0b871a1feb37e0a713c90c9a0199bd9dec9347c6dcd352fd57c5cf15febde5a418c2ed2ca7ca1c852cb474a222d95215c2ab180d46ad5280f21a0a0a10f790044c15a00555f189ca11b60a90c795d19cee6cb4453c110ce97701a2e293b5c189cd394a753f045130fa16342cac5730b3cfa953b5788e6908b635d40e888172ec6ddd83471acda71efbb1979b254382ca86223323ce3586a1d9353807e5a5f3f54c56e2b1c51d8ba269d07f5bcf70f0d2d6fd36b12d6df7f91fb63d3bf5f213327cd1caf4d878a34a36c4ba514091c94a11a55a6e2366eca193f1b293806262c919cd50ccec430b66cfaa51df31f70afc472a26dd31d37cb46ceb7dbe2c1ae8e7b5ac7bceadcfba6d825a5bbd2d41185daed4acbfdb0ed7b6b0e01c3996251e0591f3e8513bd8b0da9327ca1566602e8a5fdb89460edca3c36c57531796bbac9ed551f5d9beb6dcc22918c0515bd1a4309189471af2ed63621d5c87f45dec1157685e6df1cbd334d382687e5fd651d4b5a308c72b0c3eea0a9b4732c0dc742ec6205b76104b01b992239336514e0b8643d7347b5a56be74075b43c49fda28ec907ed0cb4a667458694cf80ad131fb02b7c3b5719405db8adf21310d5eea5839d89dd51f32460075f82911a79d90cc75a9d9b1a65b1b3bdcdec60201e9b38c0fc4a3f9e026b76407d9f5bc9d636b5c44fc1c93f518fd3e7c1e192163fc33df497ea322d6faad061208e1fe889559f6a9859bdee0db285e8d7a105b0cb58b38d1417407bd6255e5a50d11ccb7c31d87bb13f5ed4663a8f71d2b3f11921fde258c5c26b79179b2c0a47e65931abbf8b464b5fc7e46ad86a370fec2cc1e555aeff77da8378a76d0f4c1551819773433366cab2c466725e11d5bd172b9d89d1b83967614b37ec563a80957ca8e21356610c9cc8c331cad0fa3fa85c5ab1a97310ab06367d41251ef0737d102bf16083e922aa353c1de0bf9aa4aa203160951e603396aa2b7937668d99c640320e1f7db77135cd451bd3ae77c45687aac0fa66eec415b459894143bba54ec18545abcfaaae84f325152ab182d6391c97d965e0c148670b3f6df4ac1a72d6b8d88db09b6d25c3c543e831dcba8d918c642223ad57faa0b053895264b406e271ab4211f4d38adcda33179dbc4921367dbbd68c42e357d11af8ad7b30cd1ffcd4a8cac5f1ac8fdb0fd355ee347025c35320766362b5f371f68afa3349673b4754421cebfae374e3976cf6e65a826ed342e92c36e305e28f3a56b618e658f66a40d597b4fabaa0f8a1b6a40eed784a48cec193c71ca300c7cde52807bb491cc220954ad7c42e36a7265ea42ff3279f81788d40bf83366481769a88028b63b9e3d02adcbe0e3571722c0dc3febd413e403c57c5f13db4bac07c49f1735d5882a1a403513017c651d58692a11bfc0b9a1ff32535ae6283f3d558f4d6de1b3c3377a91cbb6788618e614293faaf3204a59ff2e54b7ce66a51bbfdd4d03c19164d6c6dc7e418d752f75e8af63c8b42797e4ca74d5992d0b8b176b12dcf61fcfdf8a048bfad63895dc2e311fde95a1741eb5505d1af8e41afc2285465d44793aec99d021cafb78e4118f7f33e8e6b7a403f53f77eb819bf24fc9b9e542eacb51b68ee5773b14f0f68c96aeec163e57e9b8247476f699b7b29a43e4b571c3fb792bd7ba49be2d8c7a9b475cd7378fc79bbcfcb40b24a35fa74c571c7ff478f43bdd622bee691eea7dde179719d37f4ae656f05d5ace2a8b677405450f74ac7dc2a7252a0fd617d848bf661eb40e6cb1596c3d2f99d105d2c701c324889f1f1723ce9ea437a6507059167b49fa955ac5e0c95c7b2f4dc95a199a7f57c9a849bf1997e74eb484307bd75b47aa72e72558b8597257db656dc38ce30e2f9928a9558c83c16b51114ce5083810cd6c110c74c1c22dd5bcc702806c91c82e70a5e4ec105b580f57bab6e47f73d36c62f959b058e27aac9b01413282b4360eb6066203904aa74b155c1799b391237e96b48d4d86616e1247e1ceb868dfa82eb5275859feb0a6e43d7f6a6bdea8bc76a95fd6650c96fd06f731aec5bd78c7e1fd7f955dd9fa0bd55d37b8d5d2b0c606bc6ecb56e63cbbb5eaa0d918e6db33d7a849b2f98f70c2df7136e1f0cab31af69fade312dd440242d687c1c0bc514bba29ebd5390bc4aef8c251e076e0ef078c225c0edbedf47151cf051be25e78ca7736b8fe152d7f4631cae08c7d6e71203bb604a8923433c876df3f85ca743eb54b786898254ed91400fc2cf9d942128b08c3134e8c912e7989ab41a09510df11f63573791971551453a139e533ebe13e3987bd69457e20154cd21d675c73d7df1c69110acf88df3ddccd9e15017383c82922b32daf360da8f4142a3b5fe454be0c8a27ab4a185e55c97defdaee8b82d48972e9c5a8f5044bbdee7e4e61234c738c16bbf9d8634e555e3ddef10f1cc87f486330974fc53af07c0d696d4c55a007c3b85685c911c2e1c2b824aadef005a150c49900c9c5fe1df9721c0c7c76cf0d81eb335bad635e4f7aafce9028097051549c69adefb69df8656979175655c424896a6947bad8cd4e680e2a64b4a1a5a34d097bf178a3ed6125eaf7996f2981df4b2293fd50f58dff764b8f34f54c5b7c630d48dcff36d7ba40a8f1fc2c4c7ba305c96834d0d755635b497d181a0ac295e69e95ac33625cc37c3251dbc2c87bca049d86d805775208a71d2ea9b9a1551f8ea737c9712d64df09d07b7eedee9a08eda95abcc156fd43a721d726a6733a0c0fbfd41ab6b57774760579fe0f28e849a161d5cbcd245db23d9f6981dbbe4c83076ad4588f8cc667655f8017ca70e2c6c4be5eabb938af37d0ce81d7de782111be1b8e7968ee6c8058cabdd2f56502ea54ddf876d35d05f1574c7bf7a22e96a0d671a2f36790d593dabafd1e76b088eae01610e803aedebf467f5dd19dfaeddadab08fcd92e19e3c5dfa7d382e1694fd60a955d546bb7388017720abee35ed3878ad57a7707d1ab6c3b98ffbe2822b8a451e3e6928b8ddba6ccb355984980f698bbf6ba63b49666dbd80a37aaa82b4980d62ae698631df999c277914d4cbe8a9d2d0acb9535a31c932a9629a02630807632dbba262882e7a60c3577e2c16682f683e26063b238dc61e1d0d49797049e9619d87a43bed44cfa108c928d5a822bf8b7aafbb92256f69acfe7efa0e128ff584fc255a9aec43051b1aba5a9ae3d19e27ddd8255a183f603328cbcd1349ceb42e158fece63aaf8d68ad4b8f9722f8eb5c07dc5fa2f352b1d13e9005a6e9b877b6ddf2aa20faf61e046365eb634e215f8381617496c521c0c446ee9582ae39a3368c87cee65dacc36b9c86140692d375f0c06ac034bcd83115cf8294f79cc6cef89035e9176b87d37bf4b1ae7cb207859e786379a1ea7eb6da88e0268a7f578895c071d1de2b0a2a83f577ca49687502dafe44836d66bda6654cfb507eb651770e0d6e6554182e346b6f7e1bf82ec9a5cee331174aee6c3f59c69793b4e1a1b9154d977f01eb795f59dcde39f803d35b6b99f007d3ad79faf204c73ddf826869b76adaded21923934a0228277753b551fc0731bbad1b3376ad20282516dc3868a48d72ef615d4ed4abeeb3f00257a4f4fd795b33a7a610050bf2e214450118d6f787d1b02dd48787d3904a6661cc2a9deee05b15da2dd2fa1bd09d23fabb00bb5ce55e5b5a8d95c1b1afc7451ef3b06f900a5af6d55a15adf617261478367cfba518552c0e7bdfd3dc96ca203e1d548a63dfb6bddc6516bbbdbfbece2b68df3ccceb6d82a325fe07b782a1edb3a6610d96c124e52350a44bc57ab6cd51584b7977650d80c9db476d0c327ec91b86e2eb6ad458cc34bc807b4fe55b637706c43305a2c6effe7ed9c55b96bcffc64b9a8dde1e68bcfec725f52d706ca3f686c29c2c1b6f0fd33d51d3cad0d1af1c6852d9d1604006652153eab09cf38c83ce6b1b2f9deb0d5d7e758edd8e17b3e464284cf80c2c6bede8cb5261909ad2e13c9d0d03ec8589ce7c3bad822548d33be83158c10528ac88b8a082403aa7303f3ba26a98b7f1c26976fd2bf8e297c1f25d7246a41724f5ff85f0a927bfc892039dc7602922320390292fb7920b946427418b9f933ffe8e1b3a4e6ee162aaeef7b821e0eeb030be744c50068f26419c6f3d3e378deb36daf647aeb65535e49232a180dbe4c9ab0bf9797ccd3c27ca93f5193f500df6554e7fbb21acdf2b9aee23b71da70f1997faaf04d4fe5f479709cd0d16c29cdd09abbb375ba0e4fcdadfba151d13f54d64b56a7333a4c46bffc067a7d81a35a2c296a3f131f0f93f519e6ea765fd8e8e488cd37aaee13f7e8338b788ef66fcfc79dc768d0ebf0687fd6653f4d187aefc8600b5a7a572196e7182781f665f53ef2f998f9294ffb4398cc711bb9fafee220adf014588f2daabb8c0f7b8755f78125a84e973fc2369a545a07a88cacb93b9a8e3d86a7265685b541fb695f96f0bd8773913fcf53ef45e7a3ae1fd318edbda74f93eebea43f6bfdfea90ba70aaa3b914eb82d4f13b6eb1beeab1c941e0b0ebab9f8d366f8dd246def1b2a9cfa2eaab9c877fdaf687adeb6b4bb67ee66bb9f8fedfd59733c3e8fc70998bd2c80b0d487bc3117f9ee7b951e879e9bc377efd8fed2de95356cdbfc3461aa7beeaabe69b0d16f70d9c9303458a1ecdfb7d5bf2b7c82718767f535f7773e4d988bb2aaf0a94fd53dd0a00c6408fd533bded57960d61babe5f0a976992b821ebfd5e9bbfbb0abbbcbfa69cae9b382f8b5983d1ff67eddfe8959df1395dd18fb364d73572e774effe5a0989efa65dd48d7f09b3cdb7b96907b32282796b00dcc20f7e27e79d3e2457c3cce457e5dbb85423fa60fde0864aef978abafcd3ceea5e7cec2d6cf33ec52f6d4da9bd25e1bb2330c53dbe75696d46eb08ea514cdbddef3f510b5ef56bdcd7de0ef9613a039c900ea9d72d0fccd1c6bd18d41130a48e4ea7b8a9bba80d4c9720e80a1bd7b41e3faa9f42d0ddb9067934c85d88d07eff7b97d606987c0d23eaa03dbc7d13cf552bff05840f923406926ea137e57cd1f9147f51c1c4ba55c139c1a9e776480f1568ec9ad57061d79a9945558e7aefffd3475de666d38cfbf3c736f7eea6427b6d5170d8f3a19e60f8c839ed477a45dc9a5a69cfbf2b6b99f2e712cbcf743eb6aee58687e4b8886a96dce28240bfb7696becc5547bbfb7335a36ec9e2ba0c7c67db9fbeccefe6224fad2c015eb4f96433fcc15972b987c766f13461676b8f3d4b57c921bc270585cd262dbdcfde33ad2cba480f1bdb183ec7bf359efdb1c2f2f3baaebfbf1ee2b2cfe9ddc92275efb18b9dcf6a680c912c611d534dbd1178bcbb268a7c7f3cb99fd6fe6a7c9f264cb746f6caf888c74ef8ca1224b3ccde1a6305d05e1ff6369e534e64b35a4f4f38ec6fce8de7e3cdfefda4f9f274de16ee92bf77bdbbfe767675b7e7231ad79b7dc074eff0ba9d2cefbdfb87c7cdb12224b372cf0448766fbfb7dfcd5df5f7f80de5edad6bc98a6dc7beb943ff239970771edf938d7d3d0debbd0dbf314e8974a52af42687f5c9ef1e67344ffbfc8ad65676715f2676b28a72ac19aaaf7e7e978f6fcaa84a4fabee83ef74dc5acfe8d677bce6d53ac5b95cfdfb74f9583f379b73afba5df7e66f43e7da0d3db0d40a07b5be08e1f17cac6cc5d8670194f358fbeaa7e0609bb337db0c60138a028716b5541eeb56fdf4176145e632dca17c97efb13e83e6c5928bfc917042ba71a5e7d1b9674a99b33cecabefd721469a31712ce54f5f96de1c4bdb5777e76bb89d7ec9577a8a0cca17a44764c9d384e9f25c8592783e422fb3afdfa3ba86eac2a238010ca1a9015e5d1ad2485b72f8cc632ef2a221f12f0ba0a92001afba410b1a65dc28ffb0774c8eb9a28dc8d77d3d1fa30973796f7b8faf90ae241f698781457ffedc78f7b365d27bbc18a175b109d7d7b6e5be8c3adf77211e7b47df7f5d1ef657ba7ab3c6d421c4b18fcce98a979bf0c9573a4ffd3d779e2b39313103e8a598de685cf38b79d3cce7bd6d1e4f377819d3da63f09a82e4d3ce6140e1e03986d61794ef709b2f183ef246d3cb6f4f13a67796743d473fd3afcc3139e8a71285e6927ba137f6db7c45b786b6a86d17e554ef6ed046e46f9785fad81ba3731e38ffd6cf8bf4fb2b997a57ce9eaf052d1fb2a0744c27f753e3b33c5963ca021af5f7aabd953c43ba17edc8e0161f3cb9689f320289b37cfc368e9fbe01199c82d1b40a6b84c7a1fd7e83bf9ab28d3fc7f1663f8698973ecefbdcfb665df3926345f7bed5bc34db06a606e7f1e6db8492e22accfb8c1ad7a179e622dfa5b99661edb78bb1ff6e39d68d3957d116e97158ae2ffe142bdb4bb5376420e5b16adeebcf135aa33c7696638cec996e7226a74e5e2a1d7c26da577693731da45e8f96b5ee111a0c5a9b661b8fc576a6caeed3d7b32c753b4fbb2bac701b5a19eb17aef9b4f76418fbfd7a45bac21f3e1ff6387f5f86f7eb3be7cbda9f0b249dce5ae314cf749fc3fe4e194fed754d173c3097bb72ea2bcaee977d5dc6d384c57bfc936be173e1ef1d8f1db651b0dade4bc1e952eecee5ca5ed6d9c5e8dc43f349e68b6a5fdcd9d36a3ad17e7af8f30a6bd7d6c7e51ef685554f13b35796fe37c724adae724373a17dd7df17b3b3c2b684932bf35467873bec6fd2e89cc7cff6536e7f2f6aa9d09341e4339fa09b7496f687f8b81dfbe56fa7d139cfa59d3da19127462fcf99cda0d1dde14d9e6dd6cd76efe19fcfff0f68dc6fffb5ee3a1f81d27be6f0f9827fdaecab3e3cb57be2490af7f89ab86cdaab77b1ab710b4f1316e5ef9777835e8dbcaffddd906e53eba99fa7392ebbc72f3f3c9ed765f4e4bb7e8bc7bf777c3c135fdd40790c0711cdddf37de0a59d7e76216bfe8e3cefc92de3ef8e51757de412ef11ea77677a507fcdeac9dd776975732ebc23874bc73c42db9a7d868e7a3feddfe2f3f60ac1df247fefd3e8367dfbb266a4ee6b9fdb33bb3a7e7749e7b4ded35ceae195adbc6fc3eef70fad0391cdec2287318a3ad454eea036ac39acffcf45fe9d34e7fcd6d88d2666b50f0e647eef8da6fd3390c3649d14d3673ca61fa53dd3d3eff4e13d3bfb7b76c39a6e17b69334286d53dae2507ad55e9ff2187e8b78f0960db7aee3e22c30a7bd1452134bd8da9686afe56bf79bcb77ed2657fbd50f69f48ebdbde2ebd9de978d3f03a48360bdad7a3ed3cdeed820dfb1a9d7b43bb7599def9db8ab7d4b2b772ff7993f6b1c6eedd15afa7d97fdaa6eefd9994763d7dc9db5a7fc94fda0d181fbb8cddb7620f99dfdb878b63ed5f6843b73fe62bfe8cb51e4333d3ea89fefa5bf632fe8b7a16f87b86f7b68f9e83d9bc63b7b77b1bf7f7cc716d1d35debbd5cdf867dd3ced2f0ab2b237d936b6d8f48d654efeee679cf9ed1f033a647dd967f9a3ee7769c6bdeead6990b79ddbe3fb333f7f6c39d1e507a0cc679f7cf45715c224487fa199fc7cefff9307ddb37ff7dec214ad0e00e59aa411d32f4e3d7c7a747fa91fe04f890f9c2d0ecd76bf06105faba8b3d64beb01cc5335d80bec7067b487f79fafaf507b087a8fd779087d41de021dd020fbf521ccb723cfb29e061dde5cf000fbba4bf1978788939fc0c320d3dede24df60122f19f6d750d76fcf71f7ffdf15f2ddab162ae73b0e3163dfd9f6095afb26095f9e5fff77fc2781715de5ffe267d0837ff378c77e88f1743583eecb93e36f2df7ff8305e65bbbfc2cd1ffffac3df64af7158fd7e4509caed6e95d6cf3549ce9ffe7b95edb717afa0ebade0e5cb340edf5cf4ebf2c326bff576bf8145baaadfe649b80aaa9f6fab7cb38d779bb7b8f9d8be29abe7ede66db70ab6abba4b8da4387fc279ffab070afd37eafb6e75dcfdf1af3f566f6f9bb72d6a4d8a1e7bb4f4376fabcd16d172bb4af7abb787eacf79a29b047ff7fb43ba4a5fb7f752a13ff7cba8be3e6c779b37375ca192366fe579e2d47d4b3c2c2c1121dfdefd88fe8fb3109573912edef9d10ac208558ad81e89ba7ffd116ef224fc2bce1e4a37857fed19240637f8bf877853ec62f8c7bffe489eb67fc59b07378f53d78fe26cf556a26ad08b87b7d57653bcf9ab3fde93f70fa820449f6cb57b28de50999bed1f15e2f401f129869e22560857c71cfd28322cb9db5f0fc1ca2bc29a3bd09f1d5a355019db12cf359cfcbf1a58f0bffff08a57dc0fafdcadb67866a4f9db6abb7df04e71cef45fbc227eeabf084f71de7f3ec1d8abe6d6ce459d7f80f17657bfa818ce7f2bf3dda6fdf1e05655560f7e9c4778d0eae7a0ff31d8baddc3ca3f7f0c188ea3f9ab170f71b65bbd652e7c580507f72dd85e268330ce77b1dfbd8952b7f7d4667f73b3a01ee2cb4fdbc2dbc155f7210db8ee01e5eb3df98fbd877e07b6914b9f3d31dc97b3678e667acf1755ee608f4e478ee2cf9f1ef2243ea2c99ef99b20cec2decf07779bd1fd67cfddaebe3c9ebd8933174fb3f64db8f1fa8fd1aa5ff8c37a8bd792f639c7d3ebbea099bf6d769b6ceac6104db7bad95ebcf38bb7fd6afb99b46f6e9ce59b0dfc44da957bfc44aa766cd194a887fda33c1bdffb4caa7c95e561fef99468823c24abf2f0e67e57aeb774f3f61de9577e107d4f7218baa9fb29b234399af1ff6c86760c5c186edee25d94fe48e695efff50b66ea67c366feefac9ea33acdd64d832c90facb8ab347ecbdd6dec3f849b60fbd04adaedbbc99018fe448a07f7edcd2d6b997d3fedee6d7539316fa5a82547b4bae4dc8bc4cd8a7763cdf75fc3bb1f1eb6be9b65f734129460b74956d93b9fcbfcb21b3fa0cf442b98afde1efce80de9c99f4c9d6f60f91a43f8f7b4a536d566fb8944d772ec3bf5ae4a63fe2051b762aef6f1b6da567c2a7da5ebbc97348745ea5d4dcabbc91e7cd78f569f4ebc819702f37e62a487e14df467d36fde5277f739025e660ae2d7d7efcc12c6bb38cc366fdfdbbe3838a29e7d6fae2c581dbf33cfc65bff404d48c4fe48b66407e3ecd3b936de7ae5df9dc997a97324e2fd0dc48dcb7f2cd783efe6ae17c37857fe6001db38587995aaf9a9ec6fabfdb594bf9f1cedb8ee6ffd2e53efdedc6c9b579b8fefcbf0506dd0bf3fdff77045972b8c7fa0aa68b7fbf43077b95a31e76fd2f443a178a380edeaed9dddf73bf9b6d1e7b6d39fdc7477a692efcef0106c761f93fcbdddfd5562ac3a743b948f937e429a5609db1dfdc749d3d55b0257bbb7f8231a5e26ff3c31af727e46e8dec85433e1eb9b9b7e7763b34d70cd805ef1faeac2cd43b4ba5e6dc24d25a6bce2b5fa719e204e03f72ddea02ac28b4f6b6f95ad70636ac3c1437c912259ede3cc2bde9215e2f0ffbeb5b27e9729e8bafd97295ae2a56ebefd8c5de953b6a755eaad821fb452dd4eb7dd059bcbf6ddb1677529b6abb730465fd1fcc0932475777e9463abec59caa39b9d4a44f3ffeb86b5a8de40370bffdabc850fc787664b0e3787d7b8123d373efbee76c7ddfb16b97ee432d4bdcfc5db7ed55871de4fd0e3f77805833be93bd3d1adafd7569e5ba9903a4fb3d4bd2e6def1262bb8d1edea323fade1923f0cbffcebd24787d277d926d0e59b4a9377cfd44684e7596b8ab4f5d5ff179ca8d14f9dbe6585e7ed896db87d571e5bbde551ef4a953f0b3adfbba8a566e2d462e1316193652b556d6387bfd6b4ff5df1cdcb72ccec2edc5ebce1c1bb998d2e8cf831bc0d51bdbbc7df0dffcea61878370c469b5e4e1bfadf25f3db52dc68ff532507d5ae72b34afcfec432e3c7be5e745fff135ddd576d8f655b6daedde5c6c076edf6db6d840d27f956ff0feb067823ccff2b67a852b7f07e3ddd9eb6d9c8570f50ae3303aab755b6e7d17423c54ab6c7feb533d02edfbdd6abb839bb3de5d0c6263ffc6dbcf1fb183df49864ae94c46efa6daae761fa6d9bb300edcfa90eb93295ba1f1095b7d45a4b4b2cca33f0f5e1c763f7103f1efda1c9c56067bf4e7212de02ece5dcc22f8c5b762b35b05f95b9ced5c0f8b9c0cdb95d004ac95cfe627feafe1a5f6653358f53b34dd9be5f7e2506153cddcea57b1c5435a9f2f5c9f37606e3b3b79c03f1eb665b6c356d5eb9308bf3ab5ba3897689e3b0bdf6e93621bfcd5979aa457efb7e5f6ec80c3df608ebe3aea407fbae26b3e6f8e40fef54791c57eb58daf7f3d14bb57facbf9f3137e446cffc7bffed8afb260f3f6f0c1c2f58954bd25e3bdd4f80f92329f4dd718f4df4bdc5f42df491755ebcc3b29ae57c777127fd063c49a41b645ffd2d5765b89e77b095be60f0b3cb93e4cd7ac5cef25641e22b49b7e27551c64ee9dcf6805ab44ffadaf5887ddaefce26df5e0c541fc56dca5164e8af76faf9bb7f4bd440d8fa2023f932e43e5fdd74508a07f9f1f6fff7791c5bbff4682ffe641f7ddcfdd91f7dd24f5e1f7ddeff7ded7c7e3e7dfffeb226cd1bf3f67487f4796a3922badbd9f082d0cf9eead11985da2e61095444afaf59192b66f7e1725a90a58f50fe3ab1e523c70ef5e838a52b4282bee17a2acbe3e32f413f5132156dcdf81583dd12ccbd14f34815811881581581188158158118815815811881581581188158158118815815811881581581188158158118815815811881581581188158158118815815811881581581188158158118815815811881581581188158158fd4688558579fa0d38ab87b5bb77df075be1140dd88a617f086c75ef3ecd4f80ade8166cc5fe5db0156afc0f83ad9e1e39967de41ef9ffad176912b015015b11b015015b11b015015b11b015015b11b015015b11b015015b11b015015b7d9c8f80ad08d88a80ad08d88a80ad08d88a80ad08d88a80ad08d88a80ad08d88a80ad08d88a80ad08d88a80ad08d88a80ad08d8ea3f056c55019f7e17e2eaa1e1d0edfbd8ab2e5903c07a7afc85002c9e659e9e58a64560317f1781855affc3082c9ee658967de2be120416416011041641601104164160110416416011041641601104164160110416416011041641601104164160110416416011041641601104164160110416416011041641601104164160110416416011041641601104d67f0402ab0784fafd58ac0725cb8bdd5f1f87c4eaa56b7059f4531b19eb91a1fe0622ebd585db0f21596c0bc9a21b4816cbd24f4f3f00c9c20dbf83c97aba83c97a6c3159dcd357ea91e268f67f2b26eb21d8f8db4b6056c78bf5d7f7a0571d3eaa62ec1a1e558ff3393eaa0f78aa52b732b27aac501fd5efb395a07b75918388b8ff1811d7972fadb4fbc397a5b5cb4899a30b696072eb40867b2f9b7e15c3fc1098ead635a7a1cd1c239f9d86bac91d026b11ae0e9bb1220aed7783d54ad7e4324586853f02d44bf57db0641de8676aeec8c6edf4236ddffc1e8b092a3754c441e8a7800a2cb5504455f532810e46db5811b763f4adfe17bb555b78b554c27129e4389d387853c4c0574b3f1cd76555ff025e3da1fc022f66d4f88fdf23df5f8adde7047c3f617bcfec13f50b25fce3cf93f0b8e144c213094f24fc3f2ee1fb82e3c744fc92051412e1ca683b16e341e88f40ecc970ad4833ca4f61e134a2f6797b6709e00f8ea546b88ef5dd3474307aaf0c50fa295ffec465641e58da21b0b4af4a3c7843fd6a9786b45ab2e6ba8f9698b05e56c27139c82cd1cf2e979d8928ec7d1994b6a5e51ef3d82c3ffd77efe6addad12e5bcdf37b7950dff7fe9aca50db1bdaa0b6aaf42153cbf3fea82c95bda0fe8fa8f1eb62f3ff7ed352a7e3e4224a39c42907790e631feff23fb1007e9cbd8d08fc95a5bf6f5dbc77f3faa7d645eee7ad8b55cbffc6c2f8841646ea530be3ffc4dbd7c9c24816c69fb6307e2c503eb55ce69e25ecfd6c11faac8696b8b522f3a55372277fa4e65e1aa47e2aed1c2bd8fbe9b6b099e33e3017859381c266f1d250bfd36090822210b9674fe669670818c7e4a8a5094e3eaa1700ca358fa74902872f875f5c279ccd01509fb5e576ec9af4c163554a19cd28b4b4d968994bfdc26705bcd43a991a7926603d567d9ba4b3adc78264923ab497ce28d7e48be69d6339d0cb16c5a26a8784db31a4a1cfce2287012090e1d62fb9a53104cf2001ba41c1f972fdebeb07863ad68c9981d48eb66e398f8274580468691739008cf331715389b1758e46659cd59d74bfefa73fee1d26c8bdd42f96321a8fc35731853b5fe6cb4014bed996134d32342e87c293f9cc6190fac54d3d26c81c4be9a77d872eeade631785517f5b58c201a973b5aaf25d65d816a03c66b6f752277758503a3ab7ac7950f4189efab1b2bf77dc22689b1af41350f8295cbb3228fbf4f558359b64b303565519a7b44d1a060c5fba25b7c67c2f72dd9c8e39d63195666c15c79412c7522b7e38f5f8efddf9c617810c1e03918bbc94db07b2548fbf0a6df3b33488a8603428f49146f94dff90bcf954de868f316fcc1c6b76b2cd00221e5e48351d28347e9ae08f84ad6bce2ad5fc86eadff2489fdea3d979be58f82a8648bd144ad772a240367a72c9c9bd54da2a43ccd7d08f85e9920a461a50c2b92e347c5b380ca096989f41391e34561aa1e1a533f9e453d2c1978fb9cd482d6fd8d6ec344903180cb9c8338dcd584f9a36d1767a4472e2548dc3340c523e774461679bb018375b187a1728b2543aec3447db1c5c7f4bab8bfa3295f6e2e8fbda260a919f06a7f1b2b638a1b60d05d131a5e26c4b35ec787edeca23e3a9b6b2fd3911857adbb2f853198103de6230d2c9d1a3b376e832881c19949ac995ae39db3896123addefae8f23150623507ab1b05344eacff6bd38082f782f742f9ee7ba703e3f4a2ef5537ed7ae1f7ab4abc6a4cd538d4bb335e9c6b9e1092cd3c6c3235a97b69304be68c9d3b6b5f889c2b3a60baaf39c7f9d8e28b40dda0423edd0f4d52fb9ccb134d9b5d4532086fd2d53a80ce1f0aceee171ae518164c4dcd663fc4d2d6b0bdde0e465790895a4da022ac39984f8c031a7214841e933680b5bd73fe85b130797f4c13cada5b0f4d9c5c6a00569413b920167ea927acc2b3ea8f22d87fc48a3808e657f194db18c1339759938f38938881b0beb82324283e1693f9dc1976c7b78d595edd9b6f55d7a44cb250df40565fc78dd2c88dd14ac83e71fe93f10f5043c0331c9ab2d7ccd6375f9cd167bae0b15cf4842b4328f7bdb5c6c7ea4bdab93c02ba2b26daccf676534e68cc6e4200e7845e66050b673ebac4eaf4e3fa9cd02ca33d5b4b7a8ff767cd596c99d6dffe7fafb63d3e819b7ebedb7b36a43db167188da4e7bf2219cb7166faef94b7974252316584684b9f2bc0995849b2b434d00c361fcd25ac485d2b134da4f1fdb7a9b6faf1fcaac6a6dd6f0daac353241f23235b79908c9fc281869a56baa742083933152f7410a13c75236635da869d7d56f5b1a92c9716069d02f07bbf945fe3ecf4fb2190cf0fc9c998ea59e90dc1c8bca71b21ec4e3459f3fb9936369aa2346585f9ba0f532d5f61e004037169bf3b4f85f11c8fc32c032de4772ab2f4f0a9f01543317c7a28ac7f6257eda3b56147996b075746eed31d43eb0848363a96bdb9a4125be2e038ce0c1d1c3d866f8dd2453a12347512072a96d4aa74e67a974ad4af7d14e4a5cc9b1d7059e47fb715ccda7718ce5f13690c310d1dd667635ad3661f377d1c8fb10f7f7dbe4f08975a835f31d5af3da3c1636755d37c7d01fa97b3b35c2c9f2b135bd29a2903bf160a364480fd2722f0527bf540ac79268db3c9ec623a1f418158ef5a497a7bf460d623f0591334afa7ccb2b32d8fa8c11baa61d8e4575eb223afd40d99e0c194757bab93ca242c73c9e9cb67f832b13a25e9ea5afd754aa1e9f9c17c3fff7cbcc6d0d0cf283002e5db2f618e9cb0f0570b967347b3f800bfdf5cb234f7da17e5e0417f6cbdf89e0f2c4b32c4b33dcff56931989e04222b890082e24820b89e04222b890082e24820b89e04222b890082e24820b89e04222b87c9c8f447021115c48041712c185447021115c48041712c185447021115c48041712c185447021115c48041712c185447021115c48041712c1e53fc6c7a74337fd8ee02d6ded0f6ecf97287fdbe4abb75dfc1132eb4e9e369e0bf5f44bbc1a6b8416fd1303baa09613af46e2d54824de3f28f1eec99c9e1763edcd73dbc34a834e0a0bb77662efbc0539dd6301e558caf8ddfc99bac75e53a9bf73ace8e0a7e054794bd09b1a117e32cb60ede834b5b204a8d2bf24e60a5a9edf97ba38451733eb17426119ee2bcd60cc6b2d68d9bf0b85a5efcbd9bb50d856227ea1599679fc5c5495ff89629620610912962061091296206109129620610912962061091296206109129620610912f6e37c04094b90b004094b90b004094b90b004094b90b004094b90b004094b90b004094b90b004094b90b004094b90b004094b90b0ff09b8300c69fac5f85754e7c3c7b7789c5fd4c1fe42b415fb4871344ff33f0f6dc5dcbfa6f063b415cd322c4b7fa56902b722702b02b722702b02b722702b02b722702b02b722702b02b722702b02b722702b02b722702b02b722702b02b722702b02b722702b02b722702b02b722702b02b722702b02b722702b02b722702b02b722702b02b7fadd70ab0afaf4bb30570f0d877e1061b04bd640b038e61742b01e994786e3d9af3fefee57d4fc1f86603134c7b2d4134f2058048245205804824520580482452058048245205804824520580482f523fa0c816011081681601108168160110816816011081681601108168160110816816011081681601108168160110816816011081681601108168160fd7c08560f09f5fbc1580f3a4e2ea294439c72d05dd1881876fbd7c711b33e59461b53eb0bcffe926b626b30d7d3cfbb26b66a3ab92796dc134ba4e33f2d1d3f2b9a7a97c7cad2da65a4ccd1853430b97520c3bd974dbf8a619e7b96b0f7b345e8b35a14c870adc87ce994dcc636e9b59f8253207233dbd2d6ae0cca85353b39964a4d52e9e433a00c246d635b8baf620a77becc9781289c0259a25c731a7aac9a4dd228f2cc59e958336a92d05120cf368ea59e26293806a6b405f2d30fe4e5f6c190a33df968dae6917696dbb16bd2078f55296534a36c4bcbed52d8fba95fb8b2b4b35915faeca2589a12653311f4b369e16560eb494ee48d007c39dca5c1c91fa9b99706a99f4a3bc70af67eba2d6ce6b80fcc45d15db2fb58bfd36090822210b9674fe669670818c7e4a8a5094e3ea23d00946b1e4f93040e7f799d703607407dd6dea1557341b093a9916702d663d5b7db970d57ef1ccb815eb62816553b24dc8e210d7d7616390c00810cb77ec92d8d21780609d00d0ace97eb5f5f3f30d4b166cc8c5f4f73cd3186c6d91cb3197e37499dc86735e867d1ce13b96fb6397bf3197c897314c852ec9a5c3249f8d84dc13a18d2913f12a0dfa79b9c47413a2cbc14501308747d79fd0d5fe62c720018e7bc56cdab9cf65248a1bfbe0c29c7520adb12f209d4d03ce9cfc777c64585b6c99d505f6c56dbfb5952d8265778155df75ecc0981a5ed0306968ef9e932f71ebb280219cb9cb5c770946345d404ce0e7e0a0b8742df3503c983ab3e65751ac6296d938601c3976ec9c51ec353930cf7abb0191e95fd1888dcb21e6f117d07557d9663aa929739b99ff28567822278eed3f51d3e49f97d20a2b6cea84916403be6d69e0c316fe2b225247f34c34165c9127526afde29d71d69942f724a30d20eba0c224706a57ffaaebc33c7d4721b689c2f1b9f1c83880a4683c2c0f2199c822128021952abef6bb3ee58b383c77027c7e8f28b897083eed1da93f15a72529ea9d0a8db7436a74733c11f095bd79c35bc55e5290f63451c84ca288076028a2085a5c7703b341751598001b166728c6ba97b2fa5f1781889f4a20df999450b73032e723113683b3d22195497d9b6f16c6efb9474f0e5636e33129641b8eda369b83a6c4265b00995a1d0e7f7b1220a881f19dbd2a02221fed3104d509f77be7c8c02d908f1dafabc1d8bf1205c0c253a9079d6b554e8e0f22ee67f2ceced348736abcd6c4b38389612ce75a1702c3f5c32ea37c79c514b13b511946331f92a86b84d78aea0f2fd11883d24ef46cede3517219e6312c0e9178c74728cfce4319cea65021d8861ae8cb48d9ff2ac5f0ad24a9e417f84e51fea6f45f3212cfc11a014b9fefb4c855e0ad8e67ddb067110ba267708ac4551ff0de7fa207665b0f5e4a7f8a52d0ff19da03497cd2bf20cb63c5f0e7845e660500ae773a10cf397435587cd8036ef249512478cced79df8102aeb61311595f7f2a89a78080100aa2672a56d7289c7d058868ec5a46a67f5af08647e19603ef137633df98a68ac88c2da3122689b1ad6316c534bc6125e03b68aa8ae3d862afc1424ae2c51586e5ad3760ef6658812bf575ebd8eeb8750a9e6ea9749c96f3d66167972b4f7d9c59797e7c1e354e469cc37e92cf219231e2fb755fbcfe8ca458ebcd8183410f5043c03f1102ac96cef650e447235909f4280794d7db6ad19c4edaac7d448c1c997f9c26780e4655a1e8c922783d5705fe6b150b6f35f1ff088975cd4d74a97842b79b6b191dcd1c31e4d05ddb1241af55f3339cab5346e9209a83f1bcc5712d0753d8c276cc5b336e2595dc9c78b4dd81b173c36b59c2f0209cbbdcdd204896b4ac6ca12e0249116c6f0a82e28c9d00dfec5a2f2e5927acc2b7af7ff719b8637c667343be303fc0fad5bce28d9d4fc9d4f06bd3649330aaf4b6523b33a1adab52e0de4280ac4a847332e732c6d8974e1c09a3d7b8c06aff82f95b681696cc6fa214474b3cda3e19561397d1ee4ed58b7750bb1c7681c9aa37e3b6e46e130805aa47cb2d27bf3e8bc4d38df4414d0bafe1298c72d68eb6d79741e581a9ed71e0ba856165cc8a44986f405add2d7f5badc3e9d863c1d8c90ece9d1a92a3ff2d919f433cd40f3662c37e90ea197f2d4b2a7c78fc5e45e3ff6751b1b19b455e476ffb151d2087af271afc41fe7f75834a7aa3560220ad0b740e449da7e2caacf1ec331288f32d2f64a5fb6223e6de7dfd9be69d3d06c9276fdea8d67ac0fc174397c8a7bf4be430f0efa99baf7e343e8dda2c9881abf2e36ffef8f9f6f4ac3e758ef1ac1ea93aeca3044334f3fe4b4f8f885a159ee7b9d16399aa268ee8969ed5c8f7fd76911b7ffc7bd16f94796a5689afa8c99abeef267cc5c5d52e2b548bc1689d722f15a245e8bc46b91782d12af45e2b548bc1689d722f15a245e8bc46b91782d12af45e2b548bc1689d722f15a245e8bc46b91782d12af45e2b548bc1689d722f15a245e8bc46b91782d12af45e2b548bc16895fce3d9cd33fec9688a5c55fab20de6ddeea1de5bbc8aaf3a42dc48a65becf8990fdc2d0ec97ef7622acc155eccf7322c42dff353e84759f3f03aeea92121f42e243f83f45565dc8919e2f20c69a635c761998c65884db6fd622cfbd54835ea6bdfaacc679b211ce75e1e4cbd2dae97f63e0178ce97e56c63613457e36835559807262ea51ccb4d235e9d760a446ae79ccbd34780d98280f64509585f2ca4ee48d66504c61516161f9d435b9c893f8c2b182ad6b725079a6422795b63e638cff21cceac35fdd29d5fb42b67f9a55492696e77ea5847dfc791216b79c485822618984fd0912b6930c9d78d587606a88dcce19e4946da999632df6623c2c3ccb29266c50d6ee5b7bcf9418c77cdc05ac5abb7871df6c4b192bfae6db849d9576c9ef6c131693123d6b919f0630109ffadf2b97c38bef623c5d2ba5b004d23454cae95a8cb9c81f69af0e030ac752a3400689d8b8d0b14214c8e1b873e38407dbd23662cc1dfc94c72e1c62cc9d1c4ba35c93cbfcc3a675595aa420f2b2e97892cd28ffb4d8d98cb47665a3a95ff5320d7af231d76341d5864050c4e95a396c0ad7d4a0bdd87c9ba490f50ff8efce1be0bf073fdc8c519b9521078361e5625ae7db7ba9dab66982da603951201b7b31e60b3b5569d73c2693c366efc8f084e83061b8b8fd5d72851dd3999f4a8987f274e9a371bcd9fbacba9e3074e49a8f7bf46c6720f7643c6edfc6317ff2d3e9be724b7d42cf7160c2add3d1da344a01bbe9347d0cb2d91a3d4f0eff98cbc5c35fe93efb60e14229dad022f40fb95ddc5bb83e70bbe019fe0b87969a7add62ffaedb056afe0f7b5db05f7896e1d92f4fff5b972de27541bc2e88d705f1ba205e17c4eb82785d10af0be27541bc2e88d705f1ba205e17c4ebe2e37cc4eb82785d10af0be27541bc2e88d705f1ba205e17c4eb82785d10af0be27541bc2e88d705f1ba205e17c4eb82785d10af0be275f1fb7076e93efb35ae17e93e7b38bcb9795e0177ee63ab9a440dbc8affb1a8b63f06affaf295a629ec2b51c3ab98bf0bafe2bf3fa86d870a7ee41fa947fa916508bc8ac0ab08bc8ac0ab08bc8ac0ab08bc8ac0ab08bc8ac0ab08bc8ac0ab08bc8ac0ab08bc8ac0ab08bc8ac0ab08bc8ac0ab08bc8ac0ab08bc8ac0ab08bc8ac0ab08bc8ac0ab08bc8ac0ab08bc8ac0ab08bc8ac0ab08bceab7c0ab5ad4d3af86593d4cddfd2a33ab87e7cd21831ba405fdb576f7eefb10acf73236b0ac47fef1d7c4c2ad21593f31166ed5f43ba02cfa0b89d54862351221f76342ee5d99d345729c949bb1226ec205c31f56969a3b4c4429cfca61faeceffc910a7d0614812850ae6c841e8bbec3c2360fa16d01ca95f952c1ff243a90a3bd9f4d0b311e7c43ff94e131b71950f80c489411281c1994ca48db38ba20f8328ea2182e65b8764ceee4e88710a4a0f419b8f7e24139590fc2314e3b88bb344afe72d884e358e03cd6083d53e21499db07a240fb8c11067294fba590bae6112a3278b41970084421f76261ed31f4c19361e4a533a88c823c9043941e766d3470bb1509ee035dd8d956127a8c4ad9262c147918da8836bab077e28a0e5d9b8428186cc27188da35081571102a72440523e1f4123fed03366027a974b0cdd9c6d1b9bd9ffa7bafc96b4df7cb217cd60c6ea9e914ea331a073c16c0e4b68e353b2988fe16c8fd14248aac728a2c1d7c19b5598a3d341eb2c4d6f4cffc1440471428afc47d66fd14e26896135138798c43058c543a0b4cbfc4b566949fc238b0349487f6520dfad77d43f4bc4cbbf76221f2e241bc00d35007d35819aa8241c1e56480cbb674a0294b1a188a140806548525d4540d4cc325ad840b8a7fd186d0d00dfec52885b9160bc21226a14ec1174d3c848e092917f1890c1e31efb1d3d06395d035f1f841477cc4f43118006b5e9abae60c7ad90c2ab2b36ffae0b302b41998bae614d1a8705810398c113a0ccf38965a20ba282301fa299dfbec2cf718eea4a074551fb6ae49e7812c51aec9177e798f3eb82d7b31853b5fe6cb4014bed996134d520e06e2e3b797439e7b96b0f7b345e8a61263eb5cee9537df17aef954d84c14792907bdd1b418afb763dc6756a514398f8274580496967b22b7f053fee0582ae59ae0f472d88cfd1188114f29f26c6b239e19d251908202341157136d1f30dcd663a4c4b1947075403c360895511b5d34f4592d0a70194eeea5d25691f098174e295846222d8c21d02dda910c385397d46338d707f1547ca4276b3b4673129537293768dee3dfe358183aa61305e6915224a02f2bbe4c3c36283c998f9c469edc8e0e1b3a99baf7f443e89a76e8a54fa1ca747d0096ba554bcc9b073fe519d7d46abec0757f9bd4edf1476a1ea412e5e8c2a91acb69e8a495ec32580d477755869aa42512584adaab36e4ad65729c2f0ced150075aa3c53a1927673d94fc1c12bb99d6d39d08bb9a8966185c7aad984a9683e8df9dc2b79ca3677919f2637a2df3ec50d8d309deed0775c0ee2a6cc89d546d3dd29f1e04d91027d01848506d4579000dda0e07c89de8b4ae1a652a9acb7e3ba8efd38deb47451241c05370ce4a74af6c957e517fe48ddfb32280319c246964e44817565b8764561e79ac12610913ce55ad9e8c83ceba5c7bd6d6ac04f0f615bc628417575f58f0096295e36a31c534a14994feb399cb4bc22f34535af7e642c690124e0c5a23bfa18923a47b40543281934bf58004d519ea9a6fcee5fcced82f471df8d135f8f33cdfa2992b9a09c6442e9b102f4332d77ac29e2fbba9ca76f48fe57bf37a181da8769064a477f9fcf03066e3d518851bf507d95fcfe79fdd71349b7684100c3309c2f36e145bfe3494a335ecc777dbce6b9f7796ac8459e69841e63573c356a69c429a360e39ab38d329a6d3c166c9daa9f74a50f687b45c6b2b844f3f79a0fbaf9ae8c40e989428ad681aa8eae6d9dbc79fa1e99b630121ed1c73001ffb23068a94fb376ee674d3d2ae2eb6ebc47026da7c7dc2ebbb108523e77440147b21e77f5447e1a9c4c9aca95d1b6c773c27265a13940151e0b28c457aec9519efcb851622ad4baf984d61c544719c82051e2e46b5f766829dc3aba10dbd60c6a322c1d734679accaa1b67b296095a1937bb2b1b12d35f3e9edc1d2cff31b2c3c0532d84d529e0e44ee80da1cc8c7622c2a3b450227cc53b21a21ddcae995ff120f6245dc86762a9d1c4343bac93a90f972a573996369829dcdf6de08500ec0f2663346f5867dde7bda2b43d8ccfd8fe659e85851eeb3da69220a6525372085d76a5158bb3258bba5903bb190f7e5925f0a9122cf689fd5f6dee2a2eed1d9b886be2c95b649c300d5dd6f6745bf7aee7256d33ea3956f50c6bae625bdafe872089786646a06f70a68553024413220dff2a06e80653d47f3662dc5ff3a3ea2513be7ba30d40c4700c6d1b0286d0e286ebaa4a4a145037df97cc65fb91347155d61dbd7566f5819b89d4543d7b1985cf0678fbf0c58f823402119e398d2ae59335add0276f3fd667a449b0c6cbde7ebf28391caddaab7d2a17fa09e760c80ea65021d60fa81c8d33fa4c539dd7bff8cf3f5f06e3948176bdb209df1ef66bcfcee3ea27cb59ef451db2ffb7a3ec77b3cd1f0d0bb7d98a4010cbaf6736349d09734e257cdb1284e581aa0cfc3c0480edb4a3edfa8774485362351361386e3219c6b56b4762c01ebd48a6cdce4b99aef399fd5a0a773fbc05a209d24f7326debc5613cd151bdeadc8805bc36601925fa581e7d728e61dd4a2d951b632ef0cd5ae18d12a427dfe48977f9f6d3f3ef72dc06d15c178ac03c6ec7ba70670c7f7c7e4cd2d9d66367707c6b9c7aff5eaf7584eabd2eac6d4b5bbbe260a31bbcb49267d01f69b9c73c868e7e9f563d799f79295f3afaa098c48fb76937bad6cbceda73f6fdd36b68eea57eb59f586e42ac3f37fc7a4bd6b3804274abd6d601afc81c0c4a01cbf9315e0bc1d0b55458dd2291140e03a885a99e3ce648073258d896b6198bc9f6035dec9cf764988e45691f58da21b0345c573d0f233f054550af2b639d832b199e82d114ada937688ef82e8ccefb80d7e4856da9d0cbaab2c7625278e62e712df5aeecff601ebec3fb8d3e4d851a5075b4e7b75915da56350e4ddb14b9bf3e0e323c2e324f072381aefb8b696bc852e9985cdd9730c774194ab1cff0dbc0d260a56b87399aff4aecc7b764edcfe2a1407efaa2880adab35d8fd58d369db745a0fcece698757be26aed92fd94df211d748cf9f470c19337e6ef3bf252c3fba99bb2aeed3bd20302313c5cb49757e45914c8b38d2246863b52f7416d73ba3ddf3fa0a5a596487f77ce697a73bc1cbdd645a519659bb3373052239b316eaea39d0e0b1e5d6bb1995ed0a719fbd7c53b368f91b377cd45bf6d785c35243300d09762b40c104d110f58eab6d96f4dc44a2e28b2067d16f5a7b2178dd19e0fd18b9d86676bdee852471b6cbaf60748ff2c82388c97c07901340f0c0ae8cb449a69ba922be210c922da930fa11adbe13bf9160b305b028ad735f12cdfcd79deee1dd1dedc520ba407233de6b3edbac1576b57964a93a6905e7df2d960efa70ba47774fcc600ca3139662caa339070169289063db396b43a54e2a40864fe1995b1b0d4d2b6929be3bec0b66750a0f1b32d6def57b7f7b436a77125b785c0d236487eb826e2e5ff9fbdff58b21e38b685b1074248f06ea0c186f7decfe0bdf7787ac547f2f0f2903cfa19ff9534ba3dd811dd281412653273ad95bd8b7e55f67f8e5536ffbff0e8ff9043ddf948437f705012da7f70fedfdecff9a7e70c57d6327ff3bbc65720f49bf07fe1c7fff8e0e54f4ef49775f2ffc196bfae556528fef88096399328ffbf785ef30757bfd9281c897bffe3d8ff8fb9edbfc67a86fe671ff08fe3f0175c2c15433c194bf1d783f3fe62d7df7dd5dff1ca3fe1cc316812f18fef08d8327206fbbf784e9679e351ff6f6df351e9feac3ffb1fb8d03f39f5ffbaa7419350f9d2c819b43ff95488ffd99b431c427fc599ff8c8ffdbfc594bfe759cc98a1fadf6dfff76d9a3e890c280df1bf8ded7fef3719e9bfe6c9bc31c7217e26e1fd273643f9289c39920c799fbc1902cd7fde45637fb7c6327a86e093d6c34c28d0a1ed3f81e3febb3eff7d8ef6977efee51a43b3f542b3f5ffebffa7272ffd5d4a1ad3ab9cfe1f7ffbedffd9a5ff17df1bf2afcdff4baac6211286feffa955ff7ff154c1bfd9fe3f89d510f67fd4eaffa356ff1fb5faffa65afdaf3ee37f69d43ebf730c63fffeb8c4dfeff793eddf3fff287f3e3c3ff06d1756bc3ebe7e3763bb772efff5b2fcf786ff415ffe3ff7e5f982e9fa89e0c3f6e9f969d041bc7a773fdba94a0665f9c855ebc0c9d66f6b67b9dec3a3115dd5a6f7de132d01a18f3050ebada02cf0462faa4693d876aa414c1b8efcd4c7ff0d93e3ec69aa0b821417f6d0d4d9cbbb5b8972afd7cdfcac0013f70a8e4a4663c65f63dba1f6f1b52e89f2d8935dada6d10d8f4480688aa7bcb1f964cbf16670d4126561ff3ebb72b0db2a1ec66b8ca6cd97374f22b93ef0d80ce3ae0a96887414672029ca004cb909831ce2187f193797900a3dadff0cc5f6b3ffa371b3fe79dcfea67bfcefcc45f23ff59986d45988c21647caa2ddfa9fbe24f6aff7b07fbf5b60b4df6dfbbfbf84d23f57f87f5d38f7eff7e36121e0f9c3f571f1ef1a08325cdae4342922bca9fb6ff4a0ff8d671af6ffcd67a2cc95fd051ffd2fce4e85f643dd49fd237518e2ac40070c55a3e64bab187dcf511d7e0fe5e3b1fd3d1d556337c5e30f5dab79156fd37029b36568f24168dc5e9878e68fedccdde807ff13cc3f53cff5bfdfefcfdce9bcf0fbfd4947fe98dffccb0bfd59203fe62ff50dff1b73adfdf9f8ab9efa5f351314f7579beabfb6a8ffabe97f6013c3ffdda638629a186986bf8ff3ffc6dc897fec16e93779e9ffd280ffbe26ff41e7fdcfecb6ff8ddd9cfe3fdbfd0f27abda237d15d29f9c55b8bd5058b2c180e2488192483e63e46972d40c827d407828f7af381485554d985fd6c7acd1de8a2c15d14ffec5677cc77c2d3747574362ccb1c89269a1732ed1d96ffca7e00c1e9d413f062112bb16d930e6fb6160afe12a956ec1ee26c9e76ddebc4e4b501400b901c4062d340882b17ff313358bbfec269941431ac2c9a9e80cb27020dbc5ca38d89da30c69238d9f89fa8e9d73e40cf6b84354a8ea846ebfd5259710da21818c96b32f73c106d93c7696b6d3f9c8a3ee17d0cbe357835c0340ebafae5f52c7626501f661b2f26b9d2677b99b7e93de721cc2e386707a7e00dfb373a645bf0b5354ddb67324f4316101b58cb75119f9b888ef022d4e87c813548b8d3a16a6cbef32559dfd3cdf611a442b9f0485464ece68755bee5a572b837a586705524161682fcb93f2348e55853926ce636e9bc7febe0e7872c64bb5496fcf5cf65315d47e560ab1e38616b7592d1a7a647c8917f5f7376df0e4a65443a297e1a04b6034967c74ecb5a45021afdd69f2c78b7c69708ac7ee3f33cb31901631e7db0342acc7f2256b91feeea6ac462310c7738d60f4089dd9a00a4a575c0b057be70e1b7c9e309362bfa228c8864c4c7c3e87ae3c253a4f36872c47e1e1203bd27c57cab54ef23488325e48a382d9eadc21a0ae21acbbc9e008ec59ca9b6e09a7e8ab57fba4ac14490776b78ca241aea3747a0fb0dab9040adc2f5418acd4a4153f6a3f85e4e95fc710f795b7dd6a64dbf9c41cb99ff9a4d5dee9475dc3988fb89ab0a730f86bbd0188e7a893be74edbe46bb10f0ad3ad0a166eefe12dc6901f9e13b91b128e63694302980242a0d0ced3ceafa78d7b8fc24c1e1fba32a60fe2bdd1646063ae5df8d87a73c2ea29d36d9783dbae18cdfb4a7ca042ee45bbd3811abcd297014dc8ccdbb572dc7597b5c78cafc0921a8dac732a11ebdb934282f6dc4804921e82b5ec73805dfe6c137db1273fa409ab1c5425dbd138d7022c9e2af286d1f6f7a23db02c1f9197063e746be9fb88723eff7818b80949aa7bf3e32622d91b5801d6b29a96e8d2a8f5c0c2733dc2c3f922870b18f6e29f2f32fa46f5075aa58e7e0803c109f810ba0390639baaa300d790c92566b83edb40027a0389aef8798bd806af347f383d6044e90893c432a22c71772d0a96929aae7900ef9996a6d960e6093e390df821f6f10c369aeb069dcfd0548fdada1fddc6301c0614060314c7a8b184e90ad8c3eba2b0685af22ee43e066100dd1ed5aefcef14fe485825f66db07e9f2f4a97a075f81df0a63d82ae1dcd9b2d41882b49c36fe281bfa5b9ff429a718cb96d0be78984bdec0ee1de2034f9a2d86550136e0a754fd948d5a72b5e961980c0923908e138cf7f130a9b9d731b263f496f80de3f6c9272bb24d8013a0bc89427b9b0d45f30e03fd9380ca703a1aff807686a0b519e05f2c068d40780a7cb0868e12cc4aeeb109a413c41cdeb9288ed019049ada28047655a28a52ca177d8d2508330bd53e4e0053c31745cec354e53fd48225064a6a9436ecf7c2b6c1019fb5ecc06533990b766062c5aa6796391908746b3052e772080cbc4b69f74d4f54c798f23fdbfeb3404d78a870964cc8191267481099010c0da8eb0c84028b6e52663e5f0c85b3ebb36d2869795a852ca37343653fbdb040209c6bbe9bd1c46ac792e7871acaf3d0d311d24fdebde076c01c31b8a4493f4b3bd754465b647dbe5733ef16b6dfb18e1830c63379584df8c59eb637dec3217aa021ad4aec1a8fbd07e580342bc2b97a6385146e8ff70079e56e4f4b694bc9e72299429867b1e8eb497d25699c9aab00ec919b612807e0c31a4070ac2e9cac632f7b5d576752b0d98500a4f7083f19aa0e74feed7ba8b3311b77c1c71123697e829b5b8a685986c7ed8eecba37ffb4306f8f88ea007fc19f18dcb988f58976edff7ee24ffdcf62b0fc1fc560470cc6380af682ff6f3576bdeefeede4713cf0329ff26c870186232e27b9f2d3f9c2987e138e91b5c48d6e2035131ed516ec266801910d8b71b222a9cc2e17e12bc2af04d5542cea5725c94b07b2f19387e7cd49e3fbbecf4ac40cc109fab26ec6a70c8f1175d38506a4e2d09654c01bb01eceb56887d2192eddb083b6eac7881c54f52dd184ac51ad5f87236b1dc434cc7f56caf47c5ae64917f793b949a28519046afcf64c70837c26d1befe91968a31f9d9c35d9ef45d18f0855e9be2dabc877cfa4d0dcd2697deaf52d7816ed8f202cf156da5524569b0ad8b76baee2897a518573e98d09309d45cf2405b7aa04ec8a852f7d8110ab778fb7436fcfc7a4ca57219709c0b05c92b27e9d65ec15c77eafe8d144f89a213786c217204f8b16d23d665bb49766c8f01aefd126465ceab4e4827d68097cf0b67120c2e61864aac728e89c9b79948e5507231d46d3de82e57108cc71413d789b5d2cb9d1918c45b2335785327aebe5e21b68d9be1ba43a29a6418898eb34bfaacf76f259370b693c61322eb8c004a10b3a56dd256bdf748c7a6a452ac75eb8ebb0ac17ac120a108edd1848b52b2ed061452133d73978f5d6e7e1985cb0e90b656797b37f7e163dac940e744faa96340e955a3a2eae11cdae918822d7168e13ade5cf9f227927a0e2f867c986e4c456a2bd6d934d5672737b6262f4ce50b9252d1a348385e883cead035b20f9663a024f9887d7938333888ad0ca2e6cb4bd2126d7513de92e94ed611566ffc254fe6a2dd2664f7cf76c16dfd9ff364e6dfe5c9fefd9fe4c9f4df39fbff5ef7e4fc4d2f80ff5b7d822f2957290dffc2eb6be35f6b5fb7c429b247610439ab7ea4a31d74ddaa430b86d73568edba45cb507bbfd668ed297dda55210adf7786f6fb142e99f3d6d2d71e3d0e899700d6d277eca76e7e4ffa3e8a78fd97530485e33dbe83d7079379f563c8ae8d751e4b027f8b19384c2da3be311263b559a5b3236f829db2815d00fa03714a27e191139e72692fd342724323c472cad860ab8616eb20273b8e8d6575de9eb5468b947f427d5e75235337f0defe1ce1a62b2dc094b0ebdb26689f3b39d399b1e27ea1bd0b15fd6d64a4c103f0f0132eaeef9dca844ff045f716ded9a06263a26993aa11ebefc73615b1649543da9398ddf6728ae315409e17e10b0383e7ca8b14fc1289c26e70e1395c6b3837a81ee4e7b64ab5cc8332371492a7b92c1fc9224c0afca815b30cce4c5c989b973b8b102f21e251f49027468e79a07f418c7beac8cfcb967d092ad97b0b796a4f81c5c3bdc46bd2f57048a918a68b8d33c90263d08325a91b0f9d80e8080461218ed3a7664f1fa9808c220c83d1db8e10e2c5e4fc76d0004cfc9aa4643244d58996d7d065587cf5ed48f0bb1ca9a9e262659fbb410e91e08c557751c17a5231f87bc2b8e47c633f64f7d561c6b62fe4ea138b46edc366246b1d488cf1e90551ba1484b1c39d6bca88133f78a8b0eefcc8c8c4e200d5d17c2bcdbccc37b2211bf414c07ccebd7c0e9dc88855812a5e918ac7a7fdd085d4fbe604b8b8da6da568c9c4cbed510374e039fe8297dfe7a8d8baffb39d6ee65ff032ffeff0f2fdaf78f9bf38837fa8e9849c21190538931cfeef5af39fbfff6dcf0c412dc5cc158815516ad564621d6b4e5ce3d8732fb395686fc9eaf0caf1c3289ba901887fa37465f8cea28e1ee8a5682c34ade3b6b56ee2ccb5eb6218042575862bed9ba4ef492e850ec6a0699c244974a671bc0fb33860ebc9b92a11ac50120469d25a409c0404fe9795b220b6333f360f6a888b39eafda37ecbe90ddb4228cee6f54f9c4dae6484cae8d39899bc6b91ef4ff3d251cd132dfd293734bffd67395b61446e32543614fcc63c1feff32975d6c88eeea408adc8a30e20cbcaa219748eb959e81ae0c42db314b354fc1c2f4c7717e92eeeb71730777e39e2449904802502fb4aa6de81294b943f652e2dde131a9666786bcc340d05b6e0db02e5e42934ac31b6b81861fcba1308442668b77362b306d3b06210576fd8d15d5c50b3412812b5d0eebcdaec2943eccd6e683f2a6d9d1967191efe7998d81ab5a30f5f3c28ca07b71d921429596d92d295c315899be644101fbbd3e8d49bebe4a1ebe42eaf7f25f04270921712a9e5d5a4cf4bfe40fd98ac90e41ca64bedc0763fe6abdb4434215879d97bcc3fa265526d112b6b81ff9e49e610b911391bd27ecd597d53f707fc8c06a7fb339e4829d5b9e31363477c73229e9f69583b848422e78a5aedfbc97b8aeaf145e130e7b2abfc09d41db45c0e32e45831e3c35b18e7e673294075b40c5eb1bd737dcc9cf22a9ead329de9070ec79d4c48edb29b7052983ba886705574211ce592f18466e57640874e1d6481851d002642713658f88894d7c7d093fc188a70aaae89646bc94195a9379b8af05ad95cdcae5ac98fa89d41e6ee3a0635947f3024f547ca3f6220de37c19c578f0968ce22f2f419c93dc58a5b1a346bb07883c1354f6248e0d3e71b2c1c249687206950e38f2e5628eba85c732636953c5021c6096f7f62786e21082e2a0397db1c80f4116976270125e4b0e86f588fb9c56d4bd8ecca2a348dc4dd7026eeb42908ea9168627f69477a6714c1de1dcf0d00e3fe3270e27487701b4fcfc0dcc65ababd77fa21f6d7ec84f634b27b2320b8b7c29449627c1319250edc752bb8fcc753fadb6d0e10e6468bdfe52d11c65b600f9c4c043ac8627bd6f7c225f915281020cd25d4638cb593eb18a66180a57b84782c08bf026d2252cd6e8c0ed3a6338599e8b5c4e9c5f0c067a63f068e7e73a6fdb8de261047a42ffb6bf97b38894887b3ed7da9820e17cc53abac17b088aac9bf0823fc341ad4b4bff75e8cea64187836ff94314a84a137f375f03e22afcdeb66af8541d4c3845148248e8b2d1ad5e836aa9768ec578ed8b8145e7ab3d793f9e9368aa7c45946b97c8e1f5f0216f9d8ab2efb02e579ed4443db3a3435ad949d5bb0a1e1b9f94328decbed0c364fd2e1dd703781efc4cfb25c8c523e4583a2071452032ebb0303e6cf877a668ba2a0e23cb1d0e65e5485c46c31d1ce0392bc53c341a2369d9614e80261dc1584607b13d15c82075b0f5b8e0cd00906c9efced02b61f52790a7f07a937dd2e7192650afaf71de1cd15b1a5e584931b5f23c5a7f5d3eefe889f749187f1c53cca5042c7476a8e90cfe981bcd3bc8d067db9f093879422d9737c46f6844221c9a50c4a097a4ceb57bbc3d94d16b392bc62e2fd5ee672ec3a961d65d17bb9369c2d23c5f655d3e55bdf18796a418260bef5e73232cb34c04c88dfcee5a4fa4faad501a004de27135edbe1f4a33173314bfc88bbdb1dc158592b0d073e850b2d89c0e2eef6735d13ef0bac5691a7b5a891b282adaa0eea47d6ae389c90e5bf87dbcf3be991c7d62acaeae81398e74f6e841d2aeb1d4212d1db263879996d1ed695884de2164dd5a2eda805fb681fd16c067cab5ee7475e2a247b49a5497fdad2af82432d7a1f420b0ceefb4bccf0277c7441b6be12c83d86a65edc7ed53dbde29a088665b4238d07f7e1b065a408b7783592a4c773e1751397aeaf52feb8184ead2398499156635bcaaaf0aaa98e33792ce304b17365df8b84aa31587688ad4cb80137842fb167b3273e230ee96a02a634b14cb810e255aec7cdecfef0385efae213147d8b9b9800eb9def5bc30c6817f74a598c5ea2fd7a7dd29788f1c7d942d20f6334cdbcd71024af1a8407685aebc985d19e3bec15dec51446b806e2ca2c0a02c94fbe1f6d7f38bb92a1729b1a282dca8f09600f4f936c01f0c2aafb6d3aaf399fec50c9db2ec04ad2b2d5c4097602927fd032922dc1137058feb57815c559937b97c88a6add085d30a3d799bc6eeca8b43dc5657824fe06c218d641147eb687c70b317f5c3060359e812901a3dcfa1038e7c17de48ec64e43c925a3e853cb53678f029a4a7ab1db51d791f4a2eda727c8ea303fc823c07d9744b9d50caf2dcc7b437bac74d7ec24dc681ec2381d9bb58c23b370fdafc71b0f355e4317a670a76523426f251a39b1de4301cb7a755873e5b3a7892434d5a85afae9bd6c72b6d07578a5720021acc75f473ade83bbea15886f35d125f85d6b96df0be1c31ffbd91c75e525f6d977e71f324d62497570fbee5e51177c337451cc7846551fd85d22edf323d3656eb5878225e31d87f70b252d8eb305b92214e97835494abdae792feb879ab75f9ca39a26a1e17f09e90bcda53313e8ad2c98d30c5725d7d2ebfa210ec95738f1eb0be1682a0271f21772288966337d31dcee38c51cfcbf1a5be104bdc91449533fd14452ee94d3aa0bb37f811f8e770134b9ab3468b9254e534930d41d2b3b9f8a0be638604a2a192f2e36b6a85ea5512b630fa42d0328ec55268a00abc358172673fe44cc7fce485a81504803630dcf5e85d9386779220d9a57fbba2a2c1273695cf1c5470b2b8870e6dcc32732facf227a0d815157337f87e9094dc939e0f3f88ba4835db28ff05eb18dfa1c17b4b505d9ac9373c1f6cad757c65237e8a6105a7ab9473bfff0c30584de51a7e6ae53dc991487e2a26af592e0f53f8bff4b1b32d9717224c713f9efdd4cdf90094f636683c9e1cbcf5479d1c81140f3148bec4f3bd1c66b6399f4899f4707b16e338e92171b027ce74787efbb85029a0ee3818d724d856d367d03d163be20e8ace0306f5cbfc1acc4ca6619ff1c18afe4cb3c4e63e130159b622964c9d73313a09a9b2c173351cf784de79896cce2e5ea3227c63360f36bee4973ea52dc13d0f1ed4d30e1432c94ce5d01c5d101d2042bf64750a7a2e2fe1876f11b0e496e051dd5baa58214c48871a4069a72a45d417a2c8dfcf1b1422bffda65ad9593a69348299effd72b6419301d14a5bf3e61092d484bb9af7ccacfc42e08edc0de20c10ca446543ae4246a08b68c47b868eb9a1340292c68fc311c9671556dac991e39bd9b00f0862fe4e91e839a0c751a68b07037e1cd8aa80b8dc4408ad47aa8bf30614a44d9e28fdd0fcb2394aefa617ee413801e1da09bae604c4c107527c5d21cd787f161898a7fa9702ad51540e2fa390e3c4f28dc8c7b7c7e07dc6364d1311844bb87bcd2d48b2d4d3300eb8c30f68f8c9cdf959c2c85fe38c1aa50caf199213c9adcea3d0d585550b1d71204fdb250e36bf5c88c12d88e35cdbb32ee7f8b2c1ae67d4a303170c651ca5bc8ef2579df29700d5ae81da4c0227858608aaa5c12eff71d733c0faf436f095ecae61aee0e06db9fb7d10a46528259cc6001a7e7538c6aa5111f95a117b8cfdd07ba05587f4087ba5fe89e93856779d11a1828d002697725d17efa8f54279b14ee8dd211b9110abe032238326c61886e65958f023aaafe4b5ce822883075a75657fea68cf9f6aaefded95826540e272c501bf468619084280bc67d9ba5f55bf5e8ad68497504e19384d74c73869388e3e64c1fc729e3750465c5c749fb22805360d2556c147b01910dd2f89cb9456bce0b4573836a918037691f8a187dd9d0190dd0b9a802f53bd39a9bf7ed1e7209f9be0ab31d3434aa40593f22e4e65a698ada176958bb49224557c20262b6301433336961f0b85abedf298389d814243f58d5221f01424f184f81c01c0d7e1c41747f3a3858777f42a5d63b265602e7f9d9176bd7974fa350ea648b1cd984315013b7ea78ce5032268b96c3fb4be6c5e23c012d7cb541160b5e3bc406bcc01710489dac949aacc925c96e4c1aad919e6c084184bfcfa45a5d96db602ad22ed49b6ec502a1a9ebc11cd1423579a8706e276c0477fdef45cd61e0d099289b191853a7d267948718ec0161f31667e042390133f99ab6638eb052984ecbcb8ab940db9b0d7c3d5fc95fec63df85cc686912b10de442572f0cf8511e9ee89e0b0d074a838d704c3d8300229b2f22ffaae74a8a42a72fe768fa32b91dfbeb1a4e48aa27c2758d9b5847825b55441c2e6295d9b0cd8054e48a028bbb8681b8c9b542bb0804de844eb04ddbf2eb741f4524aadbcd16bbedc9011dd23c6fbc29dd49e8d01a6ddfd2109e69cd9832139ea94c6dad7ac54efe0871da3162b0a0ec9f41d1f9fda9e0834256c357390467533f9a2989f68b62ddc6278356f290efc5b1d0267c4ae95ffeedf4f8ce3ff88b767fbff90b7ff47aef16f5c3d149ab74d3236c38a2021fafdc260bf5f1e695d665eaeeab8accb03c83c1dea542443b421ce4dd572ee8698a3289d018223358280819fb719cf26d2da4d33e7cfef1d72d179fc69dc78a74994f5e503a358794feb65486b68d6485c5c908f80d9acf8619eb1e123ccb12700abac53d549a1d0c0d76a373776ee899c1f94196188f336435e495353560905c1e2d3b4c8111ee32efd6806595377c9c59405c7118e81370af72856f825c52fa6cfa7b4cb5df80ba72b3b0ffda87fe190b0fb5f6a1ffe2da7abfefe234e57c926038ac367ff875a842294865a320318fce06509c6e3594a3d932f4efb65782f05b588b87657f18de8db7d18b4e1632cb54ea726ae87a449ede530ba672d422e6bf2b29b8b62ce5de6cff6bc5d939d5898d934b052c31c04a4738e34d94a2d43af53a3d01269a2beb138095e689d0649f4820112453f340168b0497f42a4e9b63cd4fd1fcfb1292dbcffcaf31d5a32333b2f371ef5493f0c420fc8f75c76ae8ef3275ab1151f70476c6af8080dbe22a4460a525fabe9b065c608ce64d1222b19d2097d85f48cd008bda28589aee8c61d612f04cfedd0de27976d4d1c7cfec538db59a9a659ec5aecdabb616a9b1f223ff7fcad5c10339a4d036daada1da66aac5bd0b72681e7319cbc1f96f0f74ceecba6b24b9803300ccb6f6a0d296439bea416b3754d123bdbc596e603e82b9672e6b309736abae89feee47639b9490405bce066942ab8016818a35237a3e13bedb1146bde9c26491a726dc0d367d44d75ee25df56fb4bd1af0735e7d9ba3a723adc331cd48df2997b2c07ad5ef57a80dd84d26305e85fc8cc2a13a27dcb4fe79824ca84350b327caa786f27993a3fef1ccbbbe7aa5dcadbaa1b0bf28915ee4702e44614087c1034e99e64c435d079233c73f81509756cea16bbc7f3ed33b072b62f0c5a28704b15e2a66aca45bc734ec0cc1147fbe7a09ee5d47ccaf0fe0a39a1a6f845d521379cbb0b9c436b5b64e65620235e2b0104021527066ca7f3ec45bed0937763fc226bb19c6370f72391d00a5d1e4f88d9ab412ba94e4dde4047071b40abcb07f81037c4b5fcac0018aca9cc85d87ccd157fe6dda8a7c0ab97054ff59adac465cf8627a0d58da98af0361fe74019405d9d35f334b7ede2302a389965cc7c9f8a145186af61fc832cddbd331616aa419275ad3d79042e6ffd6c4f0d15d4f013ab1ae0b4b192f1eefeb4440b28bc86b3d12c77d492f81c53e5ba19c8740966b66de9312038dc1499e76a7814cf3d64402ad60a32027d48601e61ca968e76898dc4c8b32660caafcad3838482392a2e5e05a07d0264ce5174331e8f6fad8f578bc8bef2b149e329daf691bd67efdce4bd27ef531a9d2c2263cc361d759b0b05a6df5734e73d4accc47cce4ac94c4d52e5456e565761bd666321b08810d2d4efadaa24b6708f4ef2a2dceaf29dd9a02008942a2f0e273120228f723db157494abbe747417e7a480bfaaa12b7c91944f1f7aa64d676163df038cab7a93b1eb35890ebce32bb19a7e9ae8799d093333d2f813a680d9666524f944b4884d49767fb6622ad14da4289f253c10ee6cc2fa068d9d9a9ece797b259cad8c4ad2d719820e9a33593d2405fde52c0ed8c7d4116ddc89a89ee4f5b52d4a85eb9d919c0b4efa5eb0f6e58c6abd85f9b839d5dc94a8e8117c27f540f0ebd34f52b6a38ccda854129740fddf0630a8a66d63d2b365f18df8c62df25de8b48e8949550cf0724dda18925671cd310533618a8e77c0c4f7cf4ca21eef4bb4124d43e6cbf763345d7320a609df1a6102b87f5c27164b73f71ac0ff087903c84614366c30c1d8d3874531b496c2fef1ac1baaf0e04534f090525f1f002111054e08f8908f833d378e0805353b5613d865765f6cc581b529ff1286a2ef09f3c7f49ab8ccc8039137734379df80633aac82fa0a92162b6fa6b99dfc5e202ed8e70d772df82dc0d0df717c628f80ad983080a0e6a88cffbf2180a1c8b103333bba0c86f162f2f93e9e4a777df1a7d5233f2d99118d44b399beb1903a33cc44318fbb600fd6352c47ba09017209deee10b2695c6be4d2e726c1392a6eae04d97f7083ba604adbd2bc62183c94f5dfb622e4ed38154a59131077a9d67ba374c704cb09daa19ec9df90220848ae20b6da2bc645329a9107fe6f6bc025caf8c2f4c0f7e721fab63878d8ba7d12c1c6d5da312c993f9c72a7f7b7be3d7111a6672ec2b51bf39a7c59ebfbe6cd7ffaac6adb885e0869ed25120db758afa9139b5d6037efd3277eb5d2869cb40ee4699379a369bebbddadf9063d25f005730f900dc9cbe1872837d3fc14da245506e0a1ed2cc691b787aa054677fd96abe3c374ae5210615718f3ca615ae824650ace1ab4146ad710fde58eecf4f3b2ff44d455ad2a55785b7f108faf23b736c90e6e8d802d5182917a65610ec6d217343cb1ba90f20429e3517adc4a0f8849548e0f1fe06e9e09963b11d815033e58733c75d1c036c15be3f5723b7fa8bd9dc4502896d51aa217fdfde7a0da38184a10f45556dd34a37d4080eba937da9962b7a50a47203743b573a607391e103c6344bc5e452d2830470946751c6b29f092d974498877c90a0418c3da6e3f706e6e2f79714badf3de9a287afd02f67710a952a16506952d3fa1e21617d89434a58ebcb57c5b360f04e031123cb0dc96476a70842f70657698f8b5f593a9382dfb75b16b4eeb7656bbcecaf3de64f120ef0ef16472096e619517f8ce0a919bafc70da92dcd49f66ee13faad518b9b7613595fe5c073a3d2f7f1a398046875d74086d68db66f440b15a4ad2bdcbbd96db9afd03a9f5c4b63d2598254e517815c3a33f175e20aec2644dfd755f14761b51c5c672db8de2c0ffdb043da1cf62719b10daaf8b94b99c32920f2a415cf4dee78baafb50e5fba662f154a9b07dcb61e0ac86bbf7dc4a37331d28891e891dfbc3a31ea262ae2e25011f3a9ab0d59d5269d4a062ae83817c1d430df0ed4571268737986b4f159c2acd5521c925f1a8660fcccd91ff01efcbb12b9fb2d75a3c6db95046939a621b92ad3fb1a145028338d072d68b2df3a7edf47f30a23330be20bbb0af1a9e8c479fae3cf9b7233e98201f721e31b884e33a0dd3b566871b69fe77a36cd1978986008d287bce884f44b81ec65e9915d4792974491f4f64ec937ce204dd3fcb83c1427df5d38d1f91b7a20815ab1c095063297a739da568c018d08fb9af6e20b7d9bf8207e8fac66d5e615fd6a456bd7d5d9c16790eca1e7b6f8e4e0ad9a6684eb452b93ab7d2526f547df8b7e2a884acb014f83709dad8f9ec7d7dd147251e4aab668c8ab48b22aca7a3bd67ac110e28655cceb304b851adce6c87081c9ac146bd6bc1dc4cb086dc9ac8eca34a2e9c0f193dc73b030fd76d9d30641a10d75f2bfecde9232ab2105ffd8dd9729846d2e982d4e113c3bc311d5113597526415f2088035ab074197d661f57e6de37ca1f7a3fbe6e2d6fc227bda405cf74c148e99143a1176febd723a1fef90c3953784d4422b3717545ef69c72ba65dee51dd037cd71c8beb1bde0db454472a98fac87ffe812a31686b68dfd6bb6e25b1e133824f801244f1ba20b43022eb68baf70dc82241146848da91a269659b8f3a3d09e7a2b62af76493047cc018d00847d0fbc7a399af85e2e700c6fcc1236015906dc2f62f3e139d5485bba183dc962deaf37344550901b86cf35ae83ce06197f739759d4febe45073faeec177ef3aa422dc8b57d2c977cfc28224395c2988fe740f4637cfadc693407ae3adc5439ba4b7c97048194764287f92184e1c43d17633d3bc714e1e7ce2fcafddfc2544d547faa4f5153eddf23b51aaa35084f44b8850a5ec59bbdc948453932dd6a0f45e647ecf1bd20249e7eedb45d18fc71d7290d642d5dd67de022e8a5dd6ff15ea26ee55f05c4f1b70778ad1dae5eaa6720fc1418a8badf8557af9497d680ccbf7e8f7c4e5c650f98cfb3e6b5135fcb1fb889b41217b51375abbee83216d471ec855c28c2817fa4e97b843b50195c6ac69139914350dc38227edaeea51c2592a00c9d9d922164134c505225f375fd28a8040f328e840cd5f2af4b87422b7d1817773e9c492f090108aff739953138eb4e56cccbdb208cc571b6554ed040c673db3a60cf0f54f7b9682a28fcd25135195c4862c45aef9caf7ca3ad8ea97ae00b90803ed6b0ddd6a4e5147aa38280ec08763dcf5b4e0e0ff34eb9b9433e870b3f2a7fd0dd1162f374b7a29c568618874bd80bdef7caaa1e06a68ef419f9e820fed90ad41c317c6156143098440239737a12e345f9beaf71cf4460cd8e5b95e60ad8d78d98b8623886face3c6f2585d70155de74bb9ccd5211fe98ab82203c172bfa1b6898534db82079b8a52dc02a8011698e53efefc44f70f07463fc74610593560d8657496996e5d64fd0865b10811d03575c629be331bfacd10699aab9387f9054ef2b953c9914ecd08c128de2f94eb05f0c52c8b332bb810dce3b0279db0d727f57b4956d6095ad275acbc070956cd99d1cd375135182913737897b684e9ad956534f9e0cd0199103c1d17413ace4cfb2eeb45a601ce979fe253e158f50552372f8e8bd5b44db0ac88ea8b9d82c52fc46f1aae6007f34795067553547a55049955410f6ab723ad04017e4c94a2898aea2c40b384f6b57258083538cb04616e4a54a28158e6879b71a93cb01deb2dfa0f1c64190668fcba3df1734826d736d18033b07e31f506bbd34fab438fdfaeba394437141387842e4bcf1e632d677dd69953c6251a201518960cead1ee8d1200974e4232d09d2983c8b18ab5687d90106ecf158779897fcb8ee6044b6b45320a4dd3c3773ab461828b692843706de698c6890c1e27c4dd8d0aad274249112e09550f7723edb4e4afc67106b2cfbd2c394e015df965ec2d09244a0ad6beb6012cf2538b3f518f02f505790c015805d80a32c6d66d28883269f8ba9b4044bbd67031158097d3c19b75367bf2ac4fd255d2e355765931d738f673158767c7d53f5a48795c13ff0d27025a7f5001715f5c08b44c9186c377952f2a6536f4427d25f84db492f83c2c1c00cbbab25bb512c55983fb14d7e77f8dd09d3b35e010e35a10c3f3c10c186988e22c0981dd4e4ab025f52ee5b7c27f50400f56823836b1eeb6c90fb51ae82518c038f6337861a009394baac3504adf80ab73a63c6a71e8b9672aec0a59c7124ddd34cd98972169095a82e685a9ae8cfe4a489eb0e05281704fcf26af96953d4194c75bdf57a065a81266a98bde96ef741f08aae95d5bd8847ca9abc59d9ba41a609c5577554f02ae5a5cc3f3cd8e7e4baa45a178a29f0838c0fb7514d60fa098013530f49cbb55441cd4694bc06dc8687b6bb94525778395382d3ce4575d14a61dfeebb848ec056d7a41a96bc7583aa662fb58025d55f909391cbe0f4d7cd42ac5369e9aa8641816587f811677412537972f77125c840607813274816567eb489cecabb6e66d9db9da4fe25b56fc0025b555e19d47cef5341aae278b66618d20f43bd36ce359fcf70f2d75fb7a2644fe986658e8784c6ea27096841768daf4c1bcdaf18ccacd37110006c11985ac7fbc95c09905f890d4c4b56c052e761fd069aa5bc57d7df5ab7732f55f578ffa66498898c7398ec5abd07125ccac977cd27545cba45cddb18ee7c79d5fd4442067033016e69f7114a879d6a9231b9caca49ff880fe280e149d4b576c2c9f384bd9d4fc075a8065602ce1102b61b54f149509e16547728b748b8b5de7d9432a88e63065dba57981843e405837cda68a868c74b38679e31eac1a157a1496b31400501e69e4a7e3654565f441aebb8d6cb560b6c080c6d29daaa75564a72295060949c442e290273e6a662076017cb1f11e24815a841cefd117db542162734ce2ff3d1955197bb46b3cf4c17bc91499491012f3eef6c17d8a31a8594081420d2b65d85a9c5a6b68cb558c04fca245603eab77d9f384a0b06edc4ee960139bcf6f10e1608d7386b8cf430e216c5fc859735c326bcab9cbb7fbf96a1fe235e56f98ffe278dd633a498fe8193157c04b620f8175b519ea570a5dea6602f9d6c3f22b4d26ef4b0941db36e3c32f1fd29a5a89de915f9870a53645c506985e994cd770e48fd2a6cc650936c9a52dafd81cc28fa9b0eeb9bb414ac2e1063cb9f338df5ac7376470403751b10175711eecb5ed8972e57276c284563d9338bca71a654e9ed51cb6579143b2988243b734396c1e45e6c798c7004779dbc589df5f43dadba6519e71bab8ed67bd1938e96f02ba9dac987d05352e2152a269d28d8d027502e39010a4ff3a8afeb874df7767bb71297ee3be040632fa1db4646926c336864e84f11e8cfaaac78374ddca3970103eab326bf3d52ba774c2cc542c2d52fd72d9ed1671d22e3aa5d10087dac572b290116cc4fc673895b4ae0dc4186ea63e4c2f856e8a1dd164a4f02ebe7c6357ac2baa82d57492214f094f85530c2b5cd8ed9cf16c73da5c8f96c701f304f79c511932075962d523cb1e71370d7b8f89f0a7a2553cfaabd68eb83636972be4a6296b28bc831eab6c13675cb7af393836491c0c09a20b0ced5aa62d3af4ad146336436fd6a7085582fb6430623ac7fd7aa903531e4d0d530eecd23c430f7d2670a61d3b6455318650b27c15436940d5ad7306d613c637262eac8e6f87bfc0657d5e37b90eee50cf2c9d34967c193b635984bb265939b228cea6b26acfe815d9b2f2dc46ae56840737c219356b1287cf421d37cda698742fb23817fdb13b23da98045fdecdf2ffb0febcfb5ffacfedcf8a7ef6933e27038ffb136b6628e48ac0010d1841ecfb4de9cfb4f6c23631783ec1d3bd7e04729632f9e4abf039122171ebe7e2760ff1c0c73c16e935d835f1886975eaf83cf250b4baa731a18218b44975f65a50cb1cc6f8ec01337618db93ee00d891200009a42419a442f0a302c0bacefda84dbeede358699f5fc7b67e5f0e48649f5f5cd612bead480d195cf7e90b708ed1d68dc999cb5c1d6b46edd27386474382f392b2fcdf411b4580c3280e7e6dcac7eae50ccba71d3f956832857bcbb9a6f9ac91d9f60a12192f8124d4dbb96f299eaa21b91a32897df96213b5293c4a8b8cdae7f059bcfc3c3a1e5d4afde8fca5717454dc5a4beb16611864b968b1b543104db95abd7adc43def9268fa5cb823e8b02aba3594c46949a875c9e1171d786264602802d72995d796a216634ec0aed1609c93e70161b7ca38c5eb74d69695e456846c78e7625117083bd5c201103fc89024a7eb726ed0f16fd594b56822644cd52b41c719100e9f3320db4bb41ce4e76bf5cbe3ade38d687a917987a40b248b71e843ab8ad56df744340ad3e86c2d30dd02df7f4316194d2e681aa04383d6be57dc4e5baaaf7872a5194308cbc46899ffdd4f7853f7c181cf9cafe233aa28edf9fcf7abd5b3ff94db0af541631068104b5c3a763fd373b34e373a4c8fed25fa8fd033a1e0fd9b37a88603e030ff4d08a5b0fcca612bc4dd97486ac07e466790fd2c0018ae17fd01ecf0d811944969c7ce6c93b6edd5ad9db9a4c5bb001ea74bb0a83f5ea9e5adda3e7611eaef16d284cf0be1ea3804d1de8623186ce7205f7705239b06b98709c161575a99cb3f1fc40aded1424118dbfb3a7e5d80afc71d716474fa06ab688732250eec7a7972227b3af3de6d77e1442a6268d5039e2bd98f72f1497006b7239b2a146833320be28af95f59e0a3186781e0653dba8a8c7c4e85329c619db4e9323c874e1b3343470bf1895546ee7b4a8256adaa388c392b436706b1d27a2cd185ce1485f2088e487b02575f48c20e761e3fe41487c8768d5b0a2f76d0d9d11721efe03cc12c0b5ea404f6b77ad3d2bb391e33dbd37383a92c97daace22fc3cb54d6754592f2c6addf8027babadc5d19ee3d95dd230c5ba1cb2ca85b152257709a9a4d1bc7810a4d0895dbadf527e4d18c88ef3e94e7ad631c3045f5fe2a3c6fded2545c0b4441a5b40974f6cf3b18cd2950627ff49bace71dc28940c7e8b99eab7bc80f2c69878462d689c11683a6462adbe1edf14cf78eb2e19b0fd953a035f28c624a50eccd80c40365c51a8ff3926479bc58613a1753401dfbbbf4e0bc7008296e9efc4def791ffec7a84a716add6be1e113a619b21a8ea02a9b8f7559f080b72c1cd4d987c8e749616258631be1c675cb6d8f63b96894f24095c474dcc764bce6086668dacae788ec2ddda9c91b5c72b48c998bf57238a2b062b8c04231f0dcdb02b1604280198911efb7c5b27ca5c9118d2491cc8cb3394ebf04f1d2c3274377535dd331523b4e8b471e64e60923453cd77b9ec079c7d652adfdfcfe1ca0bfc48a9c019348d7406f3b08eae8f5ae3e0c3bf16fae88e3970a318d303aef4207bb3ea2b582eb7c29566c26a83f495cd9387184b6983d2a467417431956344689845293d7edd5118a0d08a423da1cd3c283504491df2cac7125391b8841bf0da6d1d8c4c2f39e2c37b109c0c5d33efd1dfeb0ab06d09d8b3dad700fd4bc20514e420f348239f1ff9bb3b756c395ed92750f8800b710777732f4c5dd8f7e5fdf6cfbbb7707b3574242ca338a82aa712bc30d7293fa1ce56a88a05daa1040c714c3000feb2996850599bdd7cd0ef6d0c77d542c345fbc382cb3c957402aacb84d62a7d5276b25ef6b0d64a327f445118812d9fbd51f3e5fa0f29802560c63f60951a3a174fbfcd0bec5b5480470313bc1186b630373d68bb07ed9e0ae3824ade262a16066621ddbb5b84f7ec1f0d457b72fa7da4e14db8b1dbd0f519ec8eb3a2d43eb85f1474c986dbd5e3659752a9131ecdf6a3e6dd848a0d25ac8d7ae9100be31451917b891c7088fc556a1d9f9db61ea868b173e64ca9a4a0763ba0634dda43ad562689d7a4a729b8b51bf0ac029118a36fe6133e831f7e5c2ec89fc598a77eeccefc1072bc762cf9488929c5a671b9a11fe7eae9e151de082adca7df4987f05ba245a8d8d9585028e018d40ff313f3f3f2143a8c72bb5311d3456312655745460e9cec047420aa52f916f106b6700d64cac7cc30d32f07ee802b02148d66d92bb08c5fe645cafcc3b064f230120815229313c0b1a5e6a6f8b9a42435ae303ac4bd81afbbd88fbb60b5e20d2e73d87b43533107bfb181c84fd8451d6266a17ea41cc1b7d6a84eb7854a0d106898e631a76957e5330ce7be4ebaa2fd0ac4bbfedaf31c595d8b6e60c72386da9a2ca6afd55f911e04472b46dbcb8c646a1e813018c2bfb5dce5594016e6539708db899304f328aedfaf3f479eeeaf01ed0163b7e64d5a5be33b364f72142d63541e1b644d6e8f8aeb7857be8bbf45401d228e066136a4a5867e9f383f4c41c178b46c5ebadd8c3536c15f15b472807a00dba733f40188f93e4115f770e4789ecacc0b4375fa843b8e75f8c97949fcc411bce4be8f73994057d9e6a520f81b7661a37206dea7a58c7fe6e26bd0fe7ae4e19c1a7d401a9457c2f5c4f9b1243da2aee428452262b1668cf4448913ceca5cbf9bbb5451a3f296b090555859e4a3422bfd58d1cb4ce67daaf578ff3204f4e8e75268999ecf6f181bd7a0d222833f41622851963c5dcd5613d57910a503651cb54d65f6e5df9846ecd7bf1015d730b32ad5696c6fc21fb267f59296290f150028ed620ca449b2158495525864f575159d8508c0ada8ba60753ee14df757a9bece11e5c409b69da5efa508f3fd594e90d2d8ff05299af63eb2cdbe595e8706be015729993e15d04d3af9850b6ce8179d6e0fb8abcdf157adb52849b5a7ea4072730cad24e2111c3b9876c7586b159849b58f33759c19151951c397c4d0695bb94680456d1d2a7619a62499ee3d1166d2743910d3cc0bd00f0f221c8c7f75bff14dc1c6369ba7ee38be0f84f045c97d22fd75616070cc7f0dab6cad6188c8d0e71acdec8600897600f6a03aae8f755c9929d5d6be0393b17a4c4eb2b0998763c157273a511320ea57fe78be65282d18dcebd4f6583062ac82e02f42cfbd7f275d93d46bad869048731bea07c47b1ee295f79150c05de56a581e579c3ab18d8baa585eda17f4a2626b4b48d3d219e3b96c1929c098cef54777bd225d7828768d2f697d3f030856087bebbd4712aef470111123a4559d74276991992325a59b1e8b10689b00175ce4c1aceff4c6a7db92b713e57c5e3be6ce3eac75f4be7e611c1d7ad5f7ef06b4a352d01081d8f3a9950814ff5739ea25c1cfa689ec2fea95e7645ced948ab180b026045b4cf9b8212405b18f98814207dd6c0863d9ff8f3d764dcaac6bf4cb2f77bcb357b2e87700cd0fbb3545e0c2b776f289601bc1f5459a03929721b4c52fe938069d6025ae3d1b9180b8fe03bda1e900006ef30af26e8d89d0a0aea5f07135cc338897d08ceb831e11b8ab9b37184281e56ed7f1b40d90ee19cbf23d175a5d4c309c28756d82767cb53d403b80fac29994c2b3a86c08e5075bc7c57e2fa99a826eb87554a718a1676e2ad4c4dcd33742db6c4d33656b92b48e6bfb87d4685a22cb3073bdd4a366c04cb3af31f5a05b63e9de124b07b479b930db4a134f0fb05b58a220d7c7811790bd9b4e86ef728fdc2340f2b69257bd497ef2289f1ca81e9d2433d1357345864c3760d3b090e67611f29786573bd296b8b6cc5163a64cc8b549dbd0825a43d65dcbc99ac19b069232b9a224b6f6cbe4754337d8d303a8e44419f65cfa54d0bcaafcfdc05192e75c3af4ddb69e445eaef74c869a629504b372b70a9daf4e91f8ce11170ce3f94bcf605b15c96bdeff7f739bbda2af11e1594256066674ee3d22fc8f3cf214b171fe4a8bb34d47016fc472955bdef2524570e9ab6a26cf3d4d96c468010d35caa25ced666e1b9e6c389fad06a7939ce837ca7c52fe32468bff2ab8cf6cc450197901321e54ffa9dd33db6b01965f5eb78ed17f87e33f79b53b02119c0afdd71b985f72abfb2e5225473d640e99a60269438d77b40f3c05bfdd35f1562f6bb424867185e97feaebf0afc557f15669b526ad80235873c52f734567a5fa2bb247a847f61532d3982fdc7772d3318605b8005c7ce8de384d938d27398f9689693fab8b46253e385465060757eb3ccbe9a5f711c15721c7b899f64043ef978b40960313626142e3e6059324bf2757ec698f65f0a90eab49034e8943f1edf2bd9d036df2e5bc3d5ca6b7e65acf746caa10eb7b5168c025a8205fbd37d118118d17118645528569d74d7ee3ec3c525b546627e7eef15adeec43532dba956fc2a11aa8035951a2b1ac96cdeebb5f08028cfac41cb3036a58708a055d3cb29a0ff101a8e576fab8483b4fd74a6133681a3d97f93320b3d80f56bef69d744f198860a3756d5e820d74b6d066cfd379e80d9311ede2cd9e001b140e5c24587396328b93f1e8a1bb13da0a7b529dce78ee7247c1a3c8593c6d482b80eebeb0fdd9a25c7fc114139468a49ed21f79f2e188472f10cf5bba8c6cf02c067fcb8b8a9bcb150bc6bbd3dee765f021eb3ad8159e8d54e90aa66776e8519ad95acd9f034c27aa245d4e29a6f130252a05f0b1c990159a05fa7e276605f62e99428e9601f8444c0c36b561004364db66fbe85eba950f02da5d24b4a69e097190fb2f7da849faa603a140182fd02f14926d8c15c748bc98bb36b9d448df00af82dbb69fc03e6242b5078d83eb45cd00c0effd9e355e414ad9eb7c030b2c3ff5d16f9feab2cf29f7de182f815487824e3f35f79641c8e8098f2e947a433e88c7436e1b8a5cb126eb3de45391a2f8358c6527592f55e34a57fb190ef4b1255815c85711ab35bb98c0fd6e7a54efafd41a044edab8b929b848cf220d2211b9ebea97ab83c31da5047a2258a7fdb8353488e0000085e768ffc541b0b6fd6e47a3c295b621173dff82d7801ab2964a0930fff66110d082b03706e02ecb9054d1c7548664178b48c60d50312d8c08b62248133856f31af4660cc6477a52ddf79ccb8a16acf818b6979536f7e8ab011eaf559ac334f5b3cfe0524fb7e7ee1c7fe54caafeb234af80bec3c967e8959638fd9f8ce6dfa6158b22b3373705442582215e5e49288b8055988a809dca91c945629f6463b962ea75584a6509169e363ecfaee72af7cf2903f829c7c98d234c46a8b4f3c95d3a12563cfc1c6b000ee6698674601b4deebcd6afcac4da1eba6c17cd4f9068d48c3b69b035df0cfe7872ce4c937bd31e2f3792669afe5dbcb93d0196ac048a4a7a71d6d4256db89b455940c1428253ad4c882d2ffe46223e4f13772b385f18c2e03c88a4bf99a4f2aa1f421c8cdc46a2979c74d69603c57b8b0b83c2ffb710264f88b1ea0c3e6f9ec5b7df3e8cc0337470f0b544e8048a045b2a43fd90b1fd14457e5d693ddd9988dd392dc929bdf72828f20b0de2f5f9fdbd017cf8daf273334f9c03d34264d25d568a8de199b88db3a6ec15fc3a1ad373e303e6cbddd120ba362b121035b98d3ae67d57084b21071b5396750f34c39df69ab8c4a26b05184fcbb1190419d11ae21b27e228bd386f148178d6924838eb708806fac4c8d9c8171aa374a9a1bda9863ee0127179fa86908b140a6bf5fe1b089abe6c4a5866aefc378125b3032e15407e8d6cad77150e6695a2cb4b8483ddcae81ffd882229af80411f69fd88b0b08d6cbef6a8c331110ac0862f34364690c1c14690b1b1fcc76099d5a6197007df165789630e29070abd9d15f8892cdfb4470f6fe27cf1aa85fc7e6ce03a5a5bd448464a3a510656614ce096611020a45be9565711c72258d24c0a86eee4d01d7edafca617e3f2344ed94562b37ccc3e0d1a26bffb7ba4c2132d60fb9adeacccca9ddf2466f6bff3ccdd9aa53df9fca420c4e2c4a075bab80af47845305a8ebdcd3aa6aa3327583fa0e4a75e4fd7d5fafef0538bddc5198c3397bad7f98bd8b418b453bde6982fd6d31fa05fecd1538e37fb22a310d12817db0661b4eb8ae1c3fd913d542125c11f7e81c8536ec612bad0c85fe3e50551d9010b8e850b86e8d67cfd4f582f0f39822f4059115ec5fd58bab5c38b1e8dec5ae6c786e78106afc382db993749567b7f96ce7d584011407aede433617a584b48154dad86324b58514e3e0da3317fae8d883da3b2ca8172d0905eb35eb00dc0457909890e02c21788f9374004a32d6fa99d80faf55c21951d87eeafa65e802def8df59c011a8e2d28c3583da82af11da546a8bba433cf5000f12ea869c394621ea13f73adc22ad59a7146b133660afc8b0d9634334a03c78b5cabe79e0c839f57564cb2014ac5b76adf58f07fb96a3a54a8f0e326526b704c38aab1463d54015eba95f160a735adfcbafac6d259ed2a20e6571a4355639f10741b4fca4f697672abe520e36d5dab275dc677812f7c6fae073cfb12cada0fa511eac7f68e52c66d407e44c1d33e68933f4349ac7ff907a9f212b60959db36024b6edce301b7f3647b9ad72c8c1c068fac59808f9bfedb6f3bcab6f17b49df09681e4968d9abcb012e92e6ea580d11c1a11fc7cbb7e6dcad908f39515ba9387707e9ce642a877b6d021840b458a9266f75852c624a4bd2a7a1a1cff9074aa76dbc6aa1632d3ca32f237c68b7e7ccbfce0a806dff0fec51029b640b3637747840d2a79a5947ce8638cea544b87f219ebe6520b9633c894923db563cb973aafa0e3ce8d5a6417df7d97266f496560ee1feeb1907556add709ac5964866fd5e53189c09776eaaae71115bf1b8cefbf07e1091cc779cef313cabbc54adc8b108cd9d60819614a12a86f0913aa21ae02a1dcd2435b6945d26cb4fdc0196709620053b4bb257debf174557d5acf3515bf497a80ab41540111076e999f6d46641e7cb22cc5afae272d60da871015bb34d816bfe72c6b5696b03c4a47ae154733718de263d7f87dba4307fd84872bca5f85faed3e56282bc9bbf8f9c5191ada5c811c587da4b2ae522b06e6a7c78c751c8c1756c529c596c9fc8225eddff532bec0398f707c11f5e26c76104f135027aa6c44bebc91f2c8021d6c33032507767c5f03c5c01444db673ddd3afa66c00cbfe0efa4b17ebea29e274df3d5a0ab96ef123a30bafc580be4e510d04d16bab02445e25dad4d413aa05f889dfd7906e2477b4878ead753805b9d9bfe751b3658b654fa945d14fbd1f540bd42d78b7e8856065424e233e4129ffe417d6afd12f2269beffb99202cbeb6911b0f36b4496f86d6b8b816c8e6a0823da0fc911544b1da12fca82c586ded89301a189bd243f507b3868d7fb9597b605a02841f7851168eb4f4c76f04d086469eb58b2b9a2c081840508984045e1ef95ef457329325191b2af46aa1666aa27e083ac31b967d3c49c19e357131f8d117558220d32f2857ff269a035cfa8fff69d07b9b3e4a6618bee27f7fe57f90bff33fffce7709ff950f662a4984f7f9bfecf199c2308d1e339664c266999c3b3569768238981b46095c0966a5294cd6c06cb1ac0df4ddc0d29fa176769772baf355c44686e1451bba4e752f3d6f90b2f88f7d55809d5d67a5aa8c906c156e49b575e0e85591e000daa4bc91146b29e8654ab76f4911d9e67c23d952cf6b9509d08af691a784413f54162fa3e2159a3c66aad27223e6ad1d495dc8ac7f42b943298dc1f7bb311e964ba9e54e286bcd926f5c10fb0b57ab9b27367e62529c16f786b2d2f45a7f642758f7fb8c4f688586d4e44d06365ddbf27814df5dcfb5c0c579a7f5b1195983964162288544a0b96a3971a62f88791a2edf3f2838f8544faa9bd18e8d50ee8442eb628137fce11487b8c440daae3d86163d9c976d338385943b0643539b8ee2cffe4c6005b7faa3a1cdcc663bf9c66784037e030df40ac644f7d88c30d7db18e949cead921e926a493d3c020365ddafdbf5af78737e483b1857140096350c5b4905747b0a667d6fa371d483b0db697c7a92368363fb814bc7fcd9b56f814a6ddee13df5cb3e5d09569db522a415e4c0d361b6f4c21b307c44164f82c8e197ea4bf5a5e3129d57a070cf5d17039ae7e9617beb61c6018d8ca4e1c6e55e56d3e4760851848d5408517722ccfa51eb9da7680c61eecb0674d81809ee9c51db5847f59d6694b6bcfa3845fd116c35d3c0cdf5048be662d4e42cc3bfaba433bbb0f24be8aa8b76da19b58e0319617788f852d619128896b62358208235dc9ee92bc50f01706b8ff92afe73562a0ee92e742541c3b4f4b1a830e5cdd1fc7355a0914361a98749369ddb9ff4e335bc840e9d69e05a57942e61753b5760f3343664cf48e637197977acf464db359a2bc9465930796ba511bb93bc7a8fe0f99565922c6941f15917edaf29354a2cb22b5a0a4f33fea4894fe8e37b0ef2bd2da0effc62d4df7808d322fc0de4a2b14241d6cf3227e87ab29968cacf70ce10faa0fe38c45e3363e9234e3957d696b56e51b3ee63fc6a0d169022c55d77c9b98d707ac1c1aa957100c47d6ff4f92d9e675b45607235a05484ae2a59525915bb16ad8cdfa5353cf77844b7710767a8cbb04ec0b50be772ed44ccd039ef4cbd7af38bad6f462b993ee60413ca25c5765f0bca2131855917e63df8c570cad7b678d1fed1cfe8504bfa8ebcad36bfebc79e2ca38426eedaca4f64797ced42ff1e7cd4d0ca9c6ee660d1294ee7fdc8f7a14b0f28d210a76825083414097310866813a1816343ff195a8a240a3a472f1cb3ef26fb76042fc49e0169e59e36a85ab0b69ba5c343bb98a63272586d25c23980806f370e40dc9d00728af0643c32cb5bc5dbc372a0ae7e2c9a78d95056e554be73833923467f1f70cdd1b0b2f1d9ddee9bc9848564686fb2508fd9ba26c1ed54417c9ec9c5d600ac0ed50d0dfabf94f2e908690cabcbeec6da32915cd76162b36a46f18b074a46537a206727906d09bbb4c2a77cbc9d03f3503f596f8e8b000351a4f97180fcbacf491f85484c2a06ba72c6a0417f95c8c5e64e912ec0eff4ce5fe99d8be5ace7bd6eac9fc526cc934041c0dbe80b0546311674edccb71a3585b9aae2736abae2b25416cf339d459fa73ed6baf614be7ccd7244a12c9b0ed61fc7499cdc130f84779254de1ded23c5939554c992adac13d3c300bd0e9b9a12afb9c62a876e292579c59850d1de3445a28bfe6a1970e96c4ff85a686a6575814601711383734071900c69411e079b026c67b1723050d1f16afe45b5325ea3025cedd76f880d8d13c0c940f4d0c053fed1c3ea567f7af51318868fb9ff1f3fe07fd5c3efeff4f03fb33a7c8ee063169570f1efecadffcceda47e1d3c47281a1528428a07cd91c06aab7294ea8a149ea4071a14cdb3e979cbe13caaca50db6cb06572d3d93dd253798b3ea8ba34e4ee99c583100f6a46f1d168e9e87a61db4e53a1440dd003f99d790d8238ce218cf8b99d24d95a849629363c404998f362d3a64996df8866f899a127a08bd3f8411999a276bc1b77a2fcde25045f237be0f3d86202f32efa95a2440b73b4ed28888757d8dd64085b590f41422524c0775cf163b4609917ede09b249ca8c8d7ef013bc1d526c94f2c22fa92b4a040c250eddb4547c5522351ebad22c3f50a7fd155998e24e1ea0b2e0bcf6cd764dbb1bf9f7d099ee2af823edf3ecf7d0acfb27d009f9fe4a637fbe6439fbcf1d136404b389cc90ffb21a6dbd5b8825545176115a538001dcf402f35404ecee72864e42fe74f751d4eac0d36c9a07fb148cd1633a2fdf573d03bb809a439911728878f0e0df1a8850fce4b34fc7c4baa800dcea8a72adff066715028d4522adc383fb4d7fa7a489c00a5baa2374630ac02d86e4c15145529e9a72d1d7798eccb2d5ad29d06e0d01a480e994f4eeb760d908b458198057e5709ec47468079b2b8ccf274dc0b629049bb964ee8c1dde1d78adab78ef27a94e4324704882b45197baf5e160e79d237d2b010a600848af9ec0cc77516f8027abfa3e4f6f037334852c40e2a2be30c20aa00814806ee49afa3c665fb5e401dbcb498fe4e198472bcf7e649b2947f5c61af869562c76710d208b6b9b92e4a13904ae7e199151c7a1653f0cdd3403e9b1f0d36d8340932dfddeef2adbc7bc81bd2d7642018563650701bc56cd37bf830d9f8a77692cd05beda2e02dc745dda3a32c95ef04c7d372d052de105a0374ffd2b505dea18386ef43d4de8678b83470f0629e06e9a033cd777c63ec5bb7995d802e79113d4e544f5650178420c30d0c9b95bfab2e2780598e606bc014d3ecc8fd01825c9b2db31c13daf95c3d9c352370df408b2a7c1bd0650ea46431fb33f0517fe194e97798a5ff98073e5e84ba5ee47f49628d085d881923b7094530e9dd29da8a33771c44c7685d32b3510f288e2112488337692c25dd28a93e69cc200bd2280bd221c4dcf47ab96dccce82c4c7bb4c14ff5014e11a8415103ca76324e41369149d305df6405e205711ef98b8a2296736a76ea5b361e25fcd39c9a6d7b9f8f42c16317f2f62411d69cc1e795a1f17aed57a65c62066b9492acf01b19738c7eeb2b39eee2f5ea5ca47c60508bba46adc9a43fcb391baf17981c8f7f9bd72b4670b70c18ecb0ad40fcc82cfc75a96b09dee29f597afe0430497f3cc330f35fced2f3ff384bc54a0abbf2df587affb1bb3ae6e2dd879f806650a56f11c137472e0a2541ddb7775e387758688c31a934d225b3e5b4b0cba2dbeefd78cd14e73984295b24c41b4e3c87daf4c8c4958049f707e53f350ec69c9c0ed0cf818a4692be2b1c06ab6d342b71b2a0cbef23d10f3473309e76fe9673cac41a911bb5d14c27871a16c2eb6923436a28967409ba541c0de6a2c0713a054308f2b34361142d5cbee81b5b7553b3dc675e73a273ff98b508bdc8e0955990a625175c6536802a9985b0a1c12aaf2e8c2eb9e79681637c90a0f42c7a9a5b7264d4476eabe23df0e01c16cc39d4192a797cacda9e5942f27355c370d748299bca785de9d6fc79e12ffec1e71671dbc89b544df66be92b90ccd657fdbc6c35e30a4eb7e2367711b203881fbe086754ab6fd5b0f52ed265c2d40e551486ef9604a48d8121b4a271b08329a61a9a2a774daca4a661b5fefa280cdee7516fe855ae845dddcd7c5d099933abd2cb3d0a1eddd29f62180e59582a01cc3e014afa7bf618b45a530c087471cd3c0559d737355a4452932bc9c489363338658d21c95b12ece0ee2034d292bb9f42a77d62278ded52cb6c25c9c901c819e219c9a3711825ced6d9c77b25cdd1faf278f5bebd83ce8ca0df120ca875cc902c88be8fc39e64849ba3f70fa4897b99b994f16b251df47f315973682c824a0429af07ff4cc96fa8dd9fc10d9e7f98c8c0cdb2c5fb2a2569725215b76518c51dc98b6a18c2851bc1896f0d75e2494afe591dd35b005c673798a01f2a21cdce4d45451e7c5b1dd57e359081a57834772ce5480beb680a6a34c327026f89b823096aa586f56e4739678f0c502ad6b3e6f51dc97a369c799bbfc1343229efb7b2b30bf5ced7e5f6d462310349bf1c0de3cf80e6f7048a82a493b3dfd7eeb3659d1e8b4a4aeea0fb8cd92bdd325da4c2ae11ae1b2b6d8a1b6e90a7461dd1240d18b568db87cad769e07e66519b2f59091f39b633fc385a6bfc0b2679dc283cabe0f7a50f24eba5c279f15573200015a04a066c4fb78477ae6e68f0968ccfe31f246a880543bbae2be9e351313e93e6a646d3306d7c2cd68a18f562e6324e140506624e02024077894c908e8dfe2d04a3a8c1121e6255aa3cf6e56b0d89b6b06b78b608447d6cf92448d92bd8329002fa36dab91bbe1f2bcf89e3d6383bfa486ef0c9e7f8f6611fe2dfe7615d2bf0a45256fbd39aadb1e8c85c4db5bcf0fb590c07ea6a69473412bff6f7d61e58b9a7c6fca6f407f080ce7f1a496c87e6c84a8c0c82483c153dd6dcbcc7a0c574df08707081341e5785395fbdf817e406197d43d2b32c5285a0a0de65340c2b3ea8f66fbcc8a5890d6efa814d50051c09b433a0e0eca1eacac276f3a1d2f214ca7715138ce878ed6b470539918cf616fba1600fe01551dc24d3d8ce4310f7542e4059b66ec94d639a264221c3e7a9dae1f7c5e6e6bc6467fd489b7e58ea7057d145e157637e3e45d4c0db6a6abce9c4820d51831af7687a28d98ac21c685d21f42275c2f7fb1c141832c2d15ae0cd9eacb9f1a0ac7f6a49980b24a9f56d17924dc215792c2f40984b048abcd8816c070f88d3f916a09dcea320c18511250b1a4eee8a21f3b8f133448b9242a84b724287e34f5c89e2d4c1d6b05da5e0818fe106037325fa95edd9f83b91c74241872028db09616fb08564770de08a45bd02d156583a9338d223d51713427228ba08455d9421f27e67a2af567ce70f774739393ed593817746a6cab87449d1ce9bc572e4fb3d9772851715258e8990685a6b7a5cc417251fd1ce7108b7e59832e4b24caad2fe26b81ee638c79ae00d8d017c60167c3d5267ef42799cfa8c50a1c5723d2c89dfb885315a08b845746a1e6435a42c298ee5766d509809c2a056fd3253335f11871e529b660c5cf7e236168b31d90ff2ccc9a220fda0436b98b481bdad6f6797753983c9513abff1abae6e6abf35334861c99339dee3fe35e46e55a0ab9f03ba212fd9d458395eb84c84290d08adde28050bb9f0dde1381772f6348598680d1f7a3dfcb808a77bf664ab00f00b3352783175643faf9578474bfccaec158e2df1acb3ead10aa5c490144024b029b982672c443d976ed5fc760ae09d113e497a9c5f5b03ec6eb77aca9f443ead4a322bdd5165d756d69cd14bec14308a75f549446fc2560b2bc9a33e5b1f7c5af4173cc6f270a85097c7bd5a44e7deaaa553ae624197d38c2701b6572d2104dd2a268e8889fd74eba11c9d348b20db47e00ef346755172a0cea081e94be5aa95f27460151a3c617355b92fb139bebab517646e58be3d8c555498fe30b9f180d08d82900ca97c06458e79a57ee2cea9f1370363285d6c503fb989bd3b8cdb78fe9537c51196bbead48977f874a6946005baa217b1e3f72e09cd4f314145a1bf82bcca94fe59ca13533a2f644ae5db3ec12d6f28896f98b5c3ad66edeb69989c27e77adcbe050916b3e8584d816e57b36d4717e1c475f2cde79c407c37e4ec3d00b46eaaf6ef9e4c463955b52a426350c5f8b0ad70723a2dcc6e4e62f4116127ace94de772149eb929a204b42be8c2affeec39a8d2785330f8b5642fe38d7ba99b24fb326ea94021a3a26fd70cfe889f5363ac714d6b266219452c2352312dd1151a5544f0f3b51d46dd1c84cf53b72b64125ddc5af0a8d7572a087a5060c7aa892303e9b79d1c0ee8d0e96d805b235544ef57004d6bae22cec343eab4b0a21cbfe5a1123eb69ef9fbdcc769ee8dce058d75260b1189b6ec16cf35313e2e9e9c247b65bd461f3f79ded42fabff33bd17037e437c41f20cbf7b6c17b32956518da1812df7b46ac0bda467bf208bebb6924c74d6ac43f5391b85df33a3d5549956ab573f54e0594f89182107041b1a28a1a6bc5a65fa16e06dc039a05b007f9be30a1046c4aa1f31367ab74ba23f66e25ee102724203a16cbbec3fb0cd6b0eb2880c69250b963d3a5179d53af4df03a190c93c3045d6f4d6632c458aeb25c221539b66a9ff822d178b537bdad1dd9fc9f692f27ec258c2d02998c309880bd273ab1ae1b547a6573cdcfb132b508e976f9eca515eb8c586354395e04b6fa828cdc3e64a7d7ec0e1de3930803208f07f32261df61006de3b3f86e16effef1877d05f654c12e4f95b46e2ffdaa5b2ffae4bd5e5527f3991fa95b2da24a8cbe7087c2411defbd270a68179e5533a1493fbaf19979080b0cc717fb4825db3b741a110a1db1296c95d8619f26e016cb6d928b29bd2cacb75939b68d68cb3a422015d5054ddb56fae3d4f7372766da6de47819e2960d992752ddb165060c60d50a08d626c64a412274346f644e46a1bab7913627ce6f27da8762e120737eca8b7664094fd70b3ab8a2d58f14f43f84d1ad52d59605d7a648413665e336550ed3635c2423a0144051130a5763e5d2e44da313bc20092e11c7683f1dbd67ff97d0870819b398999bb869124211dc1e8a5e24645bb26557f924147bc486a057d0614923a85439a526f10157012d0ef735faa9de0189c7384b2476a1aa0e614645fa338c1a0a60dbe73acf454a120fa1c5eb508f65094825d33783438391aab81173a952ea48f09246cac0ca579c526d3436efd0319ab4105844e3df61895cd156ab9007040961b2537259792ecca1e4db435b917456f1cf7f78d5c48ac17a047b1bf84805e82d5c3786ffd0a1303744a893d2cb7bf6dc7d3135090cc762a0d010599377c5cd97496b1dce4b12d727cd21d8435e5219e33e6da280ce1304a97f618e7e7cca3295ef918ded0550643d2a09b4fce43ba2c1892a7f60fb2e113af2bfade15299da5f5f26525a6392029352a8c5d535a61b031e9bb4590343a0f193d0d547f67ee5aae8129ebcd87db76cfb0c75b24e6a78775b195e5ee20444a4540465e2ea10bf3d5146f86a2bf9184dc69057cbcac5220a8fc4d62649805664a097afad2c98837cdb39ff6712e7f246cdd10c789764edeb95c2475b6ab1593248f63a3f362f4093d261a7970349760e128e06d1fb874abefc2b239de3c81afba06e074da25eb7de91d43fb69f27c7c5bd6279ed13d3e4993baa620a1d18293efe147335ecd0916389f633392e9695ea1d961050fbf2da3a4a34549c8de356fdb183a5a64329460367bf9f0b6f574a8b52976a0ea3c366f6675828357d010d4c340f4b00180e1052b336cfc3581a0aedca2c0e494a10b9a2ab9aa62d48435852676d20e8e02332434bcccdf3b5723ef71f8899eca43ea69cc148e28878fa8a64f7e94593b4b3bdd8266a94bac15179960ef57b4f9f56f33ef4e4511011d8561c47f2e7f91ab13fe6ec7e79f9907896d81ba6f12995020ab5721856f290d430199571ec14d3eba4616e18383d06739fe73efbffea76e61ba45cf218a3221e7e6afcfcdddf92573db84cb9a2f4c4428b0232a7206cbdc0373cc912de5c005a78fc6217a5371ce83f242a364a803236f5ff992a2007f4101bddf239b6a26a3cb6332a6108e531f3975c3f45ddf0313c0c5889fdcbd7a264989a1e180e787531a0ca658057518906794abeb3a848a168d0b81c6c91ec552a42bd6280b089c624f1b9409ba2febf9351dc1f7c83afc5a162b8885e7433f45da1a967d738cf4db8d0c9c1d650911599ee284f94e68a4f91d45bd8a412c56870baa8413454acac0a27ebabd07d8351c4c2c52aa7bb34dbb0470417a76c68a951c809de3fcf4840317d070205109b88153e6df1ac5327439545ba7842b95a14b271af14bf91837e08894a0758f7ec9d9e6d186f742223d844cf3f69d425e9eee4e33e96dd58c1c5fb6dc2c37f3ec7fa7c1ca97ab73b5ed9c6863bbcfc7bec700f5b4657853aaba8d7fc775a5c2cef9051077589e52dcad5d8a318ff193b28e0db727c9c221a97c65ef5269eb493a6b424b11c433942209fe49644ee1f48f2afe2c814608089fcd6b961055277db34a79b3b6aabd99826c386042dace672acbd12de7a25b6de5cbfbd50883cb7a3d5767530fb95e0ccbabbcc8e0b7a2271dfa02a47731c4a73cdb02720970cb5fd371bca6786d544a6a6ab5d21b1345f2c8672f9d2289cd794fbb719c22ad32fadbca744b0ff0ea9ad9bbfd81f7740d26be7e45d1a046242b6b6a798d637b2a81ca9f4059f24555fd171a67da7dca9a246e73b921c8c916ee62a6648eaaa1ab69ec99831257e2649687529e0a252b9d16b457b0091d2e0eadf4836a68b7ee6c087aa02cd784f09f24da39b7ed8b870cdf906ae632d06517fe909182d83a3ee058f49cfa6e15b9e43341b79c7e0314958b4a03857554f493fc4c4fd2606d2e615c38b9e1a2bd46070bd1da1336520adee54ae711b9581426cfb6cc1c4dc7e0319e156ef50ee6a4fc451a51e34a79d57c1b254601bfad1c82181d1feddfb4912840514498e4085c5f999f2f92e28bd0fb147764856a7c614a973884f5f51c9e698b368a3a5c827cc601e779292b37a4113700bd8cde495ab390644be2a71cd6b4e44193d84bfb834314a52a09cdf9e5d3620030a43c67c6bab20fd22bda51f534c2e45f8520551222659f6f475516a5cdfefaa19f459233db1703620a34774572782abd64ed64280508361a1b239dd3341c4c5678cf6301a88881b0f294cc312af8db1afa3417945af05e99da2d3b9c3ecbc9144e7cb044bd0338d581e6de8b3b3cfa0a3fc9026dd5f8e5630fbaf8917cf37b48a7e074017d1aadbe0a36f3b4adb2632e2f7a7be872d8fc7a12109f4a79923227f53a2872f305909934856e676a8a728354b3c9e140764f715ba446d5099bad88e4d323724248e7c4c43958f028270778f6043f347a21a483af264f9db0b6c465828877abe860f7073259ec5cbc50e93810c0e00152f8bd4fcd6bcdec74b537f5d3e83712eb83a48c2aef72fdbb0f8780f6c20c8e6601817a897b4d86ce773f056efe79c0d3c245a4158af4a8bec9ce6d945402625b89fa38429665259d3a8e290e879394ec2ad48ad0fb28ce979a0ded88e637b0de7cabab67f7610b7552f51dd97cdf247bd881d98f6bab30fcdb12b2763bea1121271352a00fe421ed12ed174552bc83c4ae8131381d071dcb35cadb7fb4ad59f19795b69fc3300666fc1d7792fa3f68dbffd0b0589dca081ef2c9152bc91c0af9bf7522ca5e10edbb638207a44544f65a85592461460b56797517331a2370fc9e8a78c1c207533347024f4f860422f551ecfac780832e94ac02793c983bd755132400d2314d81f14131b1a53bae42feb4c5ab7ccf5efde557425cefd3fde76992ee95137cd294f29b257d2f0cf15cd442f2390ffd5e42171a4c13d091031aab0c8e73ba37a30e70f9fe69e8c925cfa64f9da7666d65850051b71a4ef19ba90412206244da38f02e8612e384bc37b9a497187eff5370ca1dd8c7596ac27957fc5b6ab1e6f5c6086419c86b9c9f8574e7db313ef26ef84e0e6e361b7d57be759e0999a1cc15680772ad8073e6d38f6c71d3c850183ada5083f3044ca2dbd35a6c29886120c72d8b6d7975d88b66342cd3b00a88d25d77fa0152bd1c81052dd6d58596f421332dfbed617b74aac6a448102ac6e7cd575457eb0fc09be3d8a602f8e8864536f72d5252769a88920d357864e0eb145dcc3e980ced3ffecd3e0e737103c66198f456fecabf99ff17ff86d0471e89672a3c4b3e867c8ee048fa3fb8e2c100ff7996ae1465581dbc2d10e3e9950b05d61c1ac3fba96daa9b8a7cc77b0a0fe357067b0e1de0f4e341569682fdf134dfdd936abca21a9d643ba74019a77f1853fa2d727baad3212113153a95128efbc2bc2352a3c77231ec401859b8ce63d41e760bd86e2ccee235bbc66a733774426634b2d3508202a61e431620a088dc56f9e07d454bf37bd8f201af127bb419d54962d41c4a1c8dfcfd792775acf8b00bbdb3c816708fc1f9dd8eaec28a2ab3eb7eb0d92a87fe1bc4bf634026183680b1cff517234c07ff267130338344f2f1aaa745a18d6e923043a353205261a945eb98ec2f1c0e8badbfa90bd7de77a77c1ef43fb3269ac8e39dce5461a05d0c34feb575fe7573a6604614a3b9b4a46cee87d94b90f90bc4decf5136438634620b444210c4a35b439187cbac9d2727c8a5a3871471cf103ff959cfba480b5b36d5c75e075613767c4bdf4430c39f2e0b6da940e03302c3e8fbdf755978e7ff792ef928fbdfb2195318e6e163c6a28d59e25b095ec10667d86e91e0f2caee9161cf6db31a78379b084e26586fd427be947b6fe1ea0074650d89a731facce73d9f04bc9475ad3519184eb404406081f7af8ac0d950479f3a7cdf41d6e80156e837e11840d7f56ddeec41cf192b24470a1bf7fecbd700495f76b49734c4b0a6c32fd9f1d6ec4d47ddfdacc2d45408d6bfb32c2132810e6680f267b4bbc08f765e5381043ac658114df3caf55f03a9395acee3310af7e5c9ae3d473cf30da710c95e7f47fa4e4eebc3e8796b65512c6d87ca9bf863185e7194a0984e3d49aec43dee50d638aac1d3d1d519559c8e69260e9249bc4e2348a720fee6b875d74d689f7419e3b27f071e79b1b48312275a9660cd27d6f40b6fbd75fc813ebd5c6f8d86bc4dc8c28278fa34ea7ed0c5155e4efadeb0105fae9e08c46b4a78f9734bb0e6dc39d895f98db02d3181f28936128f2bd8e84c263cc37e5bb66714efa2a271632c73321a90aac722bb54eb599d38f83b3ad4c323bbd03f2f93c2dc2c563f2e5dddad92e01aca286d2732e38c8f7ad8dadb3e782d890ae14d68d88ade6fe6366382df59b79ad21ee79488906d9091e54daec0bbb7c7f3230f052cb3ac227a1dd72071a1f6b051ea3b6488b3427ff7da6f733b634f279ae408a5cd375fa6b6622b1b6a6741c545333991189c03f31d43aa16c6f30711259ba8ef2d306dabe5b7b365396f2dc6ac7b8ca674e9493396d3bd4da70aedfedc6dfb4ea45c6b088ebdb55c57193f7882b5c2b3226afc16be43dfa67a5a439711f962288978747b24634f4e1a4f9885b7710931adea427990dde7d7b4ad38e1cca9975b6c87baefe231ddaf78c0ded0b3ae93526716af120464179939a787ed71957a12a9771026e306874d5a0dfeeb6238a45cbff24c43a06f1e4264a299895d48cf2e7194e51745c3800ab0bdd2e6ea10f31cdf73d1f5e4d9b9016317ff9c5e6a1b5d2c919ce6d792b53ffe561f2e25137444a70237fa3d2378b9f8cfda484e66003cc38b7b4c8c8ea382fda43330855829a1ad296b713fbc4cc21c77708d1a161359bc483325edb06dfd327e881fbcdbe0d1d4875d04deb6c735d49743a66ae6cc5ae7f7e1252fb72210eec86ad86ede2a0d2c8324867f019cda5e9f27afa94e6a7a2ff63af2244b29178962c9494d28de32ba872de5dc1209fd0a549b64502284c9068ca0a2bb1043a1f7a4d341a937f882033df312d20293ab624c50fab75b537c9a05876738a0ca4c098214ed1a4dd4c92cfd0876bd70bf2b787ff207615dd34a85227761faf5ccfd6083463ef427ffea3ceeacc3d2fb2231d563e5bc8c5c636e3afc5ad4312e3d87d4061f6107b00ce2496f1d641231b98c8eb24e1e1b6f650ffb6c5809efc6111c6a558eb296725afc6e20b8136deae74a5c68cdbfb90b8c1c3bd849f279cb282807431fb713270370bb48fdff787b8b25eab5245dec8134d862188a9959333133ebe91d7f559deab88ebef671bbeca976ecd95a991f652e209add013b5d807e2b8024a25405d9349350e38c3374fe7969ae72383b26837f9e712e788dceb466a2ff2a8fc398295f6ac0ef7562438469c93bef88a332457f4de600345a5633555fd25133c03494acdb518be79c57eee811923914d06e140a63d8b4df2ade9773c832d55ec52640c0560f14d73c9708cc460ed6ac39f0a18c19cff6320209da51c8b8ef746cb9a9c07ad5e6d343cbd5a8227d21542ec86e14c1324e2571f86e556c90e940eecb44554a486d26d909ee61707395d484ef2b0671f8920a2f8e10139f60896af1833cf7495f8db34c6eb4ac0cbe581a6609213bbd7901f672105658ebefdc97f9029861d9b3e4b0c499d6ef110e92d00a76624a03fdd9a85283c379c5c6b2848aeaf7af1e0a0704a3f17f6097826aff79ddea7feda1be28bc391cbc0a2f8c8518bcce38bc39e27845a8fc5b63ffabbf7e4192798fe1f0163e6aeebdbf5088951a15682d7ca302acba2c82ace018347ac5ed4b26145b956817a3fd6812885785513c11182bb6eb242ba5773f8c1dde93a8194b804c27a4fbcbe1cc4476e0426e5a8ffb84a915e64614fbdc7725d67fa10e73ce51e57b00a7df82f7590a3686a9b4d60e7993660ca46ac0258e5675f621f6a471d5a47845d88eb220e72aea81a616e6d44b586d98cb67beb039d943dcb1052346d24c13eb78f538ddc60d278cc5a0dd89f8ef9d4860fa00305ce50087fab66134731d7acd5e60511ddc8d5595b246e5d45e75f2d05827f4a42280e5e1cb9a146b1e6e514a3e2507aa774637e606d8dae063a4233182f37ceaeea736c398b542f30b87fbf2959715af22078ed6079a254e2b70318bb46897f03ba7074708a6e2a7347eb734f70786c1a56a7a41634044c16775fd26bfe19e4dfe347f39f5d875163561b890111cd4c5768a627dee79f7ea2ce7154ffb30fae8e0cdfed960fb5edb724a87f82e839a751d0de98d4e6f27df26d473b9d0af48e0e37c5f50df70c2d0ecbaded7fb6c1dcae91b4208d44da75e32b92070fa08c8034da9a03826438093a47627dc55a01e1ffd093e398e57a0a36b9b7ca0535ad71331e195307e6492f88e2454d545337ea5e623f5e7920250de4bdbf5e2d77b8676f65318344d7aea25344926b385aac711452ab09a93888c50de207e243e40da6488410323ceaca60597e437f6de18db6c2a659dc3cb77a961c259b62a87de0d9e8241c27b258915a96ac830585cb275ed3494f89bb8b53ce99edcb648177ad46d762a6f3dc0ef4e94e8c2a6b7041c85ab65717ccc20bd8b5e5b9921bd8efd0d53e15d4af16a8e46319cef1205cc50b384d09e7757a8e9fbb61218728c8b7dde91d4123f67e534625c5f80fcdcdc67d2c3aa0507f0fc1cce2b4dbb83746ac67f30bbde02f900b07035d40cfb016ae6abfbd5dd314b072150c250866854e597138dd95255175b52bbb46d8e5c7fae912c0ba39260eb590656bcaac03d30ca93056789328299f3b3dd9a2e91b467f1e1cdda0fb99a4d2b80a637f6739903b79d13819fecaf51c604c995d56f82451e77d84c96b0c8120b7330fb197c39af645b5a003fc9de94e280f55c6dd3d89ba3be113fc9309cea9ffb47d3df0bef077dd3b462ef7f8b5fda7f6fffe87fc72fed3852be24927b3b4cc02452ac7fea16d8f7573d5b92e0f01e83e1f5ea97bff011d1bb20d876c53bc2a23eaf0cf40aa9f48bae2e32fd070585c50a4d5a427c954fff7c1ce8797b0073dbbae5fcfd0ebc588a9a3d3d37424cc2fcae074ea604a600cefa2892c626fa6263f346b53a70294748fd233532be1bb2686ba7a5388774498753f3fe14506da855a26f113901150ca728dc23969348ba71ee7937275bba96c721b04a45b5d506317938d61442215f44d6f258b44bb1de60e4d0470550d3e53ef853d5bc614c5b560c9c4659eec5f074b6126fb229796bf3705e647b43485fea84bc723cdb1c5c19a48551c5e10fb7c94394e2e2e2cbf6e6e41d888fb20354bedda1bde82b07f395f03b60ef83f1d1d88af92009567985f06d84d7f6e98dbb7ed020057518f61a0e93245fd80b9f016b3e83ac9c459616575ad41d5aa581a880c74e7c359251f6875f68462d9f17f25cc7eb00fa8fe16431a0bde92f6a18eb74c9c57951023fc07d9bbc1417f1c2e844bd6d9d931fc376714f7d54b65177b48944176b6a5775cef6a35317a95bfd1c3802b8e8c7cfc12c338192e06946f6348fe374331ca4dc3ecf3ab3001dd40357c0ef4fac0d3c3bed47801c0bc305f7a4790c41cb51e23e8cebb39b6e97f9bd1063300fc03946df8f0718a97641a60a8a6fab53d1bb17a5945ae4794d1a1e52831ab5892c7ede41160cdd5c3f0a5ebc10e4ad4d5747994e628301e638613972da63b7028adb9abd1283924dccf8cb4bb2900e615097eff12669fbfdbc8eee13f6194f1894b1a91a2530f308848b90f4068fea779b00890a5d1dcede488fcc3955418462f7970382d39156fcc59051911c849852205896af8c9ab3a568da654ad273e3ea3a67933d0a74489b826858e57fc7afac9a7127157a27b0dff79cf9779aa64e5937ac8d9a5620e8b540e39e9091412d20516be4fbcf5946f1393205d3599ae618e6fe3b7963e61f4fc3fddfe68d61634f5dea7fcd05044c934fc690b70e9b84c9958f819846ca57080614f77fe120fb5fda93650427e4f1706eff60e8cda51a530a855d7c3fd3ecb96f5853d51e76886b67eb7c3a5b62044e62a24bbd364338316a7f4e85273f3b43d2510adf24d828e8697f54f76d85f2f5fd28e8d8c159546fde1480a4c4454144b1fc28f27756b4a4a1411feab98140ea9c6271b06df7da261c1a7499b48dcf9cdd9c7aace21d2241671647aa1dad1879eb7d5c80b2a1df15f1f58904bf40e98c84dd7cbafb780f3cb2aa8571f239c681a0d56a1cb5bb2b7edb524818da7b4cda95f9fb116194ed1594d49d9f425517003d3c1c5ebafd8c5ab5dd114d01d966e9be88ca2ee4f5a291dc056735c84d33c1099fa89422137aa709120244db543c9e5ac4a203d3791d3994fb388bea589445e9583734bc73bc67e5a26880ab065264e58d446aef9fdee0896324b0ea573205e3536f7e43e797c67586c056428450a21e59172f581ff45df3a2f2bb4efe8820a1cad8ba809412f4589e7f57937fd3d62cb4470e545e3accd7d14060622ddd0989680f629c2b8053dc2aa38b6e76f9d81d6dcd136570a63b74d4469ba8e14914bc090d3c672eae7aa23b9644ede30e331cd68955075a240610b136b9a7696e0bd8237d1ef5331e3e1ee89aaadc4bcb6e03bcc84cc78e03a8f935d59d90a9af118be6e7484f884ea9552286744470520c8f80cfa88775e54690d846a9339b97d58fe45d2fcca993af51b16a2c262ba4635f57352b979e99b1c801129f130c572362d5d9de53d55ab2c11c16448bfdd7c61aec02cb388f078581aca92111051b75928a6afe29e70076945ca0bdc3e4dd8701d9ecb3eb2ad24c35be22e80ec7f770d164368471a24915fe88a3b87365ff7418c305afd74d6093bf52166db04060946e22a9ef227a9036a7625a42c91989f6aa6bb30a7445f63b92dfdce96a950d103999f6e039c55a2fb0c67c19fa83bd3c77a25558a1f364034c027cb5d82508f384d9bef2760514e1a14022a4dba762416ad73653deeefd6346ec8c960e9ee2172032456843d3244d487fd522a7aa79ee9423a7b0e6d7826f410e934c4d551f84ddfc5d7544251f21e5b2f7ebc03a11cbb6755d7b6e2062e43256a71289f7530e7b64532d6307011d0afd2517557c7c003ff59c90c9c292790812145da2b7f54c3fee75da321e1d510c3cc05e0941ba76a72a2e79e80cd230d47d424eb04b8717b9a38183eef521cce1c1bae43efc097e5b7ff103d8372667927ea065dcdec474b32517781d9479fb35c280b4b0f71a56e97e5ec659e41a24f547ea11a70b0637ec40952f96ee3a3747143666b8d60edcb0b0f2fd9de0517d3a62a8ca77901cb356022de422852eac941713645564e4efb987a5b3f67aeaba533773fa3009cf34f400b3e36b64d2e0b46153b72f08612bbc28d5c9c23880ced27f652b76c1da2ac4d6ff6101fc2d8e2afccf75deffe2a84693c381924dc6904dc65288039c04ffd8d375267ffe13314d3e0a6086fcdb4f387ce8b07890f77f638a146ab02f594ab74362fbd1ca0901a58d4b3d2a3d982aecb400102beaa34dc0e473e2f0efb17e9e20800fa9730431116f0e17103d334d77efd67ee637867c536566faaf9a108a1969cbbcd1bd990d9afb40009bf50f8d113460bb6b06b26e2fb8f2568ad27c5ae3e4b6c56d7df3b4710119b7cf971c5f15ec59fefae0f21bcd48dd5b2f7292dd5c8ee3ad66e2010c437488e2d07c420f0663396d671442c124f04a0fb4395f20e094552fda205dc806bc31d3a15178186ef4d4cb3b93e7cae333c96e7e4f0c91b7a05d4c6d1dd4b6868f0fe7a3b9e8cd0d4b4876f5a0983c4c268806e16f483bf42e9c7c48c0edd8a0716b6c46a9a22899001fe82b30aa1e03ec37d042b8d4a72824d7edff6c693b620319b50199fce063cd44e5e08fe746b0c52f845266eff416d5b63644646d428d31e2e32131c051d5a4191ba75ee8330faa4600be374f01fc405b7ba36436b61c6489a5d35b2431b8273595309700e4b7fec8948031b072e75544a534e4b36b27393e9a671dbf01e4978b5c06dc3676b5ca6124a804ecf5bd93e8a684ada7c9e4206b870bc8569908f47e569925be11da7ac49a31260d0c7dffee280f0289dbeaafab51792cb42bf22aefeb2760f233b483579759a69a2361c9cef900282de627753fc50b549dba0b13f51b6100db6fbd73ffcb74fabc54331de1c9905ca5edc92fc20fca490f16bb2d2ba1f26cc144ddc21c291ae0695531257ca7682b566284d7849e09442cda7b5b154d7f62739d6309faa71fdcd58b7548ea1f08a592fcdfd38cf6ffc07d3cce0c29cebf7c98bfbefb88d314a2ff17ae3a42734004c10f7f04dcdb5f64d0b0de8131a3adb6e87e875ab7a27cdbb7c7a774538fa2cbea703b9ce0ad9a50700491cf9e329169ec72e6aed47e7b379ba2517b721ee705604ea72e59bfbd02f4f0676b30b26eeb5748e6cd7f146e4a2e4545d5f52b90e14acaab42b68bbe998dcc46569fc56338c008a294741e008b835bee6cfa6adf0230dcaaae4d6c07816f83139b713fc09b4ae094281bf88be1d108bdd3d54e31a9e66e4a8911af17965e0eb561179a4fd8d0a0b2059eb344411803c0eefa5722065d1fa429f3d0f56cb283b354fb285e0de73ca9dbd342f2b62d471d4cb84fc09aa39ecb3027ae4b67a272a0651778a750a9c7907f09f08d084b368a1318166bb6c7a3ee85dfd255f82f71466af7397b98e3ef04914999a125e05a9c3408e35947348b65393c34c4bb2f07cbd64b5028c3212528f295864b3237021b46c70393b91c565f1c2de3fdf71d29770c579d3de446d63e26494c20ab8263f339c2b4e5e06458610a1d5b1a8ec8c9b73c93f8b8fd1a68f55d21e8e82df15d76d7f2b0851f9e114ec8eff7bab1d1160d90844ef0223a1168395b5f5ee1f0ee0f288d12e62ab9dba1a56e6761ff0497a8a3e7b1554338dc90c44e40f089e230d8e36d8a3ed23f794db8b7dce94f01eadc85b8a294c47d4355d60e953786cbc8b01eb12bb81005f1aca1634f41abc9d010e3b90dd708fe7cc83d0b28dc5cb0418243f8022824a22087fcc3666b37e7c5f7f49718a940e2d03d4c6fc648356a14bd97e92e15e17a99fe24e1f7216cd7ea0d276df13302615913a29d5dd922ec86541bc258e89f7b3be2ce05dd10e10bd6ff9664f965042105c29e41813ea45ee057aeb64be491ce36b676cb086d20dfad6ee28301634e71ea2c7c88d1272a67af037e2c16f1c5e4da020b27931a84df225384fe16fc76dcfd93c38f34e34b641c593a160146cb8d16903e6f6bac2b14a7dd2cc7713604922f4cabcdce0cb0d6dd8343907a8a95dc0a1f2ffc70786ab8cf127a9be44f99daec771fa28c86d85031592e67ece4ec262ca218e75eddcb52e0abc72c0916d378ddacf9b35d70155271f61be70f91fd20a4887374ec5911e3ae5bc5a5cfb350c875748db5e8977540069e9215a1b76e7afb978a1c473e99c0626e6562979291fb8db597cb2cf2519172d9c742d669dc0f8c3f8cde9970e6e1afe1337b94565093751b7303d1bf1791b16303ca693682d19b491c72b285e039e72d80769c4426f140dce313da8c27a7afcaf4778a66f3b330908c29882e5e1a995072701ac4c9349c8711b77a02eab1e85044cf15c68616b20ddf5c8e91cd71a9b6b9f7405bcd3e272542c51f661acae0ebb467ae29b86d62a5231d394827ff5e724d4e9c29e40ee099a613d41361a0c9c629dcdd90ae5bcec7222be2e780445a824207653b085fc1f57aac8481cc25eef75aaaa9e0023e7f90ce5b4ee4ac816390bd5949d9cc8f6b4fb24f8ae71cbfe1083a860d702f19073cd30345416ca26335113e212a92bf560f2e0c0b4b39b8f859e2e3fd5d031414ba3d67fbdba2958b2b05a4be94b7e2fcc2608ec7313807f72f42a00f3c6ea22bcd74a22177ece7129fa2d5233174647247bf3bba830bc3b14507e10860482204a7cfd7977e413155124bfe293dffeb9f8b5766e7c7501d7ba0c1296de7832dbc30f1aa965ffbae3f3990308bf6141f5205df7a7be07a89a50c2ae0ef42f9d13c93529933bd0000c620a6fb37e7e7998061d31373404da401136bcdf66d6aea97b18ce3b65266ea63dc5039eba9d901b7aad3aeb3c9531035484ed3aecc70ebf8e046e737adf04038309b5bff34edbe2cf724b50f5c2f96a4ecb183c2c23e6d3818940cd02f051a32963334d52a77d413551a7e804ef09fdc46bff930e23eb24c168deb67d9445d1ff63c7e20dd5d6dd88885f43c45de3a729b7c9c8d8cfaf19579dfe349a81ea39543a046c0590d9687521e20f98c7c9fdaa0452c1bfef7136bf10a4a69b95924bc8c67db4bb4d9c8280d3006f6e26e2a0297a41cf8d18c548f75bf87ae8087d0c244d3b5248f963855ef5354b47cf0d8c2092b9e94ab0cbac6c8b200a04768c0d9b496520353b1f8a30105524d794e2b520ce6a14b19e19a7b98c482c1c6fccb0a2996f1ce7b446c0f68959d95b2432941a91a5c7750e6f3bcf1662c1d130d03160abb57b93c482756b8d341ff8a2b4b30f1da9d214e607d20a7649ecd63a5f265d17ebfb7b1b9da26a7b84c6ed1e27f84ff9b18e087e3793fca179ff7fd8f6c7869cfd6d4d9f08d0dd57d4b55e02d1b0052aeec5722882bd08d76942895d960f20d0ca297a776a2cc9bdc1bc849ba6f67ca8fa56fbe989181a87addffadd639df7af78ff7713a04604c2d5cbd535b5ce73bdb0cbdbb264fd4f98ce6951a72cf899d14dcbb317a8683fa61f7c1af819f519a8ceaf956a81911f990425f3230a08d2de07cd563f36f592e5269766732591b78280bb45c1558386b51917bbaf60c419b8b9435022a8590f22df041355f503ed6ec496f97ed2d62ed55defbc58e373002d495a954f536600de2622498cb55cdfdbb9c80f0e26d00f9ace3f75e1745333fd700e2e1e658c707d3ab810592b370ede96880ad24a37cdaaa9e81258eeeb0bd6ef61fba3d9f10aa9798cc4dd39e63ff2ddddeadffdfebf65e387c39fc87db5177210e57d60b6f0219601c39c3bfb3f44990798fc1087af503b134d486fd64d77a6eeb2d6609ad356c41e0733e5631a64e4f2d3bf84f1d0f2449a69419adb6dd1034905ec771a5efa67f6dd389053c406bad8190026220d623064052d497563ff257f9d9cddc65b23075698acbb9fbd9a5c587a654173b4e875a60332b4681641c2935bcd18bc3af96fb624060760f533b42144395810eac60b97f45464de76dfd785c25977d4a4f9d5828252b3a6874a236ff0e4bed823691f10711b24eec4695956276ecd747095daccd2894d2c9b7986030c7e1e627ab0d02da1658df1c3c1ec783832a952491946fe29929110ae2820a5d1919f22bac25547304a6066399ee6feeacefbfa00e127568adfe035c0df9d527f5bca7fa64232ab6bb1cb1256a82ddb2a2b5288ad1b1fff21e7b83a2703dd0bf31eec13aed2a9ae31a9713db9290cea14f45df8bdd432c55d8e09974ee51be1a9270162b3ea9dcc9acc515114f45dd189a0eb3b6697a559ecf0847ab9020ea4ed16f3b7cba85b4db4d1cb7e9c0a72a05e85e26c49c38d2f127fb9575dae55d7a84693777db7928381c4122859bf83c062348d1b839899a8e67f737aaef2884538a12f7feab895ddf316899cbe45ad1a4c10d87f0af20d5ccd97b5b895a0cf9c665718c9c59d112ccdc479752d8834921c09172791e26b43d406aa46b0b248cb2f978deca61fe6e7d1e175124d77d876eb8d3482a1beb003e361b8a03c9c8a5fd1430a229e5c017ca0dc5f09a39cadda9f7e94b9c8c02bc9eb4527f184dd44ce476ba745a12c588e8f5f010dff550aeedd912d9bf83dfdcea116cbdfa03cac5f94e931b602bc49f3b296bc43413eb7d7ed6469a1db8734d93f801fd57701de1c9c8abe46ed287263fa3baee76423f76afe7e7b2a967c6cf9e6fcf692b96803ff4905809ea4435ae9ca9b4297c3e93dbc243a9a451cbdfe3df3fe7fd56663d81f40fc574edfcefd585ff795ef4bfeac2bff8a61d154dfeefef8a57880298b8ff9aff238220f249cf766c0aa4e27058fc90d1edcb561fd685c306e007c77ee65ba96117e25ce6000658e3af14091398fd2dde8f8e7054d6c7b98fdd0aa57fefd44e9a16282b89e064a125e6af2c7300c8cfa8c289ea8cb69b0d49971579dd14657c173384f9bca781aa96d951887b9dfecfa17a12e7c01788180a356861d8cc5cc1d3b0c314926e8380570d7ffecf4515589575f5161773a3f5fb4dac1fa8bb6854e55b680f36214abce5c3849563825265425eb0db31c24986f4ba9873f76c8663bb3e0ca7988fffb072fa99a31c830c23467a5ef3f56bd54d66afaeeaa854e248616e2771bbad2a345eeed7eb107ef6e9db3179d51f8e1a0d9b467d71ed76a7f080ba4b99a8e47b8687bd845cbbc83ce9f6d7916840553b6b885bb93987e80d03622c510ca957da76fd19274c7b238655eb4a1104e11ed5dbc6ef599e039f739f4fb521403ba1ee7a3e1ea7ed4cb78793dfe70972f650be8a2f49befe49428dfb33a544b99fc7d5f30f79292558511414fa7acd968dcdaa08774f06f04a44cc15bd912076a0cab2ec95332c34a8dd81973042a75e357cb00f82a4485e29578052dbec89c9fac52c9cc7716f8b64b8fc866b85b43c1127c8fcc5948986c57939500a8683eac34f9a4ef674d6acb61e644cb125ac852ef00c50048aaf45392a37775bd2a608e218965f04ad233a5baa5b30d370ec38357ddd07ac259a30cfbb420209b4d50761cd3261e4b2646efbc09f736326287a931b2e587ef9bbc9cd5a56f649732fe12c9ee101bbe3f46c6171f01a5c839fccfcc13df3ea57b89dcf51e888ee3e7630523c2ade677d82cf54413bf5ec15aa610f1df83eec59f166076a436cc5550c2ef0cbb68f7d38fe35c9c595d68524bda87da0ae2473382800381f47a556edf72ef8aaccb8e3827632bb1730c45ae204bd4573c76816b2c632c913dcb6c41f41fd9c3b37bba18507feda3544d154b3ce2c4db3d3dff4fe84ff80f7f797efffe7f73b8e94a610a97fcfe22d81f35f99a6f4f5f316ac51da0fd2613fa37895dd45d482c44c99fe595dcb3b7c9e50fb2945e00269911f2b91a6ac897caf7f3fb49a0934c6e01b9159507de2f2d3e1024e76422f08148b108afad572dd85794acf76f0bec432b7ab6a42ead572d0829fd4e1a7901abe40c879d016b81b8be868b64cf791f155ca3f4700118c7e0ca5a0059f0635744b99b86aa562d404936b10099c145200f2684caa3704bdddb6fc709e6a23ce309ec1ee5807615d7e3f5298634df9ab6b30622d7035ac30c5fc23cd4827840305d7a9cc09a452d0d286dad00733d1981bf9e3879146423729581c0f386a2d784e6be9a907d0165fecdbcf2a8a742fce8731cb4dc496bc4ba9874874d4d5db6f752f9f9dcd09e79abc00e5ec52726933f478e3a67a5c3cf681a81e696eef6bdd5ff2a69898270762f0b7d37464ff4a83de1852e1444c543c5d39d87a4fb0e9abfca6411f2b07c7758e8c2b4fb4496547ed43c0ede63a79ca8989b75e24ac7fa471261a713a5f314563be5e4f45956c7db823c52aee16e6d77ac0741e50954a34b4314c347daffa637b089731c6108856b7a2f3eeb92a67588df8d01b2aa23ece8b309c2b3288a66d699d01a0eeac0d6c3766a4e5c9bb63263d46010834fb032d1b841d35f0d53935ea81ff1ae870d1eb7764b70d93e138076718884a227f5e384c2fa93c8b6a34671c60db53e8a276d202ffed4ed7a2e44f9738c2d4fd858944e207c8b6e7c7e4497007b168f230c080dddc0d95b02ec72248322ce26f8e3bc82d401a2987d63dbbfb07d0fae4bf7db4d4845da15e7320ae0cfa005ac4df4395fd08c2dacc7222d49180ded0e87d46d41b7679c4fc5653b5207a92307c218948ff9d933a82a29a022ee3a2f893084e27195d1ae3c64e92798a4ba59112671dfc0acefa3597d9a613b78885b2457499211f91c92b797e39f376fbc94acf508b956097530ca84083f0314811751f58c9c6f1f9e21dbaf709ec78f1f9120dbabe439d858affe4263b3b3495f10783d47f138338ff096ef27fa9799bc31fb60d82b45d9526ea96a768f07053197a69f30bbeea611034be5dfbac0af70b63465c76b206a222c7b179a56091b485d7a3427f002d41fe8383f1da0a981a1c0b4582e9972165891dd5d061241d8d2ad1c4dc7d6eccb2f16b30496abe223a4c3ae5f62eca3189362e3509b6ed9fe2323b106c490bfcdeb9d0e63b80bd7d30f5d0ee35c453e0cd14f4b18b8131c16ed49e8c4a044093951120e665b9217dc5819b7a89c1c1a0872dba9c7be87f4935685e478f949f8873a6aa3b35bd2567c0cb563797835e408efe6c357e79a841dee05789cbec72bf9385cf89dc9cd977e660329d6e0688193833a7265610c60f9c01143842ec208a32b44d26e098b0304d76c79490cb8f2838be5b9f89f93278f44c572eaa2a0112fa6d278133f57474647a4b61baae5bb3a29ed0504852c9ea57e97c67b1ea0f405e82c51b72479454142f766b73d69a2c36dc85d6669402be460bb36799f603b077ab550ce2290bee902d00763a511312b723de0851ea9ced02a62f0a283c6b09d2e6ccac1dbf52637e211061a4450aecad3c52c32738cf27a89acd9193fdf3cd1775562277a0799a56fdbf3727c3f3ff01bfe65f3c7af89767fafe0b2be381f7072bfb0e4df9d00a6fe2b930f686b6f6e66a9bbd5527234176fe286dcc1b4a9d5696fa5eeea01ddb6510b3f62cbf5aab9480775755b148f697f0de940d39dfcea3d8507851c299f9292306c2143111243bf28661a38b4da2e6a8141b1b2d45e8c28ff22173d64a49c62cd9611e298bc0b3b211d25c5a2ac6f272e2b13822931512ac1a4d26730ace1ed91cb53bb427b96c2179b4d2d11af454b769b35b9d04a2f0c5571b35ea3f91268b6fee4b1e0f942b6229776b2c9745300e3f5b2e76590d84de295051abe69859960d2049c06756c58a4f0334cd4c4899cd28dee1c09da18b25f293eeab82ffe862f3f6062da5968d33da2bc3549fb6b611a1e8127657cb51226237e45838c16485602d6bb4b9f7f46bc834f22af1e6835c3e9b4691e5b932031e475d270612af5a91461f257035ad6739753851998e1eaaa063b39fbd025b2beee23248ed00b14559432c9675b6d4b68b1fe88b47eb9fc806bd4cfcb64f555859c49d98e96775f8751345200e0bd4402be53e035a3bd334f027eb0a90cb1a384f2f72e5ccb96fbf31a95fbc34c395693d345de786d5130c9dea3b881a95d78de2ee028bb2d83447573994beea327fd4eeb3e396c0ee3a076571359d704e16882350862da72c7e019ceb6301f79c31151857796bab0e67f631184578d6aa48b4c075fc03a64e27b20c93adf5270cedeac7cb5e19ecf435ab1964144136c2d36cb2f9119f04308eb935995044227f23a4e033806fa97a3613ac04a2049e9eb4063df6aa677bc2d3e914b8eb92fc8410e88c81a1dc1a2b5136c713ed43e521f7c8ced38410da94fedb44e5043eb6503ede97c966ca1d13e10fcdaf7a3fac52bbbd2e60244d0aae74a2e3a61f344a7644e1d25ff9fd70613aaff80369c558f8ffcf8bfd3fddedff4d1e22e0218b07f9b81a533c09834435c8361c182665079889df886f34775587e5565dd111296ecc1cedd82c8368921f8bbd6499d191863173dc7dc48c7e57c6ee7293d063d2e904419524f97dd667e2174251002d74dc594f2669c8563a63733b2e8559438fa2449fee70c652bff97ae6b893fd1cde5c6b82ddb0a0761b8e49901193b6159cfd535d44388d65c7b425a57e45d0371e8579ac5559bf1321e71513153ace14d358d54807b055cc6358720311061f85d312cb4e3b9ca164f6ee75d8639ee615078a7a16a34a069227f612539acb7ca226cb277aa80824a51da8806d348ab08ba2675de90258b5c2179b5e2615cc24e591be85925167fd361f347a725f634d9e816870ff08db727fa1c494cb1bc4ab5cdedb81f503b709f13edafb0d50615db68870ab254e09f40bda72707b6da4b0280c7ef578be7972b416e872194a6d9e69402768940aee55d7f8f901e679448109e53da85c8e7aa9ba5eddcb48c206f6eecacedf8fc8043f21b18794caab081e4b2a9b0c2715ef78c9fc5759f1f8bc4bc76a55acc077a8b4b440e3b5b61f6a5c9eee811595e6152b09f04533b94c576ef30e3a2cd67259675180d336720b3a7aaf90a75effe66fc4f23adbd4a7cf8d0d940a85cd4436cb88c6a919764c478ff811a77c41828b203a5ec4c78732868572acf91cd57a51a4224ba499ea3d6e632602b65e6af59e97229ff44d0bd4187d15e055863d93c973d16dcbd4c38e35d5b4c525938cb8938e0d0342ade3d230812f5a6739d2c5f6f38ae84f46172fb9457de7b51b14ce21a93911f772b62a64feb7f82f8b9d6280f094be1932fa041aa14f7b7a23220f35e28c95988bc40ac2e447ae618da960acb139518f4e6340d59ef8260b33ed58379cdb475967f1b38d7f705b03f7a63222ff705b85f95b7b7419fa3fc06dff7bed0b0fbd2f243c9b71850f4472730abcbe8ed377029a0aecbb78e307c165049915842c0dfc30633353b5f8c183cd67441d827445ceaff792a64b7692246ea1413871e2711b3e22da7fd367a640356dc04dd21ac2f43258a06239362a99b122d8238250b8a70340a20c0cc586d0057538223d43b8d5a853dd172e01474d88b6fc3871f2625f8f12dc342e8ac438fdec6956e22a8a038478db85bda068e7d70734165927a179896f776d12899e0658a8f0c972b8d76dc0b927f9cae5a91e04cab01fe48f1c25a9022258d4a8386a7d887a97c5f2f25291da8d09f0dfed213e0c6e687a0075c1de31f0f5b5bc6a1686ed805473eb0c1f63b2270d24207ca8c472dec6a1b8ebef0f04b936b11f1d963bbf8b3587be694531beb044c3ead8c06a5504e5574d2ffc5aa30b3ce7b2262a92f60c1a05bb18962426abb7338918b87a08f675a5347b5b04718ec9ea11e2f653c1f576fe529d689d92b11fc788629c7d31a3b07393841670f5ae77712ca154565d3b26177de670f2623cba350f6503bca621ca5d726965fbe14e126b2c445c5e6b0378408c6a87a129a69e107923970d367c011a8cc1679ccfeb92b47ea20cd0813eb85c57d523d3feef610dc0433a3280c0ee8b863c20626a89ef373186b9e2940531cb78a4ba340cef6d40f109af6efd7ceeed32368e0ed7d0b46d69152ef39f98b7230ac1e4887fcc86d37f33a3f4ff6007ddffae2f0ac199c2d855c0d85f3ad07f7f67c82008c13f18980396a18885b691554036842c28d8fa2a35d4915976566c470539022de0c57ce11385e117b9f1ebf7d88e7cb6f60fa02d94891a8c24733ffad9966816bb11d06bdacebd8524c3f7ed37a2533fdd2c108cace2a296a4bc750dbe345dd4090cdf91b0641cc3471ea10f72c2a09d3ca3d2fb77c1a0372c5ac1cccf9025d5c39daa79ac10b718b24379222b3f3f1c59e5c96206a9b1d8dac9e851e055305c722f7fa1d648b95c415d217c3df0db405b25e59dcd8e599bd633712a6c65cd1f01ee318080b94444362f834cdc9861168d5e23544b723d211a635ed22652cbdf0493f64d27a285e4d77672a887dd25501d4bd95d7e4bab1a461a8138bcf28b96fa5ddbb44df89b2c885c347002d7a15fdcbc447ac7eda7883f8f9a84e5037e0236338f65f2fc819388c88f16cbc902352b6215bc32144a279da430989092fb8a462c9991259a7f638ee60d741aed83f8b92d4dacb2743b220e8a11d4e428ffa85d6e7884dd77d986f994d94e5901252157661c310619d5395e9d54c619a1ee8930de5d9eb99f38f20c14b89b2cf0f758d869783c0a65be57d018421c66e723da43a66a8f795cc474ea9ab2d5ba67fe819cadbb06c168a0d45abd22c1ca959d934d562ac64794e08676d5324011e5bf4ed7d7bb458e73e5ac003aa404b27ed7ea66efa789bcaa7244b6614298048f18bab10983a1af67b826bd22d1369cf8b6a58d4ba873f71bb930b575c8fd76cd052f15862151063f519699f87645abf64d5f6bccf62bb0f4ac50f9e4c897550e7eb5dbecef1b046ef7962d657a2662270f156d18299eb2fb994c818eb3304146c7025e2e4d1a099a7c854cecaff54f861ce06856cdf2ba2673cd3626f21d87abfab0cf2692d6c91e567b8f854516360ef66bf27defaf53aece08e41c04bc5c71701810a24382cd653648ea3489083bb9a9d1c9422fe26017c27fa7f43380f9f7f9cf33a9b468239ff4aba0568e334da404487b2df44bc1e99fbb702ccbdc9ce79669daf0a5ffaf774efc5557fe4b3f9eb54af082b1a27e6fe89d9f69ab72d2c9325ff3722bf5b3dbceaecd70b40cdbb50cb134aae50a5729b7688f5fffd28084d760bbd89b13b2d0bec2c616a44212f223bd86617b9dc55612488815885f2ec448045b04a3c4b1054d0557265294af4beb807526394062c8ef20911f4562377649d385c932ab252a206abc20e886e3a4919d6d09342649f9bcf6e367359a200534ae9a1610f8b9b3480289b10827194e9fb92c37396c33735e67a8f9bc69078aa868bea77f88e417b622b3efdcd5b277c6b2c899c9ad50cdb2febdefbb4e736745d4501742ae213c0c7433ede0f698d46be643c932b089e0d045a4794778634936e2d7e4eb3a7103a89989c8937d5a3667425daf77d46dd5b4d1cdcedd39cc00fc028c545fe8c36e50d9ca9aad31ba026d1fb91d6d9a3b0673404e6a36938569e8168c844c85dd7daa21f0ed9de2327b3a1d8dee4fd69611f34f7666893491e647aae3f41363970f9100600fc669259d6f42688499fc85e1a59397bdedf82be6372de562217a9e060d186e8945c30ad03d398774590c49ab5758ac70df21d701292925899fb141bd8f79948e7a91bd453cd0710e1d3c57e53c05915f9dcdf4a889590eec7ecccfd56dc45bbd5fcc3f7d50e3ad9cd6e488de72d17f2c472dfeeee2e5589e89cae170b5a68d2a663a3f3890a482aee335547155ac6f7c6d5a166ed5d9f360fa3fae29becda19522896d62f4ed325015d629a956f2863b5d1a8ea7b47da9cb2856d3f6045fa9dbf4b84b84919d547c0834065d6468868c0f6bca2c3ba66c386d1a8bfa30837b6846c7a92e8617487b3c7aae1537fb97c678f4ba8b285645113eea316cc4998b433d1a934872e24744bf5b1f801880da3c9e5e301007b2ee612748f722c4d58e1d8a57e3877615f33990f0a2db006c8b8788e8d554a6977081cc90a9a7318171ba19fda92612c763e6d48183a07f26e5b117d2cd75a8de0c57e60f89c7b161e7f2e4d7e01ee0bd8dc28d6fe18bbf8912c2db74181a4ad74b808355391d435dce615512df11cfaf1f7fecbb43114bc58330259e40cd475d7058a3542af32cf8383ed007c53512a8f00db30b38bf5beee8c56b70403918cb0560bac1ae73eccf263703e6b1d181642e7417b7b6af6071be9a90717d5036cd354f7109f8a8efba9a5cd1c81dbdc621d4d00999f70a53dacd8af9b416be90acd7d9e1d95adaa9a071cd338fd24043b3fe3b5e2fd01cbad77b6d6f5b2aa8bcae33c7e109b1ddcb6e977173d6976db0ac94caea6031fa6b3894aa5b27faa53588b0f8fc199a084fa5f87c206865bb7aa85370f2885b2952645a4ce81a9ece455ac3cd4a186d508f6400b8635550982716ca85897774333447945bde763e11b21ba44c69a148886f3faf098999b3b28204dea2f8894e54704cb9aab45239b651273aa43037b8d6f6bf3477c64ff26a906084325fddbb884893ab3b115651488f17b4aaaf7e108b33c9545e8b805c49fa828afa70612f1929b8978dec97d42866cc86a9fc96a569cd2bf01740fd3d5850fda2a526d0a203265469f00914e9bad86925583d8df4cc0fb87bb61e7d788bb24683bc731386e8dad236d00d84357aa5a8043393f859105d8914215f35b90bfaf15410d8e457cbcefde4b2f6058411bd15cf212e38fb9435019918698d98a5b9a6b713a9de6b7f16a6afcd9b90fb80e4fe6a270a6a10e769989cde83e1d13a5d5625547f5dcdebe07ec8ba91a00baa84fec14a85f6eee74e3e5298f20db4efa4b82dcdb7947e3271bf9091cf1f343e824d947e27adbfdae12a37ab634c5ea8b082d6cbc4f31ccf4fc1c12add9352609bf2db609a952b46e0e0add890fcd2d757c463d59d0c34e7b796e6d5f305b9131e6f8cf8435edf5eb079d901d6d9dbcd0beef19355c5d066a26b0fcca7b493c033ed3a5f9a67780e0e19735cb73799c38f9d33d8bcc34b8c5fbd7bf0c106c6a5669a6007f25195d2a5a65d01001a7b71be669e6ffa302a2aea5c12797827968b609da7633a79621da82768a61bb7a528348d44d0056464749beef0a4bff9e6c69f1af56d3fc19cbaad17509763a471b309c0aa5e495d29c4c8de0adc9c42fc14c318c1d46aecdd54917bfdddc82610747dff6e138f0619498ad14b94197712a3a2b21fcf2b3fd39cbd8e55d426afd047377e58e4e6863c491560fc20a1068b24c47fc5cf767f8afe232c3d765ff8f7d1cea61f557fe18128650fbe7ac046eac44539d567e7181ecd072f3b5ec6f524837ab167f72ec241699c200b7f6faf02683696e7b9a759ade43d130347608dbeb311a6a7a0bd2fb108ab773acee789aea40d1a0f81f498ad9d3f467ab9e8af9988a7ecdcc310840f77fa98b9bfd1d44d057ccbc0d0b6865bc5d3603080b80d8eca9fd8dbcc01c2522ffd22cdf486ca4b3cecdc022ae0e4919b2909b3b99b4b1c031e2c1488a1007896feaa8eb8a0f6f499e5a915bf7a8327eaa143a3937c88ab5c3aab1667e3694ce1c549f835523016c42f542fdf8dc6782b9e52ef17da99f5761ff6fd25f0f80ac215f7ddad3f8574538a437c86728331462bb10711d052a5c3053f5e3258e17c18a4addc8b64ec5ee8c506c13a845aeeeb65cf77ccca8bd2aafd12765f62589e72b587712eef40ee46c53d2df42e0e9668ba00d484c75f78cca702a071d71b7f2729f97944e3d5219632acfe1e64093e1bb0761cf37fb0f75f4dab6a4b0328fc5fe6ad6b6f09a2b2aace0520195172f8eaabb748928322f1d4fbdf4f01ea13e7dc73c7f766af2ae7121f18a347e7eed13da07da38ef8b4d85a890ec95ca524c88a2b501226d74d42636b833a65728b28a75d75b0dd90dabb84dd228c8717f905e708b73955a7c33d0b4db3dc19e635d8523e9a1fef411e14ccb582760abaeb106e8df2f9d9c2f2d1567cf07add2ac7fd39a46c5f2d1915cd353cc8a292b781f5358d42c5bed8c5561ceb11f2a3eda14e6f38885744a38fe79bb62de28332a8b186b8eb2aabd028e0ef8581ec5c54a9c5159841e91129d328487bd58740156f08c50763c5c0d71745b0af85a0edec6dc2a93958ec78211b2e1ea1897010ad73390e6cee360a2a005e133e4ebb35715e35499ec607b78c2315b0c678cf76b1b94bd83deb1fcb2d045f5948a70e0797bf87fdb001f86b906c1139c575ec06c4fdfacc6724dae4bda283f7b321c25977bdef536d6b928c73db963dc6e261b5692995228761e0712af4a3a383a8b415c38e2a3a311d68a373620a8745e00451efc7ac724713df9c5a06de94dd1adb835e211f30f526415e472797986763bbf103a1b7bc935929d10ea4fcb54a9d3aee6e57c2852f13211a297d4b6f62a605430bb3eb6467f1a82ad64a15a4eb9af49dcbb83204321a3ac369abea7cc9127c43823bc3eb54792389b45dca15208b4d7db0d4a384a6fa3edf0fb2298bea6a90b4bc198fed0974f33606b9203b75bbb830d1435a7ac3da4ddc4d97530e1d99747dd3758a577c7025b915daecc17c0349b973a506df19f0d65eb967503d9deba2eed6dd009e4fd60e04c50b81e240efaeaccab9ad29afae24d7bbb5769c376a92c864bd2b5c65ef4ad87600e97d7f11cf9b2cd4ccf5cad301e676ba7bf61e95eb637af0f1752050e848a7b455efbdb257cfa038e8e79538201e8e9c5638d2c40cbbbe53aa1815b19db02db0152aec5618c93984b6d26635769b9b68f49577b2e0734754e110073896118673ee5d9e3522dfc55aa93c194e34e2b6ee94cdb6b8b2dace5115c9965593364796d839099aed5b5e46c0f890efea2023dc02a930a74144f4aadc1abe6eeafbcad265dab5f7a8a3265e7edda41da2795b88f6f6b734705dc4901db4815503533aab3b09850c277e46a81a235fae55cd6d6f65bbd5ac8b9be298035bca2dbb1cea620a0fcfb70da4128618ae92d22d00ceeb82ae107096dfb83de7b9d18dce1b573ee2371af27c4b0233d1516fabfdb6066ce9d686fa25be31273de83b8cb85c58ff361cd7c712172f5ee8f6292cc64d60f40582e4e2093eac0ea773daa5951fc8c70d71c7d0c8402ed2165f6318e1b169700ce3eb19dbee1b4bdc9c68648ca30c533288076fe2154e7d5cdb3141d9c29a2a881c7a8205de1d05bdccfc9b77079b7bd737296fee09f2ac8421aa23ca0e609aa3b013cf663b9054c6ea275d5b17575f5a470dd556d2959610d7820cff1267827be7eb2104f3b590ef73720fdae31a25f05549c417668f0bcebd37900bbfc50b223cacb340dff7265492be535c374723681a045518cc6cb0db65b08b40e7805cea7b378da5da71efe3350b79386e0f78eb5d2ebba3a71805b98174c2bde1686642b15cb6b8755aeb4e895ef745778318beae983de1dacad5afaf20702a237e9d410ce18638b02382d8388587182c25e26e941a8cde4b56826e24c5b82153f821cef43b066f3b8c5e93c3fa101342db29983b50ec798bb9c5c0d37b834b4f4a1f0e19290b63993a8525e07e1ca3ea88169de8563cd85085b1e9edaadfc275606c55f3de35871579823c18e6601abe60a88ba885c703a78dda2151de8ff4fac29e988a4802ea1074c07960cdf3408e5d7cd95bcdb51b02cd48efc5dee443123537867f5c75c520b41be7b23f93c560b79be0b231d695c75ddace5f87d43008a4d6563ba8d9a62a78ee0eeb502f7aa4189d1249cc5d8536d722e0d6c15ae24eab48cd805322b3972e414675ebb34710d9f2a0dbb61563b7274edd1a1bb1d176bc73d6d6d8e9a48e9baa4f1c837157356834eb0db7befb547eb8823aee6cf553eb26e0d6e09a724f80d7530d7b8182918d808176134434236fb24d180b5015993dbdeb5cca26d1b8df94f1211c92b3a7f52db03b0634dcb3e539cf8a683de62c3c06460f5009c1acf9ee5a459763e9ac4094e87a6cc542ec66b52655dd381a56d107997ccece80bdc2d5d3fabe2f7736400caeb193f3f0428deea897cd105c1279733619cc335bff86b90c8924b1afe80a1c81e24a617a8d94d6dc3dbba53a75532a815f37e773a0c3891d7438ad051c48211272a1b6661a34d7dbf610ec0990b0fb3e10c134650bdb665427e1fc7cdcc3fda974d3f3c9688fd9e1d6ef0ade10ef980dd0a76b0d1df095bc27f3120241863ac627ae525a9abd6afcdd72d291e6e13bb9bfd2c34a4fb24082ede1aedf234bec6096bba8b73a1132b0889184d9e8c0e97addab6cbbcdc01351186387d8e5de3344884a21166ba15e6a5742a4f6bb7560dfc8f56140797bd0f920317cc44d060634e3c076b767fbd211f786a2ce6c6c2a427ea130715398c7b5bdcfd789417abdb4ee497d87f7a3ba3a711b5decb64212ad0555e8726f0c9bee741fceaeb9db5bae1729e27040b75a3616305d6c727787a5fa45b86f4446c0d9dadcc9a4b1d5f8bc00ef41a656764fa9e0d09e068373a5dd3d1f942d922a495522d22148af8dd55ddbbe12e551774ee069a55f0def0659729b0f236be4f6dda0d2e6809a92860079c227bdb3624badeea3d1e1fd86724eaa7eddaa88cb1375a6db66ca239a039bbda0f2d93604afd7baba3577272b1c6d3f564370578b335add0a971e80eb0d37d78c3f984c55f37d6c271e7c3ab9e7559c02dc3d1e8098010544dc54347fbd38b27152dc3674ef355812b5a9eb74cbb9e036ce7697700092dd5a145449c92928722ab144625e09ac10b03621b8f29492d8445c65aaa89454aa6c28d5c6ef94aee6917b5e0332784d41a3d4b3b474b1fdc1a59a1bc9e15ca1e9fcdd270ffe3a46b1d29494a6efb89bc06e4498d8a72be642931a476b2b33b345b446ae372fdc9d7c433deba0e11ee10c0a3b9e39b6ad85625ba1405337e66dc8f08ff856de6a7b9e1ed6bcc770387781933e0e8c065209a4db1de0d526c1562e688b007f00c44ab6439ebac63e1ccab8639ae656543214c975683c24f76b3b648244ed01fbb4567718da3109929e981d736bc204cd98b6de333bb65b41679406931ded6f06649f46cad016110c2a1e6cf8b07e2206e0504ab59781a96d1c8dc039da990d1769d56654d470f10076f6281e57f00e1dd9d070b36ded29a670333997ae5c9bdd35ab6dac18102a5e4f6aaf0c1b36cd92361d13a9ce363b4d8bdaf62a88561bdc5ad8e575ab8b920a976e08be2d8cd5961a0eae021fd59e070feb6baaa6d7adb22f5622a47292cf086b1aed3ce45201fa3e393072dfdb89b06385e6e68c050d77838832f83e5b8ff42981c9d570a6dd8259799bfedcad0fcbb948a29fecd6022b611801f0d86fbd8715f83bf68f973d2fe3d37b935efbc5a0e1ccef63d557b7de1506f68c270959129a1d76022f09ae23597803dfcbd3e12a07fc550754205724bcc8d91b4e27a9751aef1aeceee8c61418f9b295bc157744d592538a61e7add4757dc9f335421bc52580bc5441ad0da1ca1791f110141de1f6e4a1f2dabf14eb5de676d869c3ee651c53b782da986079dfda778a15568520c70c9af180196f1c7f6c5411250a5f880afb68dc2b4541536e0f11a446b1d659a42e7a7646d63a2124e0b8bef2b2274990a199cc1dbb6680addbfd6809270739f2d766b056aeaac155afd187c38d4b6f5b72678ba1646c8b80e132df6fc20dcdadf647881db61798b0d09d64b88e9852780f5f75e96cfb76e7889cdfaeb8b135b9d464ecfae2a9a7ccbe9449b981c07e7045b25580d5065456cdc689ca81d85aa32060a0661cbb8d1c439704690f67f74468e36627f5a818822b9c8c2ea54ade1c40926536a0553f8c497204c6d4e87407bf53c1866b5d99dd5dcfa57cf468421c6eac35e4c409696b82a3347f2c8c06966a8c9109c6e26141bc8a86e0aecaebf1bcb96e9c9def861b4714fc58903109c51a48ec8ca294753e846c79ec772c758a4ea868f6a7e0d41c042d8ece1b7e1557c1d694c06a475f58dcb085923fc7a5e604614f7aebc39089236677068d77b0977471782a95334f1477a9038e1b3e3a88b4738f5dbe1634efdae3d64929071a4f4ccd25a5d104edf256f5f69e728e7222caf67103387d8b752408d4e9c660c81248457eb7391286cddc2f1d416e58197741e026c5595022fcbe61596d6b66fb8d8b46b97dceed04a86fe54a2d7cb1313da3eb90787013985931b8d7c5b11eea6972dbc7a5ac2378b5bfb567ba8e0e52dcdc68da5b1f52b7bd09ab3e16422b97f6ee453b8d9a77002a7eaff1c740bca805345af8700372f3860448e460ce78f78e893710ab0a517810f68646b6b3c4dea97b3c5ec9c6a6c91498a1892c55c1326fb462836e133adeb29b28f680ed2139c3d4d0ed08c3b792dc710ef21e15ce94bed29b41d833ab9bac15aba39c9e94bb83f8cc00592b078d645b64e484347089281baef7c0339bee3dad810830c7cfd1da4b5c7fb3abc33e9659148844c1ed77978ae985e1caa6be5e413a0ed360029ebddd1170ef656684797edd16a97d9184238055758add82fb2e8ed6db5a3db3239dbbdded8873f03a69ae6195f6701574bb4bcf58656ff59a07dbb2deec8d62bb4fe852660a85a6332c318c2b9d631668add4b1ad74fb06ad8235a2acf09a8037e169150837ecb4d646619b8dbad78757574777bc2adf04f9b673e2438b6a5298b6634842d67801ce580ee7bc6a739e099d5a26f4f76b20a989062a87d1b80fc10d514acf6bed6ea0ea3e5d93f724b7ca1dbc230ab0c71a83dcef1d0a898f2eb3d7dcd5b1d847eb156c6a64c7fb180d91beb93e9d1c67bd3bacb9e058d42e750f6458b3d01cd402642def2123c1c7352110ccee848002ea48d03a3b972c9095614bf4775e2f4e7c526da0f0d217ae7b580367ac45cf5db0eb421ac0a013c215dc263919b9b6b336835b67192c46e33d83883e454a7edf029e2cdcf782491a1b65c0ec7a8708d7dbc9189362b5f5b6ee4a6b72be1019a1beb9ae82a5ec1e3899fb55209f618e5e25de8accef19c824c7f3ee24f62b4607bc3e293c5f86fd158444c9fe00e8f658361b1dc5da35163a857b3aaa3eded9c455ae375e581fb05014f51d89828d6c3378cd72eb1569109d47a030a16f782b1b5b0677767b74755cb9f001657b53c699f52e9687e3b1566138b6eb7e075ba10a5b91732efb3882367d5f50eb0c6cce96472611b7dd8b691831a183842448873cb019f73c95079d52d0a7f27a581daa13b0aa9163420bc771ec0f7a75bd33c21d1943a52ed743b61b2517393bf1ce6ba3f38adf906c3728c4d66d0419b20c89615c6163affb151bf0caa6f0eedabe92f9dda561bd923dafb3ebad2fb2f37aed892ab95b15eec0f12b023c45967df1c20bae336c4c5d570a75cf505c148da0e9a8f17c3756d561db6b47a03e11c39db2d66b3bbcd607d4ef1a7bed9c483c6308e516ed93c032d87d77a70ff4e9307aac542726d5c6d970f78a7c3b347a65529c271667532ef3b21c231cad9bbd35f8634d768d34ea9ed23605c5f975d06f4d72ecf48de0dd9b604f17d5d6940f828174fc468fb5f61a0ea714e17adc39ab679da000cf268b8c6ada4d6d5e3379a5eeb275e41ca5760702ab02cac62ba0fbf2d6552a5ec946043b31ca9dbdd9e7f01e5c0f8c7175c85514aeae9b028d77a713128984afa3b9e2a3ba15a1673ed6bb3c0c212ccb495c0419a11525e37c81f500240c42c7b7e92a2ceea884e18c5df16bf9ecbacdf91e5dac4b54290d9aa63aec29e735823899ceefe2c6ef9556e3924227866b77180c23cb3c2d4664385c1da0bdb9320bacd3d29b85e17538ecc05509eadbb3e989664fb9e34dbed05d36de4526b7b4730786ebeb1174cc4639d5ad5991d06d75673abed3a4d5415f6de0b40e4ec5f5da889971bd113b855823b28e5ec7c8d57dcc680133df72fc965b65dbabb8532ba372ae1ce5ee1db8f6395e61a9cbba647a7f2d2fbe5b4c308574aa690cc3b7e4eff96edb7fda77d31ef5be6fefbb545ffdae88ddf05a836399b1aab0883076d22d6e8d84d24c32e22539454a27c05b4771ef69034190d1abeb58ddbaab137fe0e20a275bd36620635fef1a20b22cd3846d6877ef77bbdbfc2e3964b53a16216ed4fc1aeb6fa2738f6bcb6d2949374ae04250e2cebd50b40446cee0132085f6d7b8e5e85677133bc9db1ce2775670073580c62c33be30f041dcd03605a13b971a0c9735132cb1ed12c88ae0648c76736532d4717c3b08db2d6ea8d0000a4762f04efb5d7602430a420551291c51295904f6d5bb28d96b36cb52821eb561608fe7ced651e2545b6c14ddb113e066c55ee3798af4a8f0dcc731df96928dc7cac8ad60a76889a02ee003c14aa3ef0b30110d0ae2ef843eeeae63d58f2b752df77c4c6f4bb61942cac2238163ee0c119d3245d6d59c773d3e47b78daa7ab792bd1d84931fc7f081c4f586a2fb26de033017d000415027c5d8ee02216df2821edd3ab8f587c369f44e9b1206b6099e79d9e5763c6eba2248d334ee4e9b28d6a8b81be47a17846c49a6837fd0e0dd15b8a79c6557c9708a8424e0c10c626e0792de8e7656c5b04ec8516a51a2b0ab1b5f439ba639de585e3f6eec7eb0b14a8db504764e455e183bfb4616014b997811232d8de846a2475025e8a66cc21e875ada65f0c8685b2004e2636b9faf087deb11e649eaf5dbbe66b5d6cd6c078d99c389225ac3d0fb83e807b9bbc59226e5e424df1e5d141543d654afb25eead0b994cb7eab305bf58ea54aa0f546e8ab1188ab3610d6c589dc187b6b15706982b2f0a6218eec06b3a23cf44b04be8277ac415a65131debc0accf8761abacac158be2e9beabfb937ff604ef86ca6682f74968ec90b0f74f85e5a2fd2e693a68edadc5b1a1e353d0614a5fd4125b1534357226e652175815da9de00f395f042bdd0a2839a36d60b8c8a72d8e736372c17dc1c46fd9c13303b242d47bdae743704e2d5a46033f90d813e40b1997751ecd35b7d24bd6fd26dcee94025c591192745b4d0f0eccf1b8e3cfdb338149ab223841f051bb438d0b0dc76cbbc6169db2390091847a730bdb6fd613b37f8f4ef172f46aff03efaeac6c4a54070e2759f7428632b92639df0fc4a865494e3d8cbb5489721592b2ce8cdaa8e0cae378441db93cae81eacc45bb3d76d994d67e85f5374235edf35ddac17a76092ab530d03681d6d82121c6813508dce757db2d1ba97e28f67292dcfb9d10f0d63da829a0014bdf0b82da606f72cb7795c749f219821221ceca1b79afe34dac42097af750c4856260457989d450a47ce73dd2e4c155084430c8a1427c622aa9343485a8b9cbee52ee0ecc2abb01586c6bd0be543b0b968eb7e21c17e9989267c2beb4eb68ac73f79cec2dbbf27acdb9c602ae5f7797b6a7e24d6845fb3bd400c9794cc8c4624182a9d71ae5d511396c980d676c64fecc4088a56af98e0e3611b2351cfd462419a8641b600c7b4ebc79db3b506eec5a3cba837368552c2ffa145a6f5569bb51d4beb01cb59622daa4f7ca90012010edd6699d9e1913b9ad686b60432444374c8ad0608e427802f888778564707fc1b84a0b5c81c76b6b20ef6e2ed87d7dd32c46cb7a3de8c5f2e81ec7c834cd9525c1c1aa14b2f39dbbe26ebd4d564851faa1bbb5fa0d3a9018d76cb3dbae07673edd01dc3dda8438866120f67b3dddccdfc1a76a608a806d8013bf76b6c9018ea18fbff11eb12cf5ee277a24b5a8450f52c412828d0fd5a6ad846bae254215779a4ec47a1c7a1ca5d8017a54e3a0b16b2b49fa93761fca1b875b7b09dff31b3925a4266559df10bcf579cd5c5aebd2af5ba63bec3b6a63131b59ad4cd0ec8fac5bcb0d4f68972691ed7e146f20d614505516d19e2a6fc64828e9cee2a59e149b5188ef6599dfeb789b107cb436b62e0050f1fd7c38ae36005b29475b3145821725f7a2f1fdcdb23d59a2041e8cc8d8259c6dbc6636d601544792cda9c38d4ff7e4c5a1b2bc5ef1b27a52621754d11d5a9c06a55eadfb61b7ca74975778026f41b90de01c0b6192635ab41c8cd444ad4ebde2a752f52f9bf0440fe481c99c4ed2a3535d9edcdad6a4b6715812580b02df87397c90acd5717f04367b6dbc5d3348a477dc080b48b7bdaf0703580d2400abf089eb4ff2e190cbe55dda39798fb6d1b12ad7caea18ef6fa674bdb0671473949b439c77fbbb63b881eda8a8d55e6ee801f12d9ad8468eb1bff2a2d2bbcd9aadeb33a246c59ade867d333638e106f099116e201e43fbf2a679e8b1de37d54a701b2734d6a732dd1c153f11f45db4f467dc60f75a97e9c4a7f9834f712c92b06fde81fef6fe722cfde2b82d75e920a593e45dd1105a00710193580d7bf13c86b1122e943ed05fe7d1ea694eed6b0deafcce1651d6655cd0b2931ca3a2a4219c9ceaaa4e20a29c7d37eee3d9f035caf9cbb8c411ff34ee53b624a523096a8665ee8dc6de7aa3d9d7e3f457798d3109c3544dd72405e4d4d47af54a3bc6bef169ea66995cf53d1ebec05b7c8197af7f066fe50e086019f7c8cbd3e79cf777fdd9dfae4715640c57cbe90a99fe11bffade33b9ffe67a9ef5c0e65b3db047a377a1c00717c633af902bdb147f0ba7f857102e130cb30efc3dbc095f86108fc4971ae6df1b4bfe3216b639fcb41efaf7c6b4bf0c49ee7f3ee6bb1aeb871c1e3ed46b8b82b53edac4e4f75858896187e3c7b10509cfb1e3eff4f0132e8402f37bba4d5cb48cacd16039f20a39f39e71d3737dfd079b05eec8534c4e9727ed8061d8f0897e00a6d6dcefac4fa6f5dc32f5da27e5d68790da85a8d436d9f4a8fc6afe8340837b9e90580c63e65e19f5cbfc0e20fc33f36b7036fab47effe0ff81136f478864ea8043eb8d4f678965caedaf71851f444b397b9352a52d0bc3a62f9f71e59dfe09581f36fd296bc70f673b440c0393b7699e4332fdcb7f92f73b465274f71bfe06f0fb73220ee5e26877c63082653a0ce3b12f731e99dff17180acf1603972e9fe6ff0234172439bac2756a081891fb3af38ded4bf836395460bfb5dffc2b7f287539db7037da2c3b0a10f318cd87f91bf44d9fc8efc89f39ab3e7fcdc2c83bf9ebb6f4720df4d36c79f64fcb0f932b73c96bf33b76499722999e2681b60ecd2fac0917d6b41542dd3d9e8335c6515fa87f7877e0b0febef7964bfc63b0c83c30d8611dd1778dca4fb87e0f9e5bc4c4d58045cce8e759762d8c1fa322f0e48bf33efb73eb442538dfdb7f96e8ba96834eb5a22e4300c1bbff09d2efe961ed49ff0a462ebe67665c3fa6099efdf23fdbdacad8e4172b2c9c9eed464876142f859d6a8a32afd86ac812f1ea4025a4ffceff4daaf6d9c8f7dfeef9019bfdd47f4bd9eef6c8a82d6939ea7a67fb0f517fc5af6efcf0150f16ceb0c11f8db31d2f7f8761a2f94af1b12c30ea749d1285ff429d319bf83ef257ec3ad4204bc9c4a7cea83dff4299729b66e61677fdb2e1f76aeea68faac073de25b7cc9fae5dff39ef3eff17556e34b4676388611bbc9f289dd177c19d63fdae7fddb78c13ebd3372a90df8c8477efcaf7acff2b7faeaf3bbddc8f48bbe5ae5debfea5d6ebf788fd3f774fafcde29e90b5fd381f33b7ec2affbf1717ba255fac8cd17c75fc2b4c3d52d8ccef67c6e4954bee8363a74c3ffc4bbafbe876fc3ab3b7998cfeb6b273ba4635f781bf4fe79f80e9629668a818cb6818c8e29577eaeab937d7673ffdb33fbbee5bfcf6714cf67aa7ce4bfd2d4fe69fe537ea797fc7b19e543e7d6e6f365ca3cdf6bf641468d08fde7cf81012b0f1627dc3d61c4bddcff0df8881d7080e8ebfc0e116f824ff8029f79fdd79d539352b06572d9f7e7a77dcf8f4ac71bd41e98f8719661f9ab0cfbe13f2fc3bf3c2ff25bdec3ae61e6f3dae4b356d211c3c8afbe1a3c8546ffd633e7bec71975952c00b6a6cb7c8aa7bfea3d268bff75676c3ee4d6fb254c9fcf4a51beda4c3efed7d1f1efd725e73ba06dcef544cff99fcf47080a12de95bf15fffc929e7f0f1dd571bc02dee4f31cf459c77d8d73bdf4f7fdb29fe14c77f3df79a7cf4fe8faa98651fc622fa820fba779ed973a8c65031fdb76168631a5f4ad1f64f2d9dfe1b3cf73dae4475df66b3f084359ed6c2e971a861dca2fbcd36e7f2b5e9c79e781fff4130f9d7fc737fdbc37a37ca107b3bafdbe9cfdc37b86dfe28947a1ed8de726f1e2c249677a5ff0b416c8dfc7d377f9acdf838dc217bfabc5883d86472c869daf8f38f7fff97f7efcf1a3726e4171fff1e7fffbe39c863ffefcf1e38f1fa29307d3b7fffddf3f7ea485738fdbe0af7ed0aed3e22f55d68471f1974b53787faeef415e65ce3da8d775758b8bd02dcbfb3abadfabf55ff3b6587737a7aa82db3a77daa0f8cbe3eaafd5adac82db3d0eea69ceb8b894d3fffde0eec4d9fc53b1ccfed3a7fef851c763f0e34f08dcfff1232ffde0c79f1b0898bffecf3d9e9f850008fc0b08fd05d8ab20fa27bcf973b3f9eb1ede6c211046d0bf00c89f00f0e38f1f71fd3f7e7cfbf1e7c5c9eae08f1ff5304f7f08da1f7f6e370888fcf1832dca1f7f6e7720088030f2c70f318b8bf4c79fe01f3f8ef3b4300ceef77ffcd062ffc79f2000807ffca0dfbe9afff33f95e3033ffe04fef821fbd3a0c01f3f9437c8f12c5dd6b101d0ed74597a69fde3cffd1f3fb07b9c4f902881f7e34f70f2a14100dcc07ffc10ebe91764bf07360002c0fffbc78fe337b702fbcdf3d6d79afff78f1fc4efdf6afecfff34455307fe8f3fff7fc01fc01fc0ffff7f27568882db8ca009673fd6519907eb2428d2b8a8d75d794bebcaf182b517af1f2cf397220ea37b36fcc58bfff291735e77d44ee1bb65ff89b1d67ee94d6466f3aabcddcfce3dfac0968fbf1e4a6ff959756e61705fbecb65f9f87674ee5ef4e3cfa2c9b23f7e2877270b5e849eafe4c0a9cb62b9972ea9389bf871b97b99f7757908aad77735a8ef9fee9e7efaf4c4b1f49b69befff7c703f89f0bd10c695cfcf8f37e6b823ffefdb89d577b2cfd7f3305c3f2af79e9cf93e9c1ad8e674c837f05b7b34ea966ac3c15ce2f91f3a0f93fad6afef78f1fbe73777efcf9c3fe941ed54dae3e1b11e033f8788af75328d9b903f23013c85335378b19594ce93146bf37b12f33033e9edf8f426235c737157f7f6ef51d870d2424c7bb95678d50549587552f93f40fc254b903fa8b2dc57d27245a23beb620c13713a8628da86c2021af222f2cff6d664126b1c391fc6beeff5af5bfddf6d2f530b0fd8f287b6452dec8fe5fa9ec67d0ffabedffabedffabedff796dffa61ade343a3be0b46f20c952308c774f479e082bd336fac485c08c65e49665b2d637d9d0cd7598256dd0cdc5d902b00c3eb8509559b0141161a5397436b28c18b9265edbcadb782c2db66e21478e818c2c4d86f3cbbba03e63e97763d15c3405342c8d362c2576cb41e4f8c1a551d026dec19994a1f5ee396f40967bdec1259978e72e9bd47330e42f1b3c89658a194f64a140e0b043678943e0836dcaa0972323cbc8a5ade0e0acf17331f2202d74212bf4e92863e929c825436f0a30213d15c292678763a8d26862195d689b5166c18b5524c24ab48c7bc63222e8e5daf47ce41378a8e4146429587f54705526ef213be18a7edbe8b5890d4f6413ae45c032398065c4cc2beccc8bf1da85c4e91e846538d08df15088d1bb9f2330cb3cf104c62e8402a78203dd1c6b886c5e4bf20c949f637a035efa8cdcbd1b3b727329b44c1d70276b38e1cce8eb40c161cb941387d64796b65b2fc61387a61a1b9aaed19c65c4d637b9649943ce84b0e2ec181f5d581f2c480b2d084da7bfbd9e5970fbb8d6421fca6a97c0e3078f7496e1473eada70baf4d6b402a37f7420fd287293013629cf3093c7219b16569b4b3673e9233abd00b1b9af9a473610e60690c3c1e30d0c2aad11df0e8ed1e7d60693172e379cec867e4d9fbb009bcb263bcb10d3db50d69a29de60ef8e01b9bd0a7f5d1678ea13bd378c6c9fcbb456c5ad7b41b7fc001db14016ba25b7c4c586a5e6368177a63415828013d478415e713fec8325c66cd81baded8af758ad9c41772a69f24105564cde73450560c030b6d03811c936bdd1cccdc420afd9c1a1c838a5d5a9b600c2d1a1f1d5a9f70385a3057798cc4b3c3c4cb786d1962c6329b56c827798a066bc0e340c19189362c2396b6d1d72cc3252c6d572ead7d7c8e965b0bba675e8c4c1ed1d585a2c6a6d18c65fccaa7c3303050d08bf1c136fcca83e52190aa2c60f0d62ba4afeb50c1d485c49b6db28d63ec5b27474b37975b5baa320b8a5a96e0fefe6715363c279bf012ef1b2ba74687e11222c7430b9be53161490e748c3e750ca478e923fab5a9115a855eb9b43cb234d5b0247a5014bc720daab0153c7761f621eb6f7a4488712250f0d436ecc8377a40207060d1717ee5d2dd633c29b4149cf1722a72295b6469249a5f40ff1a7bc3cf30be702f265e9e753e56e5934e63e905669600219698b3345f3f031efb4656db04de58f34688163a0618d990c65b341e126179e553a4f569edca2765a818d64c2b96f1a3997fe87d3879ef96c14d7a1970682d74730a704c3b7bce2f10138f4cbfeb935c00ee8067369d010fd95df87a4010cb006b8bc073c798f437d5d85835d806d84e30f1343a3cf87a7a3eb78c7eb495f489d7d6a5fbd65fe49598d743eb836c2010cbd89197679195f7d969e66f8c7fd08a720b7b3c8565c812c004f3dd56cb50caf08b9a529aa2db940964a2a4f914114fb8c221cbe8c1e91eb69007dfd0e20ffc41bd74cba46b4bc73c86d63381464cf2fdb2030fda2c85212e9386ce24fbb3be4300cbc81adb6479df14673db5ac2fbb5b869fb1b438d80605d886145a0637e1e5a732bbe074d62b4f3a26935d9169bd736914f9191f3ff5e78327e6dfecc733efe17fd8f5ca2de496a5c5da37c579a3ff6fc0934efac085d35030ad89f716bdcbc88363f8856d72e39367dee13694a767e1d9de868e814093cd9ae70f4b5ece27be98e1ca029aba7b749f79031edb46dffa43174ed7936d6669ee9ddddc4ffaffc57fbace1dad89be26573df9d81d165ef67214f4e9c55e3f74d4bbf54f76356b7d052f6c535a68c570ad6fcad37cc827be7cd9ccc9c64f34f1a0289b64dd83c4c1317180c827fd709cd698bbddc2abc4227b8fb1edc865f46cb6934479d566d8f4f114975796b60717021efc82823e83833ed12deba4b1f4b1c6695dd5647bfc9caa7d63e69f8b09ca9c46a1975358f26ff2ad8f136e1c0809673c199be5f7c5d68d6febd587895f02b5fc892e2a1396be370fbfa09a6cb84deb335f58b9169e3ff86948e41ada6a967d62e221147ee1739a077bb309d37ace8a543ad0e661cbb3c967486d739e37b6152ce517bfafb10c30630959d201a9620970f22f6a5e7ae077b2af039e4ce3fd8c772d785a2376f7632ce6285d5109f4bd2f17b354c7b3047657082c9e13beb4def804a805269e9d0a390b18a9f5e83e728ccdeb5e9bc0628e8860874623d7482b36fc000fab53b2e418dacff4fbc3ceb129cff8a50b517747496396e942879101ef17b0be972b09ea33cb40400f2b799dde87d67cbd79faa59947f76d604c7ef37bbf9c03dde423ad9f7c6bd37a6d9b72f698e3df96b1c8dba2fb1b79eae98e679e0204801df04a54a0f0bf3d51b1fd2e51016dc17f2051f180fd27990a68f3df54c57f5315ff4d55fc7eaa62560cefb314643be77a61b124e2632828c0fddffe91ca8425fbca82f466ce4acc11dbec89e08f1c72a84168ee337e34792b728e826e2e2f1e4f8c95922ed2bc824fbf4d5176ebe673a43545d27717e6b2474664700c0ef427af997ecea58596e10fb6a1df6d0301bc6113b294983dbd763545354513a977d15bea98f3ab9de2c902db040e3ba65c4eb04edead0fa183332cd18d65c8a933674490c825f0cacdedd6cbc1a797964c51aa0d51834d3f3c211847bc3c2b1c460a5dd86f26cfcfa1b34e88b1509fac0f49a9728cd78e21666e214e1edd121dbdc13679327354e11b486a9b8f088b7ce6faf1e3f35981c08d79fcc97a1dd8e64860e574ef446f367de126e6d5fae1e18051a0e08d0b4ba13f798e8ff5da79562f5ea698798cb478ed103a799c956520893dd1f511cd2eb0bcc66e5802b7e708c8a0109646639fa62a37c6a389561e93be6583c877b432259eedca648ed2e8b77d071ff661217fae1399f73c5c3a4b6c03196df3d8aa647690354495156010126c1983d21b97d6476f8ec829d031b9899e53f41e79cc8ce7394262e93ef2175e8a6c98cba64863f296a7b5fa3057f933fdba09ffa30bd9803fd154f9c2274fde5cf8ea099b8257de579e9aa28868e61182c3b501e7b4810da5945215fd58b394cfe96474d67529d4014ad152eaa49319a50df8598bf1830a20a4a2cb9c0a202a4ba2344b52276396af3ba7a652cdd27a35e1d58bf1c9731c6c531cd95926b2996eb6214db4516d43fb827ffb1959cc74153bdb102b3bcfa6c82d72731f5c2232bff5737d70978c62679bdcdd31c571c91e2ed1934b6777c77cc86f719c70f713fc6c7876c0fefdfa4701ee733448fc07749d024ceb5d5a32625cf5696af0095cf7089c98b380efb34c339f729967ea9597eb294bea273d9ea3b2294aff39bcd222234a4a19928eb22a005273444fa3cf2ced2c5f9682f33259870e8dde179e6597399fe5813955bf9ff317f660a253c892c06002d159d5b45050964cea232a6eed185ff6f312b6f086294a1601cbe8eb499e3ecc3f8f03e27aaa9f4c0095746a9a139f4bc65c4307e68898c1230f169f99939967968c2f6ea80a0e3bb4debccf6caacb1ee332368185b68214423c3f9bda0607da6ff4a87c46cc5cdaaae768ef81c7f9b3645a4449b7293543cf1a25ab6705b46c5a8f7dc30b053d1a7c03b9da8cdf9d0a79b00c64f46874f00f60ea53e8b864d8a4fa99653d9b69edc1fae8d17a631f4044a0a9d466b8cc838fe8e98075476c995bd52843d6908b06dca788549106ecced2766d19dee74cd3dc36e518483147c3f4b2dfeae50f3d6d1eff83b25455768cbb2c016ea788eceb1ad8d054b0dd238ae689180b1dc30a8d01bbdb31d6daa69c3cf78b27f8dfdfbbd063130a900e58c3638fb8e092690c3b4f3f8f1573e4cc8fad90bfc68b590a084f33dfe8cd92c9c29a094e85444559d937cb9e34325803cbb3049e3b52c92f631f43153c861e8c671694e58e317dd7bb99cec426640919b24c36342110f460f9f2c8b03c3374d9e42bcc7699e1405b996dca236bb7e12d382b7c286bce861db98c989dba2ab54c0e768c0d6ae754ed41da8ec8c1cacd7df8790ff1d83961f3497f5277dbc06296cee6354960c6e84076e2e3347c8d6dce59baf034d6d3ba444543187d282b967e8cbbfc7d77eaca9025e5c82bfcca8da7bf3fbe2720e0157af6c0d96443475bc15adf140701ea2b2bd737b6716c9d491675b49c77b4e82c67690ab28cac5ef8b40b5d78c203073b7316ca8ee6ec6e4e25ceecc360ad4a67b1975343a0a0bc65da910044ad6b680fda1f430dd2b3f7f6dfa675c836fab9e44c986b05fa4cc8c5d655d0da31b8c1323964e2276b407b4b417b4b257b71c45a13ca1a9bd637421e01aed12de34ff05275289865c8c6322fe936fed06913df7ce2c3375e0b082c1626798ee739b380d61301aa223fa72e8b7e634353ad679beace19d6875ea1f5cdc23ff8fbb95036ff355e2d827dc1604f3c24fdc698317a7ce1039860235b6581ed6dac3c7de0c1ae1e74de9dba2af3202af92cd71fec4b8cfbece1ddfa5e78649fb25a4c3eb60bedef5eaed7b6414dfecfc7673ed9acb3815f67fa1b8f76b5497f19d5602be08203ac5ce0ccedea8bce51b9cb22cfec67fd912cbb3062eb32f6e4df556e7e1f27fbc81db0873f3ac50ce4e4a7340b4f3e6c57ec8f2cfde4455cd2520f6563a963c3721997461efe6134f975731c30adf5b98be0c1d97d1e133e4ecfc30e3dfbcf13cce504b34671cc138f36bd7fd0a11fcf065e7b0376776969e2c969de785e3b812d308e60689b51e74dfa8eee4736c6b62ce1357c0cac58aa2b85b8f278452a9ecf4c3cfbeefecacdeb983d942137ec1b3ef6c2f3a483691d12200474e9ee0bcf4f709e15365df0f3e01d5a9f74d4a77bb8c93e0db36e52b098a370451eb85018e4da31901bfba0f9c27378ea4248464cbf31e2a4abd3e9d9b381773e2487f3ef6ffe056ad172e5e57376f40d27c4be115eb4002307d242c79442bbd0e75d05cfd423979ef4b69e4ebcfde211150c2d68c6ad78cc9efc8ce55cfc6e6e5a4c271a79d0641ba6d88e8d67f918f025f348e9e3627b8181a5298025dec65af873f2abe6dddd4360f8935e9f7cf1c683f5295ee82c532e27ffd89b779b36a1ae219c414c3cc4dd2d530aad5ccf9758966a02532e97b9b2718a95fd29ee31247ea22b478b880d4f7afb3dcfcf3cd67c231739f7a0c1075cc059e1d114e010d85d30f5c631c38fb8c9b10f637ed10384953f76883ee81f6b860d8fa678505040d0cdb3cd97e73f8d2d013dae81a224e932fb69ec834a52aa06e2b84e869fc79ef139f9c7be8154936ee648f128e9a2aa9194a6105cf88926e2844f7fe8c229eef0cdc96e4f6345234bcff1dc149bea6a9a59f30efde44b1078bcb47469a16520c824f393af39e70168149c77bcb1492761a96b648d0d7b1f7c8ec966b8b37ff2e2e9d92fe1626b91a177bccee658f9853f933af4183fe50d2cfe385e85eb29f52d8d3fe856850bf9074f7fc0fffb71bfd1ab9f69fd7e4db37dd2265b25823e3defa0a36cfeaafe9875b9052df03eede60c333ddbc9674bf012773f68cd12e4745f6c4d368d61439360d3aff3e8dea2f37c8fa7ee014b015793480b8b60c3b382c56ebeffc6761f27dd1cd98bfe2b8f4a3ad3cecd51e0a3bf8247de808ffedcaa4d0d8ff85c75a13ef2f26c640f64273cf03b8f37b706d4a8c5f8a56388e55c8d602cfaeebdfe35062c62e925069ff5cadbb38b2e06bbd20037a1a94cbadb0fd90310b239d27ec6f9cb6721e4a7bff8d9b75de69c7136dbae8926a96372cb2e10d57d8b7f93e042f6839ff2f59e898726be7ca3c934fe4c8b87ee944241c7c3871f94bc8d8767b3fffa05be2fbc33d806f5b033933f8f7b6c2ccf7c243faa80661ae95dfcc11f7afa30fff4ba179e9d7d24f5bd8d9d9f6367fff6c977c466e2b93977ca41d86bfe8f32f71e4f5afc46bf6ffdb50f7ed8b4a63906c9bffaa71200923ff5bf8ccd573f96f8ea77bdf7633fea10f4eae55aeb41e1e27f7ef5a79e55139c9402536c3fe7145c68134a5a66cd71b439c549734c5cd8eff302c5f12da734e711dfe8e0752f1abcd638e1ef3d3e0568f205d1d121d0994e2f7fe2833ffcabe7b9ca8d3f3dbbf822eff8f3fdf35ce843516541e1c2570fddfb9936acf2018f075593bec49cb62196ee80c5b2c90d2ecc6ed90f389ff38273bed5a6f5dc3190cc26f0c485b9c13644c065d2868db11597ccf1e973e73364a9b922227273a4f589173e339678cf276fcf057406b007f2a77cf5de2e7d07bb0e514b9e6f2c3fe69a68bdf1f36c702164ceabbfaf38592af166f846db941a36ace6f8fa61e74d15e48e32255e5492d2d55464659d45e7faf15c9c7cd2d232f55128f0da3623d01b1e6d68b0df7a799f7a03525ba6de4cb6d78b91e3ebfb5c4188035e4e41f6dcf6779cfdd219973087b08c38c5b589cfccbe58eee5e87da9b614330f7ee5f527dd9159b0dc7a45bae45ee6bc8a8878b09cb9ca743f0a10f19c6f19bc9976efe758f2e0420e426e8c8fbec17d18ef511dd3785096da4b2efa5d452737c7f9efc79b6cb39bcb9747aee262e5d4681b72e5c561c532f5873c4830e9ac0339d171a2fb3bdbf0e41d6e3e16e549178fd613c7b0ab67aedb9e684c3d722d191a5ba6984db0b06f760ff04dae9978e9992f6109fc75df2477c739c6c4e1cfd76f31109bfad0043f1bb22a30c522c583ef52b7fba8a3e64a01c69f7d706140ee7ebef95627bd709200cbd86f7a3d9eecadd3959fecc583d6135fc37a63134b0ca7a41c25e9d8fd74484771c0ca49b769105a5b26577903d61f0954f5686ab086f4630ec1987db6dd3c77017c9b3f98ff96bce28f193fc2b0699e7ed8d367780fa36d20e952193af1fd3df2e6fd30e92d867a27a31c737fd1e1a2b0fc459a6521712124b14c3973730a98e4c132fa7a89851f55a734b9f0b7543defbd4c76d8368f25afe0bb2f79b685bf3eae6fe2237a1fb2b154fa0c1b0ae631e4c0bee106ac60092f3c13cb73bcf2ccb35528115684a48b9409c89c96803fe7bdb9d203876d228d2deca38f2aa5942aeb28a9e8ec27985e3a6ff7f2ff87e3ffc567a201153072e616e29c8f9fe46ca2810b7bdf5508a72eec372e8d468ffdc2a5aaf04bef0c72b54c36b40bae7595674e1b4ce6bdcd9caa27dda42fb98968aec29a74db87aaba2547ca32af16dc3916f518ae75f2493f1e9f15d6936e2a1d83ab7c024f9c89ce4b45d71427c58e8144934eb3690ab0e63d9cff131c276f368d9d64eb8dafe27de39af68756e39fe0f21b9e7ed8f85816f514314dd0a6b4943b6b80164f3efa23b7fb8d8ffe9085d46efd497e89596fbd6fa1fddaef94579117b36f7e60fe2ec7f24fc321b6bed1a76eec03f31e722e3d6cd3fb96e32fc72f364e4e0d02f1851f2b9fc01a21de3c7cdad9067cd0d94b6c0a1a6ae65fb4549754505754e2bb9ce8e47373ba9777e8dbda384a23515d4bbbd631f6edaf8e873c121b5048ac6fe8093cfaca16ba3eeddf873884ae222fd307f700c473d51873dc0a033ad826feda3ff8b2cfbccc330850d60ab01c4db6c351bea1e5f8e85dfb0af3fd01f38cdb8f7e2816b2731cd9672c99d1da08c467855de24c02bfd966faac5adcb1b4dcbeade3b12f10cbd33df39e004b441ffaf678e5039e974a5e85ddb1f4e4635237f650efdef1cc6819c707dfc9ad9b6b8bee26395c03f48b4c66cac30eff9a9f3f1cdb797cd2e0a1bbd954d5ed930ea286ac73840a8a141b6328cb2c7b16dff0c9d377213ff1e2ecbf9d626c8ab5e6b57e83d3e73164bc652ebecfe493bcb31bedefca02fb2e7e7ae5de922fb0bec651726ad0680a700e9ff36cafdc15ec18c8245fe3ec13bd8e6c9b7873be277eef13bcc3e15b070a01422ce3cf15b87f2b97fb8fe3ffb9f7f08863161f24f4213f7be88237db32ffc6be9ff3a51fbed97379c8bcaeca3a7792b4474e91e9f75fefc19f3103f96d5ee4b577bbe062c91dcc3c1fb30478fe197edf3fff656fe5414f1bd2019600ee4b7529087a903e9c956f607fbba7b34c719cfc4bfb003c712d49baa8ea00aac8c4925798f50fc18682b69ffdc12f7cf3133cda46ff95076811f4f2ee3fce038feae00f3cb0fcf67fc8030f5c08c64ff1fa993ff2dfe083c49ff40b01dc7d53ccbc187be24fd7005d51534a94d5f23b5adf17dffcab1e62e34f7c60589f71f6ed7ecbbf8e8654ed2e7a34b60cf1b6d4e23df636c879cff0517780c26edeb796217d949777b9b767fe4c9a8f4739a27fcb075bea3410f3491bf93587fcf0c7def234cf5868ee76209f7b1e5de8c1539c2d96affcfd043fe54fb1f2ecefda393ab80635c5d4d9f4dd9e3bcd9066d94f59f2941ff292bfd4ebef738ccb512667034f02c37fed3fbce9f737189e39cc075e5efa9cfdb8effa31e6555e79c7c39cf3187eb29ffc8117c85058f6c7fe19bc277f7bbe0fb0befc3c3dd5152945555961c3b382cfb503dfc5c09f3f4f5e64092094e67ac2ac5ef86fb1c16fc7987e3c2e78c94fbef7433f7f3ee99c8f5d5ff3d1548ed1bfc5430f7e5f8ef739fe04def073be34768ccd922b358e31fbca8d2ffcc1c6e997713ecacc3774ffb59ff5f978df77fed0db113bbfd48dcbe77dc7d6b3e3e13d7ebf5fff3f1a877c19e7992bc0eeefe1f82d9d406c1a21fe197c1fe5e9dda7fc94e75cea9ee7bd0a72d2ff8947609f65e56fc033f3fe52bb06e28a0a5494042eb237d1ee6fd3fe9d3d7fe494ffcf62e7f818cacf3c13ad6f7c5a6f3ce851bbfc7f943321f2d73ec9b30e4fd252949735519b7d774de6b4044803e0593f38cbcde4cf6f858ffe7d7c91aabfdf5e3e78f457349ef34ae987fa45948da5d282d0c68228c0841e39b6f7757114775652fda0932f789ff1c7d5cf81667ad6ceb3828dd3b7b997b1e36feb0a181176965ad2675d01e00eb8f98a2bbed9c3f60abd79d4ecce3235e74e0839798cf92faa25f83ec6791b870bffa1bdecdfb3b91ff634669bfbb63ff6be96e0d33efcbbba81df8cd93ed42c7caa67f805cd3fcdfb731efbcdf5fe5c46e277f50ff391d07665d35a6829583c9f9090cb9197cb5590eb291be3b0652efb1d5eae035e9e657efeac0d178f8a82475eeecf9dbc96f9e896c5e6baffd6cbebe91a70083c7661b97cef87cd310a8db46e0cbee3cbe7feef726cef9b1c89a24ca14745432813a014199c7dc9e7fa0e2a80d08ae6851c89c5dfe88883aac91795cc4eb28ee25aeaab4458995a4a491aa92b26d0e3ba861c145257ce063ad8c3bb738b96dc4ef32e27f8ed51fa4458cd7b6daffa084d1465820dcdd9af933fd40c3fbb1d1f47063e68f85bbae06fe72262dc9b6d5d0c924fd8e7da4375d289cf7a121d9d620c41939fe734dd7da3071c0d6c6d46af6dfd79ca884cbedb9f4239e6fe737e9af736e675a501e82b928e4bb2cebddbc3e3d0777878d18b8d658cfd379ee394b745f757ef6f1de3f4baebd91db9dd02ff9923fb1ecd91bb7fdd294e0be83fe98d04b7bfd11b89021b6083feb737f2bfbd91ffed8d7c53206ffd9112c551aaf21feaa3487145d680b77ea8c77efca7be3ef55ddf193def5b4ffe8081362c11e11a60552c339f8433b034dad8528569a92e2e3d5fe052bf08a1cdf3ac41176643f7ad3fedd1f336bf8e6114626ca9bd5fea754e2a287312a03df7891fe3caf369354bafa59ebeebffabbc01875d98bb3d4e398a6c5aae5e7d4674d63c7333f3c94e8fb57bb95e5826f7e86b115b8fc906c7f04b9fc0a7d834f30ab1744cac61095c73682d9474917eebef5c4e437af52a3e617c9eb2a57cec3b931ee724beeb79ab59ca9ee698f7688ff1a6638968ba977ff041fcd6abc656a747ffe552433ed752801ea4bdeac197535cf48d05e99d4fcc7ba5890b819d4b67919b8bd973cd0f9fe9732f5cc85233ccf7c91f73216e3e1985a5c9897e5da0cc3d569ffb0b231f5bd6fc1c7bce2dbced6dc13eec35aff321f3f998df773da693cf25526a265282ca36c74f63e90652cffd83ccbb1eb5f9948fb907a3b2a0b98e2f74690a5ef88d2abcb7136fa6f5c35e9e01136d05ec491bb1b50b793e96fe2b2f3df878e1bf573feb5253f4e95e1a6d589a7af1119b522a4b662a1be3931fcd694317ea40a62924aaeb046e4a3aa7481aa2299aaeb224aab0a478565399d3c9ecac66c75005ac50d210fb399e02642799e842dbc80067962d7de32dfd5be124438e31d335b3894f3dc56fb4799d82f4e2f5777d452e4d3536ac4736a485368442b6c92d39caf9e48ac7eb0520647c9c0c523b0658f90fb9f7ba272ebfc797103efefe1fea777caeef3fa13385a78c3f72852cf538e18dd23b96e4a22537fc3a35e4033f6bb9defb46364c7a56d61063ae5b2b8edb17cdff817eca594fbc60fa495fe553cfbfe260ecfe380de9710acc5b3fdf71ee41797f921dfee8b3922b2f7cadfd95ffd049913501fda090fb50509ea7d4ec430e421b6ec90b646ebec8e992f3d3138746e7dcdbdb897c0fbcbd4e4592df607ec42d524a6912105d3492d23540fbd95cb06564c053ffb3f43d0be6de67f4662b6fb908db409653c53ecda182b8a60dd87deeffcca9bb6dca99571c5f2705be3b3760ee1b63295b64197f3ea9e75d7e6389e15e32b0ec250bb9d7cccf3f4eb17bf10f9d011ea4d776dccdbdef2f598574e0539f2a2ae8d1a39f14bb1b73ff6995fa30b6f5192e720b713e35ef6cc880098bf3c96f3ed18fb6c941b6c9a281d28fbe2976d3dacf665a5b869c7ab93e7a23b0391eb0ee332efe15fda0ff515fe6c59b5c664393dda26a9758d6f4a82b7bd83dac9008ef7196c0dc23f68c1b0949970f0a855212109d679d4ff8ad1b7bbcf4c8cbb9909d7fa00f33f917fd723ad4c713bd1a9b4661a278fc9dd05ef8b50de451a7fa26075691cee32dbdfe3f8167e29d173c59ce126cf65936644d64d561ce8ba32cc1b56eccbee514b56f65367be16dee23c5b2453f2c27762de716d8913b9fae34d97f6ce9619d739b58cc6973ae2b63630c3d2b58ccc65839e385e01ef5e8fafc7f99e2383dd5b2e57e7dce5b710a5bbdd1ec9997d1261d37ef754f7232d7e619d2ebb4ae777b6a8fb329667f733ef5d185a5908df527ee5405c8fe3ff6feacb951a5d91787bfca8975bb9eb3cc20dce68d381706090416d86228862776ec004a2d1005a22534c0a77fa30a340fb6bbbd7aed67ffb9e8b680ac392b2b33eb5759639756fbaaa94cdf2c6aaa240a5ee7b08ca803066dec4c1f47d94ecf6a3166bb33754372aeb691e1e2661a32dccc37db581c582632d26c623eafbc4ca21419af8164dc9ad803c7b422370b9df141de6488f8ba0357a7f0f8357d0da2fd79609adf4499dde49b08049bf72e5d737e064d645443f13026ee7e3eeadf717b46995efaa2322511f0dea77b79cdf545e00aa6470b953f9ebf8c317fb411f4c4694164af0154d3a2d5ef638a1f1816b5d98fa784e51caa43661be3310d1c8ef2c9b988cd51f44b128d9444508b64be8e1844d608fc1bee631418f548145812c995c452e1d66d6c89da778d2692ea73f18c79ae89ecb9d9eb026f16c5bf99820506920944c119db5bd51848b669f3af787ebc591439cf46cee3e03e3e5a7baff0cc5b4015e43c86386d22818ddabfca005451c657afc9c9d98af69c4f8bc593d16a1775f72c1ae84ae9f7326d979724eccead1ea2bd9de2f68f23e661fdb689047a8187c7fd4fb7ba085eaf1a4c7eb3ef791137a1c9a3dd8b0c1cae865876b6bade28394edb7b69fb0345b9ba8ea6f397d7945f98697366b53df75944cd5c3cee0fe4ca6a11a26d73de36033ddfdcf76d116688fa68bf625bab95bd6b12f953462b9849cbc039c5c39fd6fb340f2cab54fbb85fb1ccfccf1e8776adc57ccd63ddcfb8c1f3e2acd8f5772b7b1b6c661359701f01bac1b6373ae65291d315b60fdb3d5b6c87cda0cc57132287a5d388d06dc4ca90d99218414a42f69393d1a13cac571eb01fb24e47b9da44c625d878224b4fcf2eece6693b9f46d3f9cb897e746d0fc30447eb68f34e1d17aa9108af167db2565cd9bfb093378b4a9444c84316d711acfc8181a00c667040221c0eb0ee2de624f682e40c40bfc19353684c8d51fbde6deb71f89ed82fafcdb90ad1737564c8a81253242b03e09940b7b11c020d5de236f8dddd1c4976f42d06eac563c6d351d27b316d0fb78594a59a0aff662aa40e87baefeaabbe86acd1f86f9e1bf90d8eeb9cc1f5fe2cc6711b67c545d91fe87bb7edef19394b6103cfb0f5ef6d1df7bc1b66c600ebd81e7bd41fd3f923e13ddb28a2945bc34133e66d9fdedb97450688a5314df65f919891b3a727ef142cafb21b6349c6817b03643c910548bd6fb751051bb277efca05139adc2c64b82c70a284c427c2fde870a94dce5c4aa92f2332873d67db6fe9f03a7558c344416a6c247084d9e76a65005644c6d8060a6589f31d439a0c85b8c5f4bf90b36d222f2ba28a752632a72212e1785b84aec62bc933529d01d1755f8ef4c52b7b40a8e1372e0a72bf24b12d483c04a550e47d74eb1790d278ad7f35523474a9a3bea105ebcd94ee7e574c5217ac4baffc568f5044afb5730ac702bb7d1bf8fdb89eb6a4f1aa7df73bc23cf36e7f235d0207fe69d703e0191675b61680c8cb101e572c8757be1b23a5d57700ad0ab624483649aff0f7650888c8be1adaeef7d576bad625c6f7227f6d0cc0eb988a257b46afa3ecd887d6e6911ff238c78c588e54847b1969bc018ad32c4a1ab83430ad7f167bfe62a4bcd9f22c1532250a738dd7cc0dd1f7431995514d357c6b0fa6a6fd71beddefa1a2edbbb8f017531858d5f3bcc536ab06b6654c2028338a57f6fddae23425c237038b86afd680170c899c13e05513886292eef54dc38d2972b52989d84a74936528f3ac224b3494719f19c52efaf401db685c9c8db9e08d56476e634c951e0356c4de7fdeebda4de46b72b607d67b2c65b30eb77d71c08737bae87e0f76bfaf4ecee0c82809dcf114f399c7944dbc016c276768e5b92ad7de9cb03ab563c0d15e7721d8893d7d393a878ee7c8196e6b6f2f36d82d654f7f8cd3da617d5570d8ef3553c9545bfcd2cb785eb418d593f276fa7c8bb9310d20bc01a06ac73afd497937c6f750effdd910f4d567305ec6bfde4f6386a743d958a9ecb859bbc5677426a7d09df334c7d8b056ef3e60f21adf0ee1bf474504e77db43bd75288bb739a32cf36712501b631cbfd7586782dcd97893b9daba2a9a410af55ccb6203a729f2237918c1c3e2167c044a1bdca9e5a5919a04608222fd597810356b0bfcb432dfce4793ec2f6a0f83c775812df70e5d3d4e36b8a6a2b07cb70c05786436fe0309dab15b8c07bab66542862e3aff978fa03161ca77f31d3e9a45227e23455c9d94a479d85322276dd9855918fed0119c5e1509bbe99c2ca77a33264d4e6ccadb43bd7cbbdfaee98b495e8bf945ef90ed6018cc27336b7eabe54c4085de2beedfcc5daf711afa0de8b384e1387e2101439cb775526707464cb7c11e686ee395cec33a072adf9a3cd801974d5020ed138ca782a64f475283ef38a5492fa5dfd2e195c2403f83a2bec70a86db5d972aa0e21f2b276bc44ee80151d9038a2b83d177ca4569ba95a5dc891fcc56cfb36a78ecef210bdec0cffbbf7793518e06427db8ff1be821c385c113537859ccd87cb39b3e7ed24ddf988a4c6bf436cdcbdac3ff83cfe0e9cd3ce37f70558a753fdf902b3f466da3fc4e97cbfd6b6fe10c919d84811c15ddd4e359fd1a90fdd3ef2371ad2188161ebc3468a48b767ea1b6cdb857c377f023b744f4f379593328ecefde3769d63869022da3fc8fa3600a69df2a635008e616fa69ab9b705895f626f2f61db04eb9f4d9c8556e76ad2ba94fe660c6c5e1bb776c773f18ce95b5fd5546da3fa9ff9d1d0c9b36937b113c87eefb14da28f4c207cb753edc8ffdad671b8f7ddad23767cddc779e2671b2f15995f79cd6d3e98c796be03638f4da7a34c8da1486cb5c657dd60768f689f571e43a77b3fe8e603fe4852369778ee3821f124e40d5eff1adf1bd8ee632eba2ca9ffc7fd9c4dbeb3d0f960beb8ded3f963c4944524a9331ba77fdef952848de7921b199a5b29f63e68cc1b67be745a1000d0a5265ed62e1ee3731e32bdc6e77bc557dfee63edc72e647a093953e2eaa88989743cd68664a7b46aa5926d603bc81e9fa623bad878aada277c871adc20a21491171511483652df6cc2eb86a48eff3e5c5c31cffeda66e83e2c6e47b447c53d3dd2bf1315f7f485a83852f50e15d7a1e23a54dc17a0e27692e1008a7bebf3bd906c1e818a1c1299518966f6364a8217267d4d169e9a4a0030e491354ddeeadecbdb91337b22d3cb30d778258b29387c7e1ced02fb9e5f224b0b6f96f9448d66cf2b4d5476e91e2743bd78335572ddde3e207c1ed50da0e9a9d2facfdb111deb96a4e345b6f44cba0d40cdcd8e839fe27f38afd7bca5b30f208ce3fc77e0ea33e0d4d8a2a8b52ef636a3d909c8ea7a5bd8b8f6c5dd37aa6d13d78b9871f2860db6feb60c1903850700da9f6dde4f23865efb3258827d7f374194df0830021b62ade1d8dfe651c6d3d100a56fa48e5c1d0dd522cc60d6002888e2baf2327e0dfb9bb5cfaa6be80aaa7f481f13a74c26cd20ce233fbd0271e436e01a6c4047b2546183f14de44fd3b4c6e7dbf0d00e2dc1c6b6f634620fef5a85fee91030159003b1a39ad4e569c41eda46da2ac32a64c1c674c67f7a0c5f8e32d0f308e8ca5ef9449130ea37913fb4bfe9d3d3ba65876b7caed6bbbf65761725bc91f1e96d47407f1d03c13207bcfd26f287ef0d3d092ef786ee5ea9f9689203e182b4bb9eeb4de49b744d1ebb2b9b1ab0d08c13ee5ed1996ca657f23bcb63cf1fc78eb67d9f370727b9a3b60eb66f6d50b5517e658c58a122a03d475f862c488f69b4d973a5113e1d3f8dd83dbfcc9a7a73a7fd45f8624fb3bb6e6f759023389fc1a6e195bb743b7e9db587385194d09b7008f2c0e91dd3d5a3d974a5599bb5d71e2c6d78774bfb0c5a5d6beb7eae1fe85724d8934323888d8d9a2346eddb7e2e734775e04e02d7efdbbc732666fa3a748522244ed0f69a4fabb7c5f5bb5a2ec3d351a6a3fbf960a31622d8bf9d0fc4739501d4610cf6b278d55eb3b82fcb70707b8871f1672bbff15cfc10fd9e5f760184448e38b431ff8559b40a5940454340bd5706b9589c551ba068d65ee53600b84dc409d6cc9bcd1a9713c9a082324251bd9313062241f665b0f258b473aa900de0433f1ed1304ddadd7a709a3efdf3d871712c83884cdfc947c66ff883048ee31adebf265f9b7f4f5886068e1f7baca1fafd9d8c8e4a8fd9aea1332e7d19106098ef70b3c001f52d19dbce81c31c4b8c6fb7e72ac75fc8af431ed4c415d05b2eac436bb38643b4f1add33a478cbe8e64fb4f027465552cf76b8fe14fe81a39448c53ac0770fbfe3e7dbf9745e7f49623ad3c07a2d03996fb37c68ac8cdcbb2705d0ffd4e364e56bb3ef173323709287d94a9eb901d3f8d98c398eec7fa13eb206440e2675b7ad2dfac4fc77557cfcdfa783c27d657d5bf19df8b35ef833c16b1066e23969b47d739d2acef284f2346c2732af31c9d3aea97a71173756e3c5d6ddf17cd9737f9b42e17fced1c5d29eb10e0039a0cc7b7da80fb7d1d0ddb8b9afa7b597ef4eeef1e37d0c3322b680e59c4e1a7dbdd5e816bdde0b733dd4b1d96fbb1df5d4bfb9e4cb8398f6fc9c65fd53befb697ccd3637e255743df91897b5945ae99c6eb44fb7c8f8fafcaa8463f6bae823de8c8ad9ec1d52765b63ac5995cfde57eb93b97713a91de6d7cedf49fdbbc4ffab90513b0a06ac1ec7f9e054c786a0fab167e865034eba5135645c49661a4dc37db0021e4e002a8be13ddea84fe34e8417fdb5cd56c5d0600796baf3bf55c611355fc4ecf2bdbeb979f464cf3fd22a0c36e4c6450bde5421c30800a99e6da5c524f565bb7571ca36856603d827b13f9439acb80264fbec33157dee3b2445be25fc7c050410abe9b362d1894fd27d904b436eb6bd7255fcb7fc48015bce89bcdba6debe918897c0b60817494b5f6e811af8d5861091d5884b3e3397ff9eeab65d25d5e74786ae4ec365a7775b92da3705e477a7a3ab9a7efe7d435dbb1e5a1938d950b5ef6dbc0e1173a4ffb3d70c68d9c10e9dc773884fb1b8f6b70366f76f33964a4e5b1be785216c3933505cba711d6633232c7f0fa42d25de70bb8f69c6d7dfeed4de477019dafced18fb4cb67c0ca77d518ca782e9de98dc7751e5ef4db6efd5e7bcee62c9fe6dd65df6cd637f2c2bc7f18a333fe3cf9763c7e586e5fcad45b72f6cccedff1a14e4719c80257451fe5c95df00d48da7b51df469e65fa123a06bac6076f325a79cc96f665fbcf9764be7e41068a58a31e6504c084c761fffd0a7fedf37e4be63f465561135e7a3fedd13770c94be410e2f56f2d2fcdc221487dabf7e325e1052fd7a908f7a5386f822c599bf511cd850cdb7f73b55f936347631eedfc40ad5c7f6b2e7a796a6c43bd80325f11db686fd3e2358aaf03976c421eeb26c5b19c8a182e8e86fa3c6489bfa838d5419af5c66e65a422e92bcf25d7705351bd593757e41fcb5c50857d8ef809a37abe1e9175f2692f6347195a930b9d72eda8dc71d96e383e8d589cfe38bfe3f2cee4787b50c53fe8aced412e909ef6e9f53c70ff84328823e68c07fadb433e5973d1d8edbc2ff378131bd05ac42002f4feec78840e09aa4e850c87701f07a7bafab97f4d277e16d6588719b18b0f7eb4dd9ae2aacbb7ec705918e197bdde15ad02e7691dca28892aba3ce465ffea983417bbe179b27f776217d761266d22265ec3837c7c6af8e5a28f4e78fcd49e3ab1452bdf69aef6ff40bf99c7b43fc5c7fbb1b7fff13e3ae3b9833f61a703a1a334d989cf60a7bb9bd77876b76eeedbed9eceff77fad83aaaffa5eedadfd251b6f9f302ecb91f4fae08c9616cb53e2e77e434e0dc379127e98ff2bbd65f3b79df0095b16ed3eaa99fe8739cf7116ffdf4785ee67124dfed6b3cfed9f171e822c4ba9bccaf7c573bd7719e1a3ee7ac76ee4fad3359f32bf2fc586efdea18b5173e121b61f7ee440f3a5eb30e72f76e5f5d9d0bf7d6c5dd257d1fe847fb84f657f87c2f53fe21f97bbb8f6ef4efb1aca942c627fc77ea5727c0baf37eded934177d7beec33e6e1f5e073c475f780e44bbc08ee4a20e57f993e8fff5667d8fe694df5abf91493776f0d05887ccb63ed9cb117b5cb3dff83eed097fde68c33d3ffb3dbf61db6fe7be933ccaa4381cfae5286b744228f3eb90c8da2b3edc9d3e7f6aaffe800e574091de84b244910024267d3436b7fd2617f6eabb7d74c7dfdef0f52c6405f49663fb80ec9d35cf27bad90d1fe41d9f7adb77a73eab33dbe9c26ed9cbdd0b3bf3abc6e18a8db6efbf4ff9afdabc4ef63cf67e4de7a43e1ff21fec74e083adcd5db391ce68aee471b43eb5fe845b73fe8c0f84395e230f7cd03edfa297affb0b4ee6d5911fe28eef61c747777d1a776cf74379f77d1107ddb5e597631ff6553fcb9e5f63bc36fcb9f73d5a587f68dedd4a73cf9fb1e367d21f6d5dfeeefe39f5e35cf2d6619de99ddbce57fdcc47f6f09e2eca78126ce8785fb40dfaf0a7386b9ec97e6cbff7f277810c978be83ec01013ecc0852cb583163274ef5befa947f7e85f401836d0ae5b00c36f8f548fe77ad41e60d8db010ce9c7a76fdf7e026088ab7f035e48dd4017d27b1c20fbc8b30ccf3e3efd6f45179e030b3f023fc34f6532cfdf811dfebdb56e118dfffee3af3ffe6b0f696c78eb14d1b8c44fff074e8a490e277954fdfffecf3429e355f85734cf1ea6f3ff3b4d4afc274c10aa1ed6dc3100f2df7f442899e4e55fd3f91ffffa239ae7df9369f3fb3b26a896e5246b9fdb2e397dfaef49be5e9ebd42413841e72fb364ba08f0aff30ff3e2dadbf51cadb249fbb648a713d8fc5c4c8af93229e78b64f771ffa66a9e97f3453981cb49dba49d84387d2269ffeb08f9f96fdcf672b22dfff8d71f93c562be58e2da64f8f1a82fa3f962325fe2be5c4eb2f564f1d0fc3925badae177bf3f6493ecfbf21615fe733b8fe6ebc3b29c2f82e904e7345f54a7c459b04843222471472eee7ec4ff27f914e773469794513c4128c68562b6c792ee5f7f4ce7453afd2bc91faa20437fad192c05e7e4bf8764be2a13f4c7bffe489f967f25f387a048b2208a937cb2a87031f8c5c362b29caf16d1e48f7b72fe016784fb279f940fab05ce73befca381953e603e25f852cc0ad3c9b6c03f563911dcfb5f0f7012aea62d77e03f255e2d701ecb8acc3542fe5f3becefbfff0857df493bc2aa9c2cc9ccc88ac564b97c08eba4608e5f7cc7fc74fc625a27c5f1738d92b0995b65801bff809265d9be68182e5a544539dfff78089a229b872829623268ed333cfe0897c1e161129d3e4286e368fee2c543929793451ea08709dc040bb83c27432829ca243abc89b3e0e8699f7c11e4b01de2f34fcb5558a2c9e14306b9c3034e77f414f58e1e8e1bb08c03fae489e11e4f9e399a397a3e2bb24447fdb4e528fef4e9a148932d9eec793487493e3dfaf9102c73faf8390c9693c7dec99b240fc834dbbf99cec3e3c778729cf9c36c49d692fd7341a6d76d41f3b69897f35c0b1284a75b5bed3029a3d5623d597e8476112479319fa30fd04e82ed07a8f6638ba7443becefa59947e147a88a495e4c8b8f53e209f2904eaacd22f854aa45365f7c827e12c1f833e4681a64c187ba65976237fe1f4db01f83004de78ba48cb39f493c89a29f4a7698291f4d5b04513af9086bef122c99f42756dc49962c8a6099440fd3395c3eec25edf22e1916c31fa07808168ba06a65f66dda7231399f98d7285ac9114fce39f78c78b7e25d59f3a3efd39b1f1e965190e7b734124c50ced3497ee773559c37e327f49978828ac9e2218a17584ffe20753147d5f704a15fd396f654f3e507882ee5d827f5ae46637e87e8b0624ed6c9b2312b3e44dfe83af7480bb4cac28b497993ec210aa278f261e2393a1798b789b11e466ce88fd2cf1759507eac03cf13c1e4fbf74f2699266532cde78bcfd62f815bdcb2cfa6cae164fbc934f370f613256111fb33c9d21225f98753cdc3d924ba3993cfa90b2ce2a33922952b7e2ed54314144198a0a4ac7e328365022761a36a7e28f962b2be94f2b7c9b1c575dbf43ba72e1741be2c1ae3e373091e1a03fdf3e93ec3158754d3e4278a8acbf2c3c37c48b51773d13ccbde158a5732584e1677acef3be996f1c7cce90f1add0757c9a7133cc079f97e97dfb3ee2f8889ea70b050de27fd80346d08f716fdfba4d96491a249b948deebc373f28f77e645ca8f08dd2b895a26fcbe08b24f57369fc34b060c57dfbf0768fe104f2e579be9bc1153e1ea7bf3e39420c960b048e6b888e9d9a75938c927a432ade3e02139a34827eb240f578b748239fcbfafadac9f72055dd6ff9c62df7959502c3fe257fa90ef69928513f8935eaaeb74cb12cecfeb77c39f75a0584e16d3047fc5f3834c922c28a3b8205ed913ca6d90d715eef3ff1b4c5b513d47413efd6bbe983e6c1f7626399a6fbe278de8b9f2390a962577eb5b1c4471c050b73eaf16ebc9ce8b739fe088df93098237e80faea36b5f2fbd3cd7a8b03a4fb3d4ad262d6f76c472193fdceb47fcfde08c202fffbb0853f8fd0e7d9acf37793c6f0dbe63223ca70e9eb88b4f87b692fd942b14c562beadce3f2cabe5c3643b8982f0220dfe7450f0f365f07d124f82568c9c13ae72e2a4da7b5993fcfb5f6beaf8cd2658e4493e5d9ebd3eb863e380f434fef310403459b0bbb70fd1226a1e4a126823c99a258ffcdd2bffcdd3bec6e4b15d069a4fb36282e7f5897f284027afa26275fcf83d2b5b3fecfe553e29cb4540fcc0fb77f32571901cbf2ae6c43e3c72419e26594cbea34954a2a43c79bd4cf2299a7c47c9343e2975592da300213254937c7ded533b02fbf7e56459a2f949ebce0671e7ff26e6e7cff8c16f90e15c0e2ea3bb54cb49f92ecd3a40090cda4dae0f52ee85c6077cf54d27658d671eff790893e9e127a920f9ddba83b3c6618fff3c642b542645405884bcf8b19a9713582c92bc0c42227272e257c213b0553e773fc97f3b5edabfdc0d56fb0e4ff7ddf27bb6a9306f666ef36bb52443daee2f5cee37106e3bd979203f1e96555e12afeae54e44d4ec5a9ded4bec9e0f1ebe729e111ffcc597b64b2fde2fabe5c9064734271c7db1d581ff1cb26ff97cb705f2af3f56791235667cfbeb61557ea71f4f9f9fc82366fb3ffef5c77a92c3f9e2e19d85eb0354474bc63d6af2074b998fd2ed1cfaf7888f97d03b7471b3cedca1b85c1def10bfd362cc9a305fe27fd964b96cc4f32dc23df34f576472bd4bb75bb9ee11320f31b6a6ef5025300f6e7cc62b5823faaf7d253aec7212ad1693873081c96275b3b70829b1dfbecf17d93da21d8fe20c3f4297e3fcfeeb2ccecfbf4fb7b7ff7b9527e57f63c17f75a3fbe6e7c396f74d9276f3fbe6f75befdbedf1d3efff75169be8df1f73a4df91e538e7466b3f26c20b43512e7602f340b4db44edc221fdc67048cb45740885d484a3fabb00550f1919aabbb799628a3dac8afb8db0aaa71e4753df7a4f5f08abe27e0156d5eb7d6399278effd6c1aa3a585507abea60551dacaa835575b0aa0e56d5c1aa3a585507abea60551dacaa835575b0aa0e56d5c1aa3a585507abea60551dacaa835575b0aa0e56d5c1aa3a585507abea60551dacaa835575b0aa0e56d5c1aa3a585507abfa2760550ddce97762ab1e66c13ab80fb022143b8015c3fe468015cff658fe1bcbec0156ecaf02ac70f57f1a60c531df58e6db13f5d801ac3a805507b0ea00561dc0aa03587500ab0e60d501ac3a805507b0ea00561dc0aa03587500ab0e60d501ac3a805507b0ea00561dc0aa03587500ab0e60d501ac3a805507b0ea00561dc0aa03587500ab0e60d501ac3a805507b0fac700560de6e9b7a3ac1e763cb9bc8fb73a90ed4057bddf09baa22986a5a8a71eb7475d31bf8abaeafd12ea8ae758e61bcdf63ad45587baea50571deaaa435d75a8ab0e75d5a1ae3ad45587baea50571deaaa435d75a8ab0e75d5a1ae3ad45587baea50571deaaa435d75a8ab0e75d5a1ae3ad45587baea50571deaaa435d75a8ab0e75d5a1ae3ad45587baea5057ff2ceaea0803f50fe2af1e44345f41a97d7c2e0a94446422fcf57e34acfb497788ad277a0fd9ea31d42f60b5be0768f901b0d6e31eac45efc05a2c4b3f3dfd04588b54fd065aebe9065aabc7eed15a4f3cd5a37a3cfbbf15adf500e7d1f21cb27560d6f6eb3d50d60139d5707e0b9c6a47fa1439750c856aa8f7d2b3796cf020cdef9335e2f0ea2c4527fcfe79e1f78e00da8bc63f22599a058c94fba69041879b4119adc35cfb264e8b22748575948fa74126319ec9d15046cb51e6d361a65381c3af46e9e1f7ebe6401fb26a3ecaf54d94a195cff895e7d008327c15545c12323c3542ed374ada44f2b6f018e9f37964120d657e16325c1638908e327b65b34215385c3ecef8351cfc54de383fca77639cff2acc78ca738d22647aab7106e270b67c1153c18a866a116650c4f518bbc22694d1aca57b898620c1cf8aac2f3d57af9581be0c59901a3958792ca6e18468282c03478f495f27c237713a9f2a4381f6b26de155420d655c676d0a33bef045a1f41cb47a91748ad4972ea1224b95cf6a85325cbe28e2f35491aef7e72857e93089fba1ccd3fee0305667755e79cc368e586db9cbf77583eb43bd88c9f3743c5091e7f45e1451d840475de27a1ddad27bb25983f4f948142c48fa25fa5319824d2483ca63a4da37a7877a0e550487a00a933dede36b6eac812b6c7c57ed7bae8e8ecb1e55f31ff8af22cea7a60ce27068cc15599ffb8ebe88309df8fc43796eff0e84ca770d3aca7aa4ac97e409d7f9998cdb69ffca7b3e9f6d77f5582abbfead7bd3a02deb454ca793a69c6994010abaea4a190a55c8a84811a93ff7ed129fa781e34d5f44b5f21d290d1c0e45ac968c32b0858eb48caa7813657ce29b69719c4611f7759e2a39ee6783536687efdf4d0185431d2932ca14718af98af17f26ef6c5bc0cc4e5edbb628a2c02b3258468cbd6fdfe9f83c2716b53ca16fc641e0f7e393532f7ffcdd4ad5ce27f40e9efd40b6bfa5f9f1b7e2d9f95e0f6b145f8767671f7f01cffef848b1cc638fa7ffb76a481d9ebdc3b37778f60ecfdee1d93b3c7b8767eff0ec1d9ebdc3b37778f60ecfdee1d93b3cfbfbe93a3c7b8767eff0ec1d9ebdc3b37778f60ecfdee1d93b3c7b8767eff0ec1d9ebdc3b37778f60ecfdee1d93b3c7b8767eff0ec1d9efd9f87741e704dbf15cabe2ff62138c28d168b79315994c97b60ac1b69f6c82ce637c1d61b4c16fd75b0755cf30eb5dea1d63b11f77788b85bb2e6805457aa1df23a3a422073b532d0d761e6173e0baa16d1fcfffe4e642a5e1def8b4042b11378f4d3ef84a2d24fd4b76f4fbda7afbbd01ed7ffa7a1a8df189e65b8278affdf2af63a286a0745eda0a81d14b583a27650d40e8ada41513b286a0745eda0a81d14b583a27650d4f7d37550d40e8ada41513b286a0745eda0a81d14b583a27650d40e8ada41513b286a0745eda0a81d14b583a27650d40e8ada41513b28ea3f8ad32268a6df0540c5853dbc1f23f9241432f35b2faf671e598ee299ded721ac985fb9bcfe1bcfb30c47d3df3a845587b0ea10561dc2aa43587508ab0e61d521ac3a845587b0ea10561dc2aa43587508ab0e61d521ac3a845587b0ea10561dc2aa43587508ab0e61d521ac3a845587b0ea10561dc2aa43587508ab0e61d521ac3a845587b0ea1056ff18c2eae1f45ee6df05b33aba2eff2ee0ea40b6435df5a8df88bafad663e827e6ebee57c595ff69c8d5d3379a657a3d8aeb20571de4aa835c7590ab0e72d541ae3ac85507b9ea20571de4aa835c7590ab0e72d541ae3ac85507b9ea20571de4aa835c7590ab0e72d541ae3ac85507b9ea20571de4aa835c7590ab0e72d541ae3ac85507b9ea20571de4aa835cfdb390ab2300d43f08be7ab08b62b21083e5446a5f61befcebfd405877d2ed2f20a49e7ecf9dab04a4c57edd85ab4dc5bb2b57bb2b573ba9f7b749bd7b92e770f76a244bb3809172df1432e8703328a375986bdfc4695184aeb08ef2f134c824c633b995ef8e5700a8eaebe6f02d64d57c94157498210aff8d6444f9aeb2f25ca118210345ecf89b98a13292f90a8ac23acaa255c40a55e070b99fab71e8003664d5c5285391e770f528f3638f35d6519eae3c875b85ac11933a259c005d630d1954f9ce87f35c87ec7805655043919b850c47f96e4c8d90be8932b4f229fcddb07d57a72eda94b7348c5f790e8d20c35741c52521c353a39cb46be5313ccebb0745aebdbf168af83b68ca737d4795c2dc2fa28c5f850e58c1fef22570e84dc8aa9422f3955f71759b2e8b32a9f45db88eb2e5cacbf83514715d756a9443e425dc2c94110af3f18ae42da928c2f5c679c912e55b1fcb37181a542472a6ef4a34cedb70382a700dee836d9fc3a1b119215cb6b00e731d1dd2cf0fe50f75ca738dc2ab9a710964a9f45895f497e54894c7c4284aa53a624005452e8e581d45b96107b27432065133eeb3b63d73cfa1675146fa55f75c6316c8a08aaade0f5cf658ba1ccf17595f7aae5efbae367d33857e28f3b43ff0e930d3a9c0e1576357d884329ab5f70aaf3c661b47acb61493e729644062381c13b8ea3acc68dcef388fcbf11439736c73038ba2bfdb03de0462fa120d4112927a37e52b12d84432a8c68c54fbf6a1fc8647846fe2743e5506c2316fbf28a280dbc378ae811409f39a61e23601199491bc8da16c4f495ff4972fb8be6342d3a4838eba0c1c6d0a33bef04581f01070858defaa7dcfd5d18b984ea11c57210b6b65007a1e0336cdfc12bee1bc1451c0656d4286ab7d1baca08ca889b5b560733ff39fcaf030fe4a9fc2791551c5558457339c5f1c8719442fcff3a922eef23be5b7512eac23763c0f33c02a12304d739a8cd8a69f3cdc4fa652bc8c77e92fffe179ed0fd3b992c52894b76b2549978aa45384072a3c57a43aaad25d7b4e78ece5a8fea30c2228117ea5234a5ffbb23dbf576ef38f633c674bfbe6b41889028a5c108792b17ee92b1b4d4c8bd74d93bee13d9502721c4331aef67d6a72b9ef1a62c818dc8b982e15196ca1232d81fc3457d258b206db372569f319522fdfc7f3bfe3ceeb2cc893ef7839a8820cdd57444f490fbae7e36f513d79b6c7f2dfd82f553e1f3bddb3d33d3bddf31775cf53b970d028bd1c14a16ca028d71eb104f66590792e58c2fe7c1ac9d2c2778d754bb3f11c7d11557c021db4f46550bde64611e6e94bfb1dafb6f52b5e21456a1a624dc69a4fc748f86ea5926d025f7229a48f6d28b592be91ccd67caae446051d3b11a7ffefcba4278103468ba428efcbcb23ba9db0e49e3e7da2eaf12f86a11ea96f8fdcd3274f543d7ea3698aa60e61ac7bbf7aa60a57ffa7cf54f13d8a65d86fcc6d81f9b823ddb7f8a6c0bc4ada9da9eace547567aaba3355dd99aaee4c5577a6aa3b53d59da9eace547567aaba3355dd99aaee4c5577a6aa3b53d59da9eace547567aaba3355dd99aaee4c5577a6aa3b53d59da9eace547567aaba3355dd99aaee4c5577a6aa3b53d59da9eace547508af2b30a7bfe3d8d421fb8708cd5770b29ee4e53b21aa8f09f7f8d347fea7a2543f3e3234cbfe5494ea2f445491da7f1652c5edc04ff413cb303cc77c0482dab6f72310d4036987a8ea10551da2aa43547588aa0e51d521aa3a445587a8ea10551da2aa43547588aa0e51d521aa3a445587a8ea10551da2aa43547588aa0e51d521aa3a445587a8ea10551da2aa43547588aa0e51d521aa3a445587a8ea10551da2ea1dc8d3ef43573dfc3559a2242f17d17d9cd5816c87b2ea71df3e17e58f7b6468b6f77301a6b9af8bf147eafd7b62fcb52dfe08c0ea40dac5f8eb62fcfd87c9ab23217288f53721d14ed52a64784a99cda770a8d2beb97951c4e72492a52a624085df2ba9404d5c01458c5e05ae408d1c5087325a4191df78ae5afbae928c48c45875130e411e385c8dd3396d34d5dbe9956513fbef3989862a8243a3c07929a200dbfcd06468a030334ef3cbdaf4fda2f21d7d1d3a34a641fe717ef296f619b47abd5d771431db22ccc765948159c8d0a5ef70a9ef8cdbb63c4f955c58420716e1ac788643b4f15d7d16656803457a97767d276de5bb061538a05292e7a9bbebd71c2c7d574b5ef7117b9f93307b2a3d865f450cbff44de551e90faef5cbfab88f5e13216c69483f45b9ba8e1265a90c97b87f56fe80cf2c19ad487ea21a43d7582b89c0b7b116e1a19e121db2068a2ae551919689efaa55c82ac90897cda095cf6c91926ca693ea39f19ced3264e12172b5bd2da00c2acfd9d607fe1178773c9f7e1f17fcdf13bff194ad8bc5a42c93c9e2ddd5f18870b73e3ef1bf6f797cfcbae5f1e936fab85b1dbbd5b15b1d7f62753c920e17eb63ed3b7471be3ec2a11a07ceb60833d8c7f2df6be4ec2a64382c2f1b59dfca4fdb056b28db586653510ed06ead8c32b482122cfca131c7f9bff69fbf3462f88dc61a83e7be36f82b83f725e681ec706a83fb64d8f05f9198dfbe306838a97827333b99d9c9cc2f939907f97090984a25d858dbb65b6d5b19e8cb9005a9e1fae41e0e23072b8f257776bc8808a250c6dabb3d85f2d374e2f07494082bdf8da6006bdb60a76d1fdd6d93089b28e37ff88e4e29a66007b23df532be086550edeed6f00f654c3d864f7d5398794eefc5cbeca99ff174988da781d39b3a8c5060ab61227254c408f045ecad03acc5bbd3151c6ac528c1f9a35a910ff77e28e499469ec351cad058efefd3c8c62fbe1bcfc221a803dcd6614adae4504dfb9501607c87a3229a9a937b5c86dae3a8e267e45e13b9fd567145583d15235148a03b26fda1c87a1c2642e53bf41a66b89f622466fadc77f48522fbeb2811a8a68e68a50c8df9c93d40891093b6bae32964d0321485dd3d16a9221774c48ea77e862d04810a2b016bf44598088ce77045286f6331432b8fe1cbc0e1726510db407a9e4619d84207d470a8adc4e97ca6548216327a1c8a029ac86006ddddd892bea1c3445892eff29613a7c5d4938559c87075c86c9198719bd0148a30d7296c59b4cf15747ad32682fcf825cc85f2249f679cc733ce1fb7b5820e47050e8d94212c427933f5dd7813b23ac27d116500293258f943018f2b15553d72dfca4b224c47ccf314c8f1c9f7b63fb99005d5f1988f4804fbf9d413f9b9ef484b284fb1d517fbd8ba72f5da131b3ec4166024f3d82ac47c5629f2607a4ca7c831f29c2d1588c22c90c12cd85ce61bca08f3028a587daa48a48dd8b2dd840cb658852c6495a9670a4bc26319a8a34ad8a59d7a4c8c3c66b9eb9bb3f765ddf252e29b42ec313a2e03f9a280c7bc6db34aee95f15d65eab9e317878929387cc67cda8e61bc8ed8f1e36bffb9a7dde80bd79c168a2cadfce722247cde9faf47cc76ed31d23290f91af6e73dad3fdd8c985d5ff087b6d0d4fcc5ec4d9d03dfd311634f3d59a7a36c3b25f34d16c616addb9e28e0ef086660059f0bccbf547036f78fc6e3f192f7709e9be9084ca7f680b780f85cfae2733ea9d49587f969369f2ac8287c065bef9ba982e959631d3aa0329d71f29a3c275a7f5069f598d66751efd55479b51222cc5f237b9a8f9bbba55650a489f7e13511e268282c03476fefc3e27f440cbf3a4d63978133c6d67fae4844832c4d11f67d93aef1f8788cfda8c88d3c19398dcc1839a0e7116bdc3e4fb32b37f55d6f15301c2e97f14d0e4d64a98ce42d3a2f3b6205e4b13e8a721df71faec74a13a3a98bb555f90e2f9ccd49df91d280f0b036f51c2c6bb6051ea7660e1ccf4732be2f0ec333beab2e43464a47ae5085ac819a31e4e00b2957a85f93a73564213bc232c229ea51a6af4393273750780e44a39b79f476fcc806ce767924afb14cc473716a4a866d8bcfb4d6d7a636032a98a1996f0a20cc24c673d0d273d4a5ef3cefe8634516faed7d5ea59d012acad1b499db068a12a1f0a7c5850c69d60d03411954a18356be3326eb035e9342dce7d9768dd3fbe266ea65528dbf631e864446d12874f86a62e2fe2277bdc5cd7ad3aca9a1ccaf2351487d671b4f4c2ce3b4597bef541166111997c0d54ee6463454d741066610cfff4c5f425cf74a8815a92477c12943929eac89cdfd6b7c73475c6ed42f4df953bca63a582ec9208f32a969e765ba22cc0de4b3eaee1e382aaad295220a7ac818859f93fbac50c4d84b45c632534a7d51887dd928087d262ddb3ceb53f9acd2c4ba223cb55dfb0c9a8da6f3174f16a67b4fdab85845323525f56879f46fb6ac7ef95e2686637f9f81f5f4750616a977675f75f655675f7d997df5333734f98c5e8d32b41eb1421c30800a2bbab99d698875beb21e312a1d38dbd4779547b2ce8cf1daaec611d12de02c4ab00d82d7d51241f9a9bc79d35346d2bc28c436db2e5f1321f7586515384febdd2d5123a7298bdc51ca6aeb7dbd670549234e8b93baed6e8aba953eccf8d4778a9ae82ca6900772db56465d635d8aacfb4c813c76bc3edbad39b2898efb63f90865b4f90dbb144510a5c174f27fb144fc8b9c4dbebb365c92efd60796a2d9de6f5c22f8af5b227655bfb14a703cd3ad13dd3ad1ad139f5e272ea5c5c50ec6c1a6cd7676631c8799b13cdab9c7f6534d74784c377b5e69666fb3dbc908657e16307e11cac039a6d3763b1dc42f84aa7667fb64976367a3911de6e1f2a5d9b1568e77c03f58c766471c66a08a182ccb9547455436a319b653f73bff382f6c672372c72d412f48b80e73dfa4aad1ecf9242f5f069b66e79e9b050e20bbd893cdf11db26abbf3dfae3fcd2ecf44b3ec9556edfb679f9fc76cd7d896227e89a146fc04ee6cbcd2c45e754eeb67521c55f48fa8a20f7e2ce277e86d46b368a599ca9efebb79943633104c0d14615b5a062b8f41677ddbe43f1e1a5c24837ac41a7144769fdaba58da597fdd43681ca1245a44455b476a3453a8b3fe3ceaaf2b48896344c9edf43bfab6bed14a9b7997f5dd2140447a16325c163851798a8ec069a757c7c877f56580f9cb6dd11d09bd8932404119a12869c7b7ea5dabdb2a640c6c8beffa00f3d34a3fafdb31f2634f77a5cf739d8e645035767253ae2ee2b157cecba53c5740877e1bd457ea4645154dead7d271645e98e7651a1fe8b7c14ab3a657eadbf093c7aa45341c1ff829e951ca747f5ff40e61c2efeb97716b5f06df43874fa1b34551c53f7b9994f8ce66ddf8e7e9e69e73f38c87f3bd2f8a94a557bdad96f4b6a76d522bdfd5d7e1d0477ed387e49ef3a89eaf47ac8a7c06d570a87207bf115ff937cb7f2a470cb947ba6ceea1b7cb43991ce5b3f313d98179c8776015b80647fa3cd7e79e656fb5840e605fe242c610277d09782c2a7c20e83653ba21b2a94012b6c1106e75261e0696ba32d2cdd69281a051008462b9d5d2ad31e90f18cb46964fcd372fec9cf565aef4597ffc0a24ca74b608dac03628beb0a8e9d6ce7415d6147fc2e75846605e1e929b548ffb2bf55de2534661a6176748a49d2c483c4745a1c8cf0307ce4319e5c1f0683e5a84e70fb2a9bd73fb20a39a79e232f4da1f12b4d37a2cabb19781e588895138145094d08ce76c0b5f96a89055cac03150981b859fb573f01d3ec0f3e4a4bd39961bfc1266206dd69083df30ca401eb83a15e5e92acc8532c8b515b9279f3ab4d377b61bdf554a9849cbc0316228f3d5c841785da002c727e8ab91f921ba7257bf516ee493e4845777beb0020e53d296888963dd1a5423e0d570a8b19394b6a005967e865840190e600bd31840d54aca6598ea12708cd8912105d2f8c5a7b689e6aa43cf1e30414a5770a07086434b3ab5d9becafeda1914aa61c5204c7861c44c192b2d3283963623c6de9a334378b3a8f3b590d9a31c3e37a685cfc44bcc2b448efde6b13be251324647cf3f3916c81a533c3b19fab66303d502fad0b355c39b81853130ea31c36f0cd928800debc81562387caefd945f9ad678a1a5b16133a51ddac0010ce7401759fe40eaeb3670c7ac64011ada702614deccabedac3075c6b0c79991df1d8bb3b5ffdd75ffb3730daf3bd7c685e833711ccacb76ee2b588fb9a00972ad8432bff05bd467b3463de3f5e36765c4113ff117749ec3d58149d77088ce919457f4580daf4fdb5fe637465a454c5a46acc18558a7aaa8f37a945a85d7f9c10acaf0f15416ef7ce4889a34fa631dc8035ab39412a0f1c6495326a00bd3978cf9ab8438338f6a9ba213c7a1d6d02c5f23c7afc76e2c45127cd324217b75f5edabc8a357cb7027c3f82d9284d1a48f647b26c9e110f5e180778c01f7669bcb5e981bcbc8f67b0150672fac4247f6807f3b5d3f53dff5ce74f60febc6b390d9aea384e812b8dfa976fcb7a3597a3afe273c0c563ef1dd5f597b88aed0e8aa6f33eaa7f58a00cf7f798bf9881a311774b3409696c1f9dc39935558af39d3c5b09d5387cc96f1db3dc0a3bdfcca776011b1463531b9552463bd9e5b4759b46ee710964d6db9d80ec17ad3a7740a1dcae9c29fa16534285e3d16cafad070c16cbab658d5064343d61c18046699bd0efc6d3844822ff37494494b8ff25d0349ae3153165606fba6a4cf83acec7b49a91aa9aa45164a202858c3927a1e531ac032363ed069dbfa429d223b9d3f2d9fd4232c53ce75d40cd41e236d7c32b7d422cca212cf4bdf8d3707fe7a5ee917baad4e4743611de5463d72f47528f33bfd9b6ef5efffb1fc786d1e1dcdb5739bb7995fd52febc117e512b9c6f04bbc4e780cbfc2e542916acbfb14bf1a7e2a01288f1730f5d3b16bc8b6a3f75f077a7f0210a539be0fd8d88a6ca9306b7566536366921ae2eba0577bac501bb62a40a4f6a23e7ab42898eb69b4b6a958311112407fda1b31d2e38842b431808235d45f41a60efdafd481b3867f460e87ed80461e9898efb4644f37a45edabfcb03929f4f7dc0972163d0649db8a1a75cd031e7e5dd5bd3b05dd7ab7f7d4d3b2993c8a7961f882f666435e57c5477d24c7af36aab4e60a1c2a325c6075e0d6cc40533dd306d7a16490633a6ed7b63f485fd19c7514567a12ce5efcca5bad5557e752ecd3d572bfd6c1bfb15b6230fe58f88bfe5e33aa866d2942fa940a3f4a193ab858960e9a7dcd0cfb66bb33f6543c9a7e1ecf9a3bc8ec20c16617675fd3ef80b663dfe176cbabbfa5ac4824d24f3151c6a652b5bdee16f7ba59b5f6023b097eb01966f57ea53ea265e239e3fa5bbd94ee104394c9d01a2f4fe73cfb2513176a5bed337d6c02e6b9fb62bc39504832d6a0d099b80a1280f48be9715e50b5d48800233501b969ffaaf60a850d0a65f9d8c8e351970baecd1a10cb5282b454d963c4d92f4908dbe52773be2d7bdcf6b339a3d1fcbb7dfc447e7be46a3f2ded3cd44e207fb65ddec7ad978feb6ef87ea6c44fc1dbdeda76c480b303a6d0c0c0b6d42c99fc33c367c00356760d830f519335553b3ef6f0c574fc36c83e5473a76052a74816c0001f9d280325c75abbb6a6d0c75ef85a199b14d319a25a8c1808bad5a7575e06dfd01ff16a6c6682297c657da909e5330adeec48c6603acaf9efb1b53df51e91def90fe391d8fc697cb0a95efd807dfd1357f2cb35d7b99b48c767c6829c77b0f47ba06c4f31a1ddb987a72ae3ba292cc6d91ce303f04e29eb7ab2bf5fb115534e739f4f2a08f0eea2b7465e07045e84894c74cdbb610994e9dd711f358e03e9741aeaf43a25791938154749863a49f7e698ea1de5613895f72a30cb74f4abfc7933ec3b6f927f5d3bd2ffc98df2ff5d3c358dff3ed88bdf3befba939e9cb20814e84f591b65c8a22fafbe77cb0694801d61ffaa52e097ddf5e5266ad9bb6ddab9c54abc608817126f520b515ec54df3a19ad07b921bf62d96ecf2b3b533693a1e084322fdb19d7b728838d9c6203194e081969ad0f05140e7abdb0af9b6666301a03cdafb597e8c64622f651af3a1ed79339ee7039c15a5e99c387fd2ae5cf37cbbb6dffe402f25d75705a275df75d23bec2873574854dc892fd86565fbc281bd3ada321c170c6a178a6df9df0e787f5e8fd3ed28e67a34cbba2f7c165c8a871387ccf2f34686cf05fd7fbf250e613cfd9129fd0419651dbc67ff0399d628ca03a66c1e324351843e615dd325ecd41d98f1830f01c4e0806763d66c000eb37c660435b60cc5803da73e47905287de5f71118d76a3dc98c853e905c4bf67ff8327c1da7ba6749200e51ec7bac208ed3f2cda6e110325faa53903dc491e3a388dded173caf5ec5def6d7f9777a4b6666d0e1527246e1b23e74946dcee54e1eb8c61c3a0a39db3062c979883a64d57ac4ea4598198407a22ca6a3ea2bf4984b7d387cd767d9cef95fb6ef68c293a1ab955a82d71de553bc185170610fa70b90153a9469414f694f9bc1f5d832e471ea4bd6c0ef3b684ed9b5e1450e185a74dc8733af07a5f122c8941a66cbb59da3d8a4e1589304db64910b655ab3296ae32565ec4bc0365c3f896a696c3892a2e5f779f10bd733e2578a449a60f047bb0802b971ced3576cc5f33dd59f921937cb6fec935b3a04d596ff997590627c24cc5e68850a9c988dc03363257c6cba5ee5cfa4dcb2a7bd70c03b50828629f3db716d7066edaf6dca7040c6cfa0430b11e3f723a7583832b70d00d20399d621adad431b28d6f09905199887c3711d391b261c80e2137e980fdb14af377d773e1d6604e77eb986e6a00acfc78481059463da4bb859c8e0be16d661aeafa35c5b133cf990ccb32a1882fad3ba5426d55046d9c4e4e320f7b06d5946325ab6d11adef3e77cc59e58e6b93a15383e3762a41fb0e19d4d80eb97609be6fc1db56db0339fd2ab7298ea6fc0e636ce5077a314191a35a03c10f7ad014abd6cab6943631059e36a9c466b0dc5accef03d2f43cb5767bad55cb086f56033c90d4b4b216d64d2a395aa5990a95544cfe930db2c42242c75a718d84cf1430786758d9f3e6fbf789ff5db1df5a5bf8e7218474d8491fb76a9d9d8d0bf6e97fa71c492f3116b3fe32bc848952f8394e818c7cfd6e053bea5667fd35f5bd59201d478e301f5f15556599f2a82d7a1b008d8f84764c1f5a88e7a5aa61b9a33e7f43e5000136d42460d2c07aa9e63f8a0d6c7be1b6d5e1869f5c22cb7b6bd614d2004e680aa7d59a101e53116fdcc4cfa0617daf4e55ef347d77df379fbf97dc443df4543753d19a6a5e718e97bb8829dffe32bc7eeb4fca772c40a55c8c6dcc891527fa8946d999f5a97e1306521c3015fe4873ed0b7266df4b5b4584f727da9bbf1d0cbb81e7038c948b58dc5f4aa115b8c61f2d40bdc98830cdad80eed3839a401ebbf1a0c27860ca2cc99ca066ecc825c5afb39f4ac1cc4aff29c712caf0aa56b7b86ef62486ecf1f6c075fce13c2b3914cfa6515e4dae99ef32765718315df165ec26751c5d51e23ad7c1955efacef64ff56ff759be066f964fee6da2a62f418af5b5142b5657e6a4daf3526aaa301fd12d47ae2d760e5c8aa36aacabe63f9aa96811763580463872bf43e1afb69b1b2fa20f399780c6498db435ff4457e63a49ce55345ed0fa41cb002056d9fd659693ba2800953de37b2ed1ce6ba0606fa68fc95b66d2a34383a192523c6af47b94e79ee78b7e7bab9e26baaa0d32b2359aa3c67bbf49dcd01a766f6b85fb62dcce7deaff21794a5f7f6ecae6005bf86b770d97bbe628d188a545bd6a7d675d571b68a990e361eb3a5b4a474fc1a261ea36f5f68e3d1ce8c17987bdb5747ab4c9bdb8e915e8714af457de9876fc15e901b954ecd2b3d295d4752582da5fbfed007afee601b01e3d10470e067b1ee27e5c0ce7dc34c97d427fc251fd61395fef4b3ebfc192fc216eff28ebe96f4982fd0d7ae95bd1e99645c59cfd92ec8fa9ef498cff99e6331caf838aa7d060c0d571f40d5910cc11c186bc3d2aa40e65eb594a2274e998f59c13518957606b1a15980316c7a1bcd943a1a28ac9ed96b832e668eab07632a16aca1476b7249f97d858a9c589ad865a5e7508432cf7e2d7e89ccb765e02867b2f2968c2676005e73b7077cc01d7fd7c7f7fba7af9fd53d86e73e04beb868e3e55ec65761e2eac0e152a2b3b0ea1cbada3a7035cc4f4554519bd16cf0697fd4abcd49a09f6eb581f1ead9681c66d00fd3ad66cb207fa1f87c924b756021dab28cd266d435b000a7e7cf3dbb0683494adb2005b5898aca7361f142a96b63c00190aab1961a7333970c070019a6f4c0cf20d0fa5e655dd5356ef8a33eeefbfcac4ca827191d4799fee839cb35d1f9449ae0f3dfd5210946e0d73143e3a1fe183a52e5b1451c543c591746ae51840e203ac4699d5a3bee737822cfb495ca91d54753325ef50c21d32932d3a69d57275e824ccf6cc9aef45cab6026650e808647170aa063c562e3c2036ae0d860605280f5e5cd569ba160e244b4269659482347cb8abecf1a55047441cfa5576873d697ea105897cc403522e704f5759871c8dbfb1c894df4053ec74ff34d7386a26a623b8c5c7d16c8a0890c761f13bb19cda22fe099f6bc0753d421d32b23469ffb0e1d137e697c49b5c7c4287406655be6a76481c7c6ae8124276280185afedbab0d13584b2a60945e34f3dfecda780b249dd29878eca4db85914a1b4b2ef457c9901c497d1be7c030a8ad60f6d542cb6010c9bae70fb6a2e9aa1b67086c438e159df693d0920a47a65f0deabe2cf8889e767176e7dedcbd76a6e7e7e4f08e0fc8fa407cb0a47c6aab9bbdfad33258e493302b2c271df7745464d140ad0d79db379df2d519202634cbb99ec3e2d58958d395b417a62c8dac345e68c8404b7f8932a9f6a9ad14ca7e61cb701dd6b1f33af41d3fe3a4c0120c80b4ad96c124eca754d0477e44937eff0cbfefcfa7dcd17faf9d5bf9353e6fce35e1f58d943fb276679b3e654b6dc02c9e990ccf8e33a30eec0117666a6fec44ac6e69db88f22a8f31c64eca15c0e1738ff155e0006030d4c2cbc00f60abd2885199c0511f355655b4da2f6cf0cc7948fa61557c6db1850c699bd32b9e1ed7a01cb368fdc5b6d409af91b625f39f935b1f3cfb757f8c2fce74fdd218b7678dca0bbfbe48b791867b78fc2fea497881ecef7d6a4ddc7aa99e07b4a0eb94e182a1eedb36fc31e923130c8161b03a1b986562b8e34de0ea5b63a0a2b02afb26ed6d5e2dbb9ee492aa49c646a7f440a7fce2d5411b9ff2053da367b62bc9fa807b0329c7da159f69b9c24c247dfec5e7766e8ee36428a02843641fc173362589d3d59e4fd4c55e750dfb7f730c587d16b2021a39741c6652be3b37762b9f763fff705ecc3cc3e3639a7d6c1a2e0e45baf29d71e965dbd86396251caa687fee92f88d2ef019cb9031e2688fcdc072205a69967de147f01d88fb6273c07b9c63ff088e1885ae7f7c36a2be76262f620115b4918f5bec08fbbbb01d27fa4c8eed29b4bac0679028a568d3f6dd3a223617bf0c65306b62419db7fbda7e09bff11d6e1632dba5efe854e0faa88dbd742ba2f72730069fe2e17da4f1a333b537cf761e70df787c85a7efa230d1896fe979fa7db899122cd29d3e8d6480a2f333b6148da03cb8b2cf747e2ef2ec3b96b9ac40e22379c47775acbf9cda961ff53fdd3a637b79b6f572fff9301feff938c65817fa82733306f2729013ff54536ed9e2843ea503f9322f41c66042cb188f1930d207cbda46d2ab868abe96aa3eb0d5783284da18a8fd0814a5e51494318b63dd925e34a426da30de806cbb3690ba1a53fc00b2d28f68085763878fc3dad8f8cef6f555ded4765aa470a6e736fad273326583ff6a7c175af2cb7e09e60e4e73e33ba032ceea643980bab043085eed3d6ceeff3cfeedf0137f1f7ee2f6b8c41bdf558bd0012b284bcb917b58fbfe617db017c9a00a1afc04d61d6828a365d460786f7ca376f5fad4789a2eb4415f75acd418997d69fe2aa941c400ddec1b7d8f46e264e62fc1d037438ad78c21a0239b0b9c8cb783a19f990330b71814d892d40fd968a1db60a9d178ad8b5f34070da2990f1ca9601dd790341605b653ccbdafc57bef6de1335fc0019b2b9e9d29f9421df0763ecdfbfd9a7381c9bbab135cbc3fe88a5779ef38be441931fafa1017c3beab4f1cf3fb2eeec3affa97ddd960d360131a9de46d463083f730f8f7b06ea42f1ad976a9b39db70bbaeaf25c0ee2f10cc9b9a72d899d0933bbc5c85d1fbb4fe94e5774d3135dedeb6cd6233df11dfde66bf09fefc63b2198aeddef9fb34bd3602605a6335deb9234f26dd0b764a5f213de0890ca5a0e3d18bbea0c325a0518be02b4608603a5076cce76b2adafd9e506487eeda129eb5b7ae064c626907d13d60ae7014306407f8536145f8711e7f4416dd729fb9becd2dac3f68549979ec3c5fe2e36cccfca81eaeebcbf394e17ef59637f66e15336ed2ff99bd589663daf1a5b0fdb2bcf7fbe598377e4cc3dec1b9eb34d1baeccebf3beb98693bd622f3698b91bfdf8297df48afc3a8bfbd3ca636c034b3de6c48ebb7f4ee953faef695b7e0b8efd3db97505d3ded850efeb5ada576053db3317587f6a6d37abb1053fb507ed186bc38529cc28ca1ee8c8ac8d9146ab8635538371ad8a0e00a2e7c6ac3590cc312b05a14dff8003af87e59d39534d6f26f422c95f86946f86a9fe660ce136c805364ca5b5e73c51910c96d62c5e6ab4fae20fbddaa7d52f3dffd4d818048f42f6f37ef94c5cf255be86eb67dc4fcb7e263ac03e7ef2594c97135efdf0bef62dfd4d88a35c475167a7fd8fb0d35a9db60c1d694562eebd174be9dafaf62b7b5e1f58e3893e7451cf9fb3c95ecdd275ec6268c81c3dae910325a445b63af7689db62c98422ba2fd1cf5ed8ae7a281d6f36a90ebb49ec21a6e0c6a4359a9617b1950b43a462612b2498a387fa02b4e6aac2d06fe0865be675392a0554b2a14f9c7e89d3dc99fb3c96ee9243feb9ff78b88414dac1f0670e77ad12ffaa77b2362b7ecfca8c486a94f6c18b3f161ffc7f9ab7f490e1eecd87fd41fd2d603cfb19687ca1dff7c6afd768d858380e85386613206e3e75acfea8f594b96b61399ff615286f4c2d02a70e8b749663ceaacb280660974cb586a141c04b4b1311cd5d0ec62a331fa6be44a02b0106301d01fa783ad9f212aa2d03cb42067cd0466d2479f58bf3f6a5f4f49acba9dded8e8d7dab17ebd6d78f9e69ecdff587bfb57d688dbf6ce3f6b2fdfa817d9dfbfeee7f9b93523a0d441e01ada8851b911158f7426ea8d69a4813e8c4d561020b3355f65631d317106d879cfef47db6096b2e10c2c8033a03d465200ebfb9aa432060092e770da8802db715aacc73687e02cf6bc8a2f6dcbd7ac21f4dec3b1fc27ac193f71f6bf39179ba73b5f1789d97419eb09d523072e43e6645fef627f386240896569bb06b1c4d6393ffb9f1bf5f1be3639a36fdd8ba3dbf9e9fe13f7386fc989ce6eeeece6ff1cbbf9e23d1565005d39ab5cbe8b1f4fbe06731c3658f132aaa8ea27f0c4b5c194e389583a414a53a13d602c30ad748617f4812f1a29d08c540f9c9961e952bcf56df8e60c74469fc51410cb1fde4c67828a37278e3402f4f3c6968cd104402ab4b7966509c90b23a5001812ccd45a0382e4d9d3ea1d1ff5aff8e298c0d58b26b66f8926effa317e836e94a13a708d7594d00bdf458d7e7ffeeea7f616282a64a7db88294a838ad5895c48c6405d59b64e01ca978301a89ca1311a5b92e4d5423dce057a3213b2c8f16a5b2c738d2a648345f6641827c6ec99f172c46a03df8c68611566ea56ef1b3393418cd987a3a81eacb5a1c67c699cbe5fdb13d8ef059ef7e5d7eef3fd7fda0e89bd0ccf05ef2367e0bf224e6fe2e52a82cd79f7f6777b3ee273f18356616673230a15b6c9cf27299a3b96bff107c6ca4b556a3283830009b6c9aabed617c623b6606c492f75577833b272a9e7316db0ea3044f16a44fb141870af7eca5163c70f5ecda7ad9d1b2890cb7a826c2e72743b70d2cd3be7e1de97678c44e24f798e4e8d9cedda67e095bda12b3ed8737dfb27fbfd4ad9783d89bd1caf6dd20c8af43264608ef978d4601a3f19534d1503a4da4e1edbf6d09ffb36cf188c2a46cc56b669f4069cb27aa1f51ff6d0780b7355b3fb5aed27a56302a84d32f068bb42e0b192e3d7f08767e99a2e1ba223d38f930cb2402c63adaf7001527b3a10fa81a5bf40079173eb1fe27186afc2f7e3d67f49cc3acfd1d751d66bfa96944bb12496d127f9db76d146939fb623867ef565d5b66a696cd5fec2944bd666d5d2a7e71b0b8cd741aaf7a30157404605410ad776daa37c792b0643e905cabc016d7d65d8fc6892411be430d7a4c20d6c7d6dbb2963b3b1ee3baa01b269ef13b8f724707ad76208cf42566df836538b30d9f7fbafe2e9366d2ca84fe976ed389441aef7deb131e82fb231daf6d23f22767a34fee4b96cce967c0e5769d6c218cad45aefc33793f10d3b175e6d4b7d1931bc6a254fb50d5061d6be0ce968e1db4562dadb79c418bda0afba60b04d4371596bf253cfb3610a64b5d4ed22f1337f63a4bee0577cfec2168566db8b20f75f709961f6714cd3477124ed38b46bad77bc6fcc1eef1bbf8a1736fb4764ea0ff8debc4e085efbd7cf0393b2feffecbd5b77a24adb36fa83de834581f4680f1ba550226553d406ea0c28bf2014842851e0d7af219abd9dc4b4733eef5adf7330c78c0edbc2dadc756faefbba1e795ab447de92cb725b392a59d15652e11d227323e2a6c9437543344939add7b86bf4a434310f05f41c0d241c6ca21ed2a06b1e5636dca74e33253670c9d4ca788e8ba86cb9af993b0cd05dec689bd8a82182355bf1669268a042ceb9f5fcac774f64a9e137e2b0be071f3764593279cd8ff8c64f1bb82416fcd4d766e02c2a5bb51862267538e3e5ea1143b13ecb2bf1a61f0f1ceea3e11e7cc25ebce7133de1228ae6998b62d0baf93317dfd7ea1a8ffc635fc160fc99ab4c67fb4477555ab21fb1ae1e2ef5c9920ad50b0eb731979ff5f45c8b1ff9d5982ff413b2c45155b2d64ee35ca6b393da68cb8aa6e5f6a8a7859c24b4a9a31297cca85b1f145ae298f738643b52d50c317f9f68cc491d512c8c3b90d27ace4ad849de7431c736726a40ec9f1d56198a43c96898754b265b1ae28c737bc4a12bae8a8baa4efbb70346ccb1f682abf43b766ae0d71f743ef4d1995cd8897f7fe0d1bffd3c9ebd061fd5eb3187fb6ad803e1618fb0d110af0617d6a508cc5287f94265c863ec3735a0e1393fcd802bc7e7639d557726218c781457373da669810d51002581ada79371975000049f1b12ca3856769b56b71a71c6a64761e797b24a0c384b1dd1a61cbb68e6ee928bb459be8edfff9bf3fa273ebba44c1ba9ab423a9fadaf779df535deeedf9fcdfbf74e9c75979d6b3de22297b958c44ac40140d52affa5279ab60ba662866db7f343fc633913450c61166bf21e174a27953bf789303d2d9be21c4e036e7aaba0c164668f04c43714da6db46e1618b216db22974e5350956ac8a1ed55cf75c99a44af9ff6f973cde24ff50f0112a73dcd17c8879ee1f0a891ff260ff1b64fed30d7fb051fced9336e2ef8a057ec9fea7dffccfe186f9ff563fef7a1ffed3afbf371cc83fd79e45d3c9e27721ce722fb4331a095d70aad59fb15ec096d5c5eb69d288591cc58b5b4c13cd6d143ead43d62c24fe8bea536bcbbd181e5f516f36c4c13039718deedc5d4652c44510aad863a00117aa7b33e353c0d643e4137377abb8e99fc58a7eb625eefe1ce3df6414e5ed6efaec0fbbebe347e1a9ee5c8215c7d21c77a9dfcd0719f0ebd4eee4b1da7c7e7684ef5cccbe2a8721c790edc63dd9d478cddf885b94595726e8c5f7a504087b33b1de5d12e76b229d69a250a7d9352711f15350e00630b3d1d116aae7181d7b2149dd09a4816454b432b4e9dd627ba6904fca7b9e46db4d0a0955ca2e3f40f9ff9aff914defbfe8a7fc4a7b8546b433328059134948b81df27b65cfbb4092352745ee16669ef75bc4cdfdc0dff985ed0e9b7206d35bcfe0adffadf6389dee898bd98d3c7e738f1af5f7687ff888ab99916e8c6677e9b96ee7dcc841de5ee5d4a1b27b04d416659259ded882816ace05d1fb0dac053e4a0c2d4568e1b7105a749699298402f366e3701c5bbd8c17e628bbd97cf3b0984456c7527587d431982dfe2097da775f4328efccb5eee7f90b7f65153eccddafd3f4f7cb6b9d65ebef7541385388f3fe3387d1fa37f77df99274d85d39e7b1cff3b3cc7a021e41678b9bb4f813b4dc39adff4c28b9d71c3a7cc10c6af0e31c563eedec7d32c8cf3791f101650a7f1d399459842f72bdad85e617709756f12266751d02c482e4baff075629b774b5e6ffc02a9156d377256df5f576fea3027432cfc4304601f85f8ee638e02ab8ef4f1f37a3dedd93ff661fc731c7a3aec223d333fc923b4d7ca23a425ba5b0d5abdc7712fe5c0f5026d13e9f584e4b024342b04c9962874e72254a338b4f2e0104f507bfc787e3ef46142f70bf812fb1a5a6d597aaaa7a4657af251bc8b7c144432b264d04e69bae7b3db0e01655088b42517372b47e9b1525b34f53a4e91210a8c84badba01e067e0859aa6a2572e9a54583798ebcc06e7f4b0d11640b8f14ee3e81bf80d7a37835bd3511438a68682e8bbfe66fcad2521efb623ee36e3af2825cc3bfe8c4a9a761f00d43b73af6eed1e6718ccbf03c3f012dc726aaf012f79890c9d8217a33f5e948a7557d1f73b8e1caeb10733d4e451769409376dd46252e96b61ba6a569dde862b6caa911d311a0ce7c8f2a4bf70ba927535651624dd0342b82b2ed1398e909b8ae966c6a58dd6073d707bb3deca7ff39cec3fc621b9196d05c84ece1d127fc8c87f72ab6a272b3550040521ebefb68335e3ec7e2a43574590c98cd5661b623000b16aa2921a297902954b01ba19b05b2d94e84d20a88fc41382e53fa73136bf23e29db38a1aebd5a8f739ab3bdc8b36ea1a30041d9a2dceac964bcf76c75b04d0c53e64be0f558135d10aa0bf835bfec9b5eca799b1debbbfb2ffafb67b482bf771e0feb7ae2043ac4acc31abe794febbe933b460646b287a684389253769f529013f06b4300d404a32dabd832e895f0a62e90b4d60260b7d488f425af234a9b85e8591e73d7939abc498c74b40aeb984e1ae573af5ddaac21b6f423bedf47d5af1e55aefe4ff0dd5eca4f1a85c84c4ab489c3b718ceb7eb37689e5d65fd56dccc635d1db5459fc76f8e35972f63b7db45780b10a84bafbfddaf883f4acbf17ac5b20d99d5362f9b8240af8ffbafd5eba5336e62ee35a9de2a11fefa1c9b729db9d0121dd45107fa64a87d0d7bf9cd7b5afb8dbdbc21c5f81ecfa0154fe57e35b522a699ee4d8f7154d5bb98cd7789c29bc08621a958e1554c4f8aba95d46f17c62d88888494d52850fedee7e8474ab77bca473ad2c7620130a5047a91628b88d7713afbd507449de16efebaddf98e367814322d197880cddda7388bc9d02ffcf7f1c9ab3187b502d219e711371f127dd49cc6b9acd710ca39a6ee4d3c55eb1840856126e21c2ec9d49df84a290e71469c664d4b657a9a1923432c690ed729913a33b2399d66c18daea609c5a65f204df2db8edae02666728bf5b68e419679e1af3d818c7182a8987da73e8bee22de6e3e8c3f4ab48d03a045dcdd0ae23d693da133dc6e91deee92923ef3f9bfedf97c11873ff1113deb049cab07e76939eed30e1cfc437dfe4213fafd738a5d5a6a8d70e0b1fffb18278133df39e8611eed93d7c4ce78171bde4b3ed9f77a840eee163c3bec9d9d30dc2c099e7ca4d373bfe3b1bf13b379133baa97ceb84a4bd82c424ba5251af4f8073f898fd7f1fac35af6890bf8b1eff6c59893c3ef7a5757be1b7090a52a5ed512bab7f374e271791d7b9eaf3b94a04e4ad51c6cdcf3dccfcf7c6efcb0e0a69213b03d7c56f0d14bdefef73d1e3357c9193617dc35e5b346f8a376f7dbf8b74b7479f009fb0f7f57e5aac16e86ae1ebdd60d78b79e69c99e399eff3cffc7cf18b87bc4631e35663ec289baf53b9b75d8f36f6ddac4cd648877910e1f92c3dc95f5a51a44affffd7775efafa4837246f7fe1b357e4dc35334414a96680a1704a80097b85f95c04e299862c3064c453b4981e5e773c3d36a9738e0f74d8fee7ddede2de1ad9652ac8919ae7c30ef45956951d14212d664359d7794e3bba4c0795009e055b4154a18dfd31b7a95877bc90bf27e9f9de55c3b71305da5767771fe4697a5da7d129319c3195fff7d4c262b5127439fcc71dc0549075ccd651a4659e81508f93a88238a1a5f437dc0e14d44dbc5ca863fe84c3a5e2f4bee146da0c91129c6bae0f877eab03ad5da2209b33829dd2dd6bd3e9e597306d443027f6d026dcc56b0eea3b0be43531472db9c0b90eda30a9e8bc13eebd53be5aa3ed4bc79db4b77ee3303fe297dfe1efdccfdd54ace8008401373d42506ce527dfbd2de7517db92619dfecb1f793dfec8ff6abe7ec72efdb727eac29ea8afe4ad4bb88db8990bee37cfbad6ff460cec6689031f229d150b0e32e9a0bb212ff0fe794ef9d60bf2035cad19740f3e7c87f4e64150b141a55c20c7fc4dcba25dcdfc2eea3fc8a37d250e2d612f483460513faf77d06b60bed7518814cafdc31c1ef6e2cbd787390297da429f36fb88a96de08c46728a092bdddf818dcc1b7d0e6eb466210c11a099e852cd1fc9d2d5d3d2ad29adf7692fcb40c334d6eb0d9eb9262aebda9bb92c28eba9e7343fa2c254d46e8d5595b54b4799a9f353f342a8d8fbfef757fd4cfca5ad796f535ef4373dd640dff8f87fe86b12bad2e2195b9ff83ffad4193fa4fab84bbb71294277971adefa557ff24bfb3879dfdffc02c37b88913a71381baf7dbb3fe1780d69a40fa903b5b464bbe454c31525eb1203bdf0f1dfd6ec7ebdef4f7dc1eb16e9e387d4605b79c41c7f6d4e4e633ee9d09eecfa9b6778fa4de197ce847a8842d75c7036920e7b18cec0a7789e331affdfb3277552c26e1500b59a61950c778079c4f59c7fae1347d465791b8fa9fba5736bd2a0c1d88e00aeea3b72f8ed7db1418a3d48c7b511051b5a8a40ea305fda7887b966f252305fdd1912de01c4548e81b0560553c871a354c738b0d9e6c6f04cda3323d5c60b56e238add2bdfc4774902e8d0bdcddca615fd17cb846ad669d18993ae6d98ee30ef8e04bf1799c4dd08cd1257367ab32ed121def319beb5ee94e24409e544c61cddb30dd0de2b2365754dc61032d92d21b49e3d72e21bf3631843d614c679cf6c1d4e59eed0359a5fba4700bd2c33b5fab77bcfc0912da28492fe1adf9721c79c2c4bfc683bfcd81451ca8c44159aabfe0b07deb730fb9b5eca46977e2c43893cb8af4b65ef061de5fe453cee474fe80597fc410becd9588d06d1621aa57aff37fefc63fda56508ae79cd27e91dfbec7cb56b2160eeb879c1237d5738ed2be86dedbe85bbd1d97dd3d6f35dabe7526cff8c4af70709ff7a35db1a7e3117bf78ca57caccb816fd432d69c8832cea94e00c39e93318f36f7b8306d1ab21b5cb21f296d8ab480262eb12b42616147b5a9927309d0362ac18414609e4e5916f76e89a6969f90ec86d9c224c46dd230dbe05e3c08bd9993de6ec57abcfdc7f5cabf74878e47829febdb78cec5ff0b3d3aa73cddc1061fc7bd144f79ecd1c0b6a7cd75a6479a479bdf9cb98e98a11f09c52da1689612c6d97a0c0885132f4ffba0505e427f6e3cbdb612e776c4a7b8c5335c48474e698ecad50caf89cdd04aa19197bb5838d90376d08dac6827092c5925af8a79f8ff762eef8ff641257c7cff0afbfd41fcbc7c9f87fa56fc2c38d8c5e52bbcee9be778ac075e642310d56bb12a51488ab1e539ccf069b65fe5165acd2c812b61885e987155b4a448fbc12f34e00f94fb1a2bd06e015c5fe866e705e31936fc4dccbd3ea6355d297b8443da3307238f601285f28129d6608dea9ff42effcdbad469074ac9dbeda977e7b08f0a11807da20ffc84ff4aae3e0ebd46546c9bcc642d66f86ec1d1e15e6c52673cf08f1c35443f7ace6ff5effd5871d0a0a00137069aa600852bea9b293533c16bee69d89165360d74b40d745caf94ca02c54060db230fb85e5cce8d44218075b310369a6323dac7ce761380c2f00b602533140abad51867152a18472ac3ffab6dfdbbdea9cfb95bafb1f68fb5ac45785afb4e7bffde777cf1b066ab9cdde049a309036a92e27bc23323e02990547096a342ce60bc0c150eca3666a568915decbd60bc40cccae29cb1c0b93358a53a4ac737b2aa3309104fec664f74d74a1db7c4530b8aa93083d2db789c5df51e7863bb9eb95cced5823f3e3f1ffadec35c87bf9ae3bd73f2a73fe697fb4fedcd2ff66f45d7c9157edabf155dee9b500864d1d054e19252539042e5d271038f6e779c4a4a73db4044cc561cf9a99e1a51aed60246269eb15686734d18911ed1a60d6096c5d3c8e079e626cc3398c67e200679a48db5c411a157b9310e5925a7e2aadad867fbb782ffd05ea9dc2cd26923c26c3f3cd7e7b8ce230f0fb942efc099b187f8e3dcfbe48837b8b09fa0f60de607367684e1cef954cebd4ac020f8095633eb8737953fa8964dbca945d319ab529e353cc43ca1e037ca69bb74c054321725da58e0b22d3075b79e93b6cba904a21cff100e9c0b201711504e94476d4a657d5d7de4f779f68f7132689794289313d044031e6ed0257fdb03f3153fa78b38fab477e9e8b7fc7d7de6b8de47bee3a7bf8f31cb65f5643e1f49ae6dc81406ab42eb9986c9aa127709115510deb52b2e6854b81a528a260e828106f55407ad0fea1857a986aa3bddcbc5969577669c4313332bf47a3447f47693d82e4e618de8146e96ce7e83fa6c1e11ebaa7d9da254db6402ba889bd523a7c55127e3ca3d4c5fb20bac1cb4b9b9e8125dfb9778bf5c204aa1d23528d372dc1cf7c3abe7684e58b28bf2be84c19cdb8c45055a489bed90eedea594f528a7ba6767a698e228e2639d97edef85be35598eee6225185e8f7f48901a81e67201d10239d29593f17a5549b2a4604d73d626fa7c8373762f4314a7fa7ccf195c787fdf3391471cdd090ed7c9c1ff28592b39eb3f8b23d0fa5dfeee9b981f98c70e3bf1b3b82a0d994a8d217ef8c3730d3c3797c60dbfe31ce53e95be6fc0df5cdd1ab4bad311640f2be2ce38853129db9a32d48ad25574e6563eb35ba93556cc339150c492cacdfc0adf48bbc931986babd99d21b568439cf18ddf357daa89585611f04be92ca9aaaedbeb85b6896e1ee7e7d8afa75ed9e6b7f5ad522a390103e775c4b5d77dfe6ffdd0c31a4dc071ae03d00b7ef095701d19de87baa9b1ce4cf971be799b1852a5e5906f7ec111fd479cdce15c0e7c00ab92364f395235d2def7769ccefc692e12476d5eebfdfe3d8fecc536ec0ffbf8fd7df7766dfe055e83d7631ece562542bf39f220c3e65bbc06dc9ce075e378a16b7125a63218ef91e1deaf4a69dd00b5464e5b729675a9b33722227842eb8e91ccc0b9723d8a1652fddad150fa44d5f3a4186fa5eed21814ba98090d17ea072e005931184545bb6310fab4baeefd97ce5893fe993fe77f55efee538f6ee5ed525d3d88d9b007ba78c62ec57bfec1a69ed1e271c68608dd3c0a91fa1aa7edb5fa77da9dd45917e9b017c13377ed99e7694e76e4a2fb59cee092cf5c82fa6c47e818a21e2d49982d90cd1081b0a77c6c303d1ac545b34bb45b53f472441da853e51bde5404a8743794dee918161d73a84143b68958dd4bde8e22e2ed25b08da8dcee5347d3b8a3e6ff0cefc2a5395e94254edbc721fe8a9f7dad7b7d9bcc502d4fda22af5e13eff21e3af66be497b595824ce7cadbb042d98c16adc7b3b90f209479aa71e6eb0828161376131462c934d592e9bc47219a24bc8ed0a4695753856428b669cf6a59a925a6662e67b71aaa324ca0dd470c034c649feaf0eafa22dfe0717a53b3fde4aeb80a7e12650967dbe3f91bea3a2f5e6b275eca8b7c2fcfcb33c2ec798b7aeb410249508e585ce12da663e8e9782b20b45207de70586f8856b49202475475e9196e2099a584966581c3fa1567ea06a8110d9a1029a4d30263960b9696f8b7806e4d731b7886bcf92772b61773d53cd5d0ff0d8e9a53edad7be279f816278d70d47c55623b30b29c05cdda0f118bcaf19c400b62086bd95b2de6749f72dfa040b1244773a1232781b28a0a9c8ba29da586fc1d40a5b0e1ce03a39e2dc33b9d31557a53582c99700817f10a5ac80bb398eadfe9353af1b918d84c9eb1077ff011cf73f81fb9b5ae52ff6fbfa7b579015fc7f1ff7fc3d391c7ce7813739c7da6ede60d7cc3de35fa3876b1ae8a289c9f7a391ec7d7fa8137b7bbc87ed8d2d67ad1cb7b495144c3cc610a2da96d4e56944dbd75b30c38d0fc8a8d28833ad3dbb9e4e63e281441749ca7b9b5c5bdb747259a224d4c6322734cedbda8ea66c55d9f51b545333cf20bb58bca6d2b34f9fb82bedb2fedd7d5cb7c5a75c29ebce3757b91079bb8ff7326df75fba89133f47295ece1d4f3f63f28388ba5a9d30e1ce6354baba2491df888bdf91fef7decfef8f9e1fb4fcfa99de79ffb03ef48f527de9143cc818b3874f7cf9fa3d7387bb7cbc9a01bf7c79af9b3be4c6b7f8163b617a1504985fbd3739ef0db97dafda289b959269fe3cdafd433f538de7057d70bae1e44f9f35bbe310af102694c4bd5dd9eac9bdfc416483a9996d2f13d7284eb15b58af2db91dfe3a9cf6a5f92392036e68ccb28c82dcbd3ea1e410b610376496edd300243cf06775e308e973319af94f25733c8529529bf74773ef8fbdc55e214cd5083fa4a7cb2beca5dbb8d0330600fd3e39cbf78ad1d317097f9472672d08e7064268e24be8e79cccdfb98e28964f311b5d1d42b5d2faed48ccd244c98b55e52734ed7631c5193a1823102b29cc16297f682c78544782a205108469c614eb32927d68c1492205e972494fe05dc95dff38ffe97c6be87bd229d21f6fd0c8bbfbf1216ffd59847ffacad17e1918fdaebb4d33817f5371a94a75d70d8bb5348165d833d8de582ab5842986368852b27b364e11a371a0b446eb7287775344375acd59d2cc7f784664eca326d09a1cbca2c5b42b60da6aa1380eefd928574a6349e173b36ab45ca5b766ebf7caaeba4bbf762d076807daa3f6353ff80fb3cc347fb84fdfc4b9df4773c852fd7f4b9ffc8fe2af79bdb3fe75ebf733f3cf6b6ff1b3ac7a7bcf171df1dc6bd54efb85dd0b45fd2f6c1e34d19383f3718d606a5aef0a9e9241aaa0368b7cbe99b38f9cbebf2ebe1f23cebf1771ceeca2346f6b3b91cfa90ae37972f72f02fe7f5c5f39cfa902e986362152b96fda61a1c3147c40b4374898d5c0430200aba888830fda80fe952cd35ae8e5c26afe6f0056fc1c576750c0ecf23b8a97d8183f23a755cbddd498e953cf8c1b3a1cfe9cd736847fff5b2fe3b2de0b288546da5d0e26c7adb521bfe8e1dc022c31e05d4dca433ab613ab3520d5871f5abc35434848f45d44b26c2bbd6cfa32e21c2120e1ee15eed58a1189f298b4059f80c6bab82a9882114dbdec8d3bdddf77ac76bfde4a39e341fbc77da00929ff81baad1e8c48770e1393bc373f9a93f7b059cc6bb71071f6b88dd87187e18d73ff9b797e537a872a10fac3ece652d83f128cad92e002a4f3531a786b5c785f990ea773b44dcdf4ce120d0e7da4afd02896e461208c7336a9e704013cdcc892e667ed74c6981f7a2d8ee18a123e408247a6fc48b6c1a51b60dcefab79fd6fa4ebfd5cc127e3c97ffe758f3fea32ee7d7ed6dfabdf33df4ef82878803f515bc0eba02aefce598473b7bdc1749091b1168a7712e3adb05318a8da741c07a9479955c46aa9e072143bcb268a4cb7b6c308f0563e017fb9de46ece8bc824205b63e7e748949146facc64d52fe097d15e704196330613a07628b4355cdd1a021626d125c620abfc10e1019ff395deda735c361f7317b6d7c9d3bc1df7c5590b1f7367fe090771197764cad5242e9b7d54008f74e3399946a355d06ce3296ebdc9f8b747418ccbbb8eaa5b9d4fc68b8482cceb9a2a28fc7eb56e42a9152daf6a3b98a95e56708e81d727ec979e84f50375d0268559237bf810109507656dd2f73a417fd0847af7fb8ebd91a5fa0e7fca17b9c8ed2b71a31d9ffd14779efe3e9c854b351c41760358cb9c5b2dd6652cba31496ca98bd2fd81ed6c2f800b90062d4ac74d12c220b0eb87959305bc50d340138c4d8b36aa5c1edbe6524ee9c8d740c888f253cd5dcb1cf9d84631a3d99a5519c08e9a7b25d0de63d5cee8a67e5b8bcb7e58924bf54fd02ee187988315475d2096255fe20cbdbdc6b96b0efb4df01735f8a38d7bfffe91ab7674196655609263444b018292cd452e73bf742784d60e77b205d5707bd3bb1b7fd030691b5ab87a6408071336f17338e7451349881c9f213b76f07695ab1f042863e5dc8e121b1749251a42c76ad16d41a4e31de66739443fe33a29046fb3157f33ff4f7ca17f5f8f9f4fbf135f8c9b84c383fff556eff7ed5da71f733dd7b8eb40131de6ea942f7ff1ba41eb631ef212dbcb88e462e6dee0d2bc11fa4f6de5d45d30b3e8aaa2fb55e8cea92ddd84e33ea1be8958bd154011cce1bdcf475d50343fb093d90c5ab3256f26cc616542c76b32758d856e5682d50f316f3737da982f299a79ba6fb0f735ee0bd6e8520d01b44b426b970cf96fa012ae34f9f95ab5ef39c1bebd56fb431c98547e2338a8e50cab747db2c7679e6b38bfdda5b56eb7f00ca49082931b03fdf618365256dfa73ac269c5bad4667ec0c56f6f3236393749cc473a0dc61d9ea286184c0b6682a505b262bb06518eba25b10029e71baa31e2570c7a108a449b9b1e548528a19602f7e33e88af9d9b874887da82832cfdcc7f995c2d567831e6690d9e31c9cd699c0be2707791cce6add78dc3b81405a2e30742711657acf2189b0838ef3f8cc3bf384fa254556ae05dfa691e885e496bf5302fa21606d212c37df4a75f3e4773ec09b8ccce44142cd2995bc53d13b1ed2e57f4b6433cbb5fcee44c4ee71b3ca51d35d216433708c2baf52be9a55357444435b804626937beac84264bf010918caca00896b4463cc79b55016c94674b2f77f5c48141ea340a7f8275bdf4fe490cbf4967ee2e7dee8b78db1f35d4dcd212e6820b904c4099762ff398efea734dc41bb5e0b84e3fc64682a454ade4b479c30bf807dda6c187530b2eeac4a14d14e25dc255fe21df669515a20303f78b7054f75c27ff7b7dea6f7041e7893edec4fcb3fd3e70085f67bfeb4d7dc2af9cfe3e69b65e569b89a5e13ab1266f5690059ec6dc04641ae91a9315545f52b6465ab38dc36c1d7166315d4c289d9b52899e94a35dd23542f691293437a400d9413f9c0f4c4abcbc31a4b39cd59038512f6cb14c26e3cdca69d87b3ff9ebf5506f32ba185f745c17761f85f37f2b277d5c0f5e674ff7e6d3eb6f716621d935997050b952d62802960a82ed9ee9ad4e2bb75bf4688b81f8ed39ae8d7a4656f0565f4eed363232124f611855d9081959ec1772e171c6a58d4b54a17a39732baf6cef12c5ee53203c420512e5c18e31e3ef7b7bd160736588eb6402ea4f3179c1b572a6e34e040048476d175c9dea516fde3bc61b5fee85f102a0891cb280cb360e859312a8d2108f28055b9f63c6283622eefded7c1d62214d04a013210471e87e290f750ddffc1097c827acacea4e36e5ddf33cf68c5d86a1c679a089c8d3eb07cf06fb80c3282e559f80c3d9cbdc40091818759612f9c3abdc3830b2f2460324cd158d75dc040ee819c18d57b63971c6f76979b7c345b65d3a60839818110e841f34a584ee864e7ef689d67c8c69fc8aff620c3c584d14bad5673ac767f82bbfb76f5f8d799cff81938ac34e18d1a5bc6f471c30855c04e3b5d0cc7902ad824e21c70493b8ff359244ed7d7a67243d1c2d0ccc698823d44b8ac27a1b43752743f99b1998c7c09ae010cfc54c3888a3164d33be2ad914f7acf6c27a891c8ca33edb4bad156935e4a7beb4d787df16a27d147eaab56bbce730feee3e1ff8b1fbd48146f2728e4fcfb138e68efbcbf6b70a30b46e02c07c56b0259eca2280d6efe5ccdd44c5f881ce2c13cf541569d89150dea70e0b4981aa15c9423a753beea011b7f72336431b5a329c4cc5efb49877b84f378cd65dc465ef85768ba818b2f3b8bf6eefec11330536222c9efbb1cf717ae8998a4af82006aecb63ecfe893f771773f49a333bb8061eeac25c87e19ae90cef16a19b2525de250387897b06abf14f61fd51b70a2d2de9863ec422d1b5277f78b89bfefc7cdfc3fee7709fd8caf68cc24cd7e32d75323da677ad34dc28b55bb562ccc51a8c3d85e644298a39dc2724dd2d6ddb4c8ad64f0ca5b3ea574f8bed0e33cb49f908c41afb91542a1440c5a44281844a044cae254d47c17b1ec3ff00f61fab478cdea7f7e5dfe7478ac3bd38e8fa9ec63ddd8b17686d012b0a614ee9dc104ef3c0a87030479ed0814014cfa242e62b27fd525de56bbcc357d2363ec33b7ceaa5b8ac7f14dc8ef80cfaa8fbd94644e5296f463c4cbb15cbfab4b781c8e73a299ad0af2c9b435878933108baf182ce604179368a94952d49a1c58ef9232e11f494686968d9a9de968850c3cb511e008b114d928402e19dc5607f3ba63ef2ec0e7a4c976b7608870df9b50197d01d7caba37efda75a5edd75742dff3cfe693febe3269db9eae08bbcc27b1cc7bf8077562e9883515c6297684c4745edfa1a1671e86a48abab94783b72c57bec12bcc7f76c927fb14d12e1afe6e03b1f3516fe8d7eef5763ee16c1c156b1fd821ffc7ab8fd96ff1eaa62c93de0735ca74ce474dddcc425321883eb25c59bd8aef3a56356a49aef09877798ba3359e03aa8d2513a6361c4e7dd8ad5db78d23cc43aec896ec674d2400cb045a7a2a3d5af2ea8ea9bd8aee355259638cfaeca571387279f9a8367dcf3a9a718bde37b50fd82e321167ac4f6bdea413ea753fe5acffc0fdf3b5ec725cbe5631cfcd4c3fb8eaf7e1795b58a0cff752ff179bd9723dfc9ecd7433a7377d2190f9cc08b526c0f3ee3fcb506c93f8e5b4d9cfa2e0addf585b999c7fd3970d18acf73ea57d1301283a6d4891bb7f45f9e93d37368fbc5c0d773590f18d1b25140c71985aa089cf68656784ab9b0032662e9086361b09290db4daac43dca7d93166abe2a51b330c44c0218705b68a818fb29550e3350e3a90c92d05d0694690ccc753443c2a32d0c34bf9305fc7d0137cad731ce937775c92fdbbaf8537cfae10c8dfa6bd9b9f8c8437f5a3bd52fc8f1fb2ff0c37aaf34c39bdeee9636dd2060b1b86b8254cbec9b5ee644653f56cafecbbccee159ad46846ef5d91d7fe42efbfb1cd8b0bf1da0d252aa93aff6fcfac85976190f0c15371e6055407015f0fd86da599c10dac7bad94b869cd4a69ba4608484738310ac2f19cc853637681ff5817eb7434ab6842b87d27aef17ae58e5d09793ad8e4a374ee1af9e12e9ad38dd13fda74998b5385b6bbf006feb916ff965a508e78d747e0eb8bc64b0d7ff0e46e9fcd8477f6ce06a09f16ec00596e670377c07abe4d98a08dbdcc910cda5aaa957b01a976d2c586d05b6cba442a38436bd04628a79348a616a044056b8c7d9d2061c8774e701b146150b391fff88f5da4c666aba72e83e285c3766eec4e335475346506f85ecacd6c7457d2f85e0a21e70c73377973aac93ce993bfe1f5c93c37e5b84569718964a2b5c8b277b73eeb98e78bdcbfafeb49e84b0e4b4b9f7cad65b9518513d1af142c53818f31b508355d04c84e6eb22b775e4d051d0bb06d2719554d6c20fdd0976588781da13e2eb015322d2eb8758c73e29c03d75b6a64f04c7c57c74d32312e86d74ddbebf27bf66e03078e52b91bfe727994f075feae2737c58b74f7d892be56d9fc77b3caf476cd3c53a1da1125ee9fe90250e85edd644633899590e2d648ca6ac1795b5ff305efadadc6ca35029f1656e966be99b609538d07c8b053bf33c97cf1b413fd2326ba2506937bdd7628adab4947d3ac57564b837c4c8eee2b778860bee12743996b888b9283fc94569ef398dbe978b3a8c759c4b558af577fa0134b074da666537c42778422ae5add6cd3cb0015b95ed6f1c5a9537550e5b374ae622269cf6b2a8ebd891c56a56579121e325143b4c999f50e8f9a09e2d69dba45cf0443311a1cd5eceb0cb19e6b81700c3e2b3dae2b76c8577d4bfbad46fadd3f5733ff0a75ce27f5f6b2be270de08bddd4543fde179fc133fdf65b139939b54c9fd92ca00d94d248a66c6c3fa3771009554f29840c634514ac3eb512f1f961ce588d09d74e63a9eb17645233d75104614ae639ac1c3f7e299259661a4273a2469ee46be866b61cb8684b25815eabafc44c7dac3b396cd7f0ebb5124fa8967f8f33cdc95ee8d717eccf3d3c1a7781eff5b9cd126ed1a8c78d1c7b65b224d4e62ddd7022d1d45442abf30974c336704e20c87d2e04cb298d72ea79ab1aadc2da71879b6eb703bbb8f95152650c61e732b0458261c1c0baaec8417665c447de08036667677417fed17fc08d60f388199f7dc1339b996d6dbe5f6fb1566eaa3782db8564e76ac1dfdcc5fc7bdf034fe898be6b2bd8009c95acfa86d41e8289e4196f2ba8b18fc9d8475ecd1d60da68a30006f98d3c2404373e434375e39c6b268e3b89741a460242b6c13e24638b47b51c90dcbd5d437841e4cb1e713cb62eb662734d1fb85d65dd7a75467f57eff6daebbc39ac45c1efc97cf7018fb538fec5fdf0d89816ba11ff6c4c9263cbf6ebcc9453dad478c3495330c6449750864883256d4d39b3e2b0588364409dd57d9c607b8615564a4fa564fcaf13d86752c2bf69b5173c6c262cfcbadc6426b4ea9af638aef696fdda7b66b441a9ccae256137c5cca4afdf04b14e0b3badadfafb3c4dcac9f75f89eb8c2ffd8231695ea2d9660b83f8f73f8e8afba75b21e3fbf77a16d90a1b51561a6d2fc4bb92eed0abe33489d56ad1cd679434fcccbd7c7be90aff788d90dd2e55cd8d9426a3ff7cb99982ff4b91e9722f7f59fa3a8c716b1c7ee5fc6ed17696a1cf978af10af7faea971c2915c644ba752733d5a309712e949a51c3fb7c2157375a9672da2239032eb2eea854f786da3d21542974e62178087ca16fa7ee3cdc428258c078e8b88265ae2a446ec88705502b0843ee039c4892eee1286ddd856677a882ecd37b20731013bb1fe7a8c8726d7d8a7efc63dae41e937891ebdeaf5398c77919f1b3440f6b04e0a3567cac2890eb9a4d90f5aa9484ce76dcc11bad1d1839ce2e9aaf041aad20d29bc56eaf56fc6102586b7610e357031d69106ef482e75daabd1421fbb2b9e7974ca7c9ac3f98d61dd510ae792b0abea9725ba99bfe06ed52ecfafb3873464755a7eda03d21dfc05f4f777914aaa23e6ef885f7d1e7f41e60f5e37d22fac21de93d2f4d3dc6b51307662e569ab42f52ccc84309860ccf2bd92b6a4d86a622a2102871846999ca23c2ac4246618ada8b26f7ad790a5d6c93edaa4f06e97e818f944e6b46ceee319f2a3b2d5a4e6fe4e8bf69fd03e7ad107f9a47d7405de8edb874b79f744e835111ff844b2c8f03fcfe190db076f021e449869d7e8497933fe70ced30e64d1a0830773391972a1a345feab494a369297c6b5b4d018957d6adb7b695831871292ca2d7c6281c0711fe2195628bfede514b56cf2b36585982f398cbc125b88593ed5239db214047616899ccd030eb294594dacb28c958cc73d0e30900f51a8b6098b0c49e17579e7436fc8e5a787f88e2b2d0e857a558f7d5747162029d1c0e3b518fa35fd971ae5efb40b6307beceb5bed5392db32ced40bfe2609de86dff690d9b0fdca9035fcfabe77cc7b97df8aca9840e87dfb4086b95963f5fc66c6735605e6bc59cff4dcf5c3aea21352c75dcd7c7cf2fcf7ceff3e71f797bbff0dde5399e9e7775f547fcddebba7a85bb9803f56a6ddef6713cead670b35a5487780eef8e1a8ee621b63fdc81595abdf9f77f6b3f825ffb45eeff293e7aa529fcc62f3ea7c95bc521be937cfe10e9e366611cb14189e1f60bbdbd8f1dd8457f67abce7085bfc650fc0b78f77ac03d0d3ee1e16e7b1eff5bf818626f286f6064643571da090202aea8d056d4ad96042b6f9afdf643a4a7443a8cba951f5a340dc68657a9c6d75a33d0ea0a43ab5f717782a9c9a56d1bdc46187309f92c5b5067fc80bba6914a052be776476c755d7c8c03fb4588cc84bbbbe7fccb7ff7e6716f3ee376920aed1ff1401fefd1db6b604c9f7140dcec53e7b11efcfe790e7b7679a9de13af3d31c39068f3d6236e49800b56a165adf87e8788c5a912ae5fa88229f89b02c63080f35571a7ad6c9744a5d29653f88396b05be572c69c6c83a98857040691ce44aaa4888095fb85f06928e72b0a738fcb0beed7ff3826e9e0cb684907f6079b1d87b8969ff6b0da57e25d64fd50eb0fadc35d534b47e9475ce6b9f7b5f61b3c8cd8d7c6dbc4917150e18cf19f66c295f04be4f97a4619877352d63738473e0fbd9695aac05369495dc138871b1e660bc1208d0cecf99cfdf0e9788e58bda0c5ed5ef4ae2b80f5808ac6f073ecb26956d3cafa4c23f21bb9c173beca5b3e9eef62f94e7670725d9d8d7775ecff6dfb5d4759ead046e8e3ec0b1c586f7da66fc610288f0e7e1597bb283cc510af9ee3d42779196fe46861303776dc9947dc69aad7a657d490f5d25e86d63caa5c153191d16efc3bb547fd8aa387552860027121350d24b99871224254d22e60964ab8d031a815a3a0e5b9b2163d9aa554c584cb4552b8777e98ee2ec87dff73b9eac7b90c9fb4321fb1a15fa9ef836bd8ad48877bf1a277e5e8f367fba136fde7e73bd5fbe9255c8d5d60431e5389533ada79957b2f43f5436aca5af10c1127d3e8f5350df6a77bfdd275d91ef6eae7fd6df3ebe05a4fe39de6fcf837491fbc8bb1ac9a4673580be69688cc777158e7bca086cf5b6f45a82ea99a0736f6d834d57858fff00aa57be55e8f359cf1504049d4e8c690c8cf59c10bd8b1623fa240cd384482e5aef0796a78b6c859cf04e2e60c6ba67b552da9c25a47dc55c9649c1fd664c145f7c8eb36cfd3078fccdfea2d1ebef7d7d39ce9ac4f1cf52067ee23ffc0a9affeed9d01ef1ff5a1d0fac4d3fd261e7cd648f8b3ced463ef676a58993cd9d9412bfb2da7e7712f9ffa7d9ebeef5d0cfaa2b6fca1c6aae0e6b1df379c3fc7f0dd1b7b30e4334ef312a23c319e6af5e03cc7fb69ee26c77eeb177a58e7387155aab77552f98d2c551f877897ae5f61c9cef71696ac4f67ae7aa1e9d79f89e3556a402042d77cbef7fdb3df75b6f6fc760e4ab515c1d043d0ad82472db197bab4efc63fc437f923ffd710634ec03a71601e77404b4ba63ef647e436d1e74deac04e9c6cc871cecfcdc7e1b36ef6227eeb8ff8f5773e4e951ce28be029ffb15fe4d13b8efc243c72e289e12eb8fd700fc51c80b43cfc9765cf9f3d53fb7ad4031eb02f2fc77fb727eed30e981107db67ee0ffbdcfadea7faf8e170a744dcdd3edf3db21655d1485d69b13306720286cfc55c981fcf77ab64397a7afe771c1d87d8d6191751f8d4d3aa2d72fb60bbdf7f8eab87f8b5be687fbe2fc4cce48c7511df3743dfd561addfd409def6873c7239cb679d8ffd222fdeff9ecaea125d1e62cf8fcf5275cc7da4b35f9ff4ffb2469eea0f476d913379cceaad1ef2e1fbcee81ebfd0778e2bb44bd6c79ee2276edd23a7cc397b715aeb97e7ce7ff79921cf7de21f7f9ea3f999df1e8d065c75681d3967067d3bfad20ef417d69a1fedd933dfe2e35d3231efd3eeef704d616eef8f5cb8bf6effcf6c7f3b68b37c8c8fb834c7b24b875cd1214664f931ce3cc6194fbeccc5b1c5d1be3f72311d625811622de69fd6b24657e233fbf0195ef94afcc42135c4fe4c1b70dd8798e2720cce44801a10c888a0cd0f59b6de02081657b73bcee7c6722a3925739d2ada0b4ddefb04d53115ba98a1fda277d7840b1e30c998fa6548a71e49a7269e433701fca579539553a7f565616e286f77ab3c9b2e095417e0b1fec019fa746fe7896e96314f873e5039c3f5a37f70dccf681b071fece5ca522274bfa045f238de5ff1f63ead6deab4e070862ed85ffd7b7fe0eff6d7b96778b5bf426b2bb9ac93f5abfdd57f83db94617baba7454d51a196541739d17f023465f73187bfa53637bc29043e559ab71e1734976152089c6872caca7dbbd0184a39b648e13612b02c0d21465396f199d5a500cf560a655eafbc80407f15b2c0afb2d155f17ed58bf9e1ed90a74cd7e04ef0767f884fe7af35b9ff160baa7ff83ddfdeaff4fcbdf6e6cc1c6cf4d17ff9a38dde0bce3afc060f4538d3a2b758d497bef8595bf5eef3aff51f266f7024afced997b1088f76a28ff4f1fed39eb6f7bdab7f17db9e6290d7e7eaf41ea1dfa8dfb8cbd54caef17a7cc7736b913a6ccfe9681f69e63ae91a87e4224ab4ad8175384f20bc13c6ed2eb6559c4c058f88b5c6b90fa882bf8921ef88adcca5d362ecb8c0d7552620f27ccd7d08a6ee142b7588b534c4ddabf2b78810758223903eeb256befefcd539c3373b3a30da457c730fc8ded7e8ebf3ee566bb422fcadbf8f4985f7ffdde29f778994d3696041794a95d14325396ad1df57ecf1d73e6e7d9961114cb69da7a8658fa7a56c92986cc9077dc86bea7b28d5f8907e18811ce2d4b68aa0db4f1ef2844f7d456feaabc33830a56526f8ca840024f7fed588ee2ebea6f3fcd811e87a896033fffbbdafa157814fea85373c57a20305303d7910e35c12fed0979bb17deeb063fdb1d51a7bad21263fedcafff71cfd975f0e27f1cffd55e7ebb8ecd69fccbf4d28a3bc32b462346cd0c4da34eeaf62ed0c46f3cf377d4beeb0346750f223bb5bd9eb26cead1ec3eeae184c36c2f8a7de7f72a4041633122ef6387ee712e66b4602d2bc01db26b208366c9891c25ebad2e1cb567ec9fe013ba94bbe3a3b3f0afdaa8b7e39fea24e773660336ef52cd6162755407815fd591d0f08f2044362ac14cd8752542f143e8ec4740688f6ca4d29c790b439884ddee632dfbc126e3fb98ce354faf83d8f14dced89650290884a657d5fbb4309b04f8a394c3ded7a4c6830647b4b9e0fefba646e905b9f985feee5eca920ad55fc4a49cc9c77d2b867835e6c00b76c41c3e6297c1377a82d69c8832cea94e00c39e93318f36f7b8306d1ab21b5cb21f296d8ab480262eb12b42616147b5a9927309d0362ac18414609e4e5916f76e89a6969f90ec86d9c224c46dd230dbe05e3c08bd9993de6ec57abcfd273489bf510bfbd3ba1682bb407caeddf436d7f8ddbee0b5e4e9a95ffc30aea67d4357ba48346688996810b4a6826eb5a04701a5a38e175ee72bc5fc128ea4d65ab4402d2f018a2bec2c0fb69bde75b49cef57338b27ced8a1a539251a36525eefa56e5a890e776866a9c41e8d92290a8212eb9e2e83ebf6f280fe15afee55fab92e89e3101221ceceecb15e86d63e315c2ded4eb8de7f35767aef53245fbb5baec04d0c064edce4e00f5ca69377d4bcd1e486ce6e37acac917480850a1079b9dcf9043b7e2120b1c594ab3b8df6384a399b11904d651e8d24f4377139ef65b9ddd14a650190be072d1a182a940ef0a8a6eda3759309c8280ec53aeda18f399c7bd5c73d4517c419eff15dc6db7cf547f37f268ffd9df97f3de6c13e0c758b74028e77c0a967f132bc3404b26868aa7049a92948a172e9b88147b73b4e25a5b96d2022662b8efc544f8d28576b012313cf582bc3b9268c488f68d30630cbe26964f03c7313e6194c633f10833cd2c65ae288d0abdc1887ac92d3eb7290bebeeb9e78eaff337d7f7fbe3f1ed7e95877e26897bce014fb38cf7815dcea1fc73f9ce73fd753b4fe1b381a5d282bbf01732de69991b25f3a598fb3208c3a91c38ad0db51628fb9841207ceb8f57b6c06bdd8510d73568e73c98195ea629af27ac31db38d9942b1039004de2ea16c4e66bf0c56b2bb64e6f729dfeb89cdea7fdc77f8dfa9d7ab52c3eac4a79a01e983d75d075f78ac9b1fe3c4e3df9af10dbf44f7b47a4a0a04518e41c21b2775c00617b25d29b148b531f56678e9b1babb31984a691b8bcae21e1daf970eddf81aab2894d98d361ef9fa78164c919694599d50b008389c2404370b4364b4b26e167ad3d1eaaebb6eae03e689e13e3cd732cfe1028e9f59f0ba7f6193cee30c3ec630b4efb429ffb9dadf977c90e3baff37aff17f635ee3d893647f626fcee08abe6f6f0ee31df316c6805fce060eba4b7bc2389b492a1cd94b963a38bbd1532d9d3438988907d65bc18ae168011017b49e605bdb090d6984c280f4564e668c7a459663da3c3068e9b1537354c2990861e76bf35daabbcbc4f8b50f0cf42321d67daac390117c0166ddad93f7f1c35a0cbcf26e7fc22bac633eda3dbf37d450dfe7e84bb88d8fb8e557188217ef3fc495f7d77ed1c5bc5a216a2567ddea73fdc0b7b895efda82d378a7bb2a642aad8ae6f4fd97693869c88e43b467860f6491cde54c224e5c9116102347ad71d958649a0551710b38959344d593a82ff6848fb7b21265ac3738d2ea2ee9c6192f954519db52825a61b882f6c2465534c2ba0770cfa63444f932bc2a0f823acc4f140ef3fc1a7bf7f7b5d1c39d7279dde684ab3be323bf7bd68f73676f3139dfacbfbf18f35417d4d2120e364d04da699ccbf01b2bc75d624d2e1372b02dae908a15c1cc72a5119901933f04d54c6ea36d548c47521f5b6cc61c618f21023544959c934933a784d1a593eda8ad6d5645a627b4f9b1aa104c7956ad88354b950df8d4ee232eea7f0247fe0dee32951aae8a8cc71ae1277744779d5c775ab25c0e6b753aeb4faf4f39b3cbd66e9170b12053b44645baa12ad3e9345b7aa1e83c805b8f37de421f4f71291fbcc214dc665aca7e8d16dabe4fed264b21b3909d8e224df0888f1d0f20e6f5f3ded77c8dcfd49eaec7a528d52e70c0463a85be0038bb761dee7d9d963e1c7cbd2b70987f07c3fe545ffeef79ffffe379fff2fa9dc115fc23ebf78d33aff54b6e3e04ba289971375ad9a3d65774e7959eb1e4233329e66660e31f496f3dc44cb134bcd55733d5326e9a89061f68a84c6658bf998363cc59edebe86e69bb1349688b425f93c62f9397a062a5e0b133323175f717e0a1fee1f5635accdbcf7250dd9534949ec63baddb0bbcc4c5dc3a1b56a13c65d906d9e3693a8d4614dced85d35498363c26d16ee9a87bafffb50f34376476dd7abdeb2f742c0493941a7281a6305c313c8a78bbf4380b126a039e2bc682b1c7a7ca469a08a90ef892218b87b7fa3f91633ac431dfc1be9cb8e73fd76d79db8bf0bd3bf6c46b3fdcaf8f1cf7fde55ca1a08c2b08fc9e9a91e61bbea14254b18ea86ce1d96222b9d8f012ed622a67cba965b019f325af23448a7da4cd019be16d92cff798b8cccf315900695125da1866a550f5d62bdaa500de460058505bb931d7769facd917625e9145a177988b26add8837454f329c7e364645ca50658c22ced0eaf4127b9a9c51c1cedddb9f7c9af07d45dca93e27601fba5b11017be36fe9d5094f1c9788743cb21e05787a0eb46a5da44144d28c9dc98c312a9fa01117f73a39b1b662b7d45c47cc5b21f32d8f6284423344358d8734df6d90ccd988f0bf88318d61d63f03e2aea7331f167f14b1e3b701bbfd2947d87ebcf13670c0ef1f5cb1e80637fc83bfdd997dae1cf3d06677a1684c332e9dcbec62fbdebeb81bd7454b90a9efa0edee6b2863ae0c19e26ce381313b04fcbb126f891afe5650ff2fbfe82279e167de8d1f863bcf687fcc1997df282c32e4f9ce26d2ee04be72135fce6a80384d52264dd91dbe849f3fb2b3da357c80d7dfa1cbb45302ea310690b3ee812152200202d8b53afccf8410cfd8df677787317426b42d133c5c24ca7aa9e49908e7025caa88473a4c188eab75da4ed379e7e074401662bc5906f64a15fdcf502467d4464b8ca33d32ba39d64f65e1034414a1ee6d9f6f4314104df33689b011434a047ce8e2fdc0b4fbff7ebda41de9534359ed663d04649439625c37d71eefd534de9b2fbbef40c88977c8c5744dd7b05bcf34bba0ba68afb7dd14aad6d02cd9dfa80ee84867f2745b3f4999a219ef552fb69f845bb88f35f66e07820806ab9ca558eb562736364dbd4c6d3804b3be24a6395b7f73448697eab0d3ef65734d40e366002bec2dbdd5e2986795ce75a94d1cb7d7e78dd78478dee8b725c2bbb0609f0c18db637972cdbf23cd3a4ce8a88b9252ae0c853b8a24c8c64296302d48eda4dcb2b5626b4aea3dcd2c8d43dac9bef17e338cae19e156615f06c9b52bcf589a5486fe59e212752c13c09eb11fa84ebf3eb7b7de873fc7c8fafafd1a77edacb4ffcdb2f5f1ff6f4fc015d5627edf00c3b912e29ca33236698c6a18cbd325b0abb2e232d5bc63a35b93d2e934a36be7243ee648da00d5ace5cc783782675305d00a8253d2208b83b5e347bc4519dc07abd9ad5bf115794288c53ed6e8339b3afdc273d9c85c451eb852efa4585b428f43fec83f59d611db7319fef44e53d48fdf96e3fee5bef9db6fcc06f1e5a595ab253ffc4504b3be7071c7572c8fcf9ce7e9b633af657e669396ea210e7f1e4435f611f0f75f2971cb2f32357cbdf63debf75ef9eeaf3bd74e03a719eb5f11ffb533f8ee1aea25f793a77759fe8a381932c2adb676e06fde00b3d9f8d8f9ef75b7853dede89c9d8c0ebc68bfb6214c07ac76ca425507411cd3451de020e551d17ea3ee26d14e95b23d521933396250ad92bdaa29563ce6388224cf14d4ab3119eca2605f3119e5ac0d7419b388d1117882f67992eb5ccb8ecee7d9a970bd6257d407f8feff8e3f8a798a17fec657ebd56da69fc8bee62eeebad2065e327bdd456acee3cdb45a972c3b4843661f846eaf51c95d88d68962ff4f9ce2f9585e05d47426b94da4dec5754431c6e38136bcfc1bf59257154449d57d58c7070279cb4657add315efff0e9e86cfdfe735c50ad3ffbcff6397b31687f259c75e2654fcbfabddd4a4b5144afecd4bbef7ae62ed15513f3367b71cf9eec8b7d052e207bff2dddd0e3fa6f45285452a13be9b0f731c37bae9eb7fdfddf8d63cf8cfd6c239263dcd6c733ac623e3ae916475fe7746196481d14277aaae30a2212c2190d9a3b9a67b10c6181380ba2b71a2e976adf1c7f432738fe0267aa77d518272d591171a4bd38c78fcfd11cf524ec8b7cbd18a87d9263b1304496d89e4938ee02862a34951a2fc6ff2f79efd69daad26d81fea0f34281a44d1f274a8144ca50d405ea0d2877500a244a14f8f5a789e69e3513335ddff9f63e0fabad98382daccba871e9a3f703a7de2205380e754917540a6e8b43688ff689524ed6353b7c3cf7baea79d8f8b1e6dd6107cf5901c482088bb9b5beac5024570da4dd2f2dd401101f3198dfcf695ecac9779a9f3ee6e2dd9df49dbd9e5d6baf7f32fecb7ecf7458bee79b388f7f193f7f841b54a062a9822daaf21e3bbb2e25394115f31750cc96b6698444dc4a3edb0aa2169ce175c041efaf73ba98e20373ec0e51794b596c266b6bca89b5f0230f2d9c7c8edc7b5d18de01afbd09e5f1d6afa0c10afb9bfafcc7ef898fdfebeb7342e26b601b87bbefcd5d37e464863853bff47c080ded62960701c8b6642a1ac99089352f61cc73031dabd006163230c045bb2204dd04a07e148552bc183f26ba9826b46e53258365c4da60f56b1f7238c5bd9ca576a34bdd43cc657351e12a26e841f24387e067d89e2f7def97efacc30779c26c1e92a32fb27acd3ff7e19efafd323fe343568e47cb10e4c2c1dd6bae914ff06c03e7c6608778bb17ba3ce31fff99bb378e849ef05f2f7c44eff1e74ff9b34ffd9267de1ff0895ffef2dd39ebb2f23597c967bdabcffbb1913aecd28143ecfcf9934feff232e16631e7c09c47327f7b877f7c6fea40ed3837b377fa75efdeb74bb8dcc809689621e8440481889e3905b5cff945ac3a7de6478e3f72449e6c542e5ef9d682c3e6651d3fc125565e299c373d991f7876327da89fab675fd281af6ac99faff5477e17ff23ff7385ebb42a9ad4f5c0cbfbaed2a3df1eef5bb4bab88ef2e93efab3568b7f5d7b751ef7addd022aabbc7db6d20e3fc0d6ee035d1c6203d96989abb4c05ce8ca43ba67e0a2b1241f75c2feb545cefd08b962923a4d9401f9b85c8def18dd99b464a5583386cbb1934e679a1fe534a1ad0aa18ce786608ba8de6228e28c29b674ea3ba9e5eb8bf264a7ef67c491f7f849afee27f37dbd7cd930df91ccb3d23cdaaee7bcd9bbdf37679b70595f4b0f21e5120455b65f44508b7b7898034939c12a232a22ccf3028ab6c9aa993107dd8574d7267ca4111683988a9c52dfe405f2e4d42ac2b53c646bb60a79aca5d03a84aeb024fcdd2d237960b65965bddc64278cd877efe2f6ebbce487f8e8e7fe8f6b3fcf6d36f0cc0e9f7d19be5663eb65e58f84a602ec7afce8e360def49c7a6b19592d89d4886a79cc5d6f46b436a455cefcd5d84e38e28b69365a501006ca0b17936616f71e6046cd6464dd653d16b4c7b7cbc26b822a7f38c6f94195db73fdb37ce4573c249e92113afb39cfbcd797721c95c73b7bced9e3b06f39ca633dff0a4ba15f494ff0d3b14fb6e833beba3317ca65394e031b563f0779b4e460459c5d47692bc21e2f96958588e189a4001b61ab11779927aba2a3d4eb894df5d4a941aae3b92cf19619fe3e362c332c367d0084c72a6be6dbe3daa7b92e7ab897a58796455be0c29b5c174f25767114bce3f6fab38ed4f77280de72d0992647fb66fdfa9fc9efffe78ed8ddcf627bb54b27a08bb9f9b54678f7816bf087e7fcf598436c53a7cea1c94af82874daa01fc4a5191def1734de0a1bb094fa1d71d00ad9de8a55e231d4ea1183d643a06b5baabc8320b8c22e73b3aade92a96c3013bbb98e1f3843c02fc605255e1013ffe017232d35e096ea999944333d29a1cfb44dc718e2d9a77ef78f71b65afaac0bf06a2d9e7bd1fe3ef773712fdad1cf3df99b461c7d158b0557e21e10f5a0d9140dbef6391e7bf31ccdb9867fa1169d672f0846c2fea5c79a57a3829a08e496ef884940d4a334a0716be42e8aee5b069547ed3c97aedffbba844938de920a9a48f3a2d086d1729ae3d04698328f30c2e8d2f10f61a9ec8563dec4a5dd2fb8d4c9a7fd165fda8a6fd4c6ff59fbe3a98e28383bcc396b2587af392c3feab4542817257dd247e9feccd388541a09950db9f8170ecf93eeeddff749fae4d23ea2f776f5cb7cda1534c6de8c39f828c7d8edf9de3b69e85ea62dc671b3887c40ddcc084bff800d8138f7fac41ee9cb126d02cd36692971ead63798d5b16f08338533338ca023943fe20eaae3b265dc1ecf85ca74aa2b10ae2de513a43054490a6a8e22596425d311f8dd934a5e55bf43946d2e5dfce433fc136f6697f0a34d8b5fdf7f7fd98f7fcdfbeff81d90f6a107ff53cd76fb0a78b8e33ec2bd7467cf7be878473e61492ed4cfd696ca1a61576d0243d564ed1921851ad55a0f9572bd98cef698d72d2ffd36d54d0fd9e066ae1f0e19945dc0db9eea4284935f1d2fd49a858df2f5b1e557d296ba771332b9080d99fb6be42c5c6f83568d4d95dc0ed8d36fc56baff6c69f358dafc3d1f63cdee04f1ce7581bb4f04f9f7f199ea180fb80c15a726cde1a33400df1488dac0fb5da447cdccff571182a355b56de4d52da7b697b76167989b4cd0d8bb2515c05fa92e477415523a6a30766ccb60ba7add93a87f15a9844cf8d05940902c2e16b962c8b3ffb12df89035263d6080e4f35e93fe30bfbab685e96e36ece591eebf7a77dfc3cfe39ef70193ee72163aa24ee6f23e5bf4c592893f278b4e44de457b11184bb8eac314e4a3615b400b71abe59b0bc8bb9baf3b9aad2f57d2bf5ba0ea7d289d74aa7da38920a96a4c20dd56d2d9c7a610a20cd2a2f4e2251305637d7d590fe676d10bfbbd41e8dbb340445fc913be493da2fbd4a1c971a5e73d22bb1cf6bf9fcba39e5502f3b3f2999b5648d22a20388190b85bed383b572893d86087a80696347ac6723e2e49b45045dced922b5658ba0b03964bbb02a3ae9dc7799de4e88a2236cfc1ee1a8dea5402544572b5e6c0c39652ad65487157a609f9e9f2ffbb0fbe5d11fd795367bcdb3ff21ff8bf6e9a08bc78a538e99e569f83a47fe81c3bc1930b511363387bde2bfb687bceedfd7707fbfff9ceff84bfbac04f539d7fb1d3da16bdc73afc77cde57093f633ec8699ccbb093f148686d73db076d18fe1a25ba049404fbb487b60f3c2f845e9340e5e01e1fd2c23453ddd425b7b7686a751947306581760b62c38f54ced76882a6d4583ade4a68a80f74f1408155a335037390e9b2d8b5ec222dd64b791d9afd9c8b7a7edc5fe15893dc7c8cf5661fe847ff7a3ce08c93080deb925d6a432aff71d8a7ae75c6207f89a9bd46ecd6cf2b4fc5bc3dc411de0cb1dbdbe738ebad7c3b766be754606ae05baa019e14cd2120b3632cb459b8684299d73022b68be95fd6e62ba464c91ee5f73840af8175ed4f58861377caabf1cf9c48fe45b6368898b1e0b6164479cb0c2b5f50c944b9e9516f4d08b36e96957a8c753109a8172d6c90c76b39c1404e38c50fc856bd30ec6dace1b974ef0f091160c1eb359faa03a5f83133641f7378c71c49536a83cc660ff2f3d8b6131ce5d239cf833aaca8d3aa38426ae6b28370a026424b4b3bebe897a9cc08eee5a0f761edb395a51fed4034997df39ce579a6a9c7ccc0c7fb96c48657676ef069de2535ac01277fc6317ff2f761cdd3b7f61ee75925ebf4157620fa1167c6fda93e3dc427d610af0c3526b7fd359b1e635efb27bcb52fba1e2b70f4a78a6fe4e6afe223bc1ff7b477d9636ce0a36fd9c4439e466b2fe7fb0166c8c77a10d5884f0333d3e211e707b070040980bc4511d2a9d68298ab1575f398d2da210e9810dda392a2ceb741e9d3a6a6cef88035cd24a572925289a040430f835f880d2abd4e305b0fa8c9995d1cfe5ee7fc453337e687016333e7de2ee6683b8ff0373875aed6c7f0d5730cf7ee575a3097f631f82170a5016fa4120c694de5f3ba1176b3c6ce461706da8534af96dcffcb39964a4ebeab237fadfce39b318f7357892878a51f1f5c8e39a512c551a061ba013e89db4453a65fe44a16ed2e5be39da4e643504a3de51bcd27681e336821bdd6108c47c11a87d8456566e75b04245e50c9332ec43252a3853d2673eda0a3a2d92f274d172a6f91e8ad1ff6f2aafc6899cb9aec25bf73155eb48b71594fba3d7fae4db457c11b3ee3f34f1a48e7cfbde84e26aecc97ae34f93aeb88b333a4aa3d52e105a93c5382fb03af98bf64c75802dbd2812bc145126a502056bb619973e9c862599a3bc93c9519f92265562d6d7aa01abcbbd57e75a84211b3731502e4f99544c117f9830b6b1165d699c7fdbecb1ca825933fe281eab414676ccaebf77dd0c5a9d33257c7b93af5d7cd3e6079beaf5b347e8c9ff1249f63f44fcf0deab32efc3e759926c2b7dfe3aff6f06af31fe0115747df6b7db1ef3fec5f708823ef1bfd74f44abc9e6ff5c206dfe0ed7334a79e8bcbf83e033af6044038d0d921a1b590e0771f30ef111bf75bc4c423736917da9e106ebdc2e0b78638f3650ff56c8d6e8235d279d1aa2567851fa1e982e78f7189eee2bed853c3434baa01aa2c9c958dbb5ce39cf62a498dab72e71cf7dfd07ff282d31aeaee7f8b57baff91fd3cdefd1cd759f58d38e72abec959176e028a24f2fae73df1f21c67dcea65b92544f39645b0489c06a68678f08b7139d741ef6b4ad16e0c056fd6a4a7da32c2335ab41c410b72e27509f48cacc86302e183600262e61f88936f63628da466dad296225dd39134d414b93eb8d5c02cd3c677e8bab6b54ecbe2b5ed02fff95ea0d77a7d7ff451fb2be9890f67207ee26d38ef81acd35abf1b8d2ec64a15b9266c5bbf05961d14ea4150a607a468b3ca6a9705d3936ebcf5bb718d34a688827556a99a19ec369c5a33d9ab75e6aa5b42a1e697b51617d0601c86c2c9eddb9e1a3eb8d7a492062ad43a299a208e50bdb8843bef1b75fee5a03b2c8e31f08b5ee1c085f0d77661f48f7ba93afa7867dceabbbd24236ff7fe4c0b5d6989cb56e7dc549f39e3c74c1f775937ee8fb1dfe05719de464697f67f3fefbd4ff890b139e82f97acff52077a32eaaec24df166cc5fcddbd7da61be3e61082ff2fd4aba15946ad9faf73e61f231b3e1084fef815f6dfa206c16beed6988798b79375e24456dd032e858216698836e19c99158333d03f52e99e210956dbd740e7ab06a8ce5ead7484c9a26669804bc59f854788956f4e4121ccab76d8afdcf7c4fff5d7b69f5656fc629b6bd42deee69bca7d8e0f8b3d69efcc9cb7276a21445cac77d52d8237f2a4dd435bb80c00521d603a6ad45956878c476f33e6b5194d7216d6152feea13dbf329c4eb24f22a4acd476eb369ba6695af038dae734ab476ca4a6f2b2a96fb343f083eea50388ee34ff1893fb661795679f93204202d9ff24cffa8b15b24d1ec8deeaaff1143f68cc97fe9c77ed602fd807349b83caec71b2ec28f310250592995ffd2cbf019af469f3ab04fae1cdbbec3b2fc3bb18181eab4c4c35d9c9539f8518c507ecaa1580bfd18077f95bf1ae286d1df9fa9274de0e3997afa591bd6747121871a89ac124f6590390a32d79aa493b18594af2d483e89a9ba45aad807d4a30b822073bcd59278259dfe3ec8358671258240e511e6e39cae210b9435cf7a54d335ed33bb1648631a2f7720d4e03424d4480864ff0607d76c7a29a7aedc7f75572ec2d175f4ddf5f139ae1b6b73520cb9eccb6a773343307990300718a891d4d543d65b8aad1addd77fe9b7209ff954b5acd88d845ddf61ced6940b9af2e63136323360b1261c64cc35bc593ac58870bccb98a5256e3eca606d26518d9695aa16d0a329653dee9a0b6a775fe7c102f7fd991bd7d94b1f508b3ee96b095c749372d8c5469d27dd78f095e711ae53ceba371881f7bd2ee5095376d6967edfefa37fde6335f0d40cbaa9839e7bc9ce77ed2bdcf127b912e1b243eab0918866fd4b1dfc339bfa3e1ffbace1f79123c1191b22f2d67184d4071db7cfb4adb96a12fed9337ffefe6c02d63137d782bfc75b7c865dc4fb79747ce6d75c03ef6bf81fee86a33d7eea5d6a52078edef5b7fdb5af3e5fc7979ef52ee648898aede65c7cc5b937f484a12bc46e5909d7820b904e4079e2427ffb1c434e7c7521ee91c98710588bb0888d05c75a58409e968aa5b67499960b6c6cba44c9119b0a9ed8a33d72b49694781bab4d9716e31ed3781b6b458b39ae327e00cb028589ebef598530679e9ea97c2ddd7c2ba188b962db24caff9c13ffc69d9938f0ab396fafc473b8894f5a6bc7ff373ff22fd75e218b5f07a6a84e74f68080b7655aed6625db24a57743287cc0d56f3007624edddf40427c609ae2c8ae6721ace77e389e2c1dcfa1152e8fbe46403cc20056fe54ad638a1b5661c1a33ac254ad02e56bcb2f74722ecd3f7f56e37cb69557c89f0d38dd8bb50bf23ceb409e19ea31eec026d5c7db6f6813bcb72d3fba7b8f7b6fce4f78a539cff7a9de0cb9944f7f7fae2b5f761e95e3431160bdde2edd991144caa40c2e96bc89176e3d47d0d2a5cdec0cb0db8059ad34e80129e62cd77017af059445017c0305c994cd7cde444b271b11957b88b6bd50de94af73c0a76a910065f3c25bcd75f05d5e94e10c88b2cdbfa19d76c5b916bbf8a49ff66a7c4dfb810e1e5cf2e6964dc6d8a7cd0383722d5deb203465095d10d25b5a0804e08a3d248e44d9da36120352c9014aa7c21255dc63aa48ea30860c98b0a8de731b3bcc863366e329b2cdbb54cbf6bcca99af313db541f091dbf767f9a3efae4d66a8262ec7bbef9d85bfc7f90eeb132133e5de3e755fece4cb7368ede57d6620200eea530382dbae2952ca3c5eccb6a8c27b699b4e68d87ba4e1fd2dd81c24c17b36b56e426d7c4bca439f4235479570a521815fe60fa1eb6fd13abfc3ac5e31a7ae19a5665ccabb807a71ac7eefb1213ada5bf37f830f76361dea65ff601fafa73b943af5268ebcd54ff6cb92c3ee1bdc3157e9273ded159567e5e8799f9cc6ff91c632cba81766bcd0928a1a6cd2d08cca8570a1457a2b8819e2d84036d66a1628a827bd528cc905069ef02972b0866f38cf7da68f11d26a8c396bd2b2d55989f4395030e57e2735335ad8ded45f63982ad6ff1b31e6a57d608983bb39cf8ff3bb178697a7e1717ebf3cebef79117eb87e9f8d7df441f3225b814d12212d1dfc516de0d8fd09776132b50473c6b7bece8c2c42395fa347ac308d8928883db69181dae5a48142c7533469ee626d6312831a4b55db290c0e19c809b5f359b646eb25678f34424116c1152b72375d8df75815fab2ac4b4c9b181be226fd516f9897673ad5d1e43cf7ffcc23758879b37f130f5d981bfa64ce0fc7584e0c1cb0c7730cf671b9f90fd5103fae73e6b02ed6072ee5e3f336a9ee3d9c7ca16f3df78f6a8e947a7aacf0883aad2bb5fcc1ef85478bb8452af753a060ac988e98824bfaab5f4cd93661fe21647ebf98faad281161b6193338331653c6a52d1cbef6f2041686dfa31bdf69cc855debc809f4908fb6d4f0b712fc648f7c7a265ec7d197620d4ff98aa7feb608a994c3e3bcafbf3aff9ff02cffecfc1fdf3379ea1f07bde0204f2b5cc7c6e9deffe7e73bfa6a17dbf7751c7941a2b76bc6ef0d5a8c235aec8cc0883b04bc403a78c379ce329dede2700c04a1fba4686e929255ac12317621f20be563a2b05f786eba56b7bca8373ecf4648470744442fc3b1230024cb1245b43f735ffc1546ee78867e9ff314ac9bf3faab18f530f48c5c21463de5b2ac3cab90ca56cf76f9c3f30cdce2e1a8bf281e890223716a5df0788f680ec35e860ce0824535673cdf2ddc7a8b23ba254e9b6362793caa0b12313d56c84e226b1428ef40f491c6786e2c606d628a604cee0f0b477136cde340af6fd25e8c52a63464a39ac0fabb1cc99b6564a9ac545fe16eafc597f93cde60e35c75b469b598fcc87f59531d6e13375fb108e561c4daa414ba2c119391d8cd35b1f3fba00bd731583ad22750753cca09356666c6c1ed5c63b761d79085833ada8b26e42d1693718ef4624b1daae1a98504409d847540dc5addea70fa99fff2559e5546ac7ed54ffa5ecf6bc8cd49ae8aa7bd377bcb817ed95df73c9f1ff5089f9fe3cfbd8b57d11b3b8df5ab991b0c24a79ec58b75c642a726187a062a658209bb255c56b1816741891e5809b7fef47e1b6a8c27107909c537b834e982f966cc599546bf4788f9fb58792a5082c66b8c992d725a9807696fccc46022a6e6262dbd05a6e36d5c34abb9f69d3e006b2738ec456881cc39de4958cd26431fc08bbf30cdee5363769f38aa4a1cd6cd57bfef89de16229add3f9fa9cabf4f3934672e3b7e161afa4b2a2f4f4bbc4fc3fb7ae6a8c799835456e13ce1a3fb58575d6cb0815f362d91cabac3bdd4f33ad6efef93c8bf4f74732ff5d1bd747eddc725bdcf5c6f1f97edf1fed012ee3fce2616119cdebf5a3b7d31310b11c5c7f7ed4537f0ff6ee6d1d33358e5f13b0887693157bbac1bbdd91371a91e3fabf91df7f1ec8553fff4fab23bfa9bf5ba41f350ff97ea75c35e45976979ac9754d8a1e1b5713716c241112ecd3a2cf39b9004ddad066f68d754a4920d8bea3baa89352d10e691348f91575078e65c6b1e649447046ef6b8c86138152835ec9694ea86d0f184198ac6463c223dbee38542ff4ebc7d69bdee69cec06a19824270914bde6adfca2bff7d0fc7d35e69e2aa6884c3ca3862bb01f7f20fcff583be0042224b8b0db1c2fa2f7d61c33626708ef8b8c8d68196703697faee2f7d1ed564ceb89313501e6ded97fdce1f35357ee68b723068f6cfb938cefdd0dff6e177e45463bbccd7118a33b5a1dcdee229c441d1dca495d8309a8fe2755ec651becb2ac9d22aef05c5565cc0039a520313cb20b659a7bdb72200cdd3b216d8c951b26a4442618bd6709415c04d20dc2eb88a59b903b8aa2b4ac175fb039e30bffc7c77feb9aef6bc6f8f7396eaafea88936b68ccc5fff5d88b973dd3e6cb2f394e6757ea6b793e33bb38aacdb77b77788e73efe125bd995e94d271c058ee25e5aff656371362b713cef0a3a8e44e2a6b4bbebdcfbe9da3be941fad4e23d61dff4b9eb03e7fc615b6ef7a177e6a2b40561effcbf3ecc48ff0ee39b4738dfdbb77a6dd247a5ea30875893ede27a51a510751a4db9dcff2d59202c6c2667f7d1ce0efc7c564d42ec24bf7b859a6477fcefd969ecf35fc924751b6b5d073edb4b79fc73fd74f2fe103472b9fd748380213088db012b798363084992e808c7cee95c99ff8c02fb49fa96eae5fd9cccf706a4656c24376be37fccbd762738c71bed5df7c159e24f578f4e393e8d4dffc6afc73ee2db82c3fdb8d75acc3184dc62275ec9e19b54928d21984771c2a15d25ccfe8782e1db30d4a0c960acf32b73e5056df0411da861ad8f0b537bfd5d863502a4288bac100ed432a1489ac3834f21c395808567b3482ea9c7bfb8e1ff2987cad47ddcfd7f757b027667d9ecb7af0c9bad1e8b21ec49acf0d0504883b19d511e20a51856a5e4013bb188b49f3b874314bcb5a113738c41c2d849b990ba79913d7d325f3f892ce46be8b7b5ab03b4ca4290bc9850e7709dce8b430e3400730741a166ade7ce9b0bfc75b44d6c02b3d2fbfcc697dc259f633ff38736021dcd963520df9c5d7afcf7bf7b2989cf6540ba7aa09f9e69095de8816cacc0a8c70c40066b3112ada22752413bd72a8ce92858301e5333d00ccf54b156685dda30208a6e0841a56c7ec78cf4b6649439894b006db12904a78d4d60e41a176fec7fea58bb4212ebd5b073c442941cabfc39f605fcbbef4730e3b61b0e6a4d737c42fef7e77aa017fff7e1d62d21175ee0fb404dac236215ab39e54b5be64ac61baf4fc08dff83a986724d3525b5abe03fc85dd0a5ea27d18d57362d4763215b334f2444a50e1937c8bd6d663e8b02ee8736b419b66e13442927b63590a824bd3ffa20ffd3a35e06f9d357fe8df8f23cf9c47dfe10cb99a5fdacf076e1dd82d43f0cc1bf2c9f35cea9f0ee78f170052a554d68b037655b18c989b70dc0b22ef322d1f49c7f310905c300653a3aee86a5c21c32b7c376709078294adce9507e7daae235c26cca9a325c93a44552978eb0b26d6986a26d24123a1e7f22f74c92ec4411df76a9e1d63f528d7068d931317cc13defe2a78f58bebc1c7b5d1e12efd8f7209bde5d77ade232fcf71aefd5ed6ab231c1365113ac8357b6404f9a9ce8cb0f71673a33042add5962ece134350c9e13403d4c48a027f32c6d801455ce48b65f84b9b6b35a01546a10b4346665ddaa3f61664a30553382d31c69c4d5925e7b73d6ab34b7a09bfeba387bf877eeb7fbf1fb97d481cd8c517f69e9ed6e91b71ee553888867d52bfec8fe247f736e7e2964d659718160ed616c81cdc0b3bf731909d2cf349588ab5a8ea0529a1c1295e8491c2dcae6f7c5bf184ca12f5ec6e61b309b51b225c61f895e7dc6aad1b182846b648162e5e676bb4f289f26350b75fe9195eac791b823a2dc5fe1da7eb3fe0823ed77f7d59b753fe7af0c32ef70f8a38c26acec7aba464eb2ffbfac20f3a7a3ff39723bf39710e817d5cd62a3682933ff7e179ce58b1cb72d78ceaadcda6b443aedc53f27b14f37182ab7ae377e3049568b360c51e3319639ae3b906735a8c0e546fe619c19a5fd486af669ddffba684284e2309583916486bfdd4f6a67131f652f7be4b2315ccb5035896bbc3ff0fb162c7b5524b173ff7cf7f596bbd427efcf5984f3664b87b4f1a9ddd65dc46769351650480b682cd46412fa928f23c7199ca58be5e38f2e65603debf91b319b8717f70af8b8aed5257d6c2c59b39477be1d02673c6f5d73c12d7b4df02a44e6b241c6bc9049cb9b0ad63ecab3dafc93f3fe7a5f6be9df35f06a14d8c499e244021a6b33623eceeb6cf74342d7a046af68163eedb6b71717da8ff9e266d70257cd5f3784ff6f1b4f74970b9ae3561aeefe2b9b43d8a0bd51003da69d14efc327751e11dfc0aae438d39c2657be4e2441285d8643c438589e56a5c254e6efabdb547840151c272696ff6c4c133d42b9fb87e17eaa24bd7f780d9ed7c496d2350ecaa5cd66fcffaeb9ed6bfe7de1f789d2fc75f1dd7a34e2ba4c5bcdd097ed60a2ee12e75bff2a77e3ffaddb5fcee67ae3d2526e089cb6177ea83fed3dfcf3cc097ddad065fe7239fd73dd254ee3b8d8ac1ef7da0e568de232b281b2b8dd8039fca88ba0227bd00922027758b3de13b0db996490db6a391f518da99868a314a8adce5363c84d47c646b8c1358f414c8474cd19d5f6dc075f53ede729ebcf1bfc2f7fd74aa7f8a6d9321b6c3ea4d8fd9dff7b9fc2fe08338ee1f53091d6a4924d43caa55366896fda7ee9a0f633fd9c147c1652e1da58b10dc88c8db0f7ac317f4d5f821d8b1623c0ab967a34aee13f777974d25633af308c78cacf1066bf4bf26ff739c9baf7b0aaf9467edc063e668cf739d395a73eedfb9284e5b1001034d95c9548da48ded145a666a9b0177f29ba44266a2e53da175e293dca2869533a3c64bea7508aa903988278ae9cb12cee248d90165c42fc76cdea379e6b40f899db3a4c28416668d5d59fb767c48f80571dabfc6df33ec5b90724f7da55980ba2bf5440dfb833571c9ba271fecf935c92eef3723411be8aa4cf44c1724a74bde92ccc11a732d45a0405924485030be54589376ae63e6d9a80fda5bc37ae4ebdc22557cf0a7bf35c23c1f4d110e8165a7f6ce8c35a993eab74e541d71c526a9e3b91caad1d2312ff015be6d5f073d88cbfb088feb375e25dfd24fbed2da3d61e49f7ebed0969db54aba8c62d7d7d12a36ead1d266b7b41cdf7107dd25152eb229bc9debad994d6143cad161e9c09b5479fd62d234927a1b01e03a2bcdd531365c4e598cb8b893bd354b0bf01897c25e56e2115300a50b6d4c6b98f65ff4ec5ee14efca60f76ca4b1ffd1c5d155f69649d7844ae93c378e2314c2b548b1387fa27cfa3f597e730b4bdaf984b21aad208b752ffd526061e2d6cd30e9d1a5057264c07b3c4feb515fae620d6458f79b321f60cd052460be625221211676a17f286a0aa56d4f17546bc28b3c70565ca935aae164c4d918d234c3dfe6fe4307e92bb3eeb1d7da75605aee26344c77b908d9ecedf79fc332e815e74dfc9b29db3de36a866b6688af7d28841c060e86ba8f51d0f539bad1693668bd7888560d3895225a41847d2ad354e294888355d162859dac296da2fb070a14580d4960e9e5025eee6200694ab473f920f81011d7e5deeb34dfc9607a2ff6bbcd7ff82dcf7535fea7f883be0681ffa2507ab543f3cd98ba7d73fe2122086ac9332cfa9425516894d1afe3af0125b31c817bc0acc14aa22d4c421069ecda68c11c80067799082c05810cc48312e58d854190c745ad57ba4cf34b6f6668c1ff6a9f15bc706148b69a105ac36e45a95f1f5f7dcdb1ee5676ce2dfc7f5ff0b72a803dfa070609795d0fcd61ebc8e7fff66dc27db275d75101c9ff9c3ceb9f70b307088e68f21454e520a3ba850e8ebf8904118a48e84a2aa736a587fc4c07d73cecc38f21e4f79b1632cff1d3da5ebf869a7dee4a71ccaf3f97df73ce7bcca65d8069e28a4e2d578173a609b1aaa58b89e49a1f04243dc05fa48c353b84d35d0f2b0d1b3483d248a95718f464bda68748a0b4ec72342022d037597561053a326c2f5fba5abee32c5288178baa02d0f80a88863565ff42e7fcb4f8e23affb5a7bf25afa25cfe39de65d3fefdd0bf934fc100044cd826aa2ca0cb6892998a49a79cbd68287c0aa6280e8d2fe63dcffadb911d1973abfd7c345e96c74eef918c6bd3c17a2e9d41537c23647ac9ced13c65462e375a689b584ea66e1fadbc4b6ff724eea7e1ee17da2b3c76ff4a75e27b6aafc463ae3ade0e609ebf8faf529877e210f8b57848a95a983a0af23b62c9a9a44100b034d25f9ad63658105634548eb3bdff114e75e90d8f902393b3d8eac2aac702d4ab40f0c4c17dc5b2fedf181534fcbeca04b34849042ab659969810e4106b23db5bfe048fb8e8f530d76abf9d24e760347da156a16f5c0e9909eece3c3601f39d80dbd17833ec3657af7890666481bc7dcde183cf2160b3af00713ee7a8f92e09a4f9549f4ddd65fb3c78cdd6b0907c42fcd838c04e514376937c698d5fb2c924902541e52bcf5f59acbc2bb63f6d8c35cc2c4813e31d463a07cf3baf966d809e37d1fe4ef47f45eebb5647de67a75caed6ff55bfc43bfdaf35cbfea597b99ffcbf1010f993e7e9c730f88527c99cbf2af95cbaad0c02b25b92845343beda137cf718ea72ff04b98713f429ce9cba9dda6253551d1de2c6cbc15e5fd36665692d1bafa4bbfe4f48c115a270e6be210685909877bf0cb7cc4c0757505de9dd3bcf5b19eab94db8d74bdfc74dfd09739fcf4f9b493aede65e7721497de349cb222008a21168c888360e2e42099ca59b8be1f853007ac476da6153d27d60d01b513ea22c1345f6750d621a4fbb0ca6f923eee16d4eb321daee63a4009cdb1740a536a20b8edef35c4bc401074ca4f7c43d7f4691ee41977769cab64885785398f061f7e2fa3a019de57aaf24b7ee26bf1225dfc5cc7fbbcee537d34f4c9be7023aa47a11fff0e8c633c9c1a4c9bf3e3fbcc5a54c53986fc367f463be7e64a10b80b4ba851b7beb9ed73239b4227e82d2d3164c7ed7a87fff60ed29929bfb61fd7e1a418c63ace5da396517cd697bdb06e11a96db8faa5218516f35ecda9aded335dad13b7c6481bebdc552e866a8e01ceb1d3ce0995d380b795afd87c6137e192e087786d150b173971b73b30373870a61e9993b70b78df515557819e19087ac1d291ebcff5317f1c537fb4db93d9475ecc6fac5bea404d44489b47afd7ea4bdee12bf8fa6d2e1dd6cb0978fefca3fff6c9f39c754b2e5b5fa9337a6bcc0e09c05baa6011e858049aa9251a3018c831b301cc0c39cf0a3149744d8bf506130df0c4c9dbc456282490b1a9b7217cb3f5b9aa85a63602a02425ac620ee8a8ca27a41cbb8ccb9cc1a25dda575ddf43ccd136e6529dcefde8ec33c427fed8ffb85e45ab64f9d5bef8fd781ddf7218eb789fed44241e07ee924b713061b362530f84530c116d5d4ce466ae8f7a118935edc63de5ed2db7d1218c7eeb4bae8d0890b788338e563b1d69b8cff8614f1c98b3a96cc3c2b3e4d4eb96a5d8c7e12f40a9e706653ec28e1af91c2339f5b6945e97e738733d95baac1021d8bde59afac0d97ed6b2401bc1d1f6747f3f6be8fe2d76e1de9f0cda2097ee95530f2007e63cf25416b1b3cec69fb15457da3b9f8d3deca5933e166896afb89c8ff1e1c57b8b0a9b28cff14b20920a6f42e64598c8bb8513ecf9545acb028f9033d628cd776832c6dcf1800fec3d569e1114622df4d99697633b66ac403437c89af692c198d8b0967da6a7065adc0291fbb609633a8e50e57db6b7bed40748aaf8c56690d967fcd6fb546feae7bec7c9a73c2f8326c0d97fc9b3d23ce752cf9a29ab4f74bf4a968b57fe8fe0b079c1d4c49f70432325078ce1789b70facc5bf482db091e2fedb74c9d711147270db33f63296c63be9e5d63dfedc5d0537cf4499e7ed69e3fff322e82b84b340c05a146eab03573d92ea6d893d4a4d42d7a5a159ad05a375c8bc4a7bf7a59d03631bc8ac37a915508df6aadc36c396355ce9312c5d4f55ba4b59b58d51cebac0868ad2f609ef811d6933573a4427faecb5f30dff312ed52dd54c2612afb2217812623700d5ff0f3b15faf83b94e9df1a3e05889e877731ef7fbbe33c10f8bc9f811874d20cb400fed9aa48537593a799c6a6a95baf5dddfea1f3f7f870a77929beb38c25fe515b5e15cacfe3aafb84b759c67fafde3f159d312e5f254e3feecf7c7b9d32ee8ef69e74c3e306aee89cd42d2e3c5adb1d9cf81a8a8516c9966ae3282933ff2137c6feef699e3a9b4fcf2bc0fda7757c8c5ee527d7c88cbe3fd7d7f9eabe7d797f25fb6738e2bdca3c0e7e8561479e0db751b944cf77599cb4973088b78ffc9fefacafe8fe4d1c73873789d72adf6a5f7f85eeaac8b75d88b106c45a4bec7bdfef73d00bbd4902a2b519ee9b439c67aa7fed28fcf732937cee9fece3ae26c743fc231764c8e0b7197909cf312f7b700ed29af354afd5e38729f684d81edac4b196efce878af6bc0b74d16dade1d57682201c4a1ab4c1fc6ad5fd887506117396a2d548dc34933a2aeda2ca0b0fe25dcd3fbdec3efac6927c3272ec72fecf395b04fa9eb81677ec8637cf7faf5a0cd7da9966fbd4725bef5a7789a32f420a3fa516a35a13d3a30cea29407fb706a9542e15d02f258183249c2466504b240072d8de43499348ab84810a0a61214e682c0da2f449e4cf1c6a71e24148d900b6962cb55a6abcfd6efabf367c6bcdd252f7a21da95342bda8be37b0eb7220445127dd5cfe05f29ae0779a2d346386ac029be1aff47791ad12347b0df9d6fb70ba9e71671667b54a01b54e002d9719796f24610eb61b9965a5cd51d9e7a46c0e26dda2b4750732608eec8a431c3de6bc4d4ba9deba2a67adc66badd06146fb80b6b14367b56c93b128e15beaefe682f38d045347bf1c5afc2b174ff5fcfb1f46add3fd119442a8dbeae37a0d575eafa99ce1a79c6cd3eff4ce2cb79c2f8ac5f303c89192642c5fa927a5d1c596c315507c4c55cf006faa5b627957cc4ce784d80e824830eededbd2c19123abe91cc5aa7c518f93d46a840c61266a3a4b8dfa76e0e63c2baa01cdb82314312360b21be007ff9790fe9d3f77d552f7ada938f497569afc0f96c475e971a5fd9938123e50abc426fc63cfa5b4dcc1b35e7accbca7177e662d12f8bb1fc11e3f98e94d490ca9aa73ac089edb719152ab5c13e31667baafb7dc0e522aed0ded747067200a7b60d08c489d49bc9829a3beec41a87569ed276141674944cad2a99667d56682672735d028ffa05e22137ff9a8b25e5f071c8077e971be22a780c90a725acc42b5e8877cf7179af1f51e856631ce94d830caa653c337035f0f53359e4abac6c93b8ff160ff0714f54827cbd0faf935b7ad2333cfaa24f3f6bede575356d9411c9319728549916ae732dd605a76e3112fd6f9394084b501771251d1cc18d08c7112f9b7d18d50fe9ea57cf6c694b03df054069dc96a380a0bb858b836565ad97059a6247eab7e07747a7ccf4a7561216e3bb7fa777f9d21c3250d2c9f7e23b1c3557d1437f1e6fb01922c29b54c7a798e118a37d1f4bc4a90eb63e371346e901e9684441ddb072bc888b4063dcde933ef8777a882ec4baa65cadb372e0c55d7fc5b3778a09ff9e67efed98c3d9a863c33bda09ed180f9fc7b94c5f1a7acdb2caf61cb2b504b99bd98119d3c2ccc25f076e8f0d629ba6d06bc8eccd6849ac3ced2d43b8f09055de0d766c8d7373441c74837481a9aabb852bf6c934e73eb1b658cfada0f416b196f3a46746e8c8485e579b7535e8b53de3acfdcff5f31cb54e75904be794b738e53a676fb522fe63ba766fd6ec137fcdaa8ffee177f695bf3a7e0fffef7db657f333f86daf5f0ff9ec0bf9ec6973c0b47d10955c071a66f15a0582ab8ab97e9752ef76a97246ddda92ec7797026b1d9062b4a0b95a404f13e4f79633662555d6864a2861e38d64784e9d66962824960558f8ba79087ab5930c6f305030d4f1bfd1eff47e6dff25ac7dbd4f2bb44e9cb64ecb4665d5a53df4a04ef9d7bc44e87dfde06776fe38d660e3130ed4d1be5fac8b1add1f58391a6586e5dd1a12846b7887946f08dd5cc50c560b688d92295e90225f21ad2121351bcce43c611644d09b13c3dac9523da4ab6691e840a41c8402fcd6170e58a3de7af00bb6120c3bb4425d66c89cf24bfae63ff7eb53ae9a73ed669d3ac57b5ffe4777cea53daba7670045fc15ee231c691fb4597fbed68d70662febcdf16a58f36970211e5bdb93624c45d17619b026ac64330494869555654044b264804c761ad5eb071ee5392570246dad0d35e0246b39136ebe0bca762422b5206ebd59d29a2fa7b243ae9760adb6f8ea979e3acd3cd09546757f4f4af00987cc45b558fd426cdf697e226c66ce87b5ff9cbf659d5dc31f38ee89a12e7dcadb9ed66ce83b88fc3387dcccb830e7e7252e7c0c74d887449978d2904c07db2c62b3a0ca29d518e025c67cca2692c147da7b3ceee541328869b81b2db90a108502452c4a5cab906b2cc8147342d81a956a97702518b0aa70357e0c15f4b3a9fc2c5efbeade7fde8fcff66d7ab53afc4fd6be8e3bd089e864d7bfc4285e0903f7898ef0d3597df73c3fd2087c4094ada5636ec3a9cc532ef8dcb041e8c826d5e1cee7594769ee84caeb623ad6d2e8fe10569697f16694d8de260cc7bb50a19dcf4d94415b433ce771e419a46094e8e30873d5a4254e1084731f7ab3a5cb465fe803fda7ecec63c25f7cc53f9ce3fec4b9f9d7359826e166fde40f9ed6eff97573c2015fe6d32f693d630ac2c4552db55bc61ca92de86ce4032b964444bee18d900d7459e43a054c67ce782f0ccb48356913c0f0ada1ec4ccd0e21f4f672d298444345a0fd3224c11b3e4507a60b0d954d1414de3ae3f70746af8ac73af9f421504bd7cad357e7263ac5abc65fe6741f2e3fdfc7f550fd37f8dcbaf99a5ee35c1ff7607dc6d3bc1a5f1beaaae8b273ec10a21e89622253de24a0cce70a52dfc81557b6214a8088e655a834235282db10e0b530d0ade0d0cf0c1ccc01bbc3501cb0813a44c71beee41bee64ba5835adb43723c955720b2cb6741a9be9a80a59eecb6f628bd30ff6f85fcbad0dfd2a697431af713b67a24a22d6894a5ab2044666c362c14583b5584b4a66b3f230127fe247ff8ecd29a126a38147e718771de2c8fb0a93d09e71677f6b7b1ee30883ac84bb3947fb34b2f2ac1cee90cf7edf1c7dcbcbe60e7568f5cb900e66a1ab8cb4f282ccb0f4b81221b78b36aeac20feebb91b178283fd3734560f57399bcfe31dfdadc15634a93e3aefabcbfadbd16afc90453891455d24fd6fd3af2c9e1641175035f3899a53a25cca6a2bd4c609ab8afd9205ade4cc4725dcb355e32da732f779cbb9421a776b1df3fb8350bfb56541359f629be9ed9695e359a2663ad3dbfdf2025c74e2c03ee4662f1db84b215a67a53a9cecdf4ffa76d066c0bf39b07bc1a77d8693c32aae58f5fa3de8c37bfe5953e85903f403f714a8d352bde4544e5a6bef73720316f884a3a38f59c99ae58b4e413b7febaf7f526fa48fa8fb24f764b0c3a045e2fa4dac8f77a75acef9fdef6bc0c773ee8c41acdfbfe4b33e7bcf707f8a3ee642bde1dc7adf0755b1c39917f43135702d4a75c6af0f3895f60f7ccaab84bfc7203fdf8dcdd3991a78525fcec055e2e2c527dc71dfe6f23ac63da735db6703e677bc4b9da30fab74f17e4f7cda933e3efa26eb546f7782a3134fd689036c78c6f4782f5de63b3cffbbf33cbdfe5b21b807bed279f7bbe3dac67f6db784c356f2a4f17e1e573b9faf8b7c8946f0c33629e3a32dd7303f00ea8c5a1add6ba8aa2daaf23976ad495c891b11d5bd20f280b4b60da9d90867ec257d1e70f61b50439138ca61ca948e144e7cbb36316d2c9fe77da0a90215d84b1ce93117479fc50499eba95887dad3f7c7a7eff6463fef6e7dfa7efee4f7afd31c66f7ffe31eee074d9de9411b7aca436b134742cd1cfb3e75c6c63c42eaf819c3f7869ec2ceb89fb9de314e569931acc9bdd47395ae2c90e9ac38e9f0d9f764f02dcd87acb3545a893a2bc78f8346c064741f46c1a0c19795ec78b73727df37b85ff23198b9ec200c2f170e1db4f99e9e333566f768e8b3b71f6793fc1f391364a9065f29e5ac48b8fdbcc649847ac9593fef331375c5f5b45b9ef3ec031f7e7bc5b330f05688b2cdbf711eaed317e9c07ecec52e3e9d8957e35fde0f291d1c3282a618d45d42eb28e5628175b14bb5fb11d25b2ea3f8707d1eb54bf3c4cf76fa63cd4107dfcb59fd3d06b639e7a9faa1ae70416df0943b466e02acd12d100f24c24d4004e2d399916ab6860bcfc1b47502502708fa1a77a1c2da380e8c585fb898deeaf5ca37c4760e3c33a64d44a756c0ecc664066e0844c87766db9863c66ca6c795df529be5e1d4fb7b2cc1b3bff85173f5355ee40f730fe6ebec1a58cf277fe5b8df9f7e6e5038322ed507cf7408628acb39b012014595152d254acd68850fdcb1db847975a8a35c70af0e81dd06455d6410ee9876dfa536d245946301ef018ad023b58519f6122f2b0b0817ae02ad38642c774431ce332d2f96d4b4f1a7fae09f9f9f7fe8e57ee3ab0d7ecb0b2eeab2fcd09fd6f3535fefcffd7d1f7cc09fc4b70602996bedb30af743bce68c4ff8ab8fcf735cef4b30f9275d1f5ef3a49205b79586a6bf4784aa3a88e0944ff19ed1a617807638821636eade57d661e8f16350c465dddc821a328dad598f8928c482b9334d52b0e025c87d8799c88941ea483f2b9b89efc0d88710a5d7c505bebd5b9e7dffbfd712b938b7588e0fdfd304b0af90f330f7993be48f1e53c37ad636bde45e8bcbe090b882a4468eb9cb48ac8f7a56e665c2b5910f9487563bed8aeb94c7e5d1aec51f75dfbe53a37b9adb53ec729eeba34ff6773581dbcbed439772b84ba2fa9bf831ff4a39aea35f03f2d451376f30641f9fe79c53becc06a0922559cffcac4791b4519d6979944d15f10bc996242f32de1cb05e68811264b9466e1cc11a13a196155bf953dafa0523cb0ac72c922c588b292ad43c5670cb8917a4e56c9fd2406340ed930285524706b9a4c7f75fd60a783b87e7b8f1cb7eab2bd4773e8c7bca39bd5a67909587739fd56577f882b124d04418425890ca2b996bb9a2bfdffa542d429e99be36d397053dc42c47ac105bd9c3085752273d2629ac4d09a81ed3b642745cfa363ccc8155c5ba47648f7d52e53a6132269c0161481480fb4370498de05febad7ed24101f9319e135ff6df07a738e7afcfe687718f76f949aba58923d4275c3e0e1c4ae145fad31ee5405b4e59c2f9fd68aec198b882d1087561141b59ef4db1f6e33af80ffb5e9ebf6b9d56e82038fa86de77768d5cf6f37c26dcec33e7f80cc7f3f2f179060cc3c57874dbc86c3613ce7dbbb41b2fe0922e196258973e89eef74b57dabc425bb2864c4c85124009b24650402f42b046d43621868ce255b39146d111c8a6b79ab7bb05c82430b748691acbd5f861c9eff759c4b4107ca129f9dfc5bdf832f75fd674861a5e7fc533559f62cad7afb5768857bb8b725b9a88544b5ce130a3f613c306c15a6d13923b4c496b417e778cb2d0afe076e9802220f89138f156eaf51db161248cfc26003221051a65366e1714e898e428e57944aad93624b9e16bde024d155f4e7d9d13115f971b0b2b51aac7e3dd9f95e383883cedc9cf3ae5c5ed8ff9e192f5730e57c7bb27e6e8550edd1ecdd7bf9bb4642339799be7f9bfc85b9beadec3601778a396dfdbbfd7bc134efd95475feded7334a7bac365f73aa99885196204309495adc7ed7119dacd0d9e8a55062de01b58c8291ac9b25e08e879346c1cc182436a9b2b64ef460ccc0cdf463976f38da4662599df713bdb62bdde2e29308851f764cd92c4c05ecac5e65ff1d33eee970bee1df3ffa3bbddfcec6e7ffce9dd7ee2471474aea3511add832587fb10a23b06919915c8149ab27189f6b7e0f89d3ce11726f21d5ba3258682157b643755c6d98dd48416f6d0ccd688a1b51c719eb7a142bb80a1c6afac7962b77ca9ac07bf6c3be47817f4cf7e9d2f160e2b8feb3d8fac2e352c9555b816af39b1dfdf03c77f13f94dccbde3fd9ec746f0f25e72ffe84fc0a388f2cfb833fec87bfceebd2f77d5d0effcbac6f77f9e23799fae8e731834a9a37ae9b0f7b9b24f7cb3abe47d3f8c7bb277a3e31da3cd797b8c7f54ba3adfdb97d5a44c9fe6218f8a51d68dc3d44113596026b526a63ad8120d23e1de6b2140208cc42ed5d02365ead62fda2228bca9cf61cf099e49476cb82b950f5894e8a61ff3c662b0b6d3d2bb49dca00b796df89ad6e2083a7f812d354fb80debd7ff4cace56232327f60e71e63fd1b78efabe41486b1067b9696e884f7be8c1b38c22ecab3298a9896b30c787799169b6921a6689d011fe4f9827e5b13e86b1fa8925d1c5987d39d38bbb43eb5cf5c5ca7ba994b67fc554efe305f17d7c8c9bf1973381386a51dd7318ef03e5b69e7712ec25a1b087a3b4e9813e8e62623f881563967cc9a630786d2f0385139ca22e466ba8a50016f658fe3b0cf3769841b9f5846d05b6606eb097133105275584cd98217a05b107b9bf1a0a595d031350dd1cb874479ce17dcd797fbb1d1ef731c71e63efaec9e28612f27602722a1d20a6da4c34e79c167ade8f8bddd1f38cece3eee99a3f33d26c0ea046f81706893baafeea9d5475cc7096b00d689c3d649f7475e272335bc621e1df7e6efd79f79253d88fbcbf359865059d9ee631e3499ebede50923f13586ea232fdacff25aff38fe10c71d6dd92ed56171f21bb08a0d3c70139ec7bfc81f8ea9ba13866d7047ee84d34cc854adb3297b48347b9f72b108225627bdb5e095e031f576995d6f2808b6a264878c208353d8a40086995d3f8822d303560069489a6a72cf98d5a39205d495a528efdb8ce0c75bed337ff84b5e63209df13ae6e6e30bd6f5139eb6e3fabfe3e039c56bb38bf7403601c7f1d6829f34c6bfe507fc7d8ee630e89a97489d75cc8f77cbfbdf9de39ecbf2d3599ff5dccdeff81adf646ed00a8e13ceea1b59e62d2e6d5d4602c73dd42560b96fef0e4189b590d515a5c00acb8d19724fc5c5fd362c9b2a04f57ac1efb7c1fa37a0763323f698a6539c2745d6062558644a24e9251ad6dfce675ed84b685879ac37b9d0e989e7f66b8e87abf080650e5c27fad0ab7ee2461d7a06dffd8ec4436df3b21cdbae8f4bdcf8e5a84311de2ea37c9d28345f1633b09ce65ba1c428b541210cb4a2eeec80f526890d39cbb4f61097b61e6bde434691e6d366176b68136a4c5fdab917033cf1a9e0246246aaab07be9ee94b878d100557e59214faf82987627ecebff7ea5cf0e399bf3ff3e78fdef2947fe4f97bf2cf9a67bd4a75aae37ec6f1f7ccf731f19668e811fdfb5ae7a5da531ff6c347cccfab9afc9f7cd9330febdfd7c8cff3f2ab79f959d37fa02db2f27b45831252aa0b8e2a35c94a7860e4decca6ac0c75b6c5c46be69a69a405dec7da986715c358f9eddc108a70592c2b16c4ba794788af1122a6d2c8a38553cfe67a3bc2dc0659e1edb1c398342808ed9c5ee05f7d8edb7cbb2786fae83337cbe53cf6879837fb6ff19391bff71532076ed3eeb866569ee8bf9ef8b82fd46ac61b62cf46d42db4a5aad782b01eb9aa58b0fc2635ac5602a1cfff5ff6feae3f519e6d1b873fd0bdf01090fec6c541094825969017c81a10af2204ca2855e0d33f3f5fda696ba7ad1d8fe33aefff7d2ecd68d1c464cf9efd75db0ce5922ae73ef5360bdba429459d4f32ddd772150eb3358e24676ebc4e1de60abaeb7c0d3f2653cf1095d7a586e414e6d390fed82d0bacc54c1d62f75f5acbc853691db44feffd4bb86f67e39e74782fb8a9cdf9e91c7faf6fcca5c4830c783bcae2d15cffb10ea26cc423a809d524d4110baa64c279bb4a38860bbe01596d6de67a3ef50da185763e11a56cfd525509111d03f13ad6c736d6db9ed13609a21cfa5ab79553b68e0d14a6cefdfaba717494a74e37241156d9b5eb452e8c4b3ff121663dc8e3fdfdee32eddfea2d7c7fece3393c70389fe274a9de0179b4d92ec3c9a7f14e329487b6c989fab95e386c40d1cc64ae95a755aec5e0befb10ebf3dfc4f27bfacd3afb8c53ec50b37b9df3891f0e7980976bae33f3c0fb72691c998f7fa59c2d7c1796b746b94b6a748323bce5241865851588c806c29508f3d64b6d742789c088c79acfbb2a3190c15d369750f58923b7ccb5fcb4565eace5ad5f6096b870743b309a71ad0fb949a4d63d60222eb0abfe312ed3e31a46bff9623ed3abe8efe39cafc63ce9d4fd39daebdbe73edc0b6bee5daa833b36f5605ce67d48cd892814a1859c629bf952ef6e173684a4da0c948f0ca2ab7538e047ac942509ba930eed6fb5461025f4c4b02ccc60ebf7634a6c1386a5b0e7469e845573b38cf2dad7da09d3c6377fcd657692d7e77e8c7f819beab4ce478cf6dfeb7e7cfd1d6e2a2eed509f8d62d620ec307b6ee08419be49a7f13a23d6ed820223d1f106d53962454e93ca74e91475a112b7fe54ac840dea44f726a9ddb185ad4a518e873042ceb2f0266c803d5182fa2007a4649b85db044124fe13f87f7709474fd8349ff766aeae801df50aefe6a0eb5ebcd68e383d979d97ceb7b5ed82b324749b362b2c4bf22e5e32cb209548921a1b7c350e03d56ce2723484039ae2c8e359b5013e0cfa80211112395972bac39150892684afa9c0a7a6e697782689d58bb0e5be6a666164a1c460d13fc3f5fb1a87e0cb3d504ffee18bb517bad21297ad4ebd4c27ac80719ff5e35fa96e0eb19e6f126eae45e46997cb8bf9992fa01fecf5ebe0143d9e7c8126ad7eb46835eafcf0426c228e7beae22ed15b220a0b88fabe173a54314134ab9593506f266cd313309f8b82f9a4b01e98ad8d7c85e290e0112b952e886710572ec450f68240c4a6a2f5f5c6a25a0790127748672e27f13ae5c01591fa0ebec5810be0c0a5ecc0424e5edba1eff106cc23948bea350fd2cbdec0738e34b189233c4877f692a3b83bebc9ac8f6b9d19b89c474865953ad61e46def0bb4ff36d6c70ff3908128ed6732e0ef58a7202c05eee631dee9ef6fc14ef388bed67faf831e17e1b57e36d1abecce5ce2eeb573ccefd77cdff377cddbd7ccf23a489091844e43531ef9ae55ebebfd4b7778d7b6d2ff360904ed0663aeb93533d68561fb0f63e98df53ffdb45ba1366ec5ecb5c6953d7d37c0d00a2418b510f3162d164606bba1a8b58430871b1a036bb111abaf3ebe616d1bce2534b8f2b355bd07c15567293d64ad1082d1644cc9795990b2210d3020d195612142c970af75fe5213be369f917f214afc73ce89d97f9a16fe52364d516185a3d55cdd66730218ef78898e76360ed443f8e52aa302a58970219250e72433ddec6055399d3ad131df67c6ab58be86194b9d6348e022de5dd5dc6d8c00ccb24351342fb3130e5999952336a3431e2ff409cfa9b79a7fd7a1e62a81370b0a53fef39bb0a9feb2eab8efa76cef777e2cfc3b979f3de37b05505a1c4d291cabba4f41e7d3b5fcc01b3848327e990d7bcf06e3fc436f89e3d77f1fd9c554c938efa9c6ff25af8cfaea7a48b9b539fd98bf1f7b6dcc5b1d63577f11d72fd1d711fb61866db903e9894e328b16185faf12265564459bec6f56c9badc651026683ac95773b58fac2812db3f128e11053adbbc9867c11549d291de13370bf4506c38c028f0db1810ce587fa4efbfb58abd58b086b097f89030d5eacc3dff7a41cb1e947dd5b7eb2cbe4016c0eeb1ecddac4619bccf9c29d165ec957fb2d236dea1cce573fe7b94a5debf95efb789e9772a91ffde8b8dcf431f869a6b5975380182ed4c257b9c122d989bad904546c083505e7bb35d5733807f13a9ce6f922628b7432deb2084efc28eb31dd0164370fbe3dde2c9947c4340f8592222c5091024110c421013ffbebd645883c33825638aa12ab97356b7fb4892e884b9ec537bfe2e31fe47c1982d5f22956fa919f1f8ef42bca8e39e79e29f7f3d8fbfa6fdf23f4725c4a2a1c39fc1c160cb759e975b8dc8c526e6f9136f67d03d9cbd5982f235c4abbe9fd69a0cd0164618d67be2be70bdead16bcf133a2b4b056de12324342781bba32cf0a6f9245b809086e022089d47f9861d9ad97a538c7a5fc5e9ef83f92932073bd6dacb321eb8f359b475f00f6c2f812e6d3dfd7e51a569fea4865867fac63775491f420cf2af924337f9adfc916b8ccaef3f5316074bca33cd784e1ad886e77487b306e0d362200ef428605d3a14ba7d936e0f99616fe3a08375b9f5333d3db7e59b10dd6cbad80f90d66ca94953792dc83b810515a7866e6a282d96d136a8d83ab51177f62d77ded2e18d707ecc0cff4fe613daee0bfbbdef688a5f1a4e39fc6d74ef83597d5b95147cda4dd6dd229f38563ce430a0c9ffcdc85e166b4b49b9816ac66838725902201819ed0468f89b5e28ed278d9e67390a34ca1957040ed1bb39e3b669e707cb36010a43cd83165e524f292d48e4d56a82138c322b924ef107cc35e465a563135af3d9546e557fa12465738377b1b5a89d0ec0507e6f1acbc9ac7a93ee7feb2fed141dabc9623cac128d44de0eb304424e859d8c60b5b98996ddec495b8bdd57cc021b4930101a637d1d219e93ea15d4c15c2067e6040851ce28e4d21447c7c2bab6c9d3a4d1e13ef2eacca35ab841e6863bcf8a43ee72be74372f0998f325ccb47d98f755c6bd666934b31480ef68d2f4163de1a3f07aa89c16796299d609b2855c829363237d616346f38459d98aa30757cc0952893c1e2b7432e9675ac276a0682aa5bfb008729b37c9f0b0d158a2ee1cf5d484182b587350396c38837c1556e5cd7be39f8855bb10207f98bb9f6b24fe0ac2626d5cd42fc8e0d0d1773ae1916486b553cd9419f629f5c21a727b969c6fafe1e3fc4129ec73f61a15cd81b928719f07e09275e27056bd3496bce07e1865a1ef0caebf1eac7289b7a42e8f62e5496265c484356f6dca120d5f35b6a0766a6433b2c1b9fba62b708db05d5bc5da6842e225172d8987165fef22ba42fec311453ebbc37e49fab6b039963ff5b76c27eacc37d24232b3fecc5a53c773c876179bfcb863ce07627e63a2ab973afa31a2f30836e5a613b2bd59cd470110c6c94469e9981c6f4f5120403da623ef6d3ca36388577310fd6c8a09d5fd0f5b2bcef42db8c19072ee66d9f38b3211e3c9e55eff2a47dbf6e2d42457ce03696db380a7e633c5d9f3feb0b7b0f3fc322d2e745790ddcddee18d383c39cc48f8b70a45de62fd85da2892e74d83a0018211dddf82e2b531d08c6c78228f92ba8d82a74b42d8ae40d0bc7711679135a7a0ba6b3424231f321f4123a5a939215bcb06ce95090b8e22674e52a2beed71cc256182c48ec079de9f83ca77e01eec1abda93ffac9ea44e72064408da84a33e35709ee99bcf6d9dd5157a880d0844c4d49c1f3939a40387e42813efbc7fc4debdb0a77821395c50ddd645d5cdd994ddc60c091a35b7a9bed921bbb961f6ae0b345b8fa97c9005eb45d9453eb0ea8cda6b42bc69e25a09e5a6150cf9c3c229355e8a75a0fc119fb230e3ad1d94b9858c999638ec97af6dcc731bf5d5fea62ff7f7b57fb85f436c66279bf52967f8e6defd464fae5059351e5efa8f6f74c9fd1bd9bd7fe25a3faea595efed81bd2ff23aeff507f934a4217b731747b8177cfc78ca795622f2b699f1029ff2ed3998bc91fdd77892c5fef748de6907dffa6b6bf234e61b8ca6e0f51c82e7b322bf76560e7e6c951a5e1b47412bf7e75f4779e61ce5fe631ee3b718a1dfd39b1fcde160c346ac89f54d2b8ef825da3c628f4f778c3870755feaeb0114d3dd3635e0833ff5dac4665bc43510165e2f0dc4c974368451d6539be518889900412f4ba12d6c6865c66c973a42a7d406c2b5e2745094ba7497d50f86846822200b84deae62aeed92d5b84a0a9610929b5fce4b555fe8175f5dc32ff38ac3da564f79a7cbfcaf25412baccb2ed41f064abd7269772be2b4db9477dbc469f54cb34742c756c2184e219a849539491cf178ab79c1d2c9b4b8f275bf0a46cc411336d840ea50c78ea845944f858e8a586f1f62d0e8cb489a94a9805c17c3ab149cede69cbde25af6276731c5e39d5d1defeaff39f2229efb0ebff1d55ff6639dd7dd1bb84fa29fa7de0af084dfa99dea42ffcf294e74614eda2b8e7b8e3649f82617f09598c01f38ff3ff651dff6227cebdcefc72a63ee6d44f8eca3edede6f7de6f0f3c9117f6f0044a34a15b1ac46e15731fb454331f131df9e1aadd30857c548b5d4285e2d3782ba6684bb5fbd1b24411026c44a7de36add043d2b73ab3e5c427c1b07499939439f175ac9823d7a13e8eb9ab5aee4233e5ca13ef62177ce6a7aac7c43960c40e1f632f232dabd4a300e35270b4d7e3fd2b2c8e733c622de1bb767f16b28a3df3d2bfc0b4fedb9cd1fdc5f5c70759c34d56fffc14c3ec3a38867bd9c1651279c758c8eff1f7f274316e61ac81074964311ff25e38f93a84799481729d1a68afdbc89258b7096f8dcccee7f381ae130eb6b75ab7131c0ecc8e47a9c16056e67d0ad55a826077dbb78f49a54c49b11e0ff20eab12b02902892192850b5bacaeca83f1a616efe493adae80c742eebf8583b6df3711e5bb797de8cbdc1eed23b34a1d587f2177789dfcf28773d8dbee7bfdc546d9c4dc65d5584b8d834dfb78c07f340e77e770a91cf9ab16fbb60fc450029f8e379c77b7cb429892d02d21fe1072346086fcd4eeaacc505e4cbbdb98661a2eed3e2bb049a739924aa050314627e38a95de9a1ad62aaebc24853e10867a8c4b161147ed12aee2845d558e4ac1459356f4d06b9b39ac3fe4555fe15ef86fef5075aafbd7b2ea45fd5938ea0eb859dc544b37b88a4ef22723ed5fa873dc24559e67d5ecc258c487b2f40e8ef2399ed2273db5c6fc0a3c606f3053f677f29bfdd39ec6ba48ee59e96de6ba7c1415ba45da5865159a074421564125801c82327712156b0be20d4b0a8070d023658d2e27635b0eb95ad65641b45c7095e773edc144e58f91acefd762c023543011eaf98818d266fc5ef775482eaa55fa5ceef76ba0a53dd865956a930837b2a21ff6f4efe5eda9d73cdedfdd93d7d830ef60cebcac9d3cab633c608c47c84cb9b77d8527f04e5ff7a19f46879b530ff4cb79f6ef3d7bd483f72f63e4e7bde2cf7852ea31332cf5124f67f14e9fe9390ed617bebb8243a6ab3a7dc52b71b6567bd96cd22a7b3cf6fb8f8f75f935ee130e545a051faecd534deb1b9dbfb7aff63670bef7a95f7dfeffe378651fdf81e7b8d4afe5e5dfc03653c3a1765967a3bd1df762fc6f619af9618b138d154b47f9a93d3358c94c5c6333a832133974b7b0c75666880e69820595b43288bbb991f54b0ea6c455f3b09236759119971e244a680191710020141a8b97761ba4bae9deea40e7cc1b2593b11f5e570f7d884df5b7b53bffe17853fb3b4b2ddd9fafcf7d25363197c33b3de1ef60787e6a578eae6157bea32b5f61b4fe9e8fd61d6b5f2fe352240ed6301d4f7c62f7a21c873252bb20529bf940774c793ca49e27a0c00420c6a8c4a1dbdc22379f50dd6be4f4be5b2a2fcfea070303fc9068cce175d9d10a291e7911e7288835cfa1101aa1abac7880f5791cf88fb9d9ff187d967db6d7fd91b3e85a3e443679e12fb8071ff362dc115e8ebd65158c964c0c94410be90f23ac219242cbe5aeac11b3aa94da5d1a799d6f3701724c3771ee01b2bb3cd446c3d2c179128ef510325b924ccbecd660457eb7749122ccd751447b52aa3635108e01b27df88fe328ff43b201ccccc0cd91b7e7d25cfd47b8199f603c5e83f7facfe39fe25f4f72067279e8ffc4db446747ccc74beb10d9cf750ae50d75bd41e862710b18cc6c4c7c4047018373d18f59a29a18550053ad018235bf7c8dcd6f0db1c00c6d33ea91ccf6189ea23a8da876c05bb3c743a2f22829e3cee7188780758283ca3784ca08bca0eff0f35cf2311efe6cbb8efe3e56119fe5a1bf78ef3cedc9494e3fe6e138ab31f95b3979c26b3f7b4f03c77ea98b6add46314782c39c86c4b2120075a43c8be80df40d71175315f3aaa58b486e91dddde1ca9b8440614cd9635a8245505bf38c639695a54e07bc60536b4e6db59d03c965f900a44db77cca7cbc1a53ca58e53b6c7dd5da9ea798f709ab6af1f73ccd97f6b5f6821febcc650537ff12d6d5ab314ff1ccc3b9cf6a91a79313d6e5057c1c8478b3ac6f7f2d3930386d6da2d9038d286065364234e890362eee9e62329fe8d32c624d56d156d4de363dc6eddfb113dfadb9b942cfef1fc73fead3088224f2d49c8b3ed5b5e79ec6536dce659c512caf7cc78c041161a6b39b840a24c3d6caa66a9570c5e20aec52d7d6e9506eb3c9c69083141cfedc86a5374b5c8f611bb3c495f9ad212c522b10d7ac13aa89982b140b7f6c31541c1bc8c6830c436db795e525b8edff346ec5d3de7c8e17ea93ab60f03f7fe624ef47db2c7c8a3f5d665b25dc5f23ad11098b47ac2afb65d460ac8988e86dc3cb00f042dd20ed47cfabbc5db01cc50c8f84ddc0a5dde699ae142e517f6ba898afc651caf221d6db5942db8d4fbc3c2b2c13a9bce1361ef9baa6d1327ff4a3abfa7d67f8134fb99cffe05a9cdffb773c7b9fdb57d7c099fd2da7277d70bc375fbf77aa1bb8ccefdac5ab31e21cc49981adc450032dc568e15a0d29cb4edad2210a7ab8b40759b5d0d764876c0602024b5c883a747f6e6f0d51f31a0e81266fe3c8d297245ff8c05e23e787816ba967110bc20a3df242863c2ab57f020be0529ea9434dfd21f6cd36096fbf8629f5f7d827fbcf1cec7dc1bb2639e206bf7def841334fb7a9f256f45ac67c6b2c6bf425b248121ea98594e4cd026b333933863f5f53ecb2f705c3a6343445e1147489dc541bf63874608a4fc538ebfdd95eac89fc77bd2bf920375c411be8cd372e1b05f3e548a5249503956c2b0478b299a6614346c6acd7801d757d4955ae27a5bc9e511d3b41e1d7a45bf21f79fe55c76e7bcd3df5de7e024df417bb049be2ed3479e0662ad7ca0221af9062d50b220b6c180879704ce42db3682ca36f0347f90aaa991621071e02f797bbb849063e2fd92c4f2b8e3b9a90367145a9b04946ba68d0ca989e0d6908cb0bc0d4a61f90ee4a816e21d0ec57f52ff68c941eebed257749578ce69bce3bd211dd58a6876694ff7615f42ad8b39b9074c6f61463cee57de5c44f75b628fef7c261a0ec5a35fb62ee754a3509999064bcef1af34f2724e15cb805873978ec880f334dc8c6e07c6e20ae658df7519cfb7c8815d406110da2646b6247175b039be64cbc90835a2fe421fd064a45de34e3e8d77927336245c98271ec1cb6aa51935d3f27eb470ec4154fe56f0768a0bb8f1276346a7d04b0dd448aa7e2d197e407a3e912ae784e64200518852ea727a6f2290d7923ff48c8e7dec300f51cff52bcd981bcc5872e83315e8a2f2b4c090741935e736f807f186848f7f1de3f2b3ff7347ec773158afc1239755a28cffb53a89fd5887f35009e77b750facf01e524394cb52ac885e1aa81f47316f72aa813819bc3be268eba56d7a82c1925000824236b1fe60c4d5465f56658f8bdcc51a1c255c1669899dcc6e6671699aa442f5923676c27eae178e7997a912c4a071b3d2feea5968f6e74d7ca65ffa2366ccdfafa56ab30a56c73bf5f47fe25fee8bd22649b406f1aab5b0261c0a7ff63c8231577910976043a85767467e8349ee11d7d7521b787cf2a34f07cb5f30369183ba9b8372480761e03adb264409e2c05d0cd82d33641757e590e8781432ab0c86b867f695fb44f46e1b3fe579fb63ddc885b58fbff7edf8cc6352fff13bae187b5643cc617171ad65cd1e0ffe5b0537a9c3be10379a5dc586937cd4660eec63de6d04df1df4ef9bf74e35c0177278f29dc66a95d0e25e27f0619bda78c4150e51d574649a5bb8a43d1d2c0f971da2d3991e70ef57a6753ca078143af821588d0bdf962cd3eed74be29b8c8b694250b9ac1f4644efb064569b56f09668608bed1c07e505b98a97b53e70f3d5bafca73dff5a6fc007feb2a8589f1ae8053ed45b79fcb85f2273a096556c2f0b9bb3f9be53ab240d69cc7ff7361c65f66f7b252ab4ff3d20758f3184afadc9d398275df7c4193d793d87e7df04b50b63bfeff5d23ce7c0fb37f8155fd0fd479cb3b86695f81277faec2adce931176ace3d20aa670cf157f398137aa829ba8ccfdedbf9006dfda99cc73a6e53daaef0debfa5e68832749b1572858120acda003a289811e8dc1ad62e56de160d3fd79cb31cbbf95a0ecc16d37c41edd11a6b811e57cd23e75acf6a16488ae234b2008f441b80fcbc87ecbfe7eeff9673f7e5b371aab5f9ec6c5c0b5feb78364ef53efe8bb3f1348f53dcfec23ca89533869c0cb09c9426080db90e2af52bd5f6be139ca3d5581122781279fa9259510a1f8ca0847849b07dabe75359dd6b41213621cdd6a9b2cac4f11c51aa159db435b3e52436bc32d3c6398bfc1d5eb549508edfc32cfe2c6eb1f7ff4fbd263f8fb9e6cbe24383e00864d5137fc7134ef0a77ef35b9ea1efd9b53a2be421cfd20ca97eb42fb263dcee0ff3d2fa238ec54531588cd8c37641e4635c8e17280ab664321ec2a96839f160cc519528e14ac39bc600358806435ce3900c9ecb8b7c270a38f7195b20f0608653768b887c489460be82374b77d62ded1f6b5c8149628f75ccdb9b4003ed977bb74e1c089f9c13e3108bbac21d72e2bb38adefe1ff2deaf77e19bdc88ea3ce5861ad11c9349f85039e30fbc736268a8a42247840bae03fb6019109ab91c814b250f9304aebd24cabd910149067b5b59674b45e16ea0e13668892826c2a66c8ee8a04aa24d3599d3058c765632f084edeef6bf8ac4fa6eb65088a98a387279c867770a6aeca5df1bdfa02fb1b67f6b877cf585c9fd62c5d018bf2e93773dc882a7e2543c7796827ecf9cb30d1f8d4f29693f134acd06c4967a378c066625833ac294b969d490c7997ea9e46c21f23316929e5ad25a6f7dd5cf76052c92074bd2aae6ccd67622722d423bd89e7463062fc7e4d0b04f954a980f920aee83a51505c95abe19ceb66f85fe1ba79b337efdccbbfe7f9313fd375623f4ff3e9b5dfff27471e9dcb702d66c382e149cc30112ad697d4ebe3c8628ba9da212ee682b7d0afb42da9e52376c60501a2970c3a74b0b7b26248e8f84632ab48cb31f2078c50898c25cc464979bf4ddd1cc684f54135b6056386246c16427c41eedc6bcef8ae0ed8c1bf75faf199e773f236d6f0157beab46f6090ceb8fff45e9e5c79ff22a4a586a75eede3d37be4e7e5fbc970c16be1120acc4524b6c2660e3590f2076bc374f598e80febb09277412d82b4c80d5a2a2d8330a43a3413c75f23170dd8f5077f6020d1bbb5a805a6b4a9c9641cc90acc0814bf1054852cbc010138a514d45fe4c1194414b4b13ede26ba524f39f32fe40fb479717f8df5d6e61c6d53bd6d4478b2759eeee977e775b4831697d9414a406fb670c024d4584494f05809e682378bb466b74ba7531953700e1a221c441793f14270cd9ceba04d0d34f289b78b0d5c2ea6d6e09763d39f5a73a29a9bac1ad784350471904bbae9e7866ac914ae64d5e95fb783721557f051f4c71ee7989b9f61095ccd77481cb68ab9591fd69f833cad0e79b5f7deff563e27d1f251567837bcb68474709b95a32ea3f857567bf11c3c74999a7589968db07bbf167abb0b07e82287c56924e2cc906dacd12e81380a94142c6a365905851ceced92353ba414c0b03410509aacbc85efe0165fc287feb97ff17b1d4efed56fccf537f9877fa78eeeddf9fc0bf86867e31e75e2b3dc1efb0cbe859ba619b77d5be22ad762e37ef0073a48eae519c96d0c671aa9d928a89816d4cd148106133d6f19845e5ae6504cc58a1a5e2c1c059751339565b643e04143900961772481922d59ae21aa6d973cbf59386c1debb3ee82dafc7fd06651755ac1cd9cb35172f0613feeef3eeb6ffb1e075f2374334f27402d1da51df7f0d53cda63cec6bf2c4fa5d82d9a2a271872e6d3f14882c65fda6ac520eeb12bfcb48ab748615b1879126b9b9134f270e136834fd02873ef8da5e3b9a8b01e85ed6d12dbec7155f698028095b715146fc3f287210dfc40b5ae43530f269fc4b5bf728e52070ec9e7fd0ed7c98feb5d9ee9f707bd7a1cf75bf882f582d95de24015d7e580ca31a10636e2023f4a1bb958937968a09c29f48b9278244a6f940258c8086f1017c48f04e0c41e855364502318925298b8c67d62dcaf43e361c70ae82ea6cc423630038e6dc2cb9efe479c93ae8975babf1387e4dfe2327a35e6219eb6493852730e1f33bd6c4fe35cc68f4bc19470f1c0c94fcd77100f61a01df0a24a610a038a58b100ab661edae31a691bc3d781c6a0bca5d56c94b92af07571230aec2d9d0050a329316d302a41c878b6659af748b46e24f43c91763b979107c975b110f2b446cddef65d1ececf73afe97b7c28f9b1ff7af7a64776f66e5e3f89fc56d46c93bab2112e7e981fb03a689b39e3267dee2bf5af848567fff93bfeaed7bd481cb8490e7a4515220487f5ba7bce81cec6af7af52f96fbf77b4a3f5eb74fef93bfaf1bd5d530e702a44e67241c6bc9041cf134236bbbd7634fbda71fccf374df5c769696b56a5342d7326c87c0408419ca5e44701173f68b15c8c6b57808b4b648edb64ca246c4b46192e6d6628a42e2342ba49b4452f9281c3c0d6da9fb4ebebed55a81340f05bc1b98cee60832250601592162fa4f70785c8ccb88b669a58a39f7b69fd705dbe7dce5dfb3175e8e79bcbf74b3897bb04af5713b27c7712eabc1e8c2d0b9df0624d7329819594d470bdef5a9d33264c361a972cde7782501fac594ac25957dcabb1126528b23c9538a27a95d76d4563ee16d1c44f92d7365973872c09cd1d06d7ef983b011456de8489c52f31ce7fd0bfa4e3ae336e17e9be99d12d1cfd735a86f710baa2e972ed2b2d5abdee2fe52db3e3558bf3ff329879fe11eef0e9852578889bf1cf3680f8e4156edef3a906713ed34ce45760a4b2a99672e6b99dead08cfd741256fd8548a44f701673963d340c785d584061d514dc619b156b12103c4f1cd5cbfdf51a7fb852af618d6f0d7b280495cdb7d3a65511c4191d61e8f6b191120d192c6032e02e39fa8f93ef07b5c5e6ffc7a3da3df98831f9fd79f8f281c758b6befe7eff18f67f7fdbfb5fe6404e6856d5e16cb92dbb4d28c65399e86b4b9094a89853d5b4b271fa8037bdf6985a4c85b2aa52f6163a4b6972fa6d24cc231124ea323809b6cea154b2656c47900e9601558590b64339e188c4a7d36600ddb4bc6467e89ddb49457ed937cae1b78eeb3f8f3f97e7d265e63df5da8c377d9e15e8bf73af62b75a4d7f0f95e8e799083cc3dec6b35dfcbcdb1def2cb1c7e7e08264487242e3c91ea1d65ca0a840d7948b158d6cc890dab4aa2ec2ff94bdfc76efbb8f6cbbf4a9ce3d80727ff4738ec60cb9c6a4dcee67358b78be3f9f99aaafb1123304acac611d3dccf347cebd70acf0d193123cf53c3829906278cc058542d5ad8f63a297eae1753761b50b9cbdca04315ea7d261fc420e621f756c819af191128e33b3d28c7bf6e0d06b2c9d80875f65efde1a731afd7b53647ac4574ac77bb54de8febd68321e1a0491df87c5f7c86937a057ce9a79ec636d3559bf02e3fda922ff6f3cdbc4e3cb597d55687e36e3ee418d9de06c1661e30eb5752e491883c2f289b28a0dd3cd161402bd1cb2aaf7091afe7daacf7f5524beba64fa1f7cb5f8deb7480ed82585e5ac847dcff18b88d495c8eb7fea4dd49224259224a880ab106f05763fa4fbf5feaaa94ce17f864af813df37b6d4f3ec1abf53ebda7f5dfc8953e1203ce1051a5a0a85b3014864e37ca08b4e4700fc2cad4909be9a121fcd08011abd41a55636bc19a750a739f94ea2e75618decb85f461ef529e031c3bf8208eaac96a5a858828ccc8829d2c332302497eff6607f76af7ccd9f7ddf177ec23b7d8e75bcf0b1ff36a77a710fc907984f5faac3fdfb1e9f0f30ab8ebec8077f3fd5e75ed6131417cccc2a6fe36b5e1cf2661647d4a4aeb74680eea8f2440c9810f648939a24ac825daa79980e74176808fa5a3b914c311f62414b33c0250a900e79aa99884fef8dd06e69e2604495f0e814d509479b50bf3646eff5700617931738837f9fe7f80fc7197cd24faf71060ff2c54f78c79ff2f25da1c6e4833377e0cadcfb679f3d73b4e72ef6c9a99b3b8c432a5dabe311a2829af3988a3b39a01039de288c9a88e8e68a92fb01015805b5daa443fe2b8c722dd6bdf95cb3b799063802f69a6890cf0d11a5fdc6c88619c8ec31f48935e70cfd8a19baf3a7ef70affd4d5f84c3aa849b6a1eedd7c452598d4ff52acff87967d8806f301b7f3f4bb247f4475ccdfff5fef0cf70fcfe8b89f95f4cccff6262fe1713f3e5effc7730e43ebb97ceb1069becb96ee0d3fbf52a359c2f6474af8f5e8c7fc202bac81fd1ba5b00d798a35142bb4d50488e23e548574dc4506a82fc1c110d0eb2b60dacd8446870c75c7b2b07cf4c29f297b4bd151a0e3243ad82922d588d2d04f229a5acc62c1f85c0daa665b64e2321689d3fccb5cebb6aede6de4eeac1b0e46095eadd706dacfbffbbedbdf37cdbfb7aebe3f8dd993efb568e6dbc4a2a56c80968d21aed0e73e8b5f7e6d39eb0382fabcf2abb52daec2e28ecceafc41dad9999d9d04c273f800f45c84a350939e6948e0963cca534bf090b3c0a145a255130f2a3268c23ef066992264e0bb16a4c9f798560aa674015d44113ac2c2cb5dc0cb8df09ed9b3d89ff697212212d8ebc2fd8533faf92a7f9e0ae1aa4037bf92acef2e7f97ecb3f60f98857a3358d2c3d2b3dcfa7e22ed6335dd86ab7842c10404ea9cb16dc15084fb33ee6308c19c3b2800a4fb19a03682e9c729bd8820a624d1807362aacdd1c400b55de83cfa19e462c608e582435e40c78578df5ffd73f782927e7baedfcb77e8e5586fe9ec7ea8d3ff0a37debab1c64f530d64571421e54bbadd0cd2ad61e0ca2b33ed65a6b41018f39ab998126a12d7eb12230fd1a99246265ac9b98d7429b6bd85838ec2673d05d0855c21d7b1b16a54e865c5f4eda1ab9f73a626a9eb8f99dd4304ba6f110331f5cf75e66c33cc2dbbdac261c34d251fa0b9ed5fe1d3b766ffb15d2d9eb1cb05f97f2439e9bc3bdff324f7d1613fa102ffb2dd753d68322e6dde6c83ff4baaff89d677fdb7b7ff661dec7a03e3eff166bfaf5f33a335fc7bbfef8dd8f71848684cbc7d35a69ef73027d212ef4e7b5f9c259fc7f0a8bfc5bbae9bfd8f9ffc5ceffbf495effeb27fc3feb27ec4ef5c1ff1266e7ab319ff361d9e4587b7aca657fb93ec10f418739c361c48638cafa848f0be6a81527f0368972cc5db64887fb8bf3a1c75ce69b7bbfff5fcc69fe894ff2539cbc2be577de1dffd977db3d6101c4fab8dddb18d2f54f7d575fbe77ba39b31cc21a2c79eb491d6c16361e48c91e7824b771999bc2b0eaf4cb989dff3446320299c3fa984bf595bae5c5756aa25e8e793c3b91a5b20ad6fbfd9893e33897e5d0a44f23ec138ab698aa3972982d0b71870dbc26fa98902818f0a4dd66c4327d1d0f4b1b001e315b5670c12201d83457b8f4007140450babe14cdd84b6df09923f646e3345aa19968e07e854d821871b42c555b1c5f6f2b6d78387dfcf599b445813d1ec437ed6a7becca4824fdc9afd3976fb71fcb866f5efdeb9f79e79c32d7bde7b73f07552c36be71ce7d2b17fd752f4efe44d0edcc7aa3cf74bcebeb315117e48753c7cec378126e5bf732067f5d57b9df01c53880ff59c677fff0377ec71ddfc0fe20a17708c7ea366f595ec9fc7e9dfe397fdbc96a81f1957e223cde3aa53f3fddf2b963f61539fbfaf1dd7f0b258018cab7cbbb0375a52aa5568c3515ab35142e4164dbdbb4c35355e8d13669b45069a5fa832c3d0502ce5ed03b145b7b0d12c8cf06eae0b135539e6354b52f6739b16c8e485e28162ab6c8a6f96ab71cba7f943ca5470555e870a6db38ab632c24d3a01cd332f72f8eed969d22a57fbbbe2357ff299ffdf643aecb30a9ed6ea9413787b5e6bab4f75a432c36fd3c3d93d7092e7592587df18c2ef7dee1c3f6c568fc087fef75b0edffa420edffa9dbcc697ec05b61391970b9d3dbe67eb673aac440856928beaa82b3fe538b90277c31bdcb343cdfeab79b4283cf27c5c62df633de8196b266189d7dce904d2e42aacf32ad3e868ae9b7aa8b70c33dae1c11fc5031c123ad229fba9c744056caa504af3c9c2968f998b0aaa03142ab4c545ee134df5729a0331191bd4c5dba45603b233fdf693daa72be8ad776a79ff9d3ce3532e34d2b18af571f98465703e9fefe41dc1e31ca087b416764284133ade8a55424f226f7b0be436a994b3ace37536e488da601654e886552c108aedb0ddf8521ffb6c6a3dc829dc20a88ca044ab84e4bbb084baa00c0ac75c87ae0a960c07731ddcd04a5cd25ff115cc983f9fff8bedf9c3f9d444f4695d8b76258cfda3ccd55865c60bbbf1f8fad4177ad9b9f3a967c5b5e8096806acd9036778ca0cb84af97d87ecdd8e53d6f93673438ae2b96e4ed24aac8512b769214956e79815d0f30d0b71de90659999cbf087c115ed59a14a664033e39b9eda6363e9742b7faa4a795d6ee3f76da7b75880f55b1bffd8d379b0e5ff77f8a9f6fbb64b0d4fcb0e981bddf6536ca0fecc76fca66e38e10cbafedec7dba4c6ec498edecc47338e78b617e9862eb3912595b759444893743c93159b67fac8081db30895a7cb82eefc087a3147f3a5821bd2ff5813578ee2a15cfbaedd4bad3365816d510b6d31fdb9c5d07af46bab239a378415b6133eaeb92dc345d8dec95a86dfaa9176e030e76213f3ec240bc195fa7b2feda93cda909fe80e7d5e64d7c8e16a471b7a6fbf9e6c57123f1e709c2fcac536aee49a86806a50d9de114dd898e4ad5fcc06e904c0d7a1964c3d959679c16957130dfdc2c60ca495040bc72b430a43ca377a4a475b093c240b6c12e615a1634ea96ecee212c1c4b1b54c1faf68740f964c5eb55633e68d7ed215a3f3dcf801b76e2b0e180966911efc51fca2ff32d8fb55e73562ceb88c23f430aff7f791f9dbee3be47582f7f4d1cb7efed732f8a73aafe858cffffb7bdf624d3fdbabbbd7df7bae9fbedbbb7e8639f3853b521efdcd77ea42e12ff989ce5b4cae8373b9dff3bd9d7af897dc3fa24bb14889c478ea6dd0aa9d070af9528fd7480380f371112ba9536595c4a0badf8fb54c798ad91df0cbd6917a5bc7067e947cd6c511dbe2552b7c2645ac6bbb05459410d9c9880db1e1dd641c5854877e68fbdb70c0ef61917ebffea082839c805270b69b73d6497ee4c07b8e859c9d81131ea88e1e0407f93cc27d1c1df6e6158fd5b9fc7dc42bf7dc777256bb2923af99f3667825dbdfe2c8fa8d0bfc14637f67ac4be2f12a73c62b11796a59b54d7a614de207b27fc0f1f85a5e915e092be1d598fb3bff84a971ca35127a39462ff704aac42f44c41d63f62e81b40bf5c62125c692368e889a2ed4711f44ca11b652b2847612c19e69b941f56e95526f4168be431caefd2ad67c68b50bbba1b856c8af40b7745a1755669d68f99d4f6035d7bb0bee827f0c03eb748fbe53c7c2c136a9bebaaff757da57d6a67ad3bccc19bf9947bbf8065e0c61e8178f9a8269e65d402c253538cbdc871d89f21da742977aa62f7963fad4747d23d7041f77cb22d61014d3b41f87d4918f59616fb126b55b5d15beae6e99dbe085cd800f704988ad511d1aa9122ca512a2bfc754fae3befc17abe4ff35ac92937d7b1e93f995e9e3c779848ac4616d1c022dabe061bf3fc5f63c8f697eaf06fc987b1b623d5729b75be97af9d1de3fe06e7f303fadfb0666d78290fb2d9daa471fe4bfb8937bbc1a75a9dd3d249ac883bd0d02584859fe8be93947b667cd81f7488c78b474459d45b8cb6c182fa8ba430e08699493e51486a9f343932ebc11115cf92eba4b5d0fc4746cfa3afeac16ed6ff6eec27ee2e0bc4fe49feb273ed92c17ed4d1c94cd8a4dd102d9cd03ab59cb6dba137cec33a2ec406f8a98c6a65fb63ea9214da998a665d6654e3c122e634b5bb8d2c0012aa18d2a739dd4991913e4094785d2de0d987886af357642e976e994832cc7ea02dcc1afd409beba775ef95467b9b58f75df1b4ccb7fd1a7b99a5e7955fbf0b93f7f1d4ccc57f5164fbd99cffddb9afe0d7d61c948cc99eb51a1e08253d38b0dbca2059ccf8172199c7568a03a3654415d54237d66c615e60b8a4116b11e395247159c67348f637eaf23f0300a39200848b82c186615ba934e57b1c1eb79c9803002fdbaf9a8b776f55e56e8ff9aac1c7d914f7414f11ffdbfaf65d6e2c83ae0444b07eec4812bd71e2ec5d1f42763e117562081e731dee218e029d54b2da090647d7b175033e1b5eca8dde64964b981c68c6c6aef048428892c2e154a24602cd0cb9dcfca2dd1db4d48a519daad93d8aa48aa7191f4ad1deae644949d85eb6bf79fbff16fff94a7abb0127bfdcd9fb83bfe80abe58cb584cbfd3df094c7dbbd1b5faec4365b011573f4f0fbb9b7fbfae4bb226dbfff73bebfcb5e8cff4ebefe05dfdaff39f2adc57fecb7fc9f3ff55b72f341447bdfede9b9d9393fe43bfd93a7ef0367b12eae1e130e9acc7831f7d53bcffda1cf72ff3ceadf89733d73853fe790bb3f3d279fb845f7cfbd8f01f91136c3cb799fadb974f23e35589d4c9e73d4c3bcb8bf90b3e2e9ecff5cc5957a7cd20517ea0f95555a9be9eae60b7c3057c90d4887f5690886246a4ebae4c56b323bd4e05c161fb0f5cc602d76ba9b25cd79a8e46a316945aa0b81208e7c62f778103bbf14536a330b579b3522aa0e999ac902c521f41e52a236120abce0ed2621f88128a928f50c6a586ae1a0901433b09c5a2131d823a1e37f827b7ff42ff4110e0937cbc39e19de838c2ee529c06ae906ad7cee93fe18ebedac96ea5b76f1ab31f7be8b26a25c9b474fb9859f17c98b1f82ca27721b92580f18ab4509a7b2ec2aaa8f69067e8e6ef5ae20d0fe5bdfe221abc640e85fc022ea47a32bacd1d37887f579e2b83e9ca57e34ba606d6c01f1ed7c10ddc236e3d491435ca135667177abe16dcc4b4d28fab76bd3a49cbd88d77eb43ef1956a885f8d795ca3bd6e7fca799c72ab9771ea49141bb8675ad087b04988cbbcd4410fa9d342bfc215b79b07a43df4a186bd05c5463ad9f431f702ceb35d1a2183d2bc221a3429cb86a46c6a3fb20462a2922e2621351349db823be389af097719593cd1bbf33ac87fcea66cd2ba6cf7fef6273e8671c030fbfb7a032de1a639e75d2f8f79c3e7f1e7247b3c60105eb437cd82d31fbbd010755ab09ebb4d94d9bbdd92a0900e3fcd4c0373544885758893a21cf953f62bb537e6fe8ea03a2c45ed35cc4137cbb29b6195e773232fd880db907955cabbc982e6260d7faca92e7d1fc69de4efdc075fcfeb5fba37dbbd2f7c5e17f8efc495a4f3a37dafbef3788fffe16f27aeebcbea8c55e7172c0eea405f9601486b2b489cce672a7771391ae6ba346931db66746cc75abb20b5a284079aacbcd61fd48c717897508810b450462c459898ce015e2fdd8735af9a32d37d8078662e2375730b54e74fad0b72615fbed3f54b63fee973ef20e8636ed69fd964e84a984ca7bd3bc4f1b30a3e8a639cf09df968e098cfbe08434247eca791440f3a9f321347b32e3664210c81978eb70aa3cc607c33086d6c228e3de1e204b99e2d2be6673cef85dd04b75ad7ccb57c846a6c8683b5c07cb6f64b395d7253051ab84da8ecb212da01408b64c8870b30fdbfe0efab61ce4d9072ef3707d8957a3b1697d7f468a9c18a2f703a74d739ef63109fec8ae3b827feb7cbe23d5150df8f58540266771a012894b6ea6e356de7f7e321d470cf6de4876e6e60077592a1c0af7ccdd73ae54ffded22422aab1a1c94ea463a4db82c8493688d5a16ca9eebf94644cae2104fb0d61912344c0e6a73dd18a4b9cddc573e7cf767acb8f7f9c20e7a3cc25bf9e4bb1f39c30eb2705ae36ff086e1bd5c9ef4cd4776547925cccbe7f10ef290f5e030ff39397eff8518b141ea06062fe114330f633ddef99ad623824c6977c2d7f12c2ee5021b9e9511d585348f182b4d6ee7229dc21b64489156926405baa3848dd288350be7471f7038cab4f16269ab9ba4821581ac619ab7f5e975b1d8e2c8ab5ff5549fc5a2d1feeed344087a114190449e7a553b78de3bd2882a7e59a3738efbc4e15a844065b5b77d81c1fe2ee6d39ff1b9f7df7fc4e1466fe346b5fa9d8b0cff8ce51457c7e7dee8b5677938ca136e3223d81ee2125573162f92aedf1eed2030c486d73c9d2fe1a8414ec6ab841fea42fa24b2b44f3eafedefabccb09abdcd91eae6e6146f2cf7323cd7f7e7ecd5338773f666bdf673ff7c1e1cabccf554ac434df0e0ed79fd1efefade7ffd206e9c394c65e5e7f278c0a18a5091556a77ecb7dfdb96b347d45f584be2a24dc23fabf1b71f7d125ca556f0c0ff71c09ec643eaa8d5110b23b8b4563c4eab7240d49c2faba62691678848989996d34083bdb43b3b8396bee474b454f1d6b7a9862325d22218e834db2203ea349241325513acb73311c91589d88655a61657aa4e39a2c8f04a3e451352fd3025f06eaf907fdcffde4779c8519955c2b3762f5bd2c5cde73d16fb35babf466ee7b0fe697de01e7c1495aae791d58b086b093ff65c1ce5c13cf21656a211074c3fa61d30578f75fd17f7582fa1652c98551365f978404d08bc514a370686b2bfd5583e07e826ab4515baf817ae03406c6f830a582783c78232db627b66261a8a69d5e8b7466e868c7699625a5a4193380c31266e830a213ecd139fc847ec7c3dfeff47ddf6d13a71f420385abfb8d78bc46145d29bbf5e72bd7fb3d74dfb563da48b8074d4e6d39edf7ed4fb6f6b4dbf691b1cfab35cff681b184c4b7837cc89ffe85f6e2fb6a1ddce7d5d316eefd63e600eaa731ff1cd8edaec21047b396883a044fabc6fc344637799d384ccc847cbe9cc08b5360c2ad00624de0544ed843666b204cdc296f3047a88daac4d4a2fa46e33f82a33c800efae6a2fd6475df6fbbebfbf0ad61cfa53ad626d291179f617e665660e7b75cfdd155a7f98dfc4faf13f939fffe72efc391c6b7ec1fe8cdcff8fbbbb3fe0dc1df8c37fb6079bc9ed7ecca6a3f16cea1f6b5cf97ead5e7e9ebef779fdddcfaff69ff79474ec97cf1aef3edb3f3f7ba99d6c660e6d633d57b1bef99ca3e43a31c797631ecec4213774d21573f2f3f2fa60966f0463db7850406a32ce78134990e78ce124e0e08670e4f0828e10c971403c5dd6f71d8b666069ab2289f238643fd70bbb7bc425ae696d6d18f17732f275e9b04e38dd9068a292619b0b82e7685077a9ceae8a4fb6bfdf5297ed6db697182bfdb53056bee34b1ff744a8ec53fc92c3f75fc3873ac885a8d870c4b27bf95adb1d75c545b1154d38de4d18359dac1a4de80aa1c8337cbe0159c966d2f62c52b6ad705999d8d20c4a9627e568e77301973ccf03aa1e327d3c2775a92f49b60ee9c8f4355565b6d02428cd24820dd25bfbd6c88d50cf71a699b7ff09bca2077b97e33cabbd7c191eb086bfd89f7af06dc075f6919571e4f57154b6d2f9f1aa57f583f9b5c7d80cbdcc66aa3058c01c9192edf5fc3c04b33587ea8edb905317479297bbd42d77a4c6db04ee757cb6661ce4a1a32c068251e27adc8fbc7ede8f6748c56bdfc67a78f09d6d930ea5b1a0da2e75a02fd4fd28abb4917f5d5ec526ebc1e1ac09e745cff5effafecbf7fea5aff33157663f2f82bf8f83bd1af3e9dc3edfa5ed699ccb30be57ad92552742d83c52dee6cb22a7b4f4c012626b413c93975e901ab847f47ecdf41c23ddb37d3d4f1837cbe59469581be73e1720d0a5a27a330aa206f9cc6b48c1bc652d7261ab9841a144cd8004cd9456d7b083fd97f506437c1643c043a6b3fe0d37be96194865f58167e70af6f0ec729939c8a73870fe7c92d33af6f3ff7dad14d8db62e2d807bcbfff5fbe3e61dd5c563795d65ecc6b6970d7b3e720d8862a574b2e6f338ea764100bae1e3a328df5d0f546241c2748075e46bc2d75e063aa8d76b8808fc4bd1f5257de9288ea41246f3989cdc4c1cdd2810ea56390023510de40148ea7fe27b5f297d74d79403cddfbabeff02c1dec8bea8803f04e5f84c356927f96539eed6d4ef3efebec8f582f873e88e3b8fb3dd5e7457919174be91b9877bdb09b3caccc202e61703b40981a58c81a26993e1b04471b14c906955e951031091566b1666ea5f1538f0d31644eb64b547e932a8f861afe9586638834580a4d4c58c52c0a0522159a6303cd08bd6e5ff4d18e7be6e9bff44c3659c44e39cc77ea5bdec5a7ba424ee36cdcbd3e678f490481f8dd4b763aa397c536243573c1558f99a567b089a82e6fa481026c60e6d70da700f7e9eac7884c5937d7945ac2a60da7960aa78204241b021d5801610cd9d220c0a34b082d5efb2662d8e276b7c838f3d3fd23e50f204053b1eb72eb1459ad76c75c207c14ceb87db537c7737ba5bcd785b21259651c6135e7e6563aaa4af8a75c79c7b8fc15f478e6e05c3ab44dabb19670d19c702ede7bbf3d72305ca6d739ef4aa41e76b456534ee50455681df2a612a5bca3dab80d61fecbe712094a8d987977cb0223dcb731e16d9b44f9844ff12fc6cd3a2b654c94ba41860c42cd6ba533b6910d1e83caee036e02043c12eab936bf0473f0739959a546ae5e7050bc873d75e28dfe10f3ea1407958374c6fd1396d53bf9ed67bcce2587fdd3b8feea2cdf79f4a5a323f767eac09b65f8f1b3590f8a247c2de7ef3cd3a435d262de6d040fda43ed6c0537a95b3ee756dec3e94a22bfdddf1fbf73467fe85f88549e55a3e7ef3d3dbf3be77d3cf490e7d2d9fb8de0f51da746e00f5846207b8927f61eb697ce5a79e00b7d998ff2dfad1b5e3ab89e732fcf745626cf186aff08c6c1153940944a7590a7ab77cfefffef194fb5d0ba0b6309efea89f39e5cf410f36efd89ee7aa747e55bbaeb74ee7eb44fe31ee2b117f7a563dbd7663ad363cda7ed1d679e235c749352dc118adc8c30ce566340289cf8453684a5f253fa63edeb8d953af7233ec51d7671291d39a505aa962e5e119ba1a54223bff0b070f247eca05b59d35e1258b1fada580c076cce41ba6af31b0f3f783c8b7b1f7010ce704b4ecf67c7e7fff5fe0ed627e1de76f9d4cfbd0a86c1538ffc2186f1f47f125c1eaba4b3dd927974a954c9289aa6857abcd562ed56930fc8551e7631a21ce5618d5a4e3d3b0398e021afe7da5825653b4975ec53e279a12316beee21a4372c035e9c56789bc1c0209a8a998e45c6fd4e544dcb8a77f3fb9fdd5d3bc94df3805df5e66eb8748fd209d8c587fe49b0893fedc9be52afeff9b847bba4dab59903fb4ca7fb7b6f74e999f743e0642a9fcf3558c545d00b17b94b0724b8407552c04d4084298d0fb98f2fcc9758fdf199a03dc8e8e4bab6e6a5f8b9279cc1fdbc7bc1d15ea77f85c3fa0a3da0e7b87ec77378369ff658cff9650cae6ece3cec53d314b565f8ba8952a574a9fc2ed4da5b01981b538c16d32ff1ed02c955f9c9fd353ad82b7f5f1f7018ebb806ac1113edf4bd17e5121da283305bb54eca240c6936923c4f6421a67ee551a131ce5d344b869fa344a346caac4d567a2bcce93a1e50bf88ac5fb1ce387524c86c5591523dc4033697530ac2696c12905ba4f658cc109044a9909bf3f3da80f76bc28ebfe96dadca697d2fb43d0eeb1459f91376ca27dc87d7b02d5e8df97b8f9ef4d109f3efb2bcef9d7040bcb4ed5156e281122932dbe471d992b06a174b850dbf2cd7746051a67b083be654da2aa200e6a98116014791b40508c3b108074893ba6121118f71d5d64904e192df8f04908f4217852c722bd303f390cbb8ff824e28eedb2376b0da88101431470f5fe8971aae7227bf3bf68f766ec4a3435d4674ac7d8a755824ce21b6385c1ab748a7f9ff9fbd776b4fd4d9b6873fd07b0385e4692f1ba5409432147580ba03ca7f2314842851e4d3bf8f87ce4913633a7bed7db12ed6b3a23fdbc23acc9a8731c758071a6b89837cce9a07e4984bc9cd39af050eb4a6409105d0ae0d0343e673d7de1007b3c538d711e87a668800db6d9b39c3322ce194d47215f07c1aec7e6d842d041ae73349154c79a389310e59a5ececdf79388cc451d771b0873b64f2ef6b00f2e684833d8dab1d735eb7f5e28f885df6ccd9760c663d75c51af5d6da3754e7eb25404eb98a23b9957ade659a1c71265789019174cc2577e48ed060b5e00f4656e591efb43aa678b0289b9cb3dc4d4a16213eace3c89a915287a166a2a452cb9fc5c1aa5e44b97ae172fefd8966f22738d8507f59bb636fe3e6ddfbff8c95b839bf045429f63698774d5a5dbbeffdf3d8e15bf7bd6cc4317e5f1f74bbf636f4ed739c6a853772ead4a84df53c4f5d14b112236cb0ed023ee8b4f83d48806d8aaa4b92aa69882b26ac8411a7c39974d48c905c4f6a9c306362c6ba57890aaea60623980483a9365cceede132e65d9cb9d2148c350b8a6da4a0237e360779817fe37f933bf1dd1a9d7332bce1b7ba72f75ec8cb7cebee7dcba975e09c7bad3f71ead1b8edee5d7222aaa4a080e80cfb4ece7cda3ee2d2b469c4a6b86277196dcbac8426aeb0272261614775999213a9a3755ce92352ea936cccf2a4f72a34b68294e453660b9310afcda27c857bf124403b21bddd89e5707d03dfeeff5c5ef9ed79bba42b7dc63ff2b9dffb23ebab523e7c7c59cf8366dc5bfe2df2e71b3d553a4994ba8b7539279abd1591b442d7baf36d7d9041e5c85ad6a8568f0b02e7b84703e9b04d163d0034c63c00bf365459755a4fba99265d396a9bb8474da8f01d2539940451616b1d822897c0e48ceb2e2657b41b7e647dae73befc07f26c4db6d32bc9bbf5c966b5c79c82be4d817a3a6afe5de1e5fa4e5e2e6acc946bfad4a0ab4c433dd5a589c7aa231554898a7b6c0b90d86816836e261c75c7399cb2884d02f2a7a765f71817f2891acc4d2b5c065aeecac27a4876ed8c13392214ae335daab0c74cf00c6016030ee1ff055ebcfdfc1d78a853473d5daa035fe232fdbc4ef49ee3f49fb44bffde5bafb8d09fdf3be1446ec44b2b768768634f0d5c6711d6b1d3a0c4959ee8998e95e03ec05ac61ecc0583d314365cd4b61692dfdd4c5bebd4818f88b1495248be883c4cb4062c2a68505dac43c3ba8f4bb88d2b61fb362b51ada6f16edd891fd6827f6bcb8eb99df9653e8d2be7e8d3fad11937d2440dc0e73eeafff21e7de650ba92dbfda1baf7db315f6b311df98cd037eadd41c440a8e31d7304264acd438eb4584dba70371458c7a14f321d95d28c75ab17bd5cceb957b242d932827a56e05a16220f0d38e10e7c40854ce6b66a692f231c3de894898218782d54b6cb540325971afa592e9f33dfed55edec3fbe6752c32b6791dcc5071ee82bf9c6e54fe843c94d5605ad34bc3c3b60da5ebfd60eda1afe6d3a3393c572d866a56924119ed3eacf2684cc92b6b6612ad82026265343d5782c6c56c896d33609223c2186b7ccfa9c21d0010a7db0706203d3664668bc952ceb42ad19a7636b82fadf9de851820dd64f81ae63c2c00d7dbe5fefc93af477de8c2536b20a6e33f79a2ede4fe58af7fbc4da2e0ee7f8efdf27eec62fe724ec564284e7bcb9439ad7252a1f90aa15b816960fe15c527d26dddf837fcdd3eced8608f52ae19d9a71a8a5406fe2eb7d29ef357bbe97b7d9fb4d077cf52177964b67d826fcd0a3f2c17369479ff0b67d6fc9322f16ec410f2b9388dadeaf3759f0661754ed641ea908399a11446a351ffd3249546eb01d9829306722a29b39c195343c9402a452fa6b47299ce212aed3cab4c9b24d30f457bc6a2c5a303d26f686c278f3c3fdedad8cbcfdff1ee2083dbc600eec277411a3f006fbfca29d7689571ea83aade07ac6d920895e34312ef2737f8ae97ec621e8379ecb8170b236ae602f386eaeea5f9cfb25dfda77efb011fbfdf6ee39fef675ddb4cf02aa990f9836b6e04dc2596c2463ba0daae10319ff3671343159053dc1c5ce2f3b14f0b8271a6b331bad9272d8f83d563c5298531833861f31831a2f1b1a02e4f836dd31dad264d46e320dfb1990f3846be6ff847dbd35465fb8fbbd7bad3f23f821bb9a6b7b9f61b6d3fe8efb2dbd1b62b78211d8042c9f72c8ea80e54f73c6c2a452fa54d3a3c4558cdb792f2bb145402f2453ed9c63c2683bf347c37152e31d8ba41344b93d1f4f362945515c633fd3e4232e552ec69611466823c6f82e53d8c2e77a37b7dc77da8d67ca8c79b74ebeaa47f4efb1d5f3788775e1709d1efab3bf7386b45e02ec261c278bc8d6a93dd9cec73826362388e12dd151181064242ab7525b4584e77a4abc15ad1098f54147c16027b88e7d079bb10e23e4b284db9d4a6a399355067084405ce1352bb72bac148c8dc0f86a8d6971c6f17731effc033d48eae9388f83537ef936ad6f16fdd1165cbacc40ba5ff946122187013ae011ed38eff4b0d23b56e5838cae77b1d6c544410b5158043dc2a2f25c525b0801a1fbb01cc4cbe19d4fc496dbdd13aef38447224a9ca017553ee244d9c4d1c7e8965e947fe35d9abeecfb4fefcd65e078795cb1f50c1cb9d345ede547ddcccfd62f7bf2c9e4c927ffced7f3c1f8fb7be69857e26217735d1df8b38e63de8649ad836ec1876550ffe9184766c25940185a316032e4e441c6732323f20183729796c2f769a7028220e3db55463c9f467f3a54ea1e0572ea8fda3b04f053ca25a06385a5add6226290d9f23ea1c389cfbc228cbe1ed76515eb2457bb8bbe4c692d63eea974347c48b87c481d55276ef082e122efb4d8cfef9fdf710597826f3789c3d699c376b348e4a9a3ca38c29b6ca937c2614f5fc4201bb3c2fe115cd6cb7ae72a752d952d7510f3ae110ed45263d2261cabb4c68da894ca96bfdaaf7d4efbfb7cb79dff0269592fef08433ae25d954432c250440be5d95853f329e89e028d31e1c05818988776531367d265a5cc03221e49e46941a1604aa941c6f64054c3382c159c43f634d3ec4d3216f3b0122e8d7e6f04815364df582bfe700f5c3b9bc14fdc55aff68faa13a76b04c88fba0baf5f93bfe3dde4ff09aaa17b69e480410543aa130ce088f2899e68d8ce34b4c96c5c268cb99901b77184b73e10f7a95d6ad3de9bd0fdf97574c8947c62353329c056d033c834d4515d46cc8db7099f005ff71e69214b667be50d359a679e9b4bb6f7b6fdfbccb1d59df5621ff498f33c75d6af71cc679f496abf95ce7025b8d9bfc35c7f90d7f90e8ef49dedb9585f989cf3427f5b5feacdf8afb47590b638f865da69bcb33d75fd4cab60cbcb12247a130a881fe65099619df554d3979c6b1b19b6f38c8b3e8872984179ef43ab9a47a89b8f866a4e70b470f3fb0c5ab3c55839b4804eeaaab1b4871cdbe63d0dd783b4c6eb8c8a41c2bc626a4cf4ecac0fe9396777b99e707d8f9d7e23daa4ce7077c0c51c62bbe0393e9dbfc1efbeb5ffa7fbff3d87d325acf6e57cc5f2a027753ee7dfea2d3b61b577dae6b4d7dbd3f79fdbe9e3bc7c56f3d392b0ade6bcdb86a559482dd624947c3e1ade670a5369c79dd09b660ae201aee17a416179e08ee25d81957428938ebf6ce74243130af2c74443cba9a69ca0ecba39f7745e4be8477991e89021d752d460ef7914afd88d2fdce9c7dff86eaf3fd70276e7fd21a7bd14a1e2c057ffdcc374aa41b8bf5fe72cde738a9fd6ed2f6716ee0f7bc919ee5ef2c3fe1b3bf2c6871cfd7e8f4d38f5b6747bdfa14881b9bf77dec74d97f7543830cf75abbfbda7de9f8b93aff8f6b966e4704efaf33ae4d5bb098b1232e9042b598a3288b043391acf6d345e30a5f95c0866e424a3b0097bafa05a0016251ecded411f1b568fa96749e50db2b1ba239aac51996da8964f42a52c36fe3398017837d3948e6d691117cd59e5b96777d3e77ee3cbdc1db4e32ec5c57fef9703eebf4d2bd89ee285eed44bf69d357fdafbe15f5cefeee7d7db7c1517bc3ccf8167ebe675b6db6cac46ac2acd84232c2bc67d9d790bfed053aa506c585496885db5eb9fdadc3ccf767a953af0427fcf4779e2f7b5c0efced9cbd8477fed59bff5634dac4fecaf1fea9a801ef335e4f2da6b42255b519aaea8ba4d38fe63a450e8b2f87d750fbf9e9fff177ea55fe5aa5fa21f397a7ec62fb941ebf734eeedfe09e50d4f6a59725b6968fc7b40a86a82088ef9186f186d7ba1d31d8ea0858da6f795b54d80a6c50c8ab86adaa9de40a6b182f5988852cc993bd124d5e7bcd273df612672623d75a49f55edc87760ec438852e37d3cfa53fec9dbfdfd4a8fe853dbf219662d70d8894b6ea88e3c657877b5be72e817fa893cc4a5b10f78a5e3fbae579cb88e6ee307250c201ddb98a86d0ac583ac732c98f4b98da92c05084baf0cc7628b2354a6d5761f779541646969c41ccc2c25a0ade1c8eb50e4f5d845f114e820a01af089e525b69993de8b108b3b610fefd312cf164efb75fee74fef102f4feaf8453f8a4c2ed4508edc016ff843cfb463589fb99e7aee83dd9d61c9f763d5a973c0643eeb927fd4db2ac07ebde86b2c2538d770d10fe775c6c53eee7d78d99f176298aa39f4aaa67cfb529b21ef7b3ef69fd39bb4526d1ce1bf78df137e23f808bf71d4a6dbfb295cdfc784fde4ad86ecb7e3b7cbfc1017eda376debff2fd33721a776f134f1c189af6411fcb553b289c2194008394e020006c86ec754f159cfbaa19fba52718f5f2852bfd8079e38c352de18d868bfd9982535f794bdfcdb7acea3658794f8136b4a5011f33573e057c98a73dde0adecde7ceb6a76553ca02d5f42cf7fa537650effff271f8e160775b5c26d729f0f2d4fd520cde1d63a79ff2119ec7deafe7f3f99bed6d5671319f73754d0325bdc060778b1203ec0c2788e07968b7e30c303be6a695d8b40f00b3f7e3637bab13160062eb31771e764c434f62ac58d07bfda2c22b64c38838e25138721e94282690e5a9ca456c58a3a06cefa92e5d7986d7fea135ad5f73999dcefa683078c3eff6fe3ebbe0d3a45fcbadec2e6a647df38ca6c77c4a9bedb4d3f7debe8e992657d4fdb3625583a4a35ba8d463bf909b806027280524b61873f5a0d11ec719672ed1f3b12ce28184c12aa926bdacd61b5aab3cd465e0438b86868aa4a3fb54d3b6f1b2cd056414476299f530c01c4efc332cd48dbef6b3e6e151873b06c336e5ec497eed5c5dd6f4fe476cda49b7b44881de0a6e6ad9ee354eedec393fae5f5df52f44451d7f450bdc24aeece858cc67007ab2f02a9f4b148ef335d185c67438490d3846ae9aa16a4830143c05484f29ec4589baa46ae3b4860da7fa434a7583ee862da6b99f8d25173c5fcb31ead2b15863aede63679fefad33dee02ff97c22cf0cdc88ba3ceacd3ff7815dad49fc54ffdfef83debba3aa4538dcfb3c2f3d6a47bcc3fbf7da637c7b5bad4118624c7436cf60de33c3f328411672601c689d271c6f4dc696865d5bf34bcf9df55e2c7bb959385e938ed5834fa09e1a59e7bb8d467bcf9554e48bd21c89aa5966354a1037d7536006e9983d62881e9382517adecbf2695e7b3ff72f58d3fd1df0b99ecbeb7513d5702701dc09875deba7bda083ffcf6b56a58667c491570a7ec805bd7e7dea2fbeb12e540defa7bd88f0d8ca69fd30886b5987ea619039ed6ae1341d02bf36a8ffb38b75bb4b8a5243348f446f6d62d520a1a95c4015f9baa564ff7b15f3c12ae9212663e951d84c0841655cb00817e29e8ec500b9aa3d71597d3ac799eb6d166ed9c61c97d7b03f177209df8c893e1a7f6fcbac5d6ae4e68cc352b8936f696d4bb734243099180d5dc15017ea78ec97cd6651a3358a7237aecc01e326c4a5bf2560b09b194d2097bf0649949b12a82de53ae7b5d49921e61898a314282d2c3c23897283d570236a19939ae573e7017012ef5278567fbb52ebf9788fbfe27c7c8f2bdb1ee7c87ccc3ee69abab0d6076cca3ae1938da8fda70ca03cadaee3bc8e71d2bff3427e3cfe3e0616fdac4645cccd32d9dbbfe398b769a5f6a8f60d0b85d5ba8fab4c4f55be24a35fab402f41483c1596f88e97f0292181491d314dcbad2e2af94021ae856e81a00a36992de614c86906b02574b9952e7324915d160e21adc53da7629db8a227108fc31bb8a1aed4e10ff89603a7ff711eb4f884ff3baeeb59fcb7937c70e0ad38722b6d5f72f4e1c0fc149ff4e15857b4f7deeb937e271ed02e8e7db0a7d9ceeca503b5830edf68a0dda87f25523b9f06c42a5237d84d755123e015b161af98db84c26e802c6c33ee3d8fd470440db4215ab7f579a390913f4a776284c5044c7519d322db118a4aa9a89911d831b7f19886abc4d6aba98643a9e034ecf1e7f98f0b3889039e86774dbc3cfc56e30bbc46074cf90fe8c55d1cfbc0c558fb4f12c075b2d34e63dd840d1b04b5b789231f488535d6633764390d686ea71aedfd2a7f22858750a45642435ba6c9a564f984125b9725435934d9f9863542bd50334d26b1ae7a5ea249403b8088b5924eb0432e7cc0919a658530821a6f6ed0a5be62733fb183a758e93c0f75b0d3dd8b5d8eaf7138fece807a12eee19cec12f7d87f7765cdb73f868171519356f8b05fb22ad7b343dfdda9b78efcfe069e423349c9e89cd85b6c9b79c8ac27a1ab27627781e0d98a00799745a899470c214727713564282a4136ce09a2f88e30cc7184a6bcf67209ca55500d6da2180f2a7b879d7c9a3128181580505c099d6e51e1f957f0b4e7f79b8bee520e77b1d1e4c96e78381bb3e8a067f9353fff07ce5a66346d1c79c5a282ab19d8dbc4dfad74547bf2f3df3cd3a9aeb4bb91d7de0b0a2f8eeb66c2ec014838f3924a7884c566e2743c0622606402b2de03311782e9b0e0651e713bbf5f382aa7aa1198e2198e64998eeddd9c35a6e8e9760ac486b3789794a896aed751cd06193575a2d0e77da95fcff596820b952d0f58f52205e693e0474cecb39f137e7e9e8ebcd2fee614f7f631c855caedeb58a5d1c0f881bbebc0c99ded86c79c6b848ac4616d1ceecfd431d6ce007a105ccf4f3a9cc66d1a5f68c03481598d54506980f4ca8debac0b995ccedd0920baaf11901339460f14367ea2092bb3bb4742728a591e12cdd329957e40ffec12e2d5bcb60aee603f28d52e83b9ce6cfc108e258f2bad4b58de9252deda6ffc3cffcfd8d0cf7c46429ffcf75ae1ff36ef47fdb49d761a5feb50783b77cb7c345ca6554378190c906aaaccf67aec74e390b7736e2b9086ed03aa6533e7991146d09f82b6c5558ba7ba0492a06956c15e681d4c1dd150476ed23ee7735770519930211666caeffc4a2ed371a925632532fd83b8cb3d72a2ffd521bf8ad727ef392dbf679ffeaea174e0f6c88b7318ffc0c57a88af6eaa3b597ceea0596ac89170511310f514d7b925fa4cf77bd8e3c22b04b4125229960259885231c1989b86ed52f0860525ddc4b568e2faa1cfca3f3daa14a663b5a4bcb99f19e87e510a8391d298196c8cb83e5ef0e14fd9a2f3bd3c9a3c5ef19b8ffbf059dfec7d2d2f6833a7d30538e382bfd443fd4377fc5b5e7d119df4a7fed61347fa3675599df0c1feee397bced9de07b89c87ff0cbbd2c525aa13dd4248c3117391a0543e2ec62a642ec3d8404612b64b1c05db24421db63d95eeda71a8c7db39a1fda2869e0ff1166928419a68e65c6d85262c54e9058da0836cf39e95a64177c3caaf276001d1c38ff97d1fcfd72073d82e39d6d0f274a4bfe8415d5eaf577be8afce81fe777e3719409bfd994a397c8ab93c61343ffc9e375cef474ee4330edf4a72b3908eda1cfac3224f8991be4c1d58243b5dcb2aa6dedda3efb96f37c281fddf9ae27e8c035ef4fde7ea636f6ff68cf9bac0bdf88af7f634a671a8cfbdaf2dd4cf1a57af6a9ed97f6b92ffad493effdb2fe044bb9fc389ea079ed634f24fb9a56fe04323e426ba3598eae29144b80d88407c3c3152cdd670e93998764ea0370982bec65da8b0368c0323067317d3296896be215633dd3363da46746c05cc6e4d66e09640847c67b28a3966cc6620aefd8eda2c0fc7de7b4da98fe3a037f7d607f9bfefd8bf2b7a313fa2ffa57d7cb72e5c4b65953ad4b762be6d5fe9e67df4dfdabfcf75630ec96030d8b1d2b443ed4f978cf390d74811fa470b001241fd00528801ad86f7c4c6ba8ce09cab66c39c1c883287893d6cb8b2700086c6b467301da340ba6a1016b0c1ee0430962752571a26c8e40a3e260efaba5ed8177d99f3b8e8d4c7331a9c69c27eb8170c54a486a5665ccfd30ad67ffb892faef5a7df737cffd97f2ddef78b7cea539dbd2f9ff13d1fdea32ffecdf1fe3dfd7e7af10e7b7ecee8a8bdf8214fdf8771d0857bffc023fc15ad85ff61ffcf38f28c9e6a28a7bfb5bfe3de5653741e3a5eaa87598f7108180cb46ee957f186f226949ade621bee624316be929b4cc98056dd680ed99cc166cd099c6510f30c783102b4e7aa293327af689dede61c52ac18213573832237e6ec8f9ee9be89ceb084dfcea97fb4b7fa180cb722d4db989bb938add7b7f7e8377dc4b3f70dbc139c7e7ad65efc9f674ef60f75a76fd2183abbdf2fc49fe73a0ddf8d414fe3fe6a9f7581c8f1fbbf81a32f538d19c2152d82d658d0b516f628a474b0e3a5bf0b946241050752eb2c5aa28e573a4a6aecccf77b9b3eec6835d92e5c8ba7ced0a19539261a3632de6c2530ad14c00d722d95da83413a46615861e003199ee5243fdfa35fb0dfc7df989eb8f6fffa3cffc500fd9fc0007def1eb814fffdeffa5167366fef0b9f3fe7f7ee8879d8469c362e764c3de8159750f919f51e621de984c852924c17b51ad3ddd0cc6c7f10f7ac463a2a652fb758db6aa4c434aed8c4ef73152aab5a94ca14369af0126f08908fa9331c500d5afe6eada5a3e15df67375d7ff19db5ea93e39f63faf44a4defb40dfda53271fef7a9ef0ec0efb973ce187cff1acd19bedbeb767a4d3268c7a358670265c51657deea3b1f4e3080e52d0ccb04d5729552ca5c33be13e18d9b2d5a73ad591b3edb18657ccb560acec2eac7ff7b1667619856c1e09c4281a0504564984fb90e72d32d4dc77c5607ecef971ad2ffa76dff47ff78c7ff05ce7fa9be2d0e3c7d437f37faba0c48db4b79bb82e37a1bd36449f8f39ed28027096d9d048e164209c619f38225a1479897af83827f209f196c5841531cd23a9ca2dadf7169ae569b9dde0088ec26a68918a8139cc8b19d0312a3b5feab97b032ff7f7f27fff16ab8024428d3cf48fb56a71bac76ff2e1de7fe6a067e53debbefa9775bd9a6ca71f30d56f7ab6cf727a48a59178dd27de9fe754bc670dfa57fd03c6275ad35fe0c97ae9dbb896e741a3c3783f94e739d79a3c7dffedf91e8e373892a5ac348dda48853d9ef9ba8749e12541ef8d3863a338ca0d62c33030609252fd51daf1607f4ec2c20be3c21a6450ac534d846989eeb12bbba4b68cb4849b98ffd23287ad4991af7ddd9b0a37ee85eefd4ff503bfd29e3cf880b7f466b6977380173042e1194fd977ef9ff68855d0fb031ee8628dfcaa9dea316883c5a8e549a96b29b501617f76080c2d648b112e998f4b94f0021304f34e5079cf6d0450916b6cd43ec60502c96e182e389c31fdf796423c5b30a9a5b4238458cb2980256318cacaeb7d66c198fed99dd5293ebc67dedeff37d69b2ed89bff659fe09dbf73e0e67fffdeb7ee1a4d4b8d3f5d069a166bb9b7701a886def8950a4314d3889cd76dcc5b3804018f7561fd496be28ac2ae3714f476ded6b8d830d45176ebec4c56f10d7caf06d1166baf594565e87c6b8088102e158ceb2dedef8ae0f7e8cc3e35fee9aeab97e77f16e79e6f1f894870c2ee3da3b3dfb2775faf0acdef44dbe0d6fffefc0915ffff4f711df725b2f23379f04293721577806f2bb90e702d556891d7319d4f80e69f8717f1633556e7df87bb3a8454081a667f6d049c0162c5ce666a57ce2ce60c36a4c496956a4c696500fe6ac87a174d84362a03b465417ebb84988752b962f8f0fbd20b090237d9d02595fd057bcac93fdef1a4f17c73ecdf9fef3797ce0511ed607dedddd4977e5260d286d17544dc8603360d00289c3ee652997418dd658214174b6ca962d4994a51160ee08fcddfb205eb15245c46dd442c12daf50c7aacc482abb27635c062a6f1775534b3d58c5e4f76ece9b7031664100ca3eac59f301e75b1e83e1ee4c17e5bdefb0fb99dedc98a34d561deae4a77135e3d0a3769b7ed6138dd4d6777e7533a0cf85e351d2c380f462153aad410daf15fac396b0609394689cd9662381c792526e6839d084d38d12174ea533c492a2274c87b3452529ab65edc3264a28dad0a804d4c891e01e66d59fc115dff8ac0674fa9d6d52a32fe86ffc882ed9693ef5c7ccf8f36a7e0fafdb2386e736beb5b0b702e9681b3496f7211098d6d69c126f3a03438f2c7ff594a926ec8523f56c2568b30c69f790013c48c65ec4ecae4c47ebde777e0d622a4be6782da2cd5254628b4b6189ddb09e1a4de353ba4a6a31dd8f9956dfcf495f88f14f3dcf9fddd9a75ee87fc723eec77aee2f42cb43cf33b8cd1e3ff442095f1882a63ddd21009f164c996139741954d3b8cc56b2329f28530013ab455c6f13e077cc5eafd23ab732d75a055a8742baddc6ec41138eb766259aa79a248993b753d0de61821316a955500d91e8f1996ec2a7feed01971bb4c2612adbfb2411cbd397dee98b588af8a09171c2ec19388fabee85f706a86af1b9aef13bfc9fbeb7c787f57bd6c53ce70bf873d4db2df771ca4becb77c5d37bf78871fb8e60fdc5fe00b7c973f915f006fc67ce1cde2709d70f9f42ded0dd66c03d0f1d0803129508835af0d815a0a47448b1a8e39c1ebb46aa0e4c3f942519d8dad0da6622baa60b328581796398f234f4f0caf1176a02535f349ef39dcd61ba933bc7027263320960e1431c963aad44fd5563fd057f23fd757fa0697fe1762e40b5c05ffb6c6fbff2e8e3aa86f3592c851eff7f6984bebe2c852d411312190111d75b2b73673aa1a5cc28d54e26e4e359df6d016bbb5c65ccf96402011498ceadf9bacd291e46c890c1cf1aac17ee40d90dd6d16045a59e9d5020c3b6c585516c13224789702f39c73ef5acc75c609f3a9fec9659f79f7836b613cf36d9db46e9e7b785fbda7f51fe8435ebd2b6505abd88841081acecb9608e3618baa219a697f00d6f0282ba1b62872209c1cc7bc75935278b23477a16d83054193408bbb40534fc42d579476dddcc1345416f6f964156a9865143bb18157027a111a63e59f71935e397fd763a9bf31d199b6d4117b7621e775b2475fd247b968e35fed8dd7ba23478dfdb79ac76f6cf7277bec23fd928bb69ceeef86f7b9c3effa006fb45e0e759f37cfa3e9474d9fdbf716765998f5b00e8137ca2284424d25a9eb55a2966bc9b301a1f92a06e636a97d9d29ab25631804fccf2aa576ef43bac5106fa4236c5e58a5af18cbf47c4b1d3d48a98ec24244a8cf7ac2a1e56b0fabd4f11a7656f7f9a9bdf5c61ebed53cff1cd7f6592de7746f1eb9c5be80a5faa138fcc07b79e490aa5ff15e3e3f8776e2d0b929ae99a6fa9f6d1c596e5ce639a3cd88545bb0a0f12a1b8b694085e0450cd072f890d8c80db5812ec70ae3aa59860ace18a31bd1e788549e831d0f88daab433d0721813883cd3685d67d5a4b2fed4b33857f360185eded71cd6b4dbfff4ceff2db317fb5efeed55bfb95bb199198b0dc5850e5b2315a63e059a12ef33999ec820af67eef25a2bfa43b7d1ad7c066ea9cf91b97b1b13fa6abf89763f2d5ef3f3dc709d771ab4edb3228d42ed01a8b8de12eae9a869578e95779176a624294f2178ed4923e9f33e60d78813c5e4bdbd762406a3c88559e508a9e52851a9f76abc5a8f5b0337c10d05ae3faf7ce2f3c8395d00f79ae78d960aab11be38d8f38530f39b9ee9a3fbfe07a2e1d744d67ed025fc877d7e82f9fd4717dfe8e7ff0e36fcecde9683ea63bbfb67a5aa26ea1e2152abb8714e8318a649d8d273a67a289abe6610ee5a35f200f312f48746b9b41c42968cc500b7601f1daa06c5aa6c97caab57304e21d1e0b9f547fcca46a47016026715a6d51355fd7d0fbdc8fdffb5a87986651d13673a0967cae8fb64d0e9c5a508bc19fd7eb7b45fb01ee62909bff217e8a3cabd0c341d3081cc73de45b6f88cdfc505bc5a01991025684e6a520f91c45de44446a904456116af21153fb626e2eabdee3f02fd41dc21fd0dd027077c48aedffff7477dda437a4e973e89b94e20ef756bc184f0c1ec9801a8129ca669044e291f3ade6f79e080c59615baff8726df8ccb332c676bc6215d2ba5da8c3c4d7ba09b18746a0fb1a2ebb79505b6b3aa6bdaf3783f9b8d42960f78196839befaec8ab8fd8d16b7d6087f5ed7e66efc893f6fc696e4f38d1d31eea6ec4046c10f3360b223452661ad5b61b5c0e578106e748797749a5f2446f885fb09040e5641542d2c5d38c7ba518e72366784f41d856d878d0115073c4aca53f165b597aaeacb6bad0ed6d5004036137eb0c74b1ac86f4a7ea349961ed0ebf6ba9ffe5d2f8ff8ef5f6c9a75c1a273da75672f3e4575ce14ff8090d6c00775905cd59c49ef6df7dc8fbbf7d8e536fc36d589cd096e6c219de33a8d88222846aa4314e01a64d9d568186f950490d7ac8689070444776ed0a83e629854d1b94f86e06508822ab9abb934dac4f3466d8c077913f337e6f43de1689621033cba03d7271ed798b2bfa1517eceaa1b6918ebee8dffd9006647cc8099efaadfe6a47bf7fefc85771633eecc190b66ef891d218cc35c49b8e70744f47ed3d8db062047249cdd99c955bbf667a58e3192590c822361395e3506b6bc45113979d81b56623fbdc5ca826980266c5bd3dc05cf7b16ee5e9d85a66631f64b5b8b9c69519ea29066d23afcdf5e88c2ff0bb736da6155a25473e9057e36bdb0fb8023fe45d5e8ca9c1abb89f8f2d138df35d0a3c933badbf28719200ecd31ead2ef5e4c611dea45c15b308ad0567dbffd43d7ed2d96b33d02911fd3efcfe77ef7d8b632ad1ccfba4c45dc0ff1899fb67cba19c87e15aa3dcbb4b810a67c0a489965b4c337531f6745999d32c62b61f0e0788db06663021b4a1be0d8b450d673e844fa8901b1e0e298376471c8f85003ef2dadafa5a694a78b9d7398e98961e3836cccdd57adee8a043fb03fbe9f598873b4e97ceb088b9f9b4b793a7716e9acf0cca09a6de3419ab65a24385612e9202cec9d81b054a290e714e9c76492b65fa9a992043cc69019719918019f9848ef3700ad438a5d80c4aa449fe67476d7d9a30b9c6a06b123dcffde8f79640c6384154b837f2abbdd1fab8dcbb1983ae9945c79a87bf7bae57e817ea1545ea0c9fc44b2de4422fde336ffb337ff54b1fea259e5eb44b0dd4cff8dedf883fd54214d57097867a1947387fe9cda117bef3c0117db4173bfd2105c3d533275678d1b77f10eea44d1cd54b675867156c67bce95f3ff739f74b5e664bfd617f27a740ee62aeb599c3763138681bad45e4b729f01edff510bdff8e0317c8df1ea157636e0fbfeb7d9ebdcacd634fde9bf8f2ac8feb2f767b1659f94b7de2b2ce4bcad553c2f526335e743e2ee41997fbf39156eca0239f1958a5cbe7f9bc544fdb6615d3a45bb671ad34f18c51b9c0ffb03fcbaeb71186a732c3fff47765153bdc9f592d5eea79e145bee69d78c5f1f2e1fcd787cffcade7bc704eff5b1da7481cb84ebe848fbb781ebf7b679cc6dddbb593fec98775b9abf19186c7688494acd018ce88ae425ce17e51e97646f531366c9da97823a96e05c5c4f0b5c6238e7e3fedd163c0bb8739fca365146bc2c575a04f7a51e75a5c7690440d598c273bcaf1435ae222ac85eed7b4134a181fd46cbe9ea77d95e77ae6043fe7e73fd6efce78f55ff492aee6f13fc3e75510c84a6daef808c621b7fe03757c598b263dc6c187710f1c33cb9bb98322bf4428007a1253d4061aea430ea731ed660b1bde51573a7e2f2bee945da8c901298740707c9f39acc9b4ae4ca33c492b6f8d81df27ae3561ba7a4ae1ef55a80dd902367d1c350f688c226e9b13a1e7dbb8866775d8cf736b2ff9938fb90fdff3c15ffacc05aeae335c34d445c4d48ceb4d6c781be9c03ed9bdb63393ff629fff2f609fffdb3bf77fa977eecb5c037105d731370bc183f6258f7a35b7f50339122f4f1df8140356cefee6baf771fbf9f3dc1a537533ae960c7a6d1ca11d02ed93a062852a39438e794fabb25bb8c12eee6f8ab3977184142a82132ee8f3f9413fa1670bbc3c0314a0d17e3feeef93d7afb5eee863dfa6e71e1a56ce7937498b5c4310f1b81c4e02a35cc5055d855a5b4b35d164edf5789c83b816bbb85238acad1e0131c310af92aab5b3ba0449556e33c5a649e96f13a359928a05c495770bd71e2491daa67dd0659c451fe045f7cf986775d98ae8a04b7d98bb6b75d70b1a20df8b372bf514479e39e36c201df674b01dc7faeb07cf753afbb7e1e13bce1f06c958e1a90e6d5c306751e528db0d8b79b8068c9b5a5c063ae16d289467c4dc1f60670853a212a1d8881752e305d539472e2be11de6548b55de0b082798af5759af088a644fb4960bd8ec646f69b77230c6d57020ae6a3307e771c7f7f6f266e1b0631ef438ee81fbe3668e033ad1240b4c5aca3bd17b1be15a9016f12e2e3d836a1d609cb9c1ae8d62e53d26b5327195bb99d63ec57d6e64a361eb8fda071a21c422c10441135fc55b3c6640f6d65350e17b9fe7e3b01a2669cfda10303dbcd28b7883bff40e1ff859dc0f5bc1bb626f6f26afb5f9ce63f4671dc7577a4bef3fb34e427d991ab97ac53fbdbb109b7d809f0bcef3e1fb3bd761fb98bf4fa246bdc472177cfb4fb433de8d6f241cabec8089572fb98cf7beffcdfedd7bbcc85734c42ecce3ff10ee007d74af5df5f93c812af18888b867ccde26907621681c52622c69e388a8e942807741a41c612b254b682711dc312d3728e89629f5e684e65bc4e1caaf62cd87563bb71b8a6b85fc4aef164eeba2caac132dbff709ac66a0bb59e7e17dfee9bff1f78fc5dfffae0579a6f9fbe1593f7de787baa1c6e9dcdfd2a7a8523e7cfc100374714ffcf9c93df16efc83aedb1bcce28cfcf9e61ed111058d58542822e5d0f21d660434df2e0a0b2d5c4be07abfa6c24ceab22365d62f5cac5203dea122d058893633dd0b0430777e3874b111ac12eef7096de842d9031cd19e3918f9049338924f4cb1166bf4bc867d618f7c16572591df8a9aad53f788abddafaf70689b39c326addff3cd5fb49997ef9e6fdacc2bcfb3f7d3aee045b5d3f3dc1eab2d6ad5a684ae64d8f681810833943d8fe03ce6ec9115c8c6b57808b4b648edb64ca246c4b46192e6d67c8c42e2344b044c22a97c120e1e87b604be93afa65a2b90e6a180773d036c862053a217901522a6fc47b48e5ee18fbfc811f4c398d5577ec35123f3ed7b1ffb7ad7eeb9a8618b824df1a8d584013549f123e1b911f24c97547056a052ba3099470a875597b04a74c82eb77e389c2166e549c158e83c18ac563b4a87535937b9d4114fed764b8067658e57e1b105c5589861e5af7c7e8631bb74cf7da7affbdce68dbcc57cf431a6f9fab9fcd0877cbd37b6337ef0393ec8a39f6cc297f4b4fe7ecf557b007ed21ebcc540bfd6cd3afa5268f94d1f8a425d962dcd14ae2835052955211d2ff4e97ac3a9a4b4b00d4484bbe028c84066c4855a0a189bd8659d8c269a306210d3b60b619e27e3d8e045eea5cc3798c6ee10833cd6865aea88c8afbd0447ac9663f1158ec8efecadb31e9563ccf06ffaab71ede531a0fb58781b9f62e12f71f3931fc0465f18fb103b5e7affd4bb7c632ea4090c1684367684e14df8584efc5ac030fca52f5cebce1fcb3baae5237f6cd1cc6575c6f3964798a754bf4705ede68e3e96cc43a93614b8ea4a4cbdb5ef64dd7c2c75510def8403274297b358574e5cc45d4665f353dc2897f3751fd76763307c8a01d4665ccfb3d15fed8aab1cfecbac82c5751ea383fdd9fd407e60177374c226fffdfb748fdfa475a22fe72e6ba7dab6a375837c5ddad46840e2684068eace8f54c51c6f24c74230a72b306d2d59a336a328e1a530d058dca1620252281ee7fca15b5016b0deefc3319b4c4137a2919510f6bb4bfa7c3dedb341e8d8db9f5a5751a9753ad2773137eb57fab8db77dc2e17ce29ab44c576332e7629d0aee76e7f2637a98beaa0115165d5b03d9ecd37cf71d2c5bbad5f983058709bb1b8443369b30d02de4346598f0a0a7c3b37c518c7311f025e75f733b03659811e1225185e0eefa49e19a1e67101d10c39d293a3e172514b32a7fa9216ac4bc164850bf62823946460b2e50ccefcf246aea90ae531c855ccbdb5d8dfe511d44574d4c6f8c42e821fd2262c628e1e0487cb74ef071cee05d6cb43fc72f9b96624fea03ff0b37b71f8e8036461dd1a677498f0b10c1745ac316e9a7e2945c09a79ea284c0d58c5150bb24a5a944023d4609340d5063a7bca2a389276a38500b9b4c08345210dbc6cfd546bc65303f5583540166c24b4d80cb9fc29ecf80907b3fffd689b02f3a5cff784137daf332da2a03df279c2f6e5debc90c73a614262008b643ff780edfd112de1a8ffbcbed9aa45147f9aef4b9da12122ef90efbbc81df2fef3d5709772b84ea246cd22b64b47aff9e82f612e4e73c1bb2601f4f55db1fb073cc5d9dc5dad9f8697f28edfd62b5672a41f78d362ae1d348b5f3fcf8c1cfbf2be11bf3f0565bcc205dc05ace1814137d958ee92baa983b0157181d742a938abad35023660953ecd141dc8fd3e26701c1a2298e9d0a0b699848e799fba72c99c56a00a03690b6f510a440d85b9e3f9a98e3185def9fd71c10e7d27c793b9accddef54edc546fbdb82fbf527ffd39dfffc233ecd77a9d1a526515ca3340db043033fbcb9ff29dbe5b17ceb9eb11d4e71b428710f5684ea27c866c8608843de5438381789094ed26d5fe98a29703ea40405560f86311a2ca5b51fa00302c77cca1068dd82a664d2f79378889bf95ba6dc4d57a9b399ac61d3549e9177a23bfdebb58c4bc5b67e02f9eeb8aaff623d87694a74ed727113ef96baf5f7fd8fffcd9990be6b6f718442896aa21535d781832cf27f021b411c6516c20a8282aa460bcd4c3b27188925e46b73bbf677d50e98f7c1cacb2e88f49220652d7d7934898a464f3d8c0033416034a3bec03b88fea8ccc40f9cdb5b2773599ff00174b11735da5ce618feff7fcebd7dfe26221e3c980ea78e4936c9bd632a27ddc33de68a9cdee314165ea601c44561eaa3c49b4a1e7470ce14adc8902ed68cd02c1e524a6b9ca0ca544d88a05b457ac17442acfa62c062cf24a027098b049870832c22b5c2c177cab872f682d6a3fd46f77a12e107ca3cf0e37a1db94d86e07b14e5771097bc6bd4d687701a6182751b6cd2853be0b4ba423c1f8a00f1d59e0aa8b04f0ec18081f1bc8205a2e0495bbd06eef70afee90624214bf3b31561c977ac5eb3c20040eb84237f640de80c3bb21c77fc90e25ce7095709c7f418f589b15febfe70840be49802ae3a35edfabf1f73628b8b1f74cb7a5adf5a2978f92a29846b9c3149a53db1c2d281bfbcb761e725d0b6a36a00c0206ba89e4e6362c154174586485b5c6bdbf45151a234d8c13220b4cedada89b76c1bd8051b5462e1e04a5dac4d5ba139abcbf62836ed0ea36cdd77980ff77b4f3675ca5c7dcc9690fd4a77af1199659f422122aadf1dfcf5dc65355729d82c901232db8a99d3efb81efacfa19f79ab482bb45a86fe3e8c8ddf1fcdd173f7ff8fed3ef098efdba9ffac12f98eafff7911652c572e1e026ab7f3f7f0e85d7b8f95033e3ea4954bfbea2bbfb1377ebdff18e7b3ad49bb4129b6ff52e11a685bd84d2f512df1eac88d63924c20fd285f74981ab907853c12783b9ed6b810613ead21da29dcd14abb9fdb00d089a663d0e08955d560db6a1a21deb2d948ced0d2f7283d78da06edeb1c88b05f596a9866eed5d2a52a76c0f7890abbecb64efcfff40dee2351ee260fb5fbddefb90935b31552672d0867064a68e2401c03ce1e66342f148b2c980da68ec579e9fd4ca65ae8429b396736a4ee87288636a32543246f4bc60b0dc64bde04929111e0b481482316798d37ccc89e5925212c49b8a4432b8a2b176c17779d747f2798fd8fbfe926fdae6d7633ecfb376c84f10bf3d8d7393ff827458fb65b313d1ef8eee7ead28413006ace135c6b1860366e40f41244672d7425ac59d4fe29d2c709ff0769ad5629394fa04d73096e31c874c3cc42467a9fdc7cc2ac97cdb534cb74c091fcc998eef7804d7ecbcf7f14a4fcf3e2ef1def4a79cdbcde132a95821477a9e19e81516e832cee612e7d133d6e6f3fced4b4fd0554cdde427d67b9356473ff538ee8778d90f7b0171ef9bc4197409109374d7dabc963850ca22a5d804404d28b107177bd68e63b7fbe7ce9ce1d3177bb37f20678dd62930d56cbf1f0c6b93d6e8a0797ae1794ef8d50b3a661ff28b58e582e5f7548303e6886466885d6a230fe958270a7a888828fb0cbffaf59c599b70bd89771fe5cc7e7f9e7b06dd4672ac64c59ea4fb057ee39f9a7783957ffd94bf73feea39da83a6d8d7e7fb9807b0552d1c2f09222b602a18f8ccb208c85bc65137b7d53c31ac6dcaa40a228402de6cfd923929d5379cfb06e3eccea713e0571a08382e177666a6baf018cbcd807691b021956e03058784f07c3c1fa362066eb42fbc0127bf09cc0a7bf7ce873ef0164aaecad3670627ee98cf6dc4b127b04881b95fab6b79ec9fe2c63d1bf7b8867bfb396963307cda8f2b47dfe1c4d5435ab23175d123024a9f19f912f1e18c73d4e33227996b39a432fb64f94bf7cb2167d09bc505bea363b649556eb032ee174ab429c31b52a17b51caf154432176ad2adc0d19227f3451eab5dfe74968a31cf36e76e6c75fcb511f7ffbd33e9e3fadd5df5ec6afacd5f3bfbb5687453f506f783de6eb354a2bd88a503b8d73d3fa94c42857be0675d6a3dcafe53c56cd248c18e2b54563201fb1c17c160ef5a0dc6e24f70a5ec626d1f325767e0d44156ba4cf4d56ffd6832ade0a2ec8dc6530d5d50645b686eb3f8680a54980c458cfeb2042f8030cfac57ed8abb5eddd8fcde9f3b8afe73533d8367386fbbddfddce9fa27709f51e13c35a12daddcfb4dc47456e4e41f7805c7b3bd37e7584354e5278211f8b78a6b52de1763f05728ac7e86eaa4b232430599478b28810c868eed21eb5742cda4565063168b7dcd10d9f9bde9ca36952abf0804ffc686ebfd227f13331d3892fede067fee54eeb6ee32238cc5f3ed559c79c3f5a026422764392da1288cabbc376be15baa7230d5a940edb34826168374f0b270f79a9c6a126181b975d5c7b3cb1cdb91cd341a0e911232ac8346f290b14601b258ce64b56e73a76d4c4af74edbc763cdcfed50efe346e02fafe7728f15203f98acf33f891b93ec4f2ac3cf2f0b23c0d4ff37ef6be76e80b9cdfb6060ea5038d30af92b451a1131bb1e62d83529f62953f843ab2b370bd4bb403cfe83a65de485608e092ea4139e942d8ccb88b092e21c14e5ea6ee83b92887421af9c3dce96ce19820a5fabd087fad104765aab1735ed2cfed772978972ff8ebdff99a8be69abf343c687809e7aaf62438c6a23f616f0e5a62a538e5c95ebd6ed1f2184bdce2273122b970bd29aecca900bfb485d3ec42d7a28b9a6e179137a1b6f4528efb94062662cd5ae88a600e1f033ed885657b879ddc66d072e7bc1d318755291d2ec9d83366c0ac056b9e12deada6da90cf29727d10188c7ec0550186eddebf16dcd4669cb54984b5a306ea9573f0bed7fdbbe720b236e9dedf1ce92ae54a93ce51abed83e7dac700fdadfd2eb40afa0c5040e9649569bf3ae6ca8e574d1feb7027236f8b99e589f2d7766628912ad4a485c033c3b37da0dfcb084fa462bb40830f61cd96be31317d97cde3654b30432349e99632b5098a72cb39aee208f7f4f69cfd26ad502e477a1b47bfafccfdeff33cde77e7fe65ccd39e368b383ae0a1b633721ce7066eb55d08ba9d4ffc0d034d25c6ec3e2d753be68d2e7ac8820a87bee1df9873193e894ad599813759752d1ea53f382fa21106d252c3fbebafbd7e8e53bfc96de73da6fa2c73bd3ae999486c6fbea07f7688e78f7357ba723c59e131dd5123eb30f4c2306abaa0967e36f6444c548b2b5dcced3690b5d064a53fc524270b28c2396d102ff06a51ea362af2b95f782075609839adc25730395faf7de08d1ce9dbac1a6e5fb01d930bf96679c09b899aad675cbcad919ce56ff43c01b4158eda7dda7755b3a72482ba38f458bce6b1b88ce990fb3d79e893526b11ea7f39853ec58d2c1c5ccfb897678095c949fb393ac6d8d772da9b14b4cdd5dcd03937fe377343c34d02d4dffd78fc9bfc7e42379cd11337bd91956285b566c0d8a4c7546db88befa786e298c426e61323045db370bc5c501889d2c341a100abd13c5d0e37535d19a85075a024a11a9ecdc7133d81702eecc14a6af16051325f14a8c4a5b99e817690e8ccba2797385c4ff3c79bebb5ae1fcbaf1de72da9e0eef53c1e5e7fa8bbf519c64b37a60096311077d4cd0bea306fda5b51ea8a30ab271b1f742e2b7f6de332301043033e8e073e81c502a2079fc9e5c2fd632c6033c2daba134c68d8894106ca415665bbd4c99f186f7a567608977a152bcf9391b46eae0dec6dd841f37bdb2657eb033f96d33bd8c9833efd486ffec6146fdf3bfab5b7e436a513778caa3ae30ae0daee4404b5058428b561c918b32580c58df7ee4e70a8fdc5fa2591f7a59cc04ff8937b9f573ee30fd5eec84b79fe3cdfd394c245a889d807cd936febdb90c338a9549feafbf5cebd5009181a4d9e1179e7d75e121a7935d57492158a2600b7a1a3f78ce0d6afba8238c3c7ac7ad8e0325fcf1d7d85981810ae8b206c2b09bd151dfdea53adbdb9669555c3fec0635549f01fe29d7b33e6e1fc1bde2633fc368ebc5a2e4ffbf1b6384b0f985033e0d5a4ccd7d4c181cf044410adfc71aecf23cb0a0bb9f1a33f1b090596f08f81f4405f54dd03e7b92eb56124a15851db83d2ce4b59c67a6cd8da1c8a3b41918b78d92dca8126202ce6ae6510a88e9a7b177205a7dfd6670e34bea021b5fd11ecc069fe32c3cae5513be5dd736847bd82dbf22f0d2d7110962da35040520686b0f380f4f92e01de7daaaced8262530064e31a47496d29a69963619403a6ffde652a2f1630f7e710f789ee29cab78018dec82f3363aab36956c13aeb61e713e6488e0ba465e04a2df0ebdcaa079e657d25a2f2c5e7b8548f02b98a2bf8240e1c4dc738f2732e2ff99070f4f0e63357ea5659adb6d2f9d566fb719c61fbacf7739d1fe267b8440dcfcc5cbc99455e9e567893bef870c77df2e1f37d8841fc6ccf003fb2d6210dfa0551bb19e882c4154d58402353f99638cc6454b9017bd8512d9f7386611c592ddafd1a04443d11686d1691e0d91885e16e08a92dbab4602b1c354f0b266bce9a79a67b1a67ca63c0d3719fcf6ee53c160e3b612baef615fc405c8d551ce187132fd27edc531fc10ddc2f14e61947382864990093e152c058ebea94953ab6e5120334b8cccd7f910bea32dffbbfdbf452704f3ff2659fb8a08e3cefb762f5e339cc3b3ace363eb7cdd880ab0554865fab3833fc0ef178874a73c6346f8b618ec5f8f746d2f526d4ad4e40f8b070bc2026a5899cfc69513505261ecf18dc6217ad454175d44ffa586b0346872e053ae2e41c7ff6ddbae38bceedef6b75aa52f043be653fcffdeb7aebf5b5fa11fd840fc73fedd3bd2ddc1eeabd6feaa8da69fcaffb89426ba9b0f54761ab7b1cc5202cd51843d56475608495ecfcdd10fd4c6cac3747fedcb773f98acbedca7ab0ed8cefbfff98a7fe0ff89d6fc63ccdfb2b1db953bde446ec8e18ab0251582611e4b13e59855553489de1b8507602f269dce74f423377beade789cd46d81076421b63ee5a3a0370e9d72a499d3fabb46af34c1b3e71f57b85a9a401fb0db2ff9fbd6feb4e9467fffe4a0948d778382a01a9c412b2819c01710d42a054a9229ffe5d6edae9c6a9b5b7eb3979ff07b39eeac36d4236d7fefafdb4b7f5cbe62eacf27b5137062de3c1adb0d093e864fb09f8b756efb4779f3151753f13e460b3a786f7240506eff6fa13ae8cee3ff492fee3775f6b599af738ae9fb05d3671d5e8d80c4eb5fa5f62941efba3dddfcf99eb6d9473e4ca9f55721d0bf5e63da7df3da3078c2779191bfb2658c62f67f280eb501db00a3ecc036c0f1887d7d9083e05f92064c39c215d864e77cf6a326142da21978972a439337945e99f55a6e5132e028b957abaa8703b33a5ab200a852d012e8741c6b4c34ddcfa3a4734f2e621e380c3a9815d2c7dd6a110043b55a2871fd808fbf76e2e62781d7a94febbfdfe77bca3fe94d1ef767f274ebfff7d5b21f277a9ce563e9d0e48b83619e2ab7be8f5a11dacb081e7c26deed875fee161bf53c177f2621dd28957f20636938c46ad8cbcfae88bbffd0cc011d7f4ba1c5c58602e410924d0eb7b389a8a0a40df689f339353528fd0bd612106e00e030054a1496ca83186bee183f669d6cb2863b0211add67b63716d163c7dc60850bb914f528f0a16d52576bdf1e6ee60c06e14b0eeeb36f584a71e83105e9c1dfb09e5f64d7ff204f7f76ec93dea964346df73e406c0c9fd3830cfc49be1e6c438e4b5a0d61067243e86047847652d46851a269a0b9c1ccbc0d4d6cf2122359e48fbc57336e28173bf680728954f8abe7d5d4505cc9d46c5649add70b8607928eee835237ac9c76898e01e6bee92325aeed7bd9bf6b222c3d8b46bbd41ce9ac266770b6cefa0237e093215aeefdaaf018c397910712c1fb973d3833af93aff0edfb7fc86ff8007652eb5952786bea3625e5b89aa3c61325dbf0659ba8a85c0595b2711577b8207a6eaf77aa57a534ac6d08d02e2889ce4a25331b005c6a29047e4aabb664b685133d5acd996df0528ee7e375cf40bb16e856f98d57fd7be0ed7fa7d3e9d79c282feb77512f7ec665ffa9bc3e8d77924ffb7d15c1f5b89e91967ee5dda98a44d2f61a0a3849dd91c34a95e009ef653ddad2abe5f5997cfeff664dd671a4dfd6709cec858ff3b936be67b7bed9ec1207e68b2858f93d42818976d2c45bece8222b9b8785939fe5d5908eaee465de878fbdd43f7cfffd5887f3d0c82afe51cd26a6f93a8df2190336084acba2eee32ab473cca3664d01dfcafeb74574bc92516c88126adf94f789c86be9e677d2c0a6287291028e980347d4c609e9b59f46a8e2d5704e0f794f0242ae192f33433122f1275ecb4b717ad2644b58a7ce7079d957bd496d659944d3561add263eadedcbf827dcbb2b736e6a9569b59d331562bb8d65d9ba226a1ea80399624a2414710e64a54cbfc7bd7a9e0b5c60ca36ca991ac4e5dd82c546e66082195a262c47fbdf25ee48cea3d8480d44b3c28b03401a69ab9646aa5c94faeb3cd1f7e30b873ea35974c09fbc22374a36f1b1e6fe1bb1859bc4f6cbd438c50f8fb6dbebf83fe2ef8e34bd87364c287e0caad824c05bc90999913ecfb1c1c7b4b4225a2a9f3b082953490e7993945a52aaeeb2aa93c406dba09471e8344f0ca935878f1dab32930b544ad4e8909136a1fa8914789a46a861d4bb157fb7ce4c0e12d1f5ef62c5cbaf7dbcd40cdabd9f985dd063c77ed95bc8ec2138da1c87ba9337e303785dace76067134af3ce371b5b5236485cc433d1ec628e1ed2a8497cd679e144530ed13d77f6be199e62a7bdf7ab2151659724bd0a638d6255139b522f2691ddcb5aad78a12781298d7042fc808e467cd96e24907d5082ddad7a0e93f33c2a17f68a34d2b0be510ff3fb90cfbe81fdb8518eaed3fd3d3bddadbf9fc1f6bafe94c37e710294cb0d49e388c3cc40222cfdd5dc91355fb6735ecbb170da0977a05085ea935e3ea746630bdd188a0d392d155fd05192f48467764ec84422e234d4779a6d50ab226078bf673a35a4b1889a710c3dfb56f99d139fcc2b9fe94bddca859af35245a3b58c729d15976cfec39e811bec19cc9c4e2f1cbe3bf68dbdfd7cdcb3efd79bdb2d36d454daf94c815fdbb92ba733636a24952c02e3d720eec988da43ef3a7dfe99dbfc6b4e91dfb7f045bf81579a1db879aecb1d603328bb90304d30e80cc1e4d847ca62b53413d786b4e01d73f202eb114ecac088b5ae2590eb9072b960a44ec7ebadaaf30e73398d4bf8406ae4cb5e3d4aadeed2880df884273e471b59e52db7f56318916b6b40745a056d6ac4ffc29939e3fb07b7e87bf834eec1e714563913c3eabd5d1e5cd9ff00562acaba44585e8864c0c430e7359f2eb4670927d8f94217346c8bb40e406036368ebce81e58133f524f1472caed617f0f89c6403ea8428d127b602aed5b8bf1701346fa91a2df90a169178edb6d82d0287419bc95cc4f0dab78d31b062ed53a4b619d7cd74b35b9d3677f3730febbece0cf27fb6277daaf97f15b7fb99777f155bec54234f3548f767e6fc319904fac27776184f902e95a71cd19fabd9314cdc39e9418305394433f89b40c0cbc24a5d7701b5a210b567ead8c947a265eb65bb11c6ea40d47d8c06162348f191c2d5397984139dc51e7ebdadbabb1e6dff7a3826ff48cea6c07f3f880f7898a8b7c92e1a03be0970a4b2fdce016becb87f10f72ae9f0974e8838d0506879aa20336337c96510eaead650d29e1c4c4db808ecc0c3531077c9e5564e4bb7c1a57d6a37298319f60e09b88cd7a2448f9c78af99f9db46dc8d088ca4212def36988f20ab3dc4b05ea98039f848384e4728591e772c3ca17a26b79a160f009ebe7a77bcafb5944367bdb3311b0518e36dedcc5dd993c4aa584551c7a4996875e9172fa25df5f9ebfcfe17cea2d7c8c23bfcd4cddc6d5707d21dfd3643b78c0253ae2d1bd9de7270cb6fdb3cf52a8fcf84ef04e46dee6cb9a92b3f9a973eff4373f95d678fb3eeff5e7cceffe2b9ef6d56f5be7fab83f6155bcf671d77bdf816c94abb732b4f67e5f2bdfedcd997cdc2bc6b3b5cdaa2148cd834ffb7ca84989308823ef633eefef1d0fdfcbfdcce1cfd2e1cfb1a1ff69d75fc195707e6dfe03eef769ec178cef93bdf3cfdceec5fbee872d49002f168ef6537b6af2925ba4265650651676d8766e0f4799293b0c240f2a35ca10e96666b65b0838a1ae9e8595b2998badb8f410d5120454c5014448021e2fec36480dcbbd37a021b83748c6433ffc0e9e77f8133ebd037766bf1070991a5dffaffd7ea78bc7bfcf61efffcdc50aabcf1cfe59ce9fd5d1f6f3fc76f8fb67e6b097f59fefeb5edecf7f86c3ff441d02081b8e7d6aef64390c55a4b741a4d7b39e6db9f644c83c4f224928c49c334542b7b9c76e3e6686d7a8c99f6ea1bd3cab1f4d02c96302b823eab26315d622f22221701003cf610899a1ab47718feaab71f8bfe42cfc87bcff5a1f7fd4033f8b7144fe21b795ede58bd02089e4b1cee5dcf7f4c04b7a654c114da8d1ad256cee958378daeb36e17a1c836e9220c26396cf93b2717c3892598f4422888d013213c69f7cd1ca85dd6ac649a1ec6e24a36644c11f28ca360c27a3da2f75cd9c81119a6a8c6dcde68e0e3357de2aa6f82fbdb6f703cee9b5328e889e8997737d51679eeef7f69f189de7ce496ca0ad0c619d1ae81bfdfb37a9c5d19981f303af8f31cc5fecb4b7f338f5245c772ee89f8d62fa312eb3ce2f719fd4e52e2c7984416065767ec06fe215a23330dcd2025bb16159aae46bee109352fe8c4b25b1ce0c493d8f39bc95b57445c5398d503267f6c607aa0b798325689f832a1fa9ddf0dadaefd7f7fe8bcb72b4432ec51f8f7bce6e703771114723fdb7e614bed4cbec75e617f33be690f0b7eba3ec96f4de34e0b221107574f96b97550d5c448d1932642536f41397902b63277deae8e74b7e05de0d76f8269c632fe31dcfe7f16f60ce8ae9d57ce2184dbb44f050166c3733f45d0c1b84015a53b784b8e65e68e73645818991be5b149ea70a6f8dabd68eb93648c4acc5b835299b42899a51a6a53f4758129853c1e39d60a8c6fdc889610605e5cf04a8f9673be2877e43395ac6c2d3e97858a4c65e16c9dd2bee44913dfbfb7b4a3fc9a2df32c2ebfdb9785d37d72b4e36c791e3ff933d8c9ed40b5fef72d09dc7a17fcb791e9cc7aa7f5f977f7a36fbdcdb73bcab4b25b2b7bff7c9ee96ceb038d66eb32f7be9dec72a4e7d7abb01fcf4dccbba44b848cdd11b7eb6733ec2cb998350397afd867fed1c4eb3ce8cae49eba05595ee93886cb2e53b3fe41fbe10ef33d7d36ff0e2cf70d47a3a33119491f786af3738fb5b871e27f71dfef4e7753ff628eab4decb2778c4240f5ff7fe9c6efbeb8b56687d904963b84c1d54243b08b28aebafeb11cf600dfee5b738f3ac97ff7d07bb3fd6db7df2214f798057ececedac883fe9e4341a6db23a68e541fefcf9f20c2502c2acdaffcbf3bfcf9e898bbf70bb1c72b46fc7ff74269eb21db46201d77f63f6f6b9fd7dca8ce1f35e279cf0df4ffd0aaa9175d92a4383c41942358687e71221adafd7bbd3aa1abcce1f9fc35e7486651cbde612c0acb0f772f5f373ffce3b7c18d3ca95cb77b1d8b6c7fe79b4fb186bfce8c7642e6952c3cad55f9cd2edac28cff8cfa35d6aa843edf6d7bd2a275de9febed003c3dbbd5d357dc546fd88d370817be75c6c20fadd2635dea4cb635fcdfe9cbfca8bdd597901dedaa0c77bf7c906058718d90987efef1a9de981aee3c1ec58e3dea40e7bc1b97fcffbff73acf84ffc34dfc08a3fcf8bf4233be01de7e2de4e7a379f0356fccf7ccca5a0b24a0a6650c889efe4dc67ed13292d9b45fc9e54fc2e636d9995c82215f1642447c4d15da6d55441bc8e2b38a6259c66139e27bd57e1c92848697ecf6d6951eab55994af482f9fa5d14e696f7772395c7f870ff09d8f19fe4b675e8ced80b39ca33faf75da8f7baa6ff2a0dc81d3ef5f1fd391ce1029831829254160f019b6d73dd368eeeb66e2979ee4cccb17aef203ee4d32deb4543480147b1f03ddfbda5bfa6ebee555b721da7b0ec0d056267aca5cf51c88619ef6642b45379f3bdb9e954da90a5c33fd0dbcf61fc57460ff9aff08dffa79a7bdfb8a93ebf4df5eba4767facfffc33d8287dacb34f2dbd3effe80cf0dbb091c0deea17ca21169032ab1984ccd14d880949e4358e704b04930f281709126601807666ccc5dc2ee8d66e99b7235839e15b336629351c0edd6e2266929c2d877a6ab5810ce6d6ec4b5df319be7e1e4537dca69fdbecd5b7ad0a5d9181e64c6b764d7e73ec49faff97baeb3576ebd97f91cf85d7e26bb462a9233ee7a4c6a3417ccf262932c59816633a85d8ea61dee99414c5d3017d7d8985a7145c49c1198457c871d65e00acd3296c7b1f86360f8380805a4182ab42838e1157e504e57f1dedb89924369069f7b55cfc8aeffc065fa8e570f7fc4623aeded57b2f14b3dfc1dcedacf71ff9fc6575ef6f868d7edf5f2a9cf677ffffe3dcf13f7c20f642aae6410efda103bfa519928c0e56013336df855dc4900a773a77be0358918cb3719f3c182ad8d14629b6bb9894dde0611ae02133d25307fce849654e42d8d149d19108576b7c550eac4e9806fa235ae3a945ccf7bf975def2e43bbde0ddcc0ebd7a0424e222ced6e0463d825fcee1183f3df98ee284d3b33bf40c02e5689d2dc1e007f56363091b4811a792b577aaeafc19943ca9ff6c84989af389128c4e0da6592f817a0a286e12260de9e2edacf79654481172c5b9fe6d2aa719a8432d125b85e837f027ba604e17a8d25a31d16d16453e9953a47f5e8fd49e8d5d9efce36deaf23a118376efcb2a9734976b06fc1b61077e3987534cedb8af99d34169e8e777fb4a8ff3b82efecdedb097bb500746c82c2a2bfc90f60c60d134311b9a41916dfd888fc228d8cd0c1262a89e89461b02b04827f68630d8491bcd830a9a5ca02ee336c002c599ebf5dc5677ccb0fb39eb3c9f8f2cc5bdf1c2cd6f55a3f9e6bcc2c35996d1b44d1cbece1cbe7b9f13be501b72268ef235a7caade2d6a7bd34f02673d8fbfd3d7ed7e21ff0d6f9a5355086e7cc8c3cf1ed762ba391a4c5a8a095b7b907728e75be097be5c62c5f3391d78bf1f031e4cd1a6b99fb8ee7e0090f191b3e2823f7c3a81ca408d971cd2789402503dd24a8aca95f62471cee5400e3fa56b522bccf2a5ea8c8ebdfc4423ed6ca9e6248641747075b475f5553f212d77a8d2d5da805ba098ec0c7d8dbdb18f0cb77278cf2eb64ae39a7a4645c6fe2885baaeaecb80f7ae1586e50e46b4e71a22659e79b721e1879ad260471533d0a1b05bece57412d9fa52307a4188d24d05d08860f71849f98ad8345f5688535aa95d19a71892599fcdef00227b7ea19fe7be76493191aa4e6f44c3feebb7bfbe17c8d745a119d56f84c0fd83b796e24116e9433dc5dc11bd67dd6c3ffc1dffce7bbbe3b071fe7f96f8cc64b329dca7bdc7bf339e2f39806865fab7c065a870202667074ef03cd7131a2c41d4d7c88e2a047d3a4f2bb40e771e648df2f7d8b156c1570662655ae7d3b3608f450c6254e26e45e456c4575692e9cc10a57a4c910ff98bbbae8d77c4f1e9f391b17f1cd6e5057ffd3fd5a5e850d7294d5ae47d3bd5ed4794ddcc6cb4060a44c9561a5b4aa9b5a468d87a90f0283ef30db6e54adb1988c56a1dbb099d1344111f489f61ee5444b2e3a4ca0f65954ee16f568472bb8e193bc8b233c212691f710e5a1792da6e69b98fed779b28fb1e09faefd5eaf9f72fca7bf69f67c883b5ed57b12f76189e701600676799b00b94d45eb1013ddf1b2ed290cb6ca1e74a29eae94e01d454d95a1b8a3c67420c37642840ab861afa8994f52a0a6be499e1347b794b55eccbc163b60a32a1466f6e32631bd705178b7c222c96363b84b97af399473f1e6d333f029335f62fbecb046ffce11fd53cef6ff2767ffbf95b3dbacd26d7ce96e8f3fe5d1fec3ddde8f77dc8f63ed8e7deab5bccec6954c41524a1343be958ebd923dd9de4334559515f9c8b338fab36150eab0f46c1a0eebc02438e0de83ef605ff160173a188586c5982b1f131d1b31533a8bbc49b01cf671696db2c96896994deb3b4d1f73c5b17d6daf25efb388ebac2eff47b8f3afe31dfd88538e7546edeb7d428127c4d17d8614c0919c862e31292f7722f2468c92262ee52a60db01abbc29e6da0d2a2b092adff26db8f7810c59b52b26f07d56fddac4bc69028e788aec3e136a27b86f908934e6b62a30cb6000511ff7fa867d7b9ffc02f8892ff0ca3a5479a86f41877dfba407cfeee991eff746f1b777ef74d28b6fe6034e38c2d7c7d9823a5fd252b9b4025b56eb5044924b3bdf869132e64c478b8ae339cf27a9e33d2c5cb5093881a4220f84aa84506986f67615221bf249fe98c211be379ba9aae06c51373d89d0a334cb2d313d82f99fce375095f09b72cdeaccf4746ceef5c937b04d6e82b3fed63f3dc9b0d7cfa71cd275fedb2c157246277889cb6cc5746eb0493ef723b9f321e97cd1fa33633821957af64b4b0a9b838cff1eccc0b6cfec36cf101f613b1bc4408a580c1d1f62eef7d33e000110aedeb2e5b09295de840e5c29a7346690e437f4dfdedf89639c7bf75f6d09e57af9d146f8b8a767ed87f318da3fd74f6fdee9b8bf6fe6d39edeef7a3b817983b8b45c02ac76af9b98d60617649ad9da5485f6b8d9684a751c18dd929ab99902c41493253df4f1304381dcbf0739c13c1824ce30a0617b17bab20dcde62e03bc4b1c65f9b6da31ca639fe25c56fad676c2bfe5df675be136bdcd97f6627c3d7f81dfebe7b46c2ba9d5dddccde73ef3f8acf70adcebe7b9b0c67396db8bead736adb4e4111ae03ab732ce9f1762384a35b2165c6d2924a528b94e182e92493e0e6a067dca0176d576ce9b564259f12a7f9e333ecedceb7dad6fc7a5c6b7c0b4791def64331c7bde4ffc9ed7f56f8a566406ee84b30614e02d2e722a8a5199180a85503678f96b9088c7de9f8c6681562cacedded7bf371269cd21a10aac81cf95c5dd3c4fed4127b9d706942773cef90c74f19c0526d18aa63cb618407231915ffb5b67f4c50907ed322ff94db0bb5f30d60e67f7056fadbf0eabfba023aaa44630e8991583c00c4c1de19aefa8ce67be2dc74ac895a8f02661ca9d4f46267779a04413635a6e633085dc25ebb4986e09f57850103a836ac4b4ec12945752376bbfece612fa2b0951c96ced25026c2ee888cff2a14279b6dbdf5db853c202c9654eb0edacc86e1143af6281fad9fe73e4c1b4264d2a0e71f473dfb7fef8c81d7d8dcc086acf6313c2954326140cdbc040f1cc18a2cc960f6c3205acd4cb44b479003c32b775138bd810d500e2f17a95562d0b2369e132b784dbc0fbde8799f9076410954141ccb99d01c5474e10350f999373269a65f8996fe202cfe7873ad63335629f79115f6b543fd5537ee4049aea03bfdf999ac52336eebbbeb44fcfc83c334923eb3738ce1fedb0f1ef656a4a9d55dd261647fc0ae5f053afe0fb58f0871848f712c3c0cb817531c753a15e8de1013b553aac5591d79c6acc4ebc39dfa999bf810f7c711e7b79b15fb7a03d62b9123d8bf82e090fb9f56d6a583aad5fb0aaaee44a026d1d425563c1f9c295a12895c9fbdc51955cc6ec8f19f09c2613afa0e3759f14bca24cdd7106270ba4c661814b5ee01cc3bdee2c777239848c8eb40fa60637e046da419f421f62a7618cea29d7c43bd58d7fb117dfc66ded6f84a357c511063371c468dcdfab586c8ff2e2f3f7edb1d6f13afc3659e08e51bd6151692585374a6c4fcfc01f8b97bee547ca4f593b0e00e63343d9d4b066b44492f4fc3133d503069e1f1a8fdb39cb0bcc7249eb472b06cabbdfb583d41dd901d0357150a390ecfd091e71341d60749e8fea658d1321abcb38051f6de8ffb4b68dace2b76b7ac0d3f2ff653b7fd5f36e37308501bc075b6bcef3b52872a00c5ec6dcab708906be2635e372a02a9550a837cc6e3b51f32a654d1317234027de5ea70641394ce2026d7969d5a1c8d71923eb808e34ed47856faab1d2a848a36680afb6d74ef7f4a576fa2bf9b1dbbfff0d7a6e8efb7ac4d0da81f79fa9ffec2f07f0ba3e27cf56b62c240c8cb9ab1a8e48a3e0e32eb1ad32ac6411dad64a521d53433e2b038e995671e2401d0230c8ca78cb6d65a6ccdfb0886c7ce89bac1a26a1f91bc6865e8bca1b2cca5f30e164ce11eac3658b2423b78a93ff4eab033e5d132f8755b6b37ae520f001af69fda1ffe4792f4f53472f6786ec67b57aa33b0fbd83fda7f8f9616fe1368ebcbddcfd1b6b3fa3674f38abbbbf3af14c6cbb824d6c7a9b542010bfd6e59fd7c599a3f732ff6dbdfa8913fecb1cf7e9de357d6a0cdacc3cd65bbff66819ba5a7c8b87fb063edcf16c7ed50ff0464e7c35df1fe5c6d789136c148857d4595b733b4f524826cae94456a1a972e423e6b94c44e325155a0b07afb089731e11180b8b1257fb34ca9f4327a7c2e67658a3e9c20ecc34c2e1dc0eb68ae13613dd4a19cd8417f940d56afa0f4e918fef77e8857be97bf8ba3f327bc6b7b091ff31fe1bf9f1ba47efd73cbba247efb0e622303a49ab36487b0516bcd9f9b68733ed4559856ccac9bd329a29ae8817b3bc9819d34d50e911468f3b1a8d0699dd2641cd00166825b85cfa0e79e0b5227119effcbae154c047e9641d379a1d17cd5dc006bb2bf932f3a48efff63fd0f376ed5fbce2d71a947358113b5991e20306f83fb012609f08d8a40efabb66877a958bfc23a7bdeb0eb67b66e4400afd7cf9dcfc7ec6cb5b9d9bf763bf3933eb23e7397e540e6fd225388dfbfd9e4e86f43686cd46f6d2c918c41953e4dec8c3396a60260228b977250fd5511f67152fe3cbd8ccb7c2b83cae53e469e9bce0c4bc9fc78fb02e452b33670044383462d14de60c9659a9a9ec0353a1e621437a4cab2113765bf3897605cf9dcccee733a391a4f657a92d57cc1936192c57d4c1630a48194289052d8d80933b55373d37e315e1fe06db6dab8434cff3cb9ddec540d507d9fd9d1895f9dfe328ff1cffafee88702e2bf65eb61d6358e695b59020a57222dd86ddf7729001b2f22b3060bd8474928bd0cde70a944658f3e5bdc12caa358b016ab37e3ae0933f204324f70bee861a89b978dc06b0dcd202ed28cd1fc39e0c70a576991def028daafbdeeb1494ffe0f47beb375f8855d1f86667f89d4e700e3a60ef771957e766015ec73c0f0298ade844b68a638b002fe1dc730383e8d086236c1248ca6e4929be0b60f32c4bad45397c4e0c394958d3a55a058b8877c1f2d7261468427a354dedd6508687b9cb67b226754cf19312db1dfe8c61fd65cc24705ed777138bc6f8db6bc677d3f7bc231fedc7bfeb648e76a9995b33814ae94ebfecc58cc5a16f238fcda04d9d612d8d137fd4b1fff65caf65ae6ad9a4bbd71a90337d335fdb15475b919de10c7d7df7bd8edba5e6f46f6fe899d8ccdfb300cd38f29ef7637cd9bb57c9e680571795ad32d07b5df7f9d9751c915ebdaedf0163a2fb3ce7ae91460e66025a078e9888ebcc0cfedace9f73ad7bdbf939fd1b1f3a8749b59302956f6cd2136ff9711f3fe5e40f36b02ce3dd97381bbd141866157be987d8fb0daff9b17fec752f0534fef67a1f6a9d3ef902cad1cf8b10aeb39abded43bf801f7c6eaf2fe0667eac21fab1cc7e37eeabac3edc1dc1775935dc1db891afadeb12c389ac474506c8b374d43341b24e5869c6b5724280605a7825ddad4132f90354e9ad13a87a6e58773330e461af4329648539775220d77e11740b441aeaf029877f364a336b51b536d77927381f24e5d00c1d4c2ec8e8fd39dfa5dfe1841b1ff3a337f1ab3edcc9f772fbcdf7fb355e5e8bdbec7784a35a31cf9cf5ba538edf65e361c4510964645b1cc030646892188fab109182023df3857ec63614582027e66832e7cd248c82adb41fcdcc9dc2b8d41576ba20b373238848e0d7dacc10994bd33713177d617b90ee72fccabe9dbfeadaaf67353b606ada57d77462c08b45ed0f24d001713db1d0c18a88b617cc2b5434ea68a4070ce4b170bd29055dc8ea9cfbcba19d082ce6936c3067300cb417cec7ed34ee3dc8cd86ab68f490f544b29edc2f4aaf0deafc2929b108eadc9e199fe2565ff32b561c662f7180d71e89e042fcfc1f380b5fe5823fe32ffc705fce8d7db0b30ffde1877eb3ba7ce9136f4fe35eb9676a9bed863137751b97ddcad7c8176c0d68dd6c291bee846870e2106f81721846d2f2351a67a043b8ea9e941896a129cbbdac991978bb60cdbd0fb008b9dc8693d14342d1545559979a7249a3c697b61c0717b8edbfdf33b1d7a1c1871ef9831d022ee8862675b647dec88bf533d98d38e1df8d79b86789e8d6476e4ba54fb8c157d6f9a287b4d7cebd41301770e2975d1117641c6b69a4657bbf4024484adcde432fcc1c0624209098de5d02b666cab848c7c332d19a2aea3d4864ef9863f7fec49b6367d82510d773a177b86a728ad4bdaf39e5f5e86b9ca6efc72f41fa8a290877b1b0ea377534877b73e13e3ecb316c8fb2fe929f70262ff8d3fd7b63db1d75cebb79b4071ef52be525679e3da7044bfb971103afc125b330cc47be23c701d5cfca44e6bd99bb38fad371a43d66e7b972fdde37144ac2e18ad6c8c2c08b421b458b494e421b13c63dca29670bc7df8695b6e78e751757763f17caa09fead02ed43a7d2777f86f2cb573b9a5b7981e9f62ce275ff7783626d32fb9fa5ff03f661106a9e9bdc1d5f02f61e057a983c04ce03c36f26ff14bdc00cbfadd98c7f3d3e56afc22d3c1699cab628e654a758ff9c8c4a0297c7bbfbf7a2f1fe6b86e8ac4c6a339f76a26babb45c91331c1c64274e19ce98e5492ce515e24c25b739e3f84868cb0c68d628f5b49ed5e322245354c78c14de97a5a152af08165deac866effee2e7959bf7f61abec12b1970ff15bd97e0187efad5f7591a7fe83bff5f37dddebeed73d7531c85eb8c0e9953c3a6e132c6c622536b61236d829a0470a613fa4b28efb3fbb19e04f196f0a5f0c9f434af062395cfbee28ca4ab4ce20ae04fbb3f175e3c590ad24c59b807a2671d57251ea8896ad19d3694f8a7c974ce215415e9498ffca53bfd99faf737b1fb9237f68e7bc8c77b06df67b080ebc54bbeb7b401725da041c354a10ebde9c4266ca6766667d081a0b8b613f338661a8f574517b7749656f94edd959e425cab61e79940de23a3016347f08ea0673033f7173ba9a3b5dc38b1cc585b4a8919b73a4120ca5230a9e2c3ed7ad5c8ad56eb225d4f1898ffbeb5a21ff26b9ffd49cb652a02239aeefebf8273ff4ca7ab7a61342fad944b569af8d30d24416b995c06ca70a35baefbd3946e84932ac43ca56c47db484ebe509fbd525423dcf27c84c2a3dc5402ee791a4142a830939570ea43125535f7b1bc6c92ed379a32ac245056f5523ff056ea87fc1e618eed2f080239a5fce41b09bc42553d36b8f7cb147bfeccde7f690ebbef25ea474dad10247d48088701e4a636d048576a93d4418799083a1238be9803af9e33c42ae107c9edaaac348da02f17558973be5fcd9654637a69a0d88f97b40a2669d429d50432f45f968aa09d731d03ba2f113bfb69e2bc2565ae15512056f31cfced4740ddbf8c45bf7968fe2951ff7530c0d1e6ae00e58dfd11b4cbdf020ffbfb6134caf4dc45fdcae8bb524b7d0276fc63cea94e12e15fa14af03dd0f7844c5dc517e1aae81cfcacddc696bc56d30337e756482c390e5612a7249ca0c648e355f88e1b3aa797edf07dbac46051190e1712b708fac983ff64111406ce6cbb852930ce02ad13848680c55388c702d673ebfc875f1f97ed5fef381cbc31d7d8fe3fe267d43b29fd59e8e45b77de5ba7f3f8feb79119924cc24f70c409194ed36a0d36d6a588f73178f19f75a4ee56a3eb9aa76b7ca0c6e9cc5bf395bbb70034edf1abfd44b1ee4cedff14fb5085771abc2918a322ba664b470519439b64520af92c2377ddbc3cc6dee16c22a64e98d029d0da8404b0c3c97034f12e7118411aeb3b02d88dd82c564d4e09a594985e3793422c4b17a65e23c664326216903cab74434d7f0acbc6217a6e3afce267f8ecdfd7383a3dcf9061fc74d6ca24fe31e74374c2b0cf6776126bc834feaff002763c1f44695e88ef23f601e61678ef41ad3bc62004761c17ba5b1af046a623d1a0884ee49d9b541395c72974fb26284658166091f6d325be139b31a52358d60de24ae641e53cf492672ffce049768ce35f1fcab7b08ffbe672cb6877cf24c78eb58e0d52cdacbfc4b711bfb56719b4bf338dc914bb8aa077cf62be23b7e085d65a23ba525c7a0ad7dd1b4d26e0be23c1ad2c4eb90e5f542f8d7c9588383ef72ab9e6219fffd0cbf1b737f7e95567f79567f14332100e66a425058b00e17681546e52e74b8419d6e879d0ed2aa194b53b64911743e6873c66c33a903c08b7c8c91676786dc86cedae4702f8b6427b5b616d19f0185fe864e62233486837bd3bb67a5b54aed6e862fe0067c3b5e598f601afd7e9f2ffdd2973de0ed5e8e4f86b7e06c3a8cb53fcba77acae3ef5ec763d69971949b0bfe68fa65b7c2a64c4266015a5abb45a4621f3590ba9a2ad72b89bbb76f7825ca7624284f08681e794d6ae936cfa9cb4319e101ad60904404f9088fe8ae7df00bd97348a692b534a49e4999772b3e812adb597b3b729d390824e3f7f8499fb0882bb94e847a7c1ffbfacc3b9056b9de9fdf63adfef4535ef3fb98bcc3e7d8607ff3c46772d5c779c3e6c4dbb4495d0e6478050ed4a75acfafce1cbb112fe47b3ce983fdf57e1e270ca8eb6228011b7a126212187c9bb0462af8bb0fb8f74ccc3f2bcce53377d92eb43d29dd6649e06f8005f7558f8cacc07741810d51767a2178e947783217f9735ce187b82f37ccf4f08201c8f4886455eb2e0a92b35e27e9ade443a5fb9978b9f36fb0d42fca082f4fc7b04c22efe3d93e5b1f7703dff42023f6fa503a7a77c498783f8f530dd295bc137c9a71de49275f11313492c27b90cb619bf5d893dcdf10c15731f805b1ab41883c9f172420bcdc65551e2ad39b0abb2349c505619cfa76f79818f676e1aa3971892bc400ce5d65053de971d8e2d0c50fb4bf1d1f495a956fef27fcd69e5dec75b4fbcffc58ff65bfbafef58e55689ded40e7ef06836bf56f56e640dab6710f477650ea27c9b811d0b2cbea51b728b991ec862b7f376c30e09a6ad464b56eb8c9efc3c968aa7a5d64aebea70c01bf6a405c22930b144a27b7ef7b66faf00f505a99b8d44552b6411ce166fe3967f143fd7be0eb6a65c5fb57d93d1eec3ec694afc4d4068b68a467429eea722ef66d6f67c5f4236ffbcf65a8f9f69d7eb5ef3f8397b17ed0b76de97b8323ec4eb7334347693d1a2dec6080a977e7037b458bd1584d784897bf36b46aee15f44a5f4b27b4799bd5da5c383154354e52e70f60855c2751bec6e574a5ccc7cddc0956a9408c01b4a2057242d17a3ee86edbb77d38e3dea53af3ee0cc7de0feddce3787fefd7017fe49803b8ce5fae6445dad4c44f01fdb3c56669de1bddc86716f69d06511b85bc825289ed06f7365c38daa3367f4a7bfc18945dc01ddc649522b4b262c2f03316599f46249c23f2406d2ce2aaad94b0bbd01de9b498c219cc8b5be574e2c8dbc551d92a61bdfa11d1391cc1c3bdd2bbf7bace3fcf1bf2a6c7e70df7c219ae840f3c12e76bd48eb5ed74fab52d6574f9278e899fcb877f706d9f3d8f8798eefc46980e89507b19718821befe4d0fb6dbe00738d5631a8d2a325141e668c4ddd1381d0f4758fb604ef371ccf43dd6e526601e9b538cb8e32d17d4abd8e4f7561504c5b50c029d47440c7356201ee8d12ceb71c30ad667762331e040546b180234092933138af87770aadfceff6b1e37b5b9d4e73adffb3b37f17987275b760866b47cc6d7d6a0f1a929b9da2a944302f54019fa29eb479a2f5bc3377e19f7309ffa4c77bc5c0fa4dd3c10c10b26244b45fb1c9b9915f01848079b33401e174e39a082ac333e02899b0f32d45849d4e045adeb39f258ca784f76edadea3a7e67867e96ee418fed1297f733e39537673b2bec73786ebf33b369e3c82b16155acd8cbdcefbdd2a47b77feb42edcffec6210f808ac4e1a79ea98fb5b1e7393e8e7dc507bce7fec06b19e16d6a587feb54776731573ff0afff9b4fe6538ce5d843732eb7bd4e4da5b30ae799c13ee2d29daba56813019bf8dc9ccf3fbf9d099ca715d6a98396a9c3ded6197f5a97039f60c573797cf66c5ee5738f0fdfa5e3973a5fb88ea37fcbcc33f771170bac65cdd733212ff92d606fc3dca006a3ce2a544821613a86d5c96f79378f193dd45483ebeeab7a0ae1681e96b139170484251269a5796a2b97835c12f371976835e01329127bb0c10ee8684556b17edca5e5b0272c5ec5a0ec88207526b67051e23071fd0daf3111dc33329d17cacd570ac95868be4aa20b38d29f73088ff1277bf86cbcf406b82a797e5cd7fdff821fd93f7e450cda8f04a7f2418a4793556d14966a2745fe14d70d0e44e36413b6e1651b64130eb83b8a421e83b0cca7a25c7733e00de25286ca893799a147bec61177d8762e704e1c2814d272a1150a8537663db9fb3996fa879a96737982d7fcf2d7356d8983fa9940fd4258c54ce49bd4682fdd893377f24777e2c0277dccbdfa6de20c378979c8fb9cfbfeda7cd8c15f142cde723d7293aa1d64851a2d224d18b3ac04fe192cca3560ae0484919eb366c45c642afadbe04cdef9a25be2921b21657d06478f98fde912a806b2cfe7c22e217571c54a9ccc5d1ecf99b5128c244135dda4d1f99a96e31acb75fc8977e74ccde04df28b07aee02a75d0a146fdcdf827dcc72be3de915e853ad8308a668926516c926de6282f10aa62e0d756d9ad50bce14995d7349a76d8683beef2968aad110869f8807bcce834a7aa139adfa530b78926a310113be8c99c1a4377069b01a718a9aac3ec1ff80a87f7d89f0be16dbe11c3b8511ee63deff2eb7afe9dc78f704198dd159931ec54b85e4907a29037e3fb5e82d4247352b6ddac5776ba6b13df652085c17651b60f6169ad7da393612f0d622a5351ef3129f3febe8f0714f024d6e429e11ccd85575380c6c2f182195046a6fd6df8b95efd421eecf0de561c79dfe87dfdd8d3fb7379b01068972e5fe4f871fc1397ecb51c0b5da0bd2ea1e44951c5ee21e908b0ca8ca1071f8d7206a59b01e2869a8f59245773c1390796cb74d90540bac46d646277510a80196a84a480cfa92b456cc61bc1781bf79e497536084a7f876dfecc237cb56e94eeb44d1cdd2be7601fb433d17c43f6de0437e4ecd8c7b34d763391effd8b8d34bd3c0df7fec5a9f6e3ba1ad1471f699682c75e46aacb0c94f886e57044725c119f82c0cc4c34b807bc96b60feec1b0080bfda0a8ba132559f3c9a8170807a19def7c035b52582483a32e139e086df53c33868ea0f22ea9240a61eeaaba693fe5dfbff619967184352e82fd5d7f8b47712ec7b14adfd9c85fd76c9d59c3ad8cbc421e70ba3a9dede026ae1ebfd3cb7b0bf955664bf8b8ffffd283cd09dacce1bbd8e0cfcad16b19f96d6a784fffd8fb73f36efd1ff47a30e619b12603e674ae02f993df4b8f95718775eea750a3587303738d16ec573f9ff055c2fd6dc8fd7e3ef13b5961ca6d2be6686ace275c285b3aa2f0f20495a6dfe33bdf69adb9dd18d8098c500c56ccf4570a5e570376fedc7f3f8f75f0cf5f6baa612f05ccd39a34b179494fddaa4fe0e8bfbef4e364066fe3c3bee1e3bdfef7fc7e940b8f0db4634ebb8e217fc4d07be0d09b61800dbf502173499920fdc8a3bd0f686f9460706634b345d56809a5216cd251ea79d46616a3de9818032bd4cd7d3241f57ca28a6cc28ccc641b5229c2cca6e0d01fc49ff7f392fe3aac47e6a05d66f0dd3764ebf6503ff9df6b5e0fcfcca2519ed55867cbfd393ae8b34ff399d1dfcf38bcb206360accc4690c29e20d66390a7b1572484a1e35828b7c3d779b1589d88a3a5d4ee8c8135153d2881bb1c676128d0681f6b6d418002e72738e1a8b308c62fa673b77b4e0933c0e8ce62eede520e51a601b371435f5f93ec1dcdacb91445ccad9de8acfe575bc838fb088463aab74f923db40601a8bf671e1783c3390a722f4246b69c49043556d37a4daf678e2dde3820f24e87c1179728130cd0adda5ec71435833bbdf9f49d3a3b8825e8a5039336c3309db405262fb36ac99e901a147fea262ab987db60dbece17719888e0cbbe6815f1468e3ff43aff57fe96d7712fc68bfbb3fcd13f8c5b1edfe5573b330fe3b7fe917fe107b9a3fc890112aa5ed6a264302c612d0d0c42db2b122df3a4ff3db8072de2554e43a1ed45299ff944d3b9405a1a703b9f703a33bc50324f70670a18274eccbd79e692fbb968a110689e38d69296fc2131bc59bc1cbec192f8fd8d58f09b5cc145ecfff83fc783cfc7e10f3ee675f535025ba424b3ac46c50cea3286ca492b7d9fb88d8727d3551035f4de50736540be28879454380c2092cad454316f1cd4e526341ab840ca17cba113da7c8a4bb8c9289a27518329f0a20527852af2076c0f9390c16b71665f721d6d5c97ad747815477cfdbfc2977c5d5be159879eb30ac1d43dc8a97fcceb149ffa36ce93dd3200b7cac1465caa0d2ef25126ec2eecf946ba53801dad4353adaed38fbacd9ce14e8d61b57fe7e472bfcd4d30a61301b7a9e98199907bddfa783c9b1fbea347ccd2ebf4a2d482eb4726ec1599201294ed5d5acb47cef2415ce4551ce5ebac563cadf35e32328a4bb4c51366123a32a96d3569ef2d29c4b3b46a2471729c2c5b9930d4e1020db212ba0942abb9d031afd690d44dcdd8cd7a435e6b8e52312c95e8f4d7b1ef17ddc95a597b9b347ccf1fffa58dfabace5dbef80e96d04df4f6eb395bc75163bddfefc33caee570ea66cc8b52360c38cfbda4fad5dd1b5642ed6e2c387996b55a2b3d5ad12be5471af1ddfe5fe2a0cb7761fc29c7fbd3bb00b36aff2fcf33e3c04bfe611ee0e0677dbf37d36e13236f7084778931dc24951e3007336cd83b9fe7cb05839c87ede64a39f12c4f5830df890bdf0003ed4d9de3de6efe3bfea996f9dbbacb0f218d0bf44405a918eb88028d11967c46581ee14a45bc474b59ad6f12834f0dab7863879dcbe5995985b6d9697e1730e8ded7707edd7bf1b106f48767d17a94d17efdfce3397c1dff8431775dec673533a51bf33f6006f53aa6385ad41a07a6648c0d6321b817bab2a3a005698dc6d2e577dcceb78b7a4444dd8c32a39d5191277eb95e11618d138ef13c6a5c660c3d52719ca17cb6706c2091d6a2d42413dc3cc47e3ee3409eeae32ec4897783c10de4dc73121ecf6b72e895f29fe7d7add93d5f0e2d2594f06b7ec77bde50eed18437a3052380896095d639e0c27a92ac03be830a5a11734ef35508ba9daa79c86b3d9e4f4620831ea280998b48babc5279eae409d6de5cd8b8252c5f71d68e4333bfc4e5fb597f44a35c3a6437ab2efad2bb1be5889acc39607d3d27f5f15cbef97c8a435d17b7603d03e144b7a178dc66953760a5b6b29260127148f87480cbae4c1dc565af1d66f064ee10c8c4d4082077fd4a875969f7b884926b3466e668c7ed78232a3e52a6b418e52db115a4b5f4980db641a9d7fe3ffa9c93438ecbabd589d7fb5bb2f516ebb983795629988ad73eab8fdf9df219c1757d3d68f4e823af55937c4e680c3360dda95af394ab3aa4082c0adc86a66d62a773033a6ae924f7056f8a14e8bb100cef88f3c7081db81302f472620f923edea665aeb3d21f0454cf529aaf44c406d86c2a06e433bdbaaf47f7c7be25b45b8470fb82a3ff3fc86becd7777feff3ac2edb63bdfc414e7c9acfcff21c0d26dc9332f28dcc2696743524862e338399d4c4d3854b96215511af3827627827e174237bb59393d1800bdd0a66ad956e42120e677e096ba1c913374bd32fb8272bbea60e1731e0784e559b462424f0665cd2af6b22a31c48611d6472f601a3ef4b7b767f870cb4fe5b677241ce2f6fd13bb0df379ca74ef7da27fb611e27dcf5eb7a07a463e12cc25b55f0674eb19f1adc0c7b6f3e334b33041d58b8244f4cc99440930c328b6806fdf1901007967199cf17e12f30030d6435c1a18b424ea7bbb4c7dd3dcc0673ae495a1142049ff05acdee7bdc655763071cdebbf99fc9fd1d2c4efaf430eea9aeffcabba1ab50076656b55bc6a65b158dcacc20536aab28abe5635036556cc83b5a5ab982daa6a5b618cfef17c5c8e39576659141dae728d0a3193388a17a6f4796ad4f00eec58438a2c8416c4efbb8b02deae024a3e45677a34842b8b78337efb0d5bfc696d9af59194744cfc4709954bcf85efc63fadf6dc7c86fa583800ce126ae1a1d9bc18b5ef9309f53dce3ba1e72ce8ccee613b6c3aeda30fa7b108b6142eae6d1df0d135ce1c7392f3784ab98b09ccc00ca5939d832a39d659400bf6c4c5f4f777eef5b0ae1388d14e4d55062d0f9a9ed4de272e8a5ee9f5d1ae96006b67051adb7d772f11cde7f2fc3bec349b0bc4d8feefb315fee091f28e7d8db741ae7fb3e75843c0530f7050fe7b66f72474e63914319a138eef37ab16c7178a54f9ded60a544b756862e95f3a78d8d612943b84d0d7d99fbe5336ee7cfd7a9e6ebd4558d74c9e3ec84279539c326ad5fcfe917f304a7bbf77d1f3ced150e618ee6a85909062319a10eb35f2bdcc7604e7d536836f8974df89d33742b6ed8bfe3bd9c9fe3d9f909372c66d956d92d08347142011f32469ea93ddd25766604f5ef5d26f08c30592af10b28d4c039836c06fe1854236366a8c7c42d7bdff90571c4ab58c841b81cfad2fe63ce59e767bd3793b5f73c9f7046edd60aa81a7371cbdeb7d77bf30ea3e3eb3ad2fd7fa79f3393ec6d012d4fbd02b1e8d617b91e0e3c7ab791bb89387070ac538797c7fdf3f6f3b15eec927ffeff47fc9ddd75315695ccdd3f5d52fb6628ec6d62f0828d8793d0061b1fa07102507be041832a501aad70cda10fe47a110e71d20720733555a22399634d491f1814c0a7d05671108d3c5a590223f42828a6dcb050007eed1605bf156fc987bec1b736e6a7fae5bd3c38dae3fbfd3574f9a646fb2246e07ecdd38ad771441a55b17651f15dfaad18ce6d64dde7b15feeb6a5a5814012493d8b1a9d55bfaef59fbb99e80435732f2e034319c3c76ce26d31e491641a4bc4e7d8c95d72bd8e78ce1cf03faa8b3cacc3367db52bf77f03709d7cdfdb24c0c2259f84423ecea31c109bac99abd7548fe2c46d9e3253af4217e3503f76731bd1cc41d142232ba8a740708fc5503ef148dec52ccf178c8c08f77729641b1fb4dbd4691e43c49f14c221adb4ad8c724b8a51f3139b24ad791b57477cf52f6c76f38636fbb3127029a3e98b5e7df9dce2ddf5b11a3c419344c895eca59e2362a5086fa54b58e6709f97b0531a8f099777dc25207425626560e289bdca1c2b99db68ae8adf5b7f42302bb7c08768c66cb20e7b5d1053ceb3899c0bad12cebc755caa5844f920bd800f7b5e070c97c9659bef76f7fba556ebe5ef9ff84582ec32465cdfc0cbd86c060b9bdfb36af8201cfc90d4a4cc26e87e66745636412dad06db8583ee52edf5f371db2ae63d4a888aacb2969939da2c263cc6423ea87e344d4bf81c57d25ed4f2993088948b6cc21a94f657f70d9c97c15fe7276fe6cbbc601aa4356ea4c35ecef287f9fc8457146c7ccd5d86709d46a453c6af2e31c9606e5b76e83490b92ae1069c26f6af95341eb7b2287b22da476a4f21ab5434e75e22231909aed7a16829ae1bcd1cdfe0d48b327b5832ae3d05723de77a826d1211e6899fc88dbdfc94d1b7b0b0e04d6472b497297cf072ae4fe39fe290ec2a99a1aa6ec67bdb64c0eaf0846c9419c380a3d007b8f31d8f309b2fe7e376450acc43f8b893954e68398c94db00c1184ce868b22871b2b0a5adc02f3877d1884205160e19332d1f6630864ce8673f524f81891c71ab1ef143bdf51535a6fb7532751b57c34b3c8ea75e989bc8f7531dfcf6e54ebc7c3eedd575bc8dd4544d52e539d3b8ce22f99886bfb6a222a318e6735107568a741902b98da167f309e7147128781ea43030e794705a0e4b1eb675860283d5cd061b53c00b6fcac576939abf0d6222399f9420e08da90a5dc537ddabbf3d01eff2f517f27ad90e1efaf6a5837659852ef689df5037bf1bf7e5ae1db00905c9b3dacb17e1293e7385af8b59fe1c32ec2495b4831a87be41b6194241ea2824eb2667e6e8da7c733f8b749e5583f6052fe25b58a5b759a363bfc18b9ff412a7ff309f93ef74652c523e31832f6746374d45bb59886090d53ae0a59ea97238490b62fba2ddd008c97b53760bd13c71210bdfccadd024017688a4668ef184f4a2f69e338ee842e332ebf160c1863bce89cf6ddfa2484e78a5fcb452d7eb5ce37f7c268db76711fff80c2acae71261479a18260ec241359c873a3678d906d2c094bb39baf60ccae8223ef7ed62dd061fc8934fb21ff75a9bce0f81c15c79276d6bc0abe926e15c27362932200b85f4dddcf557896d5f6707d47eab9ce14a0aeb1b3db2375987a7bd8c4a8d56a7c75cefdbcf3fea5b6315b9e742ae63c0fa18f2bbd0d038e3a8ce0086fe443acc651617c40bcb5fdbb8e232d6a3c7d01e80a49779e6a87be5e82a36861385022baef0809a2319d4644b26de2a00c0608677277b328923def3dd3008afae516f0eb2253d60d35fe21c0b6e819ff474907102ae0f77ae3ef45bb5e98123df0657e3fa1a2d0e27ea41a0fc1e43bda3857e487a7fc360be4b6b0612fec75ab0e1eabe9fc2b446317674cb7aef3973b9c191b653f16bc3184f521399a26a65ccb49df4f889d7ff8fbd7feb4e15e6c2c5f10fb46f08c81acbcb85121025969003e40e88bb0801594a15f9f4ffe1a15d3dd85afbbadff1ff8df1deb5d69290c3cccc9ccf7c1e3122003f8494d598e739b187665a7a647eb7981fdc0be384cf7fc3dfbb7fcfedc1faccf59a94dbaf79b1aed4979fb4c1e29a55e2faddbbbfdbded18fbc9c40544265c778eedb7e9cf5106fb029205a8c1f8188c4c027f049905227ee6a809db64a466d4e61d3855576a34d39ea73f5b19eab94dbad74bdfc341ed772b7473ee63bd4429d75db74b4121ce4b308efe3e8788f3ce5713fef5feb8f0637ef8f85e32d03ed11081b0946189ddb5d8179be92fcd108edd5606ee7b164599f45c8f341b95b94c304976dc54b36890d2b4a68ce665a3358541bdd2fd428ab511e2f872de16a4223dccc2389e868334063165287f6acfa046b727e2ff98a63e145b331928d74f2ad8c82937e5af50dade27be1a66feed7bf757d59b31818498457a9c1ce1a7de6512becc6fadc6ec6cda52070135650a36ef36bdae74636864ed05b5a62c83db79bcd8d71ceb588947edd16dc056f726cebb89e7566caa5d6dfaee3ac990bde4e677da0536db09dd33620e1b04f385a2d946d1043c40b2a6d4e5b9739d04eed16610d59a993ed19dd0c42e099c86996be130c0e3ec8b4b7a81c5b82739326ae3de0632fe4951c8b3ed3a8b20642473cf83e77f2d7757ca735b5945c54cf3c2ea7d8d0d75892d4819a38ea9abe5eeb57b928ef1093ee72e9b05e8ec0cbf30f7377a13f674ecadb7c20a9333a3526bb04e03555b00c742c02cdd4120d180ce498d90066869c65a51825baa6c57a8b890678e2e45d622b1412c8d8d85b11be5afb5c3542532b01509212563307eca9ca47a41aba8ccb9cc1b25b5cc165ddc0599bc77a9b0bfd59d7f14557b2bf3e974c4fafc5644ff6fc3fb661a7b60e76a953b21afce89c98ea1ef56b36413605c49610e98fdbb4404a5688cc0c8453bb8903c3f2b2b13053923f306d05048bf5691f1bd8455d3a1afa31871419701a9450f36bef97a886f9ac673828e52871733b891e3b6103cdaf5a7ccd4fbd618ef682774038b43df131bcd4507fe0533bc6194250240e2b92539cebff9cc6eada5caa3a714ffa57a7be9c3914bfce8fdf696e2fb57d9ceb4bdaa82dfac1dce312cf6919ef53a6fe4a27f7a8921069bf0762348c91067f61f7514b0d8c4367a7cd008ce39af6341c3ab496235ca13a5eb649aae19cf10084ae9c23820065b91f7065a05e6c336db06695bd2325cb09c8f44cdda88dc11bfdec23ebb3c2bea4c95ea4fa709d70faa576c6cd9ab6477d84d767fc3f5e2b7fff812fedf1a8e97ad4e41b6e135da97ff5b72fb95eed5aee367586651c5dd5c6393cc79815933bf8a3dd561ceb3c8e6beafcb3f6f2fcdb72f3f13ed13014841aa9c30ae6b24d4cb127a949a95bf6b42e35a1756e5888c4a7bf7b59d22e31bc9ac3669ed5084fb5ce61b69cb03ae7498562eafa1dd2ba55ac1a8e755606b4d1e7304ffc08eb49c11ca9d0ad357a9b54c779a63f3ec57ab74d2b560ace76d7c79adec327bad8f6e99c3dcdf9ac429b5437957098ca8e73406f8b833aabc14c37e11458ba188b49a8d053507a8304e6db907b9b45f97b705b6ce0793d9887bf3fc53ad4be5137aadd2307f63226f5c1f7328b2386eff558bdfe9c0487fdfe6d1cc9e15e9928364fb50ed2f2b74696eda12f5c00644e819cc7b5adf1f2b69c55ea0cb799e3a9b4baba77efc59fb249f5e12eae0ef372acdb7afdfb19ff7b0bae02d7b84781cfd1549479e0db4d17544cf77599cb51bb0bcb78fb5ebbe5eb73f988a72e27af75c0bfce4b5ce604fc2fdc0153676888c82be208a9196fd522f24fe3f9a13fb7d6cc1eb1a3ae5f767f5101356ee327560a87e8e580a9a6ccf62d4901fc2b211cfb3aae53bd9d091bbb7e05684aa0b618e316116bce683e22a021412d31a5b9b92016f78967f97643718f9b581709a58feb05b4cc649c5fbbc77c5cbbae07bea907a9df2956b4c96afacc13721ceb57bf9f757c6fbb6384d56f5dd8ab1db2514bf5062c2ad3081522be6131c1642b46c389ef888a39dd9ac3bc96a069a63aeb7cc6c66904b1d4d06aaa333f03ea81536470529a3e2ff7b8822be43c7641c950603c6a19c32bac7b7d426ff361161c6e5247bd706f7fa75636e5702d425026d1351d0cff4ef74090273a3de2d38eb6f65ffb672dc2dbe644f4c811eccfdeb7bbb9d4738b38932d2ad12f54e212d9f13eade42f41acbf8b426a71ddecf1d8330216afd35e39829a1341f09e8c5a33ecbd568cade94c170dd5e32ed3ed2ea078c55dd8a0b0ddb25a3e9070a8f0ddb44a904a0f77de7ff7bdf7737523a7c5abe7bd5d1717e632bec4cbfcd37dd60b7eb8d31fb150cf3fb7e7fbebeddc167cd2cf191ec50c13a1627d41bd7d1c596c3e563bc4c54cf016fa95b625b57cc2ceb02040ec25830eededadac18123afe259955a4e510f93d46a844c6026683a47cdca66e0e63c2f64135b4056386246c12c20fb50c9fdbb3d19fabbce8e7f5acb2dadb7e988b8f674b7f0ffe8bb76d1e7cecf31e8bbc7d6a4cda733bb76910f4394b9c6e2e88d4a9dd6e530657410f3b5cb10de1c375b61c92b84796d0cc65a6ffeed322d352268280309fc1c648b48949aa2e16058ea9035be2e6534cf295efc815ead19e90525bb8c2a02ad8074078697d2b260de469056bf1ed1ab7bb9c296dcccd63ace65f7ddbdb7efc20a76992b085ac90eb9448805c58234dfc62d4c32c1293b8f636bcf22fd5fcbee25aff1abf749f9c02505925957f5a5fe79f0fbe4a70a3afa20d322239e612852ad3c222d7625d70ea9603d1ff314985b0044d19d7d2c1115c897018f1aadd8651f3375dfeee992d6d69e08700288ddb721010f4307771b0a8ad6251a23176a43e057ff674cc4c7f6c2561397cb8151b9672a625ceb0fc866fd8dde51ef2d2de696ca5936fc5a93ef5166d9e6ec60449f9a64b55c330f963c4464e780578aa994b3cc62c0e870fe8366dc436e1689feaff3494aee5c7ef50bbfba6cd938fa08aac1ab671848b53dce0e63afd1dadc02fb91fc68c2383db7287c72a0f89ea66bd151343faa4567552321a16b9e93b70ebbbb2cc226b9fd58d1d132cd23af76363650805435e4f06b21aaee630ee7ca775131b8ee2d22c4228d628921301e4dd74bce3dacb639df5aff5ab3e6833d45673d46c3d8ecf4b1c68ff0e5b77a33ff1ee99577d8ac993bffca037ffd335b04b383a9c6bdaf9def9faf7f6fc6e3fe0cd6a7798767f452d8b40c32c2e5420b8aa99ebef53ea4d172a67d46d2cc9feec536015012907739aab39f43441feac39635652675da88412365e498667d469278942625182b9af9bbba0571b79f0df8182a18edfc78efe43df42b557f1c177d25838b575b447476ddff3736fcb0b8f2d9e16799fd9e55a1a6cead3df3aed659d565e4e7936a06ebe42b6390f9d891102e4910a40a6b50db5a946cbf621733a3de1cdd35433d729536dcabc9a8ee341ca7dc377567bcc3dc56c116686d74b1d6271053771c18738be9b70be71868edff3c0fdd4b60135e37879b66bede1ee139fced1cb5c705f8cef4c331f9823fcac4641a0840ac752485b04c2409c194249ba5b2388fe264a0d6266770b17239fb608572b2374f020b5bdcdc2612629bb5f89aba6ac7e34b202ef7929a7015b6d51d5ad430d3512a262a6996de65ccebb9fdfe388bbfc9e86eec4b8833ff25a73fa60234e631b613373587fe618d8a3dbb8f1a721cfbbb44479a695e682066b6aa0363120086d6fc02082923525658f20a8194e95bf67956f642ec394d9ebb9ab1a3a6616270c303ddf0937d638dd69acd440dc8b267554c3990c84b6daa6658389fbc7f8c04df2757dd7cbfa79b72ebf8a795dd6b5f86fc4bcb86a137ec4b9f799337cca74fa3c4feffaf3a398d75f4459211d731d8e659e72c167860d4247b6a90e373ecff694e64ea8bc7d4c875a1a3deec2daf232de0e12db5b85e170132ab4f1b98932686b88e73c8e3c83948c127d1861aedab4c2098270e6436fb270d9e056cdedf7fa93d7f051f7f19dcce6d5b9f9faf7f6840fb891ef843613a6204c5cd551bb63cc91da9c4e063eb0624944e41bde00d9409765ae53c074e60cb7c2b08c549336010c4f0d65676ab20ba1b795a3d6241a2a03edb721095ef131da315d68a86aa3a0f48a8c3feed8c798d70fb16fde517764c6d92073e0d3bfb17ee60fcdaec4c58e73d77cd49cbbc8b77187fa10d0a4956a0f7f3b9f0dcfed9fe3ecb7d587e05233d3d2643cf2c2a08490c006b3311a08d660a48b96d0e148f4e28969661b962d8d75d98715cb898b343a1a32a2619ed9b2cf0af690c07c95c0bc4655bcce223c9dbbace1cb366051bec65016425331713f391baeeaa24cee54f3088efccf6974335fd2e1de542711db8b5a5ab2024666c372ce458bb5584b2a66b36a3710fd4df7a6a738c220abe06676f05b232bffa84f76f19e7e87713073e9b27dcc77edc17f3f6abf1efdb84b9f9fefef37e4ffa831d167bdd404649345249f3265f5992b9652797148e0328356719b0f666e85c3daeb38a4c99deab05eda3bd8c7a754c72ae5c3a773dc06dca6a71a6f931a6abc1653e16c7673e2ed5865da7e09bd706c9be151ff1a26016d1fb812e6cc50d48f98226391a7205e87d1a31113b861aa2112e6bf64c956be2302e436108da18da1dc24406c43a70991929bd468eea5a75a24ce709d709cbfe006f6834b988752700f88fdebefc41feac83fe5a4fd526bebe55c7aad69f541ef2b73d149dfbdf6541a95aff5ca8c8fba82ac95672cf2440dc0eca8ddfdfeae8c40e65adbacc6fd716f3ac357df7f9f833f6a9a6e257fad1ffd1ebb78e4937e3abc77a6c3eaa5867ef941f7f2f0de2073702e1ddaa6d5504bb868fe69b09df9f17fae83f86faeaeded5fdc399a5dfe9ae7e6ef76063b08a6b561f31d8cb4bfc95577dba56f0dd3aa96223ad3d0df31da0cea0a3d1a386eac6a22a9f61d71ac5b5f825a2a61744ee90d67521355be10cbda4cf03cefe006a281247394c99d291c2896f3726a6ade5f3bc0f3455a2127b89233de6e2e8834ff7b5cff18dbdf5fadcbbc4b1f1d64f7f775e9e6de23f5da38bcfbf5813fc1e27747f4d25ffb3daf62feca41f024d408ff91a7279ed35a192ad284d5754dd361c3f1a291440167f6ed3a10cdfe9bc5ff2ff3ee3b9bbb01e7f74b739df394fbca1f6a5fae8ab3e5aa6c935751fd7ac6a907480854a10fb85dc06043b412920b1c598ab95467b1c679cb904e46359c403098375524d7a596db6b456790864e0438b86868aa4037caa69bb78d9e602328a23b1cc7a18600e27fe871ccbe7beccc57579538e913ea1fd077ce47d738ce1c0b88843bc766e4728971cda62390c7885b9303c9fd9a608a1a76530cf7daec284b645ccd932a12df6a93715ae855328277ed58d65c50694e31811d6a7ca72167463d0a8d9498ebbb8449eefc21857e2218ed044b86a8e6d79b3f6f27bcc9f8cac239774b60745aa771f738b9fcdc1476de01fcfc1c73efc6e67c6c7f374464eedfec0fee34489bf52c77118059a3fce51c8959551142367c84203d58c7830a3d05dd4fe9ebad63a2538a74c2d934a5bf3924598a3084154e1d2a4598101a16692727b27a2521305db08addb27da6417b3c71da560fb1d0ddc9fd8ffb75a7897343b2f9e035fc5719e52c3fa1637b54fee10ffad86bb1306d8dc666ef05c5b724b5dd5528cad955468bb8030960c15698178e28826258f3da7a53eed83fbe448b8777847fd7c8ffafa5e5f0df729879b246a8ed859e95ce37ff0ef743f3d8c2bc85347fd7ac9151feeab1ffbf3f939fb15874cc592ac677ed6a348daa8c9b43ccac68af8a5640b9297196f77582fb54009b228901b47b0c144a845cd96fe98767ec9c8a2c6318b240b0a3146a59ac50aae39f182b49a6c531a680ca86d52a250eac8b89d97f6cdfb83acba560b1a1c6cc81df2d61fda3dddfb0caf8d79d72c2adacac8db1cf19de1e0362c32518c97c8a1658e856dee85c23bac6783690f3d52aa7a4ed008d50df41d1813269cc4c83aa6094396bf35aa77c922920c55d0173d7b10856565a3612074b4a446a611db1cc81244dc064a7269108a62df865fdfff3eda8c679eca368e509f70794de350fba8fdfea3b3e243bbc7b5ae7b7f0547da8cc33ed3559d2eb5737bdf8f3f840cb6d27d045ca9d57c34b4b8dde98cc13e2b958e0c7f1f68125d8c43bdb4ad9e32c33af4ed7a3ce63d46ea47ebef9913f4c8b3b33bf6e1cd58bcf4e760638d9bf5c988dc619a97c9180e424d5902609302e60aad438bd17020359c647a3bf7192b51c56aced4dcd7584955a6f11204a4643663d899eab9b1209ecfa8bf0eaadd9a1acae7369ca7b5fc35d31b33190d3b19e1198b6ecdb1fd7bffefe129fcfffcecfa37b6fdbbb1ee8fda0a376b9161b588a02f4b112dca6e9d11369af3b699db8233cd36fdb1c7309bec33de0e528e2de498be58b646520efd80c97ae13663069a7960e43becda2689049cdba04da09c67cbd69bbb591f94036dcec4c0ef85402abf171f6029b868d28ab699eb6d3387eda5a3d42bfe9df7e37df81f95ed411ed748cb2a58bc8ae374f3d16037e3a65ab8c1359cf5cbfeff26c6fa2e5cb1ffe6f9055ffdae1f5a779bbd39faa4734921a4803d300af6a9ad62a28b49683436aabc1d75692fa1d27c23d793d22c69a9f054138a8dad0da9265ad8e7112db25da0437be1e4805412d0de8bf1be7593aa3549241f16359a23d6aca5ad5a51e5fecdd8eae7f7ae9eedead5fa89fb8ef74bbb077ff179bf9b7966a046e883b3eee26df5624c05dbd8c8dbc59899311f4ea836a4d450fbc0507548b113ebbfd7b4464dacca3d29b55d4c70286ca678f85b0b75d989a831708d677ea4f63ea03a327291b8704af5cea2bab6cfec7645a0f8459dd53e75275a7c8527fcfb7927ac44a59e0e3e5e560d7722f2b4e778dd897fc17ec75175e25f9871b83c8c71cc91f6eabb8359f1a74d2b3690176acd3eea449f63a3eff17e6fcebfe3de781d47bdc2ff3a7c3aec7939029bc3f926f8b538fdf19977e09fffd0ee713fa74bf024a2a03de2dc1df674b6e737f2bb965d083db120793f03de26d63c1d4366842027296f1fb00dcac518cfa8c13c5975db403731a7ab3d71f02828fd2e8e904076ae892a8fa54e7bc6e43a2dbb3cd120e5257e8aeb6625c79e97d4594f088419159f684b0e9fe2ab9c10f7ca0b1ddb3a8d6185d461dcd08d3c19d84579364611d3729601ef21d362332dc5181519f0419ecf29bdcb7d4e1a5e9eb996f9adfb9c616987b18a237c1d6f3d1a9877b17b6fda3cdabc9d74d436ada076c45b9fdab9edfed6e3308525c0257a4a5c5b4b9437608a05a186735acb3d2bcd9844b0c7066a582facb0ce346e6f068903b494d83ba9f9bb45642541d919882a2f1b3f02a21a941565373560e9334f97259b4b3d3392aa09f115bcf54df62efad3262f36e5cfd1bfba58173b021b110995d668251dd6a4cbd7b9920f79a5c3779ffed5cebee705fa8febb217cf75d9eff5ab52c32b6791dcc7d19fd7cfecafd8c9c3bedda43a2c6791b54f0dac62037f835fe1427f7fb6bf3f6bffb8e70ff7bcd419e662743c97b4c35970e46020a7f66fe355851ed16587405ea70e5e07e5ce8c8d3f20a95a6ba6838a9410247cb323aad1590547a96b4d1388e854172a73ed5e0265a57c88696d4d934ab8a8840245d260ced04d010bb25e280a2d435462e547b6962edb0ff7de2bbc47403ac322e6e6d3f3de8f8ae0230efe424de5e9dc9d5cc354ed8eda281552dfd664b947ed9471d4bd7e8a75b689b9b739e6f53f7c76f6716fc347f7a847f1c21e26c86d76720c95808de075a3272e7462228054b0f02361306eefc2de1a09177bbc929850384d0ae5c5155b86a3769ae872c62bdf4c46edc81f1fec57ee138037c8817f710f472935f74c359b5b35b9320716897eacb33872405daf21bc4b3df52ee6681d73a94e3c3bc7bdf4feb3162d07e0d67b7bd2a3a570b47d5a4c80745a73e1a0bf546b7f05051bcc9db66275be211cd799ee055961b909680aa9e53d71ad654c4411544d17184117ea5d11e8f90c476210daaa60f6a4c34a2019c96dc29bc42fc440448f80dc8d13546e9fef84f38f58e3d338bf9c9b2097115ecd22bc4d74f6f4a64ef7020fc2cb1c446c9f3ed7308697729bde730ee8bcb7e3830dfb4f72e7af9e77358fa87fe4e1fcb92ff18c5998edb57f3f93f813decdabfb78e9f78a0615a454171cd56a945570c7c8a3998d5915ea6c8d89d7ce34d3484bbc8db521cf6a86b1f2bb992114e1b25cd42c8875f381105f23448ca5914773a799ccf46e80b90db2d2db628731695010da39fd4efee44deef62bdde8daca13fdf777f898bb3bc42877316fb7c77177e03a7daebb2637fa6d4eee07451e2c08fec52ba450e46b0b1e98dc6db6990b0d56c7db0595f304c65d50ed0644e13630ec0ef5711f3a6ce62f5b2881a072d96e04958a8ced1e3be6caaf6515d7702b8108b88d3cd25bbf908b731e5dc6d91df15cdcd4661c6c85cb36ff2d8cefc7760f67929567157b9223d0a63a0667adb09bb55630b0f798c9308390cf47c3ed5483c61caa4e3a22e1caaa88f222aed43aae5489895aa3c8dba5a3e12ae8912eed7c1254c24d89e789aad43326f954475b6ccb75a6d88c97708009f2532300898e7a5a75aba97e2f9ff8a89bd62711fe176bfb0637d7331ffb39feb64d5d76950be38ef378a1edd35c4ae7b13d6abf71eff05c206f9fcf6e46e39d64280f6d9313f5673d77588fa289c95c2b4fab5c8bc163f79efbe14a6ee3cc53dfaaab3c7efbfbc4bbce63b4165179f2035eda3f73cfdd1657dc261550a4b03a316a4ddf69fa45c9b41494dadc9deca8c33ac4b141285b87bc1b1383ea94b00a8de146546d2f410e42038baccaeb14e01d714c33e468929289c678de2d461bc05cd8faa57aa286f413fbf0ff37fb5c87f7ddc591f7cd9a81ffbc96f96d9bffd6dfc1ce1cf9294feddc6847504b40b0c7dc9b64a59a07556c523031020d43e2ca4d58e416a6e6da07f00969c326d1365a5a0a1144b4270656feb29d726a7259b5bb80329c127fcbec6e8e69e3e0d170c0cbe6efa25603d1a359a0e4c3e2d65ae6faf48ea73bea7734b1fef3fcfe799c8f353be733f0dfef24f881d686b4437d32885983b0c3ec99811366f8261dc7eb8c58d3390546a2e30daa73c48a9c2695e9d231ea4225a6fe582c850dea44f746a9ddb1b9ad4a510efb3042cea2f046ac877ba204f5410e48c93673b7098248dccafbfdba86f03ad6f81e1a9ac6eb1acae35a7ef5bb76d4cebc5123b0f36d6d3be72c09dda6cd0acb92bc8b17cc32482592a4c6065f0ec340359bb81cf4618fc638f278566d800f837dc09008891c2d38dde148a84413c2d754e05353f34b3c91c4da8bb0e5be6a266164a1c460d1adb5d399a39eaee940a1e5c17f7b1723fae1f8a6d5ef737da8b93dfacdc47ef26fabf92a336569196fd7548f77928b815fc95c70bb67ae67e24a8d4207cf438ee3508f01b107bb0462341f7b84dba5b680c29315dd4bad334895997e453bc2023d25e86fc0902f89e0a4970a83529feaa0c53a336facf9aae2233fa6a784f32a1f7711f3f9fc5d948bea2dcfece495bee647fe67b18923dc4b77f22687f0012b591fc7fbf0dc7216219555ea84ab88bcfe6b7c34040947eb1917472c861c019056ac8f75b87bb65967cee90f71c3c35d3fe17e1b57c36d1abec6944faef8528775087ae9046da6b37d72c6d864f5b57a14ff7497bccfdabc3856277bfb69ffda13cefeb678028e608c5ccbc0d0dacb3142920ead80b1116174c79c0d48c064cb391a13c22aa22cb8a8e498f4deafb06013a11e77b2f29a70ac2671d9d4a9639a82c19e14a51e1acd53cca94e98b4d158ee783901712468f6090773e67a2a75592942b0f946de777f17bfec4d9b473bfb3a2e7cae9fbaedee21abb6388c2555cdd66730218ef78498e76360edc47e18a5546154b02e05324a1ce4867abc8d0ba632a75b273adcf3b1d5cea3d52073ad711c055acabb878cb19e1996496a2684f6bb67ca3333a526d46862746bed726ded4f35fc417b1ca3ff92cee861ac33873d891138deb18f6bf9fd673fd17500f64e1622ce78334a0b6b42964316705c06d5ef8100ab7d58f9b79d43aea7a48b9b8f319d0b67fd3d703e873517612de1e758cebff65bff332ea4afe28320d7488f7bdfee7ecd341ccd34359d3358323db744916d49050206609c68623f33265ba6b7a16f08330c373b59e479cab0bd70544e19f217b53f20a5b75944b82250c6b35e02ca180a59a6a35e9ac46e37c8fdc9fa3bbf2fef8ef39a2dc14af06ef77c1efc17b4557659c5b423a6650936c7333e9ab489c33699c3f62fb6e08b7e1ef31fb7faba542ec3de2be8583d6515241430674e077bee4a260d582daacec255878852221db524b1e9962ddbc9dcb14d49cdcd4c1fb28c4e3ad97b908ca916568f3ba2772655a89c43af62404d7d1d6d99f23506bd073af6eea5b77df20f386e4415bfc600ecbfcc6d9de77a1182e5e239a6f1957f77270e8af31e3267dc33a5c3fa57fbeadf67843e1db9d36e9a3fe1c8fe4f3f67b8cd4aafc3e56690727b8bb4a1ef1bc85e2c877c11e152dacdde1f07da0c4016d678e2bb7236e7dd72ce1b3f234a0b6be52d20332484d3d095795678a32cc24d4070130049a4fedb0ccb6ebd283fc9ffd7d63ed591ca0cff84f1705491ec419e55f2dafed97fe481f9e9fe19162242fd09d7859b58dfb471e4d5cf7be7b3fe9d6dfc8d7859b4958c3d6410aea423f77139cc7d22a768df82853da499ad286732c7e08f31d3e02a05937eaad9eb590fd53c42ebac6e546acb66a6e3785132b188c472e1b225a6b1cef4c17e11597d0cf02ca1ed1497e2c9e7f056eedec378d447be826f69d9fee758c5ccf5b6c2f00e637cbcc7fc6bffacc77dd35d4633a8a326d2ee36e998f9c231672105864ffeecc2703358d84d4c0b56b3dec312489180404f68a3c7c45a724769bc6cf319c851a6d05238a0f68dc99e3b669e70fc6bce204879b063caca49e425a91d9bac50fd11abf6919b6c777857c1e95356b1f61b3a1bddac78bcc358bea9153d8de79b7e9c72a3f3db34220ca4e1441a394ea37c96d6b48fd904a0b1c7a6e071806bb52375b314e56a1df42ca614af7d8345899283b4883b44601e52e04a278f38f362e642ea530a52add1c5bedd2415ccfd72384dc2968b5a8c09b00737e7465dd65ef5ff3ede177f38c687b68eb601a4d19f1fd52a1057268bb0ddf90039590f8383ad9de98d888d409386a5a3b19a244c8d331e98b4ea0ac41a2e9ccd8e2d37031e353aaa9a10516f93f488d20a04640c2b398e4de6e6816f2bc44b399d02196045f7412956f25e9c9dd5d1c7dd8a2538d8521573edf519fa019f97ea6621fedd59fb6bbcec99cb9e1627ddfeeb3eeb3d6a230e7358ab22d54fbcd7afda6f4f3c3db7dd9938f47a5a35a558b67f11079ba9516e51296721b492b8f69c599fef7ca5ea985853eae23263d8e3c48b0561dbc46e023c567d4cf1342cbb40d67fcca96692a0b6f6ac164a5638e6b55aa6d56a1f1bf18068acf44f352897c671175fb3391f35d17fba1f76f1294e0d32c73e734fdc366e89cda6e1d8eae7d08a092cb7b18ee3641cebd23621a5f249d8781fd2769e51738ca2bccd6ad5f3baec13c2c6be3e84a9d63dc5448a800e7331da1892d87b14b6bfc2319c1095b3944a9818de2a2e50e12bb1bfc02bfcd3fd708ae184a04e75a8bd8e315dc1cf74577dc8e5c09c15c17f3e3f271c7897ed357d5694b7f2065a3e6f9d8ce62ad1102544168bc202c219b69cb12da76694949e8acbbc9df5cc5828bae52edc07ca1b1125556c601e8e2d1c72359f6a268cc16a875dac10cff545991b713d194c418e532e0175f22952b2a497cfd34e720644084edc8806ce337df31d5cd91d62ac108888a919074d6c785be9c03e39fa86973ed74ed8a9dbe2af73c9e19ceab62eaa6ec6c66c1a332468d44c537db34376f38bd9bb2ed06c3da672250bb6176517f9c0aa336aaf09f1c6896b25949b56d0e7abb9536abc14eb40f9033e6661c65b3b28730b19132d71d85f5fdb989ff82c87757ef06fab636d5814b4929b2ad3519e39a7f1baaa0df99f6b0f7fd987a38d8ed8d14717a7ba416d16b12711a1228e2c25cedc98378e3f8ae96e9b1a70e58fbd832dda22ae81b0f0f6d2409c8c277d18657b6ab31c03311120d8cb5268731b5a9931d9a58ed029b58170ad38ed15a52edd65f5ca90108d046481d0db65ccb55db21c5649c1124272f39853f838fefbf85bf1c23bf889d5d126ece3f37abdcd1f04a6af7bae30e02c29100e2a3c208ee727fab04d9de12a31441f90bc16366c18831baa79d3b4f456a21aac03650d448f97711fefc538a7b1e6453e61461c095b54522d6c54c73a2a123d2f782d4c6928cc99f570c51ffc36aefaa4f9010ef73c9556c13f1d9bf7f1eed3fb37a7f73ed6087d8ce957fff8aadee126df73066859a576cf58b9f8304e9c3dc9335ef7ff9e787dbeae41f84c23e76b7ff73e31888ae5e2956e9fe0b03deec34b9f13ff07b1088f27343791d6cd04c3bf90339ca7555b107bb54ea120642cf4cc518e608ffa4c0ffa14a0c9dc6dc6ac976c01ffec0f3e66e26cd6526137286ccd377280ab66427b540a86eb446bb71ce666caf26ec14113727c2396563d250e3bec83fecdf9fe3e87549ff509c1b014471ff28587a7fb58537ae4ccd112be6b85c37659c58e1a2b93efeb8b1fc6bb148eda7fe3de03eeb70e7093d57f8eb6e35ffb5a7f9b86ced1861484e700e9fe76ee7a65e2b4130e65cfc3769b69de4a2864fa76d32486dc85f6668bc2b649f9ef35712d154788e222df4acaf6a1eb6d386f0d36feb39eeae6df245200bba240dad0e18451df606ba956838c03e70af6e3db3624730ef7857f9c86a7f530f9c67c49b570ff3c65eec157189e700695d8c4fc6aaceb82fdf9d1d9fa651fce7bba1651be9bd547fcfcf684c7308f5c38a7da41ff567dc9fd14d8bba067f59cd08ee89d48ede617aa1540e110f93df2620341aa751be2887e41554eec26c73d7602e2ed91ab82b90d74568229632c981d566cd592ccf196b16a36b467f5829b4bcca49f445693b0bcb9d73c0b87550937d5a996c052598dcf3cd12ff7dd8f351e678c9874bdfc545f7dfe2ec99efc11781251fe5e9bec364eea0b757257b991c24187f61fb8c27eba86ded5c6fe6e67fadb3e1df309247bbac03b7bf51ec84a6f33d3e593a8d014694395556816108558059500b20fcadc4954accd89d72f2800c2414f9435ba1c0d6dd9e76a515b05d172c1559ecfb49589cadf03593fae458f07a86022d4f30131a4cdf8a3eeeb907ccc395e88918697c6edd375f36f9e22bc3dac9d8483463a4a7f1507799ff3fdd76ecd9ece352b6d7c384b46afeb942fff4fe2c0fecdb9f1fe5c3af57915477e9b19aa8dabe1e655fdf3056ebaf3730f6b59879b7ff51d2f7540fb8f6be9a4a57fc468e86cf0e5b977eacfbfba646ef699c35ed7590f2e72795dabe1bcd8a70fb5b8afb9e62effcff339be378f7542a981cdcca14ff2a80fce5ecfc9a763f78c3b7967470fcf3dea196775f0b656f5266eb4b7e3fc9dfd7fb19f3faab1fad7f6911b2d3a721bd7227a3c6b35fc808b8ad86bca5b181b79439c6e8480800b2ab405f5ea39c1ca1fe70f4184f48c488751af0e228b66e1d0f06bd5065a67865a536368f50bee8d3035b9b46d83db08632e2177f31975864f78dfb652a970e13c6e89adbec3497fa9b6e1731ff11b7becedf75ff1dc5fe273bbcad5f1999ff078b7ba8c0b7d78cb27f0b26fb573bbb7dbfba4ec4a69b387a0b03bbf120fb466666643331dfd063e14212bd528e498533a248c3197d2fc5758e041a0d0328982811f35611c79bf902669e2b410abc6f4995708a6f60ca8823a68849585a5969b01f73ba1bd8ffb5db0f7dfe7a33afb53d6356dcb7be97dbfb4f7da573bf9df37d7bb254453bfc43837598d30a5b69114b91b00b4a1b68ca59e01ea883620b0cd6a7b17aa3f5a5aca5532a61a71e08c1468201cd8cc0c31611403d4e35d68483eb787834c6788f63190c49b871c6c33000baa05bb9bb1d7ff6c501b47ec88cd4df5567d83db617fa7fbce27edff6edfcc1187e0885d76866bc18f5c0f3763d7e8a8dd30a309b21ad5a21cac19653b0cfd9e91dca2b4ad6780fde5ea514f192461cd14af563da69bb52c4d48f5611728b40b14b37d5db692e01e176a430cf49743f917177627209cb108aa94c7bdac58e75fe1b0f9be869b57bc8e7dccbf8e79bfae8bfb06ffd59d74d78df77575efe6eff899067ea09d3f8839121ce63424969500a823e559446fa06f888798aa98572d9d47728becee0157de28040a63ca9ed212cc83da9a651cb3ac2c75dae3391b5b336aabed0c482ecb159036ddf231f3f17248296395efb0f5bde26059f5a6567c702df674c215797accafcdd9bdea7cdfb4798e371cf7cf5e567073e6bcb885bb01f965de4ff5c64c2329420d3f0404614918c7fd23c063db20fa458db197719c71b14f75ed0553fc2d7ccaf20e36ff93f6cf67c0696f86a0caaa617b8a0d1e7cd73376e2366c7d2c0aeb89e954a735528b4a3924a2eb20fa63c6956a18f7dacce93aa47c7366fc5923233338cb8399d68c4227df338a6dc673230e5b3da0a629b907322e1206b02e18ddce342c58297b6c67062d5b7f660878739effd98e7f034f7117ee32e3f97fe8690d9ee7eff98e7be399dbc4fb8d112ad5b022e709f1cc85822e56f221d15582c72c99472b83f45e92389ac96d9033372fc3920d421df609674e604cd60b962733205beea222d1f226d4779d5fc1bdef963a77548cddc73e25380c9d4177377bf1be0eeac5af8dbfcee7bfccd7697d7e2b87740f3fe9799e4e7be6eddc9df7d1b98ee8364d4867b2254c1dc65e0b786b66c07316e37c9750d3f323ece2d2c42115966f883526c8cd088692da9db0635d68f96eb66f75019a2ed3901b567027eb72400a84a73dde224d18b28680da4d91aa9541953291732b26d55399616dd31aa9d451ebefd5acfde7fa7dfff46dd826e1ad3adba6b79f9d70a6b7e887af394735321a2d2973879748173a0c7065f7a96bb973da6d05ff1213fdedf57d419bfaf5fd7c77ed7ccc0cd65ec759ffb90f8faaf1d2def3ba062967fb19f9732be67c20f86ac739c318f83ad1599d91c781afa18e70457d3b4f7cbeb90f9f9193ef5383d5676dbeff73c28307d76cc735aedfdda97eec1ef622388f65d01ed7e8f735274f782e622d7da0221af9062d503227b6c1808717044e42db3682ca36f0385f49d5d448318838f017bc9d2e20e498787f25b13cee786eeac00985d62601e59a6903436a22981a921196b741292cdf811cd54260f009eea7625ac2c1477ef2ff57b5102fed9d7c6ae9a8f68cf7bf5d5b5ceb624e1e01d35b98118ffb953713d1e396d8c3079f898643f1e497adcb39d5285466a6c19273fc378dbc9c53c53220d6dca503d2e33c0d378369cf585cc11cebbb2ee3f91639b00b280c42dbc4c89624feac7ea76220d355f50dcce6ee2ef89c97f6ce6318a146d4e5b9cef736ad2a46d453387e1cc40455f17ea8120d393edfed6680053e55db4c5720e48dc99c4723b13d9d438142a86a56a10a1b429b8f4b833b122485c788d6d982962028b37d4ab2ad8ca419d38eb3b1a8e21a8f25c0e6b9cef7c2188af21b5886fe3e6bf0d0d671ec2ae1f867ade7dbd61e2bbc556a8872518a25d14b03ed8751cc9b9c6a204e7aef8138da7a619b9e60b0241480a0904dacaf8cb8dae88baadce32277b106070997455a6227b39b495c9a26a950bda08d9db03febb9633e64aa043168dcacfc6cffaa36ab60f51dadb47bd8bd84837dcce3a3ed3bff7cc6b3de66ff42d5acc3122489065d5c8a808e3d91b13ce1d05a12dea1a092fdc26de0dc567ed6e30da12a9ef5ded6b77726a39e31a7bfb79ca02daaa523f7c366ce941f4756c1681349032e1382d6c2cd3deae0312a3c1ade0dbf2737a9fe5cf3999d727a5f9ff5205d1efde03c753a955ecbbd87778a45d5ec6976d4d0829bd4619ba37ff5feb3138fd96dd80bc236080a93abc900955d32d33b7b011b4a0bf137a3bb414005f495bf0ba9f009fbb347255c2635f25909ed859d97893dd9c6bde5b2084da646d9cf19ab02bdec85dbfc9adbc30d8d589072330fcb214a353ca1d4bb977ed32778c05739aa2fe7f1541f1cd7ac1267bda42ff61b38e7f7ffd3fdd6c7fc70fff080a8c4f9cc7cdb8f19a1b773d145dece0768eb8fe52cd6719bd276890d51c7d41c5086a65921971808c2aa0da0bd821981ced4b076b1f2b6a8ffb3e69ce5d8cdd7b267b618e7736a0fd6580bf4b86a9e38d7f6ac6681a4284e230bf048b401c8f1e55a9e73cdf5291f746d4cefa5477f1ad3734eca7f35a6cffdb8b516f338a6ccca19434e06584e4a1384865c0795fa9b6a07ff01ced072a808113c893c7dc1ac28852b2328215e106c4ff57c2cab472d28c426a4d93a555699389e234ab5a4a3b666b61cc5865766da306791bfc3cb3609cae17b7d946b7157259f7de973bcfb4b5f5a67853cc6904e18b43397c8558cfd5d78570da46283ed9f79eb8e36ab46eaccf775a95f07fff1662d604a5832eb4b23adbc0752306da6edb699f6a8a7acdc630e0b51351c1b721fe8882484d9beee69b4fcbdc76035c89cb80b7bc8482193397d0461418dc46938231e5ed4f9de8ff287a926daa0ca1f64c9d68b12a1947fe2fbbcd260fb62fd1bb3c27f4277b029177581f683fe56bd4cea0c15d61a918cf349d8e311b37f6f63a2a82844827ba40bfe7b1b1099b01a894c210b95ab415a97665a4dfaa0803cabadb5a483f5a2500f983043941464633141765724502599ceea84c13a2e1b7b4e7082d58733fceb3bbaeb81194779ace7cf3839fd1b38fb9731118eaac4b57bd1bd78929e79ec4e75a66fe6e6d48f1ff125b97c6c798bd1701c5668b2a09341dc633331ac09d69425cbce24867c48754f23e1ef8118b594f2d612e3c76ea67b30a96410ba5e1557b6e633b11311da23bd8967463060fc714d0b04f958a980f920aee83a5150dc4bc3ff9d2ee1337fe0bf790bdfb671aca577d853acababcfbb867f40cb0ff78cffc8969df4bf8ee7ccf9674dff04177775cfc5856f32dbcb1944152b8419d45e9e413a98477f80285b9568749f86c3b9d44d3bd5d103ab3d40a9207e38d40505b5701b401df44434ad47b6a607861cb03eff1b8e869b85cd721479a354c38a4512209a4fd8871af70b3ed8f7f3df2f6b3a33f0f6babeeb9f3bf10c3c8f3be8a5333c69bb7ef84cdbdd8e550434068d8e35801644e9a98e2156a817c4dfa5503669d5fe9d6a4d4d344fa7ce602081e749d7c254a17cc1f362dae33ed370eff73e90bcdd24bad0298353a1edb6cc106d68773c29b0888d789ff5120700a24fea007a11056dac0fb789aed4f379f98d988e7697da009d69471d33bd6d4e3a4d87fe9ccf978bfdd2f6b322b8b5864009e84de60e18851a8b88121e2bc14cf0669ed66cba703a95310567a021c241743e1ace05d7cc990edad440039f78bbd8c0e57c6cf57e3934fdb13523aaf99555c39ab086200e724937fb99a15a32864b5975fa67639d386c1973b33ebe3307f9a92ee0bfa0d76ca095e05e9e56d9b926003e89636efad2e7e77cde6d63bc0edd7cefd74d9241a50907ec49013bec34fb4c3d6e7901f7b4806bdce7f662d4d68961cd7c9a6982e5ad54792f75506002570cca11038a2daa6e1f3365f8e1d0e4f51f9d47cce624337884f5b81cec8403ec2bba1d379c17b98a2bf824f6e0847919ddc02179e97fff1b75c11fda7d3b972f38b99f689bed376b618b9574d0e0605f7c838de2c81e601b87c836c1c2f694b4bd5f412f134a87ab94611c72738279a0c70aedb9831b1ca95f81215c7f2c1334c68c73ec533d8f58a46239666866a8d5a2c855a2a3a57f25be72e1eed708ddccd311500b475d8bdbf777aa153bea6ac57cd78a286fe469bcdff4e3a8c33bba51eb8809161681894b7fc0087c58b832216eeec50ad3acc43a71cc6ad60b8a1d39e0159acd5d39a045fe2bebed7ee15a0364e44bdcc7bbb4c2a3d4c9e759291abf64485211a63ab353ad794086d41288fc8c047bccaf685a5f38775307f6c97f6d5d7779a63f1eedffa95dadff812daae7ccee1207aab82e7b540e0935b01117f849dac8c59acc4303e54ca1bf94c403517a8314c042467883b8207e240027f6201c23831a419f94c2c435de27c6e33a34563b5640773e6616b28119706c135eee6fc69be95d13ebb48db9d927ff2d0eca376d1ed7ef26e148cd387ccaf4f267396a0ac6848b15277f34df413c848176acf92c85290c2862c502ac9a59680f6ba46d0c5f071a83724aabc9207355e0ebe29728b0b77002408da6c4b4c1a80421e3d99669de13d1ba81d0f344daed4c461e241fef713f8cc59ede3933b0993a2f7a4197b9d22b78acb14847efce878f79ade35ecff6a092bcdb485d95d2793c9cabe5c1b74975f5f49e4ff0e7b519aa9f710152a733128eb564044ebc0291b53dec8b6f61b5efaa63fd757f9ef1dba2669bd4958d70f16a76e63ec89c6193d6c18ff4ae4f31c9c64cb906a6065d671aea2990261eab8e5450252aeeb12df4c446b358ef66c251bf38875316b149401e7b5a767fe3423e5183b96985cb40cb5d5958ab64dfce38912342e1260352853d6682673a66b1cee1079e9bcff7fc9b98f0673ec43bcec5af63fcda7d6206afdb3cda826d5aa962c6bd6daa6bedb99ddbf2d2d09b24a3a13577f18ef5722fc9a399bade2601540b22f48bbb41271ccfa07ac3992e0136bc367573880c9c4b205a6c7b9b90c020a41d4a406e2dec864a03ae8481a06078b2a8563d2a0310e86022006c49f501aff2b56e6d84b72957c52c421bc1d9ee4d1dcb873dff2947e79777d4d460fb838d4d39bc86d33ef22adf23ceffbacd539c7308b2ea60d7419e8db4733b379d9f2ca9649eb9ac657ab7243c5f0795fcc5c65224ba0f38cb191b073a2eac2634e8806a32ce88b58c0d19208e7fcdf4c71d75babfa8624f610dff2e0a98c4b5bd4fc72c8a2328d2dae3712d2302245ad0b8c74560dccc7bfbe61dc18b56f6f531a74f3e29efb17f2eb6ff71fc5ffd8dfc396adece6f9b8b28d5cd1619cd43a0a9e9a2f45ccaf1686ae05506ac3c2bac358fd8388c1a21eb3c917a378ac9a3b1e0e59670fc57169226d19f7d6c281e97dd5fc47fef624d04a4c090552d60ae5cfa9ab4b1abd862ecd95837dd7be1f85ef24c270cdc5b8cd347ded95763f6a217a55fbd7f19d6fe3876cbc3dc7c074371070eb1376d1e6de72e3bdac5f8701e9eb114fe0d5cfdde43ccd0d2576a9b42cc29b4ca80090f43f54b5251648e68647f9bcf7eac1fabe4ff150e3b9ec357e339f7c2479cf1c2918ed5d1ef39c7723ef6e727f5bd6095002f9e43da31bd99e22a181017d961e199341c1a0cc841cc873b1c212b50b4e38e5813925b537db59bf68f202ca19bb996e6135164058c1227d3434d2de3026f13407512c10d2abd8764d90219fdd94aad551f620c5fe789dfe55c4f3933147e2367f68cb38e509372b589a3673fe76bcd6e7f34d0ee101b3ae3b8419f70d0a40e3c8efdd1965deed7f9ae701b5e6866d8db39b4b5a0da69bc6c2dea347fe750aaac54a350498bd8ed3a6656286a4f4f1ce1cc9dcd3628267d42f0d3a2f636b45aed67badcfa5c337d5b3d21dd74673d8a31444ba2ffde4d0d0b20e5e901c068ce3cf7acc1f4c5589ffcd0ebb9e3bb68749ff740d69eef05aff6c5cb673fe2014bcb61178ea9291c36ce8822b4cc370bd7ee82281b20da3cc9313650d9eac46e3b064493f4621b1095247a1713dbf488de75a2c78e5fab3d1b43c42a489312765209433842f1421a48876359363632589d7ce477fbf21cb8e2f79fcf850b71cee7b98afefcbb278fbcc5f37df85bfbe9424dec75fe83bbe03c9fe7f62dff417de897f67aee2ffdfdcca17d1b2e2a2e989955dec6d7bc38e4cd248ea8495d6f8d00dd51e589183021ec812635495805bb54f330ede92ed010f4b5762499623ec4829666804b14201df25433111f3f1aa1ddd2c4c1882ae1d131aa138e36e1ddf47bfe1f6af87e8dcbb95e7bfddfd002fa62ad0a6e966fecf067df39e1dd6fc3f2d02ea46eee300ea974ad8e47880a6ace622a1e648f42e47883306a22a29b4b4a1e7b046015d46a93f6f9df30cab558f76633cdde661ae008d86ba2413e334494ee3746d64f40660fa14fac1967e86fccd0833f16ff7fa9b38ef603f01f68d97d7cee078e860b756b47ce8afbd44ebfe30139d896777d3af2b01ab322bb3db6c2c4281d0debb4124558c807117945a8d9266122175c4699e64d70d570342ef799a190e4b848154c641d6cb19b0d44d4ec626d38e1ac89e370389d13f13077c560aa67da621c034edbd5c21e1a18b2152a504e7bf6ffaa5efe30265aba3fd818d526116e6445bfd2b07d8e0380b43a6bb7f283bd0ebec10391e76febf1dfafc5f3b9f87d3df167dbdf1f75509deec8cdf58607eca36ee1732cf26dccf20b6e8fcb3c00a73ecd3f9ecde73e3d735e80b588547f0317c7531ca1634ee55fecf5d3fff9e2ac04eacd9c7c36765fd9fa086971e4699ff161bdf1313eda888fe3fc9dfd7f71edfcc8cf78d5f6eff60d67c6a96ef5c29970ed9ea5755300d798a34142bb4d50488e23e548578d445f6a82fc19100df6b2b60dacd8486870c75c7b2b7bcf4c29f217b49d0a0d0799a19641c9e6acc61602f998525663960f42606dd3325ba79110b4ce5733adf33ec47fbef627be71467c638fddc483f2b2ce9bb4463bf17d3ea4cbfc323fd39cfed087836f7061dfb6e7766fb7f7bcf1858b21d1269d4fbc8a000f2c22cb5af0dd16118b1ffcbfa0542553f08102c630809345b9d216b647e24a69f331fc452bb85f14d2654ebec654240b02c35867225352c4c02a825204349293058585cfe5fb7ce4257bfffd58fab7b870aeeb9ddeef4efdb9bdb9e6d79dfbfb232d4feee649ba6c71e68a7d50961d2e8785e8451946d68031ab661a0a24356359021bf55e1e332f670cea3e673672e89646e52009872bacb0f26d8fa534d07df7cf96525b8fabc72e8e442b99454569fecd9888e83df5edef7717306605fd1fffd9fff8cffec77ff63ffeb3fff19ffd8fffec34dfffe33ffbff22ffd9f10e988d409ed6a8f92f717bbc69f3c55f7b89479ff9dfbf9dc3b2db8c3245a902990e0dbf52db18e026566517566a40590e48f57b7013a6e1d88f1fe056cfef91d4689b2e4191eaa015dcd4bea7c374a798e7c5f68ff9d4cf38cc6fd5fbe866cc72086bb0e4ad2775b099dbb827255bf1486ee332378561d5e9adb9d5c85259056bf1116775017bfa7817ece9eb364feb901d7ce35ce8ec491e31928fb7ea10b804428dd8609c6acc0b7bacb01beb44935aa20db754039aaf05ebd4b0770b82caccc8916447beeb9c28a64b160c04152349bb56a8c92e614a2cca7cec733a485ceb57d08b2433f2a5647f746cab3cb581732fbcf6613d64cef0e938169cb54984b5131fca8bcff4218ff45c47905470ff8f47fb82766e85555cb3fa4b7ddda336db2bdfe4136de0f4ffc7de9f3539aa6bebc2f05f3991b7bbd64c1a93333d23ce456203366970994602edd8b102240a3002530637f8c4feef5fd0b84d673b73cd88ef0d5f54a501210935436348e37906af9613684444918e675cd50b3d286e634bd0c4856a71aeb7bec8b3448eb1f039e3ed7db694cd7d78d421f5977b62313ee8736ee393f2e2f915befd63bb3558c2afe3a95ec9fb5dddaac156e16fc2565d8b71d07262bcbccfb4dffc051bcb80eac2df45135dc9553789c44011d84049787f37ab2c5ef510e3ae2135a62eaf7bde1cadeca4140064979eb455b0150d4d893278d04f030b2d6c90b330656713aeb70bc04200890adcec8909b2c5da0761cf5358647f0473f5251b4b5fe3d42e8963e4fe80cd3b7debbf5a7debbafde04161811a7f81b3d813973ce6073ddb75d4ca75922eed553fa1aebfdf8ee338ce7a57f0de876f7dcd47e3559bef8a4fcbb18eafda35afc45bc8beb4bffcb2ceefee31db6d9cd1efd987f8189780798d6febfd75080d550013f5d9504ad79713dee0d4e740413bc30ad77e86261e0b6460c9236d17cd3547cfad3932ec218aa640b4a7365b9ad2b86770c20673bae5dbecb3cdf595a9b4fd693a2a331d8164c2931951fabf0347638c9dbbfcc85ef35bf6c2f5f1f0117be1aa7dfe0ff8595dc5febe2bbbfcb86f798ac0194ac2194914bb14a524a5955f958ecfe5b991e5dc33aff52c20eaa6a4ce038aa8ad208025e3d91a91b525cf36de68b6f58706228c3a74d3a487a55c2429900d68ac3c2612ec11b5ed41bf0ca89a9217fe04df24bbaef06f8cb35ec7c1faf63c7c5b876e743006392ff606afdb23dfe153e234b121286eedc3d3ebce27eb733e239aad8a6e862a8bcd770623ed2030868097631f865b5dda6ca00db69a0446a6adbb134e18f8295a228a9efd39b1701619602eab1a2fea10e656906021301f7948ed0acc69027859c0b0a86ca9cf07ca36d6863421e0bbf01b2c254ab44623ed3caef20bffa1533df9a0aff52673ed1dfb086cb0d2af6a9bc3e5fa85cfbfc7b7875fea9d5f3b3760f1485ce3ccd8351851a55fedf5fd8bfa947af579ee67ec88c399834c7f588f2ff0d31c216af2fa4a67a295cbe426c95c561bca5b13ca7393cf0d5f7a5c3f335b3e5034e179276eb58c6881e332868238320c3713c698f9737583edfe0033796228748dd86864cf93a5c523fecab9c0dbbe628abc9b4054b8101ff70edff5e3310ee7e16fcc416ed2702efded39c8b47a7abd06767aa2e5aef4ea93be37201f11c8303a4b733d297f5a0c920c2b2ab5f978479419ab7132e30d55ea27d11cdadbcc62f4df063f66fd94b053454d4c5b366d5870bedd5b1356d5c9dc102ca0ce4d4518da9c3076135df61489c15c3fb69d900d00f92edf9bc8cbf6b1ccc36be7edb1aff413d7d11793542f7c4ea06d1cb483efde657ca83acfc2e78c0873e1aaae8b9fea1139ec81cf6afbe5e5bcbec4cf9df8055eea4e173e96c77175c54ebcea6f18ff5dac96fc9b7c48670b5f72e07c7d9cd6fd54af11f5df723a7885e3e6bd716a11c318aa851e979319d535c2b94b9d615908fb739712cea66262f136a7557d0653950269cb6a49a910aecc5cde581138deba0e581b7189344090cb319ba9ddc4f6dc1207ec5c5e7dc090156d4ed64c495b9b3be3929ba86bc3bfbd5fbc8fc54f91f354d632a8e517afc782f6c69946c715c4e90b04d968e21895eb3476297d133f7421ebaef1791f62bb5df7dd61719ad4ebc2e978ad3e7776d1611cdb33838fe8a8ec2bdff2251df57c6ff2b19c7067f52975f38b783fa8223d45bf750bfd0440da78b2bd35b95cb112c32076ae2027df9a9c51cd1caa20895292c892e7c8156022dee6b6b16fab53cb8e363a94975aea329a2c965329b78d8cea5aca6e03a51ce9a990794cf453b3e474c26d3f8df7bbf43df461fff7d93eed0764c175fbf76be7c8e7e537e7c865adc31f7d85c25778cb9edeb3df749bcb5190ea8e95f4454d01fccc8e36c15cd48391888c0cf16887042f4bb65682774d2c4c5e7ed0e7330624fa7ac2aa33c4099566f647063f5b7a50db79766e0754ea198ebd038aa16b9661b90e59010a4a83b1b917fb889fb4dfdef7477f779eecbe739ebc539f5a86bf83297e1523ffae3e1864b4f42d7b49cc7237e3750bf0549a3af2d485e03798eb9291a1c58c29e7be54269e9323d7ce01b123713ad44d4bc9639d132c629315528ca129114e53a2e53353229d51f519dcee000726ba0c28da2119cc916b7fc407e04d99f6b63cfec0f9ec37629e5faf4b735edb9e6dec5c2ea23e944a3252a3761cd99d4fcf17649f2de8d3417f3685bd1d5472d793a8e7cfe5c252a2a591cae28c357e02a01a50c91d4f76995922aded54f849e6518fa4644b46f2660642c1b41f191fa84620eb3d0da885bf3318ece414c3f10633fd026720b2f86487461ff2c77d73efeaa5fef5eefc625ef169fd7bfef51ddee71cd7d4ddb3daf5f50bf2cf9d25790c86fa5497f205c84009257b83605f031695665c3e776d57d09252b332d9f66d34f413bcc58adb43230002098d086fccf44496f454587a19165c4b5791424d226d7686a5f21a934b9e6daf0325d991a4ff12937645fe7dc557124176eda5a7fac241c77fc5f7f77d0e82f60ce5f5bdd8cb33dd6b3c7b9d1c78778cbd72367c550ee857b91bfe96afdfa6e3d138ecc31dce8d2df7ab6bab481c340123d546549e425b505dde88edb93c99b07404e4f156dfd99cc1d3b93dd2339d1b0b6e6ac0a96db0d80195ae104e4fe509b623d78521a7b38b9e09594b67891ccc810152fd2751b629d8a9154c008bf819f702fbfb4d63ebda3975a7ffbdedab317bdbeec7ca7b3c70b3956669df7106cbb88ed8c875a2c81bd49cfd4bbb4fe07cdbfdb6411f69737146585505b0345cd618da5cc2cc6cd9c255f973660b1eccc8d696cac873c4d18c013c1e4a1b24cbbae7889050dd232c00332ed96820595b5c599836114ca9543c89cebdb43ff7aa523239618092ad687ca75fe685ddf4caf9c721962d1abc7546a4263e6fe488133a2ebf3abfa7ab7b7828ed57130822970b8fe9aa2bf170affbf3fdd7759f2c35f3957edced05f393b9b4d22fe7e611c7f15fd7711cf5ba16d1ba9f0fe9e2173cfdd770185d7ef68bf35d0f0ab90fe98e1cd35557d2bde6cf57a7e7afb4f561bc1fcfa0a4d7d235f13dba749babb2fb2d9f3df3b4de2fda9cf146ea9a40b2389ed369efc5716390a3961347cf8377391fc7dfb4076b509c3225e6e843b7cf7772cdb4f1b73f875b8ff44c677ddb28828c8e41923bee3c5c42d84fa165d860276db5047378a82a33569467365a3eef6c01311499237707a5c8f41446f04706b42dbaf49584f124c141401e1056df202b9adb49afd29d7063277dd64fd89f9f8d754514d023039639f820bce503f44d310fcfcb6cdb3918cd4ad2f906689f8b6db89d4077ab737d559f23114092ce6c9db31464f9acb1b387e1d25774cdfe1cf7d9d9787d1b23de8ce3bfbdc6eccb6bd7997d1c1ba6cbffe37e668662d866fcc8612b9a42659b614e9d7b0c809a594a3e27e7ba82c0e738f78cdc8760afcbbf330fdd6fe2ac3c2bb3d6abdaf82f7bddfd55bdea2dae28a2bbbc510166569972ee5923a0fa8abef09552d652238552bed099456532863ab50dde1f14950bd5198478e33b3a6fdb516a31b26003bcf3923cd31c11e900a5646458a62d78c42ee750e90f34068d0247841eb715aff3d71bb99f25a53f52d9f7b9bb9f2ed6a62f8e2d280813b8ad483bd70ee54f9ad8723dee73ed984fa1fdb8317994f97350c151ee6069b3092cddb4774f0266d8893e27d4e064c39b273d6d087efb5221183bb4b1393941999a03457f0892edd8a05134e1a339d819a509d4d487dbc1d48e04db7c5cda1cd134d9dd12d8e75f69c7f5c4b9e6b3f311ecf677c8b0c7f29a3f533b7f5f79d662b53f376e6dbad5e6c09d65332e4866ac9f89334fd96a80462323e9ed261c11ecf9788dedbee432e5d4caa86dc1194352b5d476740ca0fcd3b3655d97451d5b22b5001a4e5863198c164b98e609e634568758081cfaf0ccd2ad36145fc408784f56fa071d87ad5c2864efad23fa37e1e7bb766ef694712aaf10d7c44fbc521fa6dddffe14ff12c3e9e089f79c05078740309cf1d6e5c91cf1c8081435361dcc0358ec10d3177468a8686478fa4895480a340ca30a49f9ec99d9e61326eae99921983b716ac0f1524bc83080029d31ecb367932d4e6469c6ea536f17eddee192fc14ef869f81d23d72a1f31fe0b0677c1ecc3fc0f7b9fd9ef9d367dd96efb32bf74bf1a59d5916f68093b040da3216ab9b44a2db6786d968557f67324605255d3347116f28fa96007da6a51aa3315baa0db5f5d4d1294e736396d007a2e46630478ac7e434985369c2450572a808656360305b9eb039203b5a7c972fab9ff637e4cc2690de3bebde4da0b046efdabdc94bdbec6b6bf0bebca68f70c5ae9a3d1e2b79055bfcd6b94d34f347331e26f2d000aa6170ee4663984ab77481485ba471c6d84dc8d4e055115b746bda91034022402942fe507ed07982fc945878aeffb42dd0f31d904f95c76a06e51e66fad340a20f5e2aa7960c72c0a86bcdfe36be8908a7f814cbf4d2bf9857a9eb184d6c98361ffbd42fe545fa437c88c3b9f50b5ba974614927105438ed576ffafb66fa9a38ea1c996ce93a4fe5c157e4c8a3c6d6f6de651d02781e87e22d7f1832d20b0fbee70323ad346bf62d3e16cdf97ee36768ec7c85c62dce71f6591e43d74f939d6e0b9320cd33cb5179e4200133913d63e48a485b09cb221740bb175077ad4936633814f9f3d9ce1ee2b5cecb9ced909937a403832bc7c821b1e58002a402e3a634f3a16eebbc9ac0a13eb0d24781b0eaf367790cdb76155a0efc14e5a8e1a7004cc367f23e67dbf6052fc317e7b8afd01569f66f85d483b8c42395929191777e854d7ff859c3c7bf4229cd268e5821c760bc261668dd375731496ff54dcf1e61c156c8d496b6238da3133b8b4a734724c08f970694d6369f57244563a2e40a19026d966e380d92a546c1c0a8fad26c4e97333632bdcc5d0623aa024bae8063ac5c876ac8660148f281cbb0ee545e6c754e90bed0372c5168f12e26a6ea55df1387dcd835fed523ad6d731e301edcee1a5ef1cfaf89a52995138da3004a9ba5c60245cf224d87c5c696c0c26455304bcad92cd1b949559a1e037e622537011ff582e1983799d29ca56c39b3dccdcca21bc4f40149d87c2a918927abba2d81d24b54d31ee53b8d62dedac93fbf6b4d3cca9a03f7c8f69d3551c08a5dba5c44dd262edbdb7141be27ced459994d7f359c24505f20a82f1baecf4fc7018b0a04c0dadd519630c4c53077081b450018de0cb20f16d41538b77bba1519334be548166e8133660389ce3d27724df0b49c4adb959118999d8905b0b40d71348e28608b94edce63504acc32429631d177f4a7cf01fe9bd6c75a6615041a7402b7bb335e1af36d5db36d3344f10bcce5cb7e9b7e0b2f43db6f2805bb96c3fff49ad93438aacfd9070c52d407d3c9b724cd19c4515d77545e83058b133026922a5a4959a211483c8908b304445ed2db6810c9018ca2994d1798eb4fac2ce1020b2f4dbb27680c4db18418c22682e7c8b9ce95d2331ff126171998119edf996757e418dd2068443853a3c06c3890620251fa7e0ce9c62f8afd9e36074987ef286b7bed801ba8ede4d7eb57b6bac9e7628b05a9c14ee548b7122021479c98ec780965fa134a32b447864360b2f147c9c6ca8cb527839dcbe325806c642a5404ecace78d54a8396a35a9fa639dba4b4d3238b3d13925c1de25fcd46636be226b88863d9c323deddb38e9e96ee29cb5d527e28237efed5c5ecdf1e8bdb9d49c757f036fe8599907198839bdf21c91e9ced499cfc94077891c54403bf27c2a2f5d67d103b23a204e64cfaca40a403eb0953e83e760fccc92856d91d818ea0b48c10a8d429648e4a76bc929b1f50c01fd7720c90f96259b9edd634d27e75c68a85036208288250ef166acfab68df05266b17e6a50d4620a3e12bb67f7f7dbb9c1d3a59893d3769ffcf4ba8bd5f339ece70ad3c8233c7171325b8341ff192a40404cbe4592fe534f040fce654d9fa331ce227dc22e78dfa65b2dedcf5c28acadb9a86850d082a15e1026d7898544c2e4489fd3055268cfb59161f1600d1d5df7129b9d305af55dba0152404c0ebee1dd79cfd7b9fb120455165dc58d5c894f19f7846ff2c7ebca7d2c275c8b379d586dfe5ff01188673b22fb23353153f9d9a7623c034f4bcd066b22530e837ce7ce75ea721b967009374b51ae27ea3390c1dc4afb3c1ea239c9f40dda89bfe1285fd9d498184a5e4e189b9f4123331215225b9e81849dba4c39c24ca4ffa7fc4ffc0e93aa5dfa5b9fc9bc735de2ba2c042bcf915964b21f3caff8ae185b2fcaad6522eba7744ba05d1ecf2dbe1023d6015317821c27604632d103ac9e0519d9d9126180a53e00aadb38edada7d286c5665f454ee4f976b84176c8d98cc46b8c5ece6c89059631224cdf04a3c898817c37b5803d0391666532b594fecc96849f3a241ea2df861798e38c6eda3d5a7985947ed9eed1d315aacee3a8bcb9ffe08849b3bf0285355168eac177639e322fb9a2be345759ac181151ecd24ffb8c07d1de26be76bfd4070df7e8e7b8bae036d1e962636774086d32d0537d69c23c4509f96933fdd294a3df1a243ab26dde05eacf606ee84655ba162c4bcf89067068fc0650c870425c8bd2079d273393514ba2f4255d6257b354aa6650607556b54c2e62262f7839beaaafa8eb400127fc8de32b58797de1c2edf24d5fb0b4dbfbe075c6e7d5bd5f7db7577fcd2783155c475dbd8de3a765bb07c616ae930befa4dd4de0c1ffec3a76b849435798379a58ec68c036fe232edc168179d867db5dd9c7cb71c5aeb0c29ce399e2973ec901942b3fdee7bbc7265c8963d9606ce406773871cef7229cb97d9d477b0436ae793adf5ed4f365ecda162b77cd77a687145cbaa9bc43d0c871fc2a2ff7277132c7b1f2cfc62e6acbad6d11978b225f29be1e8bc832248d1973807319cd2e7f42a02a68a43ff8b6b1b56c7d842d0041dc672d5b1e6873bc3313aaf9f6e352e372d157c21e1c1a5b6364244421437baea7c1c8882d09e801d57bda5c359012ad0c457f26995d114b4e41f6424ebfa35f7d605eb7dfd8fa2e3a3a13c0ed815bb9956fd7f1fed73193f598c4ed1ef8dbd895b7f6094eb0306fdb35dfb3b7032acfdcc7f6d8ff66984933773fa5670fb41135c128474806c319d713fcb854f44139f2868660da06630179eedaf9ce0774608c74db66700f55fd9f08e69359da4f2c59aa4c3b4aadb91e5b16f90d1cdd848a90f8bc68eb4c5f853249a023cf35887efbc0e55eec71beb36f43a020b45882836cd8bebf16abc521ae3adc46ff54cccb97e5b6fde30fbab8b1662deb3f1df3723bb15105a5623d8328d6876a8219d2f341ae681cf9adc1ada867947f33fecae7f6c91a9b6402eb71f8741efbe04dfbfe3a9fc4db710cbe0573deec814fa041f148a52e27339d0dfaa23e9d5fc3151ffaebf2523359d3b6e46900d186ecf49505054432646976393153020c4e962c2bbc164797259026ef7c7faf892ff3f7cfa29ab29a7d2a07e468c074f97e4a0e2816c79a382e151f10d9b4718fc0c8237334d452d5460c8070a48fbddd53cf636cde076281133536a0bd74777a3575c4df2e07a0ad10164b34b512ba707786100c6dd61cba82c546a295a9c0053a4b2c4a4d284c5e893fdc7e4b3787de1f3f97bad2df68bffdbc3db4e37ece76fc149f93ab3f91c2ba8124f57062ec6c8b202c09d04d4acb4ccb69400d5e4b92a5bd030ee654dd50842191a863b372e4f3fa74067587488835cd3e3277b2ed6539302db472d332f31c590e60d8432c59210ecdc93c123137131a9bf7657b72d3e6cc8cdd78704b27508f5c2e7aaf5dab2e1efddf6dd7ab6537ed3b6ff061255668814c76ee427d813a0ea34fb6733155b64303b29acb6c114c43c64f55d64f048f507968a61a8b472effccaa43c2493d6cf6352483de7464f3fe48770815259363373e673ccfec7c4ab852f4a47c38a9fa894113662a95ac6983d2cb8c449755e8d9c67bfb442fd7222eca5bbff077edfbeaefeb0564e141bdf5cd6ccbedf8e83ec7b9314bb6aac61a85060c476345ce1fe28d3fd4056ce9489f1bf93327f378445cece8a319a58ec7955bcb31562e8d329cb0d2334f7febbcba003b71496c2005a3fcd905d435b85c063bb0469cbc31194137ec726ac13c7793efdb9f464e442feca4b7f436de832d3789afd0d5bb7ec5dfe553c4d1a4b18de036f7d3c66fe5a21e5ff2319a628e5d43a589070a0d891d1147ecc13930b561b4742d9afa72fedb4ba9469208ce00411653329e5dead311f84de4dcc1733ab75394bab05812a0cbfa305c5adcb867716ae4cbd186f094024805439a71b68db277ceab3f1edffc4abcab9358b7c7fefb248fdb0b4ccf4738a9be91dfa0b54f8efcb8e7f5e97cfdbe80897569c2a174c1ea491fd896b800963cf11234356499351344834c9ea0912a06364a4c08b8996de4d8511d73442c5f51cb5922e8e6e889756151a1f96c632b4ccfa48612d84ce53b72cf6330e7a764694a8f5b0dba6b5ff9bb98d8732cf747ece7e955ae8cafdacf1758f28a595f6009cbe96bb1a5dfb3a76dd6f2287d705932b51869831c229a23f14193d81e96a9423292e919fd1d58f2d4d8e93da2803576169c3e34e08c7b5cdb54ccfc6cbc9d3064440665eeeef4dca4c6836d4532b1741b49cc5697f588700204901d1916fa743c824fc77f7e779e68df394fdea94f1733e4add8cd6d5cfbafe0171f02c896ba59b2cfbc3ec4acee04f64cc0b6102198438d311492464393d30b9333f280d2c8a4803525a9a7b1aae6a563dea73a6b704282247d6cf0eec6538aa5c926fc2c61c55ac74076c10008323d0150a791f15ddc6eafc406bc3a97f4977898bfa1631c6231767d71e0c33db9c730af6090de956d01050fba9d4bcfbc9161c7600d25d7bd1151d10eb0064550e30c0683851000f9d9977388328931ada7ed8429585b917feb008cbd398181a31a169373412af3368b0a93177fba89bc715324691248f48c3ebb55b145ff39ceff17326f4cdb9827af608d3f1597fd551ec8f7b881ceecf737c6d8693eefca832b789aafcb83f738adb9afae9b330770266b5440418645e9d4843ae3d2f1d6acfac8600d53b330ab27447059718776249e423501732a114766f1dcc8c81c45262f8fa1222ff439f1a6122ded1d710c67c1da00cd2dde2810c515a6b94c2061f417d8d6ef1a5b97bc3927fbea5fdfc3e47d5e4d260ea95ce7e97d3fdaf83bfc06c81aa7b392f06a841b39727acdb4fe599ff31b180771bfc489c07b8e31b5d3706dca402412b30674b6d6011a3ff33433864802735242bbf4668e31b67835c6bb08e8dc96b3658d0b149737ec7c62d9ee8600bc35997ce80fc5b1be7bdaa29dee193cd83d732c6b58807b070bf1d21eacbf6d240affd0de188f537983470de67fffbbe3f6f8b04db89d3886655bf4773027030c7337908425b41137b344c3ca806ef2c6663afc948f0a5f97814c366df70664c6e7d8dc7ddf8ff55be263935a8f6b7cea9afd878828fdd2835ad746d7ead5f1d77c6e2c8a2489e60158b0662a582893eaf9630530af6669399e3ad4d115869f3974391d3c0a9693ac0d6926f89c30418ebd9e5a464a7855f7399dfaf66365dbf2b391c8859f0a9215979e216b4b98e6a23d07ac6b496b5b76d7df86cb812c8bd3fa5f14612e3c9ef399173e59ddb9e0b97fdc699c8b975c771e242b176e4ae444f9f99a367e81c50e1c912245ae702a0b4dfc9c734ee4eeeccf7ef32c20508c6c02d5087320f1def527bc72f6f925b91625a86263d7d1295268e34378518f8e0bf573dc98b6ac4f3d093c1b0af80d29853a17b29aa4ae3d69b399daa09a02149910a478ae6a962da71ad3977d471c7a5cfed3b33406012ad8808a5006b6970083c8f93390cab93117658d820950c2a5cfeb9235d2332ba5e5f41d2ed49767001183a0f0debef77771cd761cf7f5bad196dbf8f37d627fbf8b313b81c0de7ab6ec9a340288915d7f4e819de639314b1d7091004034c63c4af190942e0f906fd1c466c1c4dc3dad675cce600a7823917bc630ac261c3b049cca58237de4254875e16c4318baf3b9191364aa3db381711d274a235fd9e6effb197fd7183d9457cb3dc185dba24ed7b5e1e77c7f2c9d4712c9919c0bd802b3d9fca9a7cb9166008d0523f1a7cdaaa2c693df50920b1310dd1b81524b4bd3e5ddb53e942d7fae521f481b34a2731b608680dcb514f09b3025877648c63c8a91b285d6a054a00de664485ec12cd3d53b636ff74db1d205bfc1fed055637b7e166706404f1fd1cc60c98e58ea5ce7e8cea0844e65ca6a8016c4ce4b0cd02218c9132dd5352809c6cc02a2cb683b1ba2d860848d65919458229a2ae3753097382c479a9fa01ea494035c94681c5acc682218d2b69cedd0c7b0b2f5df11f3fc6bb6f8bf773fee726f1964e5dd5fffefee6712defd7577f7e34ef7d2a0fef5bffffbe32ec9bc325e077f90607d9f64ffcae92a8cb37ffd5a65f8affb324873ea9541715f567950e0659c97f7982e562458075959dce71e4ebc30f8635e2cb2ba8438fbb5a8ff92a0f4625ad43fb3b6acb3943fee8a7817dcfdc5727deec75dba20c1dd5f3d8e697efebb8c9b17388663ffc572ff621e2db6ff17dffbabd7fbe391171e3896eff5ffc5087f31ccdd8fbbb8f8378997777ffdf26811fcb82baaa6cc61b0befbeba127b0c28fbb71b6b8fbebcf1ec7f6991f773a8db3e4ee2ff6c79dd614caf3ece3e38f3b3b26777fb10cc3feb8538e3f9d7fff3bf70873f717f3e3ce207596cc8f3bf3a4e2224ddaefe831fd87fa728193e2eeafc71f774f659cd61531037cf717fbc0f71996617bfc8f3bbda8ef087d96e931bd3ff9fffd71a75d49ca3cf6f6490f9ffcbf3fee061f4feafcfbdfab6c5504e4eeafff667e303f98fff9dfbab3a360d9b44fdd6477f7d1220deee74196c45971bf592c9322f770708fe3fb6e50fc2b8bc3a8a4d5bf70fcaff3b17148517819f117db8ba1734f16b8b8fb71374ef3c5b2fce995d1d9c0eb9e0e17b8bd6d79cb3028dbdfc662d1fdd2bc1247777f652b4a7fdc99a54783433f375746e035c3ae4eab2ce49806c53e755beee17218e487df56509417a9eb5b176f680bb2aacbfb7f775de55f9f264d4de3eceeaf72b90a7efce7dbb6f95a6d41fec33d182efe4817a4290c04cb226e5a9afd837d68a446deb4ca5ea4bcd9385d9f7f5298fcef8f3be295dedd5f77ed32a0ae5cc8b6474229e0da903c51e4a746819cbdcaf912ca730297ab45650721300ea608a8555ea0cf714a3764200e7da5cf22a9cd7f2cbdc8bff0a04efd3d256f226f8e479e7b15b95e86c435e628e3f3eab979d8c2c79a7211474f547095c569eb86d798fd7bb537ebea353a3b228bdd0ce4bed29a497e26f6c60376331e9d41244232d2e727f93750cf7df88071bd049a6245602f6ce1984fa91a8b2bac3021cec06aaca8ac07b7c9c9fbcdbbd3c6ddb92d978cb4d24ffb0932c506a6ed70ec1a8d40811cada32debc71eec75bfc5d685b0715b9eadeaef39819350cccf1ef6e697eb1cfbe64b65707bb55b6e43a967c6eef23b2edb802860478639eba794190fdc74acbc78b6570122a2342ac86978b343d84794ca11ae6af394ad08141a0a99f1a0b7eefa6bed4121414eb8f2b293ef4fb71d15ec538c9c16a23b963731e6d5f9a45afc9e548b55c0e5bbc9c868fe0523168f631177edb67e8e17ebe758f8d3cbb4828cea7f7aef17d8c4e301536207e4c839a1083b0d39950a6ba480d2e77ae1c43c09353de8ad9b3607fdd2e70cd657c06ec2a1c875b45ae52cebf141145aeedbdee5b6f924cd77af7d67dd4edd7641a3aa186f412512b185f5741478c7e34369776682eed3ede13f1074b0e23eddc387b1b26511474f5d86990fe6d1ba8b1cc27ccd565aa3aa1ffbfcd04f07aa8b317796770ade82391fe92ecfdc6dd517753f853e1fdd9acfebd2f415643bb578ef727bd2e7d98b3c2edd425e8417391cd99e8cf3768e1d5d332fea7ea06be8de172ed4f3f7e1e75d38dc7398b97ad647a7eedf7a739cbc3719de74f98d679d6c9c707b3a8b06eac65eb683cb6dd7041a94a44d08c05337ea13970e3575a1bc9bd42684a3b27e4357651fb656f4aa8310ff33ea77b1c46f6bdd7582bdb2cd1d546d8eedfdd97becb13df66f68dcadb6f39ac2dde7b9c747fee1a071737b8d9b7d78fcf3cf2f68dcdcebfa36f38abe5d57a6d58cfb3d9ee33886fdffaaba7da9697f441fabafcab831c6ded2c3ffb3b5ee54fcffbefbe3ee7f0e3a7e3bb2ce55fca2befa3f24c8838c0419aefefa3f615c462bff0fbc48efc3c5bfc2b8acfff831a5d5fd5a38b508fefb0ed338c8ca3fc2c5dd8f3bbcc87ec561fbfb579da02aca20edaebb2639bffa7790ad8b8b5bd4f3037a79338dc3a557ffba7cb0c8afdd5d2fe82a0dbabb791206a4fdb90cf24511978b65bc7f78b853b5d7c5625906a408ba4fda8b89f3abe6ddff393185febbfef632d896773fee82e572b1ac4db05f697d79d29678b10c1645dd964590ae83e57dfbe73cd1d5067ff3f97d1aa4bf8ad752d57f5ecfa37d7a5f948ba51706754e8b65759e38f59689df48caba21976f3eacff8fb3b0cee7225d5ce228a034aa0bad877d2de77edc858b3c09ff88b3fbca4be91f6bae96818be6bffb78b12a637af7e32e792cfe8817f75e1ea71e8ee22c58567531f58dfb65502c564b1cdcbd25ecefeb8ceaf6c982f27eb5acf35c1477ad9d755f8fd3c6e0aa8742186cf3fac72a6bc4f6e1d73d09fc55d88d8efa4fb98cb3b0cea3a89ab9d624ff9fbd31fcdf77feea57f31d7e5506453333d27c1914c5bdbf8b73eef4c6af7a3c9dde0877717e7abda3b1dfceadd2ab3ffe9ec645d9dd68071c5e5679b938fcb8f7da22db0b1ce751d369dd35397d480aef7811e0f34bc20902db7f71e33ececa609979f43e201b6f498acb6494c67919e3e39d28f54eae0eaf2fbd8c745d7cf9a858f9250d8e0f52221c2feaf74eae70efe4e2f4038ac863cfae38e1e1ec5a60b993eb8b224b7ad24e5b81e99f5fdde749bcad277b861724cec2939ff75e91b1a7d7be57040fbdb33b71e635d3ec70275cf8a79751709af97db7b177b8ce9be9f5baa0f9b95c948b4cf3625a4fb7aeda7e5ce2d5721d141f49bbf4e22c5f2ce807d206def603a90e7d5b4f89aedbdf7b6781fd8fa4ca832c0ff38fa7ac27c87d12549ba5f7a9b796e962f989f40126d16792d3d04bbd0f35cbfe8d7dff7ff485431f78345c2ce3324abff27280f1975e3bce948fbe9b7b38093e32b4f72f145cf285153748e365ee1531be0f17a4b83f48dae2cd64b518fe408a7b6fb9f4aa4e66bf9eb65c069713f35a8a4e7244c1e5c8bd48bc5ff1aeacf9f857f8ea83fb027b59f69a46522728174990bdf1b8b6a5feb63e1305340f96f7385ad67af20753e70b5afd8a29fd7bdad221d5a2f840a29772ec937a57ab31bf93e8b86206ebb868cd8a0fa56f759db792e67495fa2f26e5abc9eeb187a3e0c38917f45260be9eb8d6c31a0bfaa3e917cbd42b3fd680972f91f8d7af4fbe12c6651c668be567eb17936dfd659f7d2b23c1f693ef2cfcf9174aaa45ec575e4b4a1a671f7e6be1cf03fcea4cbe4c9dd7221e2f6853b9fc6b6fdd632ff7fc98c665f5c50c8a98047eab6a7ee8f565b07e29e55f4f5e5b5caf9b7e97a9cba59715796b7c7cee85fbd640fffc7b9f1915c7b7c2f80b454565f9e16e3ebe7510737891a6ef0ac52b1914c1f20debfb8df78ae863e6f4078deee356c9a75fb8278bf2fd267fcbba7f91b8511d8e16cafb493f204ddb84078bfefda469b04c68502ee3f7daf032f9c71bf3c59b1f11ba575eea06e1afa5977ebab2d982bc1c80feead72f8f2eeea3e0e56a132e5a31e5af7eb53fce13c429f196f1a22e22bc7834f7832c682ad36d1cdcc7172992601d67fe6a9904f508fff7b595f5535b412feb7f99e2d078a997171fd957fad0de5390fa01f9e22ed5f57445491697f57b653feb98a20896615c3fade747334952afc451deecca9ea5dc7ad9aeaadbfc5f5ed889ea05f5b2f08fc532bcdfdeef4d72bad8fc8a5bd173e531f68a5278ed59e4e1c8e398d71eaf96eb60bf8bf3768293f11e0794bc92feb87574ede9cb5d9e6ba96a759ee599d73ea978b5218a22ba7fab1debe7c7cd88e6e6bf733f21bfde489f648b4d162d3a83ef34513da78e3b712f1e1dbfb5394eb992225f2eb6d5e583a22aee836d803dffc53bf5a3a3829f15deaf200abc4e8c5c265c65cd26d5619735ce7efdb1664eef6cbc651667617171fbb81d1b794d4bd77fee3d428325bfbf7b8f97b8bd28d35aaac769bbe4357f0fca7f7b75a87173d92d03eda3791ed4f3fa6c7fc8a367b770be3abdfc9596dd3eece1561694e5d26bf6810ff71645b341727a2b5f34f6e1c916e4f92bcbe0170d7049e3f2ec761167210d7ed1388cce4a2daa027b94365d1564eb6b8fba1e38dc2f83a2a48bb3afbbe8c4fdfe77637e7e651ffc9564752ec72da337531541f96e9ab54763e275875c1f4c79101a1fd8ab6f1b296d77e6eb3ff77e1c1e7f36156c7e77dbc169bb615fffb94f57b48c73af1922cd8ddfab4519907c1967a5e73722276bf695ea09d8299ffb9fcd7ffbb174b8b9efacee5e3dddf7cbefc5a1c2a29db9edaf55d1746977bef0f2bca1196d67270fcd8ffba2caca6657f5e549046e4fad2ece25f6d7c71dbe7291367bf02f9e744dfae27e511567071c78d18ce817471df59f63f6dd38df1f81fcb85b65316ecdf8eed7fdaafcc53e9c5f3f3697f5b0bffb71b70e32b258debfb3707d20d5c992f156eae64f2d653e9a6ebfa1ff56e2d325f48d7451bbcebc91e2e5eaf846e277beb81e9a242bea7f695014ad787e2de161f087ab6672bd9b6ebf72bd9590bb8f6a6bfa8d5431c9bc571ed72b582bfaaf3d6d74d822c0ab6570efc7245eae5e6dad266963bffd5a2cd3b712edc7689de147d265757eff73e1f8fadfe7c7dbff5e6571f9ef5af05f3de87ef5f1f1c8fbd524dde1f7abcf5fbbdf1d8f9f3fff9f0b67ddfffed846fa1bb2bcceb9d5da4f13d50b435e2ef702f398687f887af30ffee7fd838b253eba05b76edaff61e7aad6defea32cdef6b23aa43ae01afe14fe195c43eb66f5e737021b9a9adf800d3760c34d707da7e03a4a9223b0c183ecc6e755663c2ac259eb7c2a37cea7834d68ca866d0f36a105c10e7372864cb13f5650e5734ca8727ae1f320410ea27e66ecd45df17c9e577fd5c6bcdd842614389f2b9b9895e31113a24c5dfbe65376cd59bdce67103ffe7e0e17e1732c229f07d5586acb32bab2c60a62fd546f9deb0762ee6768ed7120198f484e943044509e7b03b1c125370ef9b1687b0add0de2a7df6385eec68abc1a2ba0e7d6f555ecf0249676d8719d85bed2cf7025329e62871e14e63ec7e67e8ac3f67b67a10b8564ac80b9a7f429de34756dd2e214cc11a41c82b3435aa4c88c6b8a8cdfe5e77272e12ba09ad4dfd87ea74a06e2dc85bdd04d9bf2eaf6a26820f29e632cc603921228ccc70a283d67969dbcf78415b9722113068cbef633830623a33f56f6bf67a16b8a739f1318e444cc58e9c75e0ae664d07b1e0f16e16c24463895cbf1a8ec626c9fbdbb72d37e129887efda1208766420c63e67086385a6753b06b38b7a705d192326740f6340a8dfad0e793980e22c09f7fc3363c5a098039507e52248413256e4ae8ff6f5dd841e74eb36179a3e94c48deba8916f8a7ffa9cfa1b419df975f29d9374bb469558f81cc9dafcf7f974eda9b09428d11a8db410a5fd6a3c20b99fa2b55a6d429527114e7bd964f0942147ad7c7e9c4d0622258ab6fa58d91175a14171a6854489e8588a6c203f9db6df024139418ebabbcc6fdf1ee7f975751db46dd7cec9e3d83e7ccbd3453fec7974f8b37e68f0a8e080633dcbb38d6fcee96b7f201e404c4d1d659d226b119ef02164753b12385eb95cbf9c70e5ca758c9ca4768939798514751d0cfa4b3f6637fe08641eec95cd1cabfab1aff4e309c7461eecad91d29fe3aa9f114813e4682de8a3c1c5b2c9983716c8648fed00bb3ebcfc4ee64c36d4e3f7442ecdba3e384d33abc7fe7a90825ecb99deb475d32ff59cf615fb612cd11549fbcb3656f753ff54de8c07e1f37870ec9f692c0e0f757c5a8417e5df37cf4f005d833879184b2cc5bc1e21ce6e8127cd9cdbf7a514fe34f7c0017157cb3f97b31ff632a005ff082d404046397208c531ee00042da0641a3f6508ea0bbfc20d4061da805b1ed763b96e5331f7537ded43ba42d565dd9e9a79f63c90e7cd7da5bdff7caccfbead2ae4e89bfa773d2eced78dbabd044a2ef27e3ee18598c4bd950f01e39ef0d5d4f782eaa4fec7b997b88e11d5f7acf4f120534fe46c76c2d5904f3b20cfc9982f7c0eaf0827577e1c1deb6d0a8ccfeeb9a6c2fcd9eaead7806440e5c7e218c8c66c92aab99fca55609ebe9b34edd1f2de3caec7ca016c93788edec666864213dfbde56014577ed58ce59dcf6d1bae83ba7e98eb17c86ceab7709f16e5c464beefdf2c3f6bff69b84882f335bb3f0873a969dbfa19935b16d35bed65900791f07c3e9657ed3a46fb83f81beb6932e5207dca0f6374a452cc8b6b3f9d8584a38c3710a36be3a96ec306bce3a8ab4ec6aedc94ae5c47159eaf8fbfd371d7aec9d6223c03dc0c8466acd5e3a81e0fbface2f93f0c9ea98dfab7edba26c5dea6ab8d9c2fc0671e6acb85ff2c7c86fdf3a1d7671eb8efc3cfd4d5ff327e867d78e439b6f7d0ff8859d77df147ccba63d21b80e606a0b901686e009a1b80e606a0b901686e009a1b80e606a0b901686e009a1b80e606a0b901686e009a1b80e606a0b901686e009a1b80e606a0b901686e009a1b80e606a0b901686e009a1b80e606a0b901686e009a1b80e606a0b9f9a17fc4e3e91f44d0d4e535b2ae1be31f00d29ca53dc0695896f91c9ce635afab77e0349ddb15ff8d789aa6ea7f034fc3313da6f7f0213ccdff3f3a5eddf0343739f625397629578eb01a95073b648a4df851979f65d34d9efb8eb8c6d92c0c2e5c532783d6d5f8141a73c1037ff9fe8e28727502ada138e96f1ad7f04c0b7f99628ad37e391e906b3cf167799dc012f6efec882352dcc676c8a69bc511d6335884aea3b570996a9f1eaf26713f2690166880ff1ca4b4ecdceadb581803f1cfb1dce4755aaf26b64203f549f7aeef4674eafaeea77289ac45a8f2468e3850a9d5a671bb278ecef81c4b71429369fc946943a9d276b36c90317f0ec27cef9e5e2247dfb990d0f190e9e00d42ec4121c259b268f307fc052c60b18f0181b93e8b53bd71439ff06d8c8b8bd820d93eb64113aeb0ad67d35efbfb8d7b711b022b1fc4c969dd28ced4710b3500555dbfe7d1eca16ba37c3c64fe6b3c8828cec60f63095438ed57cfe653ff67174b800c84fafd358e9b34addbf468b64250489e07c99f5d3b346dff3c20ea59cc90f922f4147985942dc595188d4728f2159a8c3b377fb5dad47569ebd0b8ebefc759d4400f2669178bc6dc8401cf3463e1caf8cb2799b140b0b7781ee9146788e238097f5abd438c0d321036be22af9e87f6c15dff380ea31d72540e39e3fc18fe4cd8f87cfd3d78ad56c9113290e9d44f670bff004f131a68d2f3314ced0a738079560e708b95a7800829a0c2a7f9345010302783b0d2864fa7e5d2602452979f2dd40e5ee567b3b289d763e2623ce8ffc65c7f3539cf6b8506e102396a35696112ac7fd6a687b0c9cc24edfab7ae4fbc095546588f95f69e5a257f9e86fa250361ed55d121bfe96998eebaff1540b154b7a15c3c372ef4a02083b63d2603f1d966fad349264638d3e9697b7410af0857adacf2537c84421ceb7999ef01c2042b324726dbc036549629c603425d2e5a5fa93fc50e88fcc1e11b8e7dc11699cbd9e57ede75f9bc057779f9fdfbf17f5226e6404552504dd27a9eebf4ecf91e2a32628aa6cd93439ca5051924f97493f79fff19f7ffdac42bdfd54af7890eea28c308ffa43adafb4675b4a9fa4d1dbda9a33775f47bd5d1bd90784b0f3dd1e746ad5eb6d739dbf84a673adc9f173ad2a90e770611c4d58bf7f630e2e21c4e790a21bf16d3eb349fa7df2d1418b17eaa1dea3989afc6f96abe6d523d86061476c451e978642c5ca783809e4238157ded3b62811ca3d683e6be02223fdd0ae311a9f596102bf20e7320192b524852b9f08e50eed5a0d58b172adbc4917b182bfb75430b5d53e45cb8cdd140ece064b58e103117fa5ba7fb746bb8725dff1d0fc426d660ad83128566c8191f744b97073ba2f44be4a82a1a2e4275f7b4d5e61aa3b6eb59f37edd0eb317f569a09f456d57e04accd160d3eaafa618f9e9eca0f78e1599a9bfdd8774e54196f5cddef309f4f3acdf2fe1adb53efb966eedc1d9c37880379a35dee98397b0d5064e9c1ea0f9ab0b3b68d5c4c23bbe77028fc5eb8b670d94af8dfd56ebdfa76dddf599b538a72618329d6d23eca1c07f1ea09afc2cf4617fee1d60f6b3879331def4db25f4f857ab571de0c1f5f81c0f9ed6934a545bca02fbe5d8ec280c9afb17faf96420f29e42e7de40dc794a9ff595595db7122b5b4a14bb854b2a7db6b331d6383eebb7bdde55d775ff7d8b8b6f2a2ebee1605ff85cb1c029d811b8655afdb0d60b0d8a1c51eef4ba731df342077dde432e3be8ec47f4c1766c12d240f15b38f3d1de7164d6859b439d8eb07bdd57399d4e1c7d4d1c757e78ff48f1b0eae0afd08380afe7d5f17b1addfd1fd3fd8a0ec5f67edce2f3a40715f091ff6776249bc0c5ec372a804dc56f0ae04d01bc2980dfa7009ec98817918b0f2bff78be08e1211ab05eb9d5e3efe7f8f177133152eea2fed62b30b765db4895a2df456afde5c37e42e096e24a255dd4cbb9cfb11bafbe77dc013a8b7c4914b9421c68236726c0d2e64f95361817c71d8657ffad9f63d1c20a987b100963090c2d5bb60ed185f7f98e502df56bc9fe301e10d9de69d978102508a2a859adcc4da832c0d29b1d9bfaf978a3597643f06200add28612d710bf304dddb67a759a2e3c4d279ca4abb45abb531af218d9660419cab36c123ffd9eecdb36ed2205b7114beb762a7d4ef88dabf7bf7d522d429b17a9cbd13430c52e0aae5daff60932c50c4181eea30bd75a939ff657ed8e143929a7b98e7c386bbe01f374471450b62437a0448d764a283e690fe4d4df39ded4697c7edc7cab95821e19e055439ab28ff8ca03c650681bcdf5a88dc7938ff5a989a091e39690674d1c63439c59430644a0ce749afbbad6de9129269ea3529737d6384bceead01255b4d162c9486591b979afecd33ac87e2ac74d9bc26d311e354420757d1a4d7402f50582fab2230fda8febf33648fb6a6d457850cf8924af82ba9f1514f9239dbed70e4dffa6728e393bec884e429feb85c88936b546d390f3645a4732655097db46fbfec6d59ec4485e8d95da52dae608ce4295abeb803b8dbe173ec78ffb68b19df5674c09dc16332ea22e57ee3ed66e8fbfc712587596dbde8a0cfd0c14fe409c7bf5dce4b5abfd621c342ec16e232a8f1fc6a3ba8fedd7c6ff59bf1cfa5739eb8bf45c5beea2ea9ecd3b616d36d6039d7b8ed1107f7d748cbcd62f2a6f2c3c47cbc60ae8e146b3ade58db0db6beb2eec855e5b264583a7cc8582a076643697750350606bebd252fa73176e3f5937d05aeedd2e31aec4b51f8bac9f815d3d06fc2ecfd7cab41bd22496926607fcddfef85099f82ccfb371b7f299767cba1c65ec8eace523e536e34e5669b79bd05933b5f50356634558938118f9ca662f0f37ae632c6a8bd68fc5935de326ea348bd3dede32672fe6c53ebab8891c7ded8f007388da9fb6519a5f9fc775fd9a68e539ca9270bf2e36e4355cbf20ed295133865dc7a0884feab5a9894ead564f0bab89285fcbe8a495b39c5eb88ebef360b37635f3c5de479c1e89153299ed64eee6e7fd0a765657ae096b0b535de3c147dab6ed57030a8dd58b2b91fa903263a5895a5ff9bc58af2db107b7391925a15bf71b07a8df105d356bcbb35db53b0606d042eba013889c07a5d0e555da9d92853ee7b627798ebe71a14e0f446c7be23545aee548771a69ec26b1d8c954b06bd62e65bb26ac2ef899b1408e91bb8c41512ab3fec850f7efa8e7632ef579758eecc6d2cf316fd496ded075f4dc4f89ea2728f71530adc7ebc9383c9175468e1b72be3e5fb7474bd2d4ac9b2ba26c8509d4a3666768a45294820a41618e1c2d24ca6367b1eb910fed10a5b4388e35b13fc898ff8435d93894be6938762ea79dbdd87bfc127bd09fb55dc47d963d8813fe64b9c73f1f0f6663efefb20735f5ff327d1027303cc73c088f1fb11abb4ffe88d5784c7aa30fbad107dde8836ef44137faa01b7dd08d3ee8461f74a30fbad107dde8836ef44137faa01b7dd08d3ee8461f74a30fbad107dde8836ef44137faa01b7dd08d3ee8461f74a30fbad107dde8836ef44137faa01b7dd08d3ee8461f74a30fbad107dddcdc5ff373fa0f530635d2e28fa0a071562ef1db5e55c76487b86cc2e33f82c4e99caafadf87c5696a7e83e2dca0383719f5b765d489fc7881bfa97cae7f8a55786e7ce515b9c21c68711449eb2f8e3bbfdf09dc0715ed6f5c47dd21671c77989b2ea8aeb03bc3f2bcfafeb838f8e637c14d8dbcce6b3c10f7181e1a8c0ceaa7c6797e69f7fe30af10d4d73e64eb34149de6a76c59c4d1d5f4f5ba53cc6d733f9b9538050d36054121417016efd1cce34c2c0824b93fcf9f1aec82a3cf714a3764c0eedf5dbff16e851c83f120a8c6f153e8ecdb35030572ce71487efa581e83ae8e1fc643e95abbac4fdb681a8bfe915144edfcd0c7c57854d4edb342523fb59a00af0dc627228eb11ec762bf432093633d65d6e78dd6e7582ee20e5b104feab239ba42dc968ee34d18544fb10bb785cf131b3578029941f636270aa8ceb10262df69d9859e7fcd16fff73fe45b7cff47be0cca320e96efae882709f76be263ff1f5c121f99ef5b12eb8adf56c4db8a785b11bf61453c110c2fd6c41d826c7eb92692911a79709bfb2969f0266e2b5b573e27d432b295ef9dccb41db0262d4695c119a0fbf511a774456492a391b1a8f39f0e9ffea372d2909e869af4474ade9692c7644708ff3f2b25bf15c47f93933739799393df23278fa2e12825c795788e046cc3dc8747646def794009f5955a3bb71b145a00fb2c8ec5157270d8f01482bd367d868cdce0b4ff1b419d199ba2ed2976e8a6fddc574085956d44143b3ce14bd9a32ce72eec856e6a8728edb37e3a0b3dd80b2127e6b555100c04067322791ef40e9c4c64a4e593586c11b8171c37beb2091ba4b3d25fa181c8f855c34db4f6215da1aae34395880c062dd2d096fa1668386c6416393a83abdef320d6e66369bb7639b9182ba087a0ce36df172e9e81f218e20cacc64afbdc1f25cf83540cdd960368ed2bf6b39f89e558a12bcc1b91af6cdaeb91cafab1d8f2993ee52bac3067f934793cd5f947b449db72aa8684a3853f10693012d7b8e5f5a910b4c3da62c14a3ff7336337091bfe9fdf63e569ed0eda763f3e9fb588c8115d13677cdafeabda9a788ec570c245d4855bc61bf42b04e5c48302c5bc1e8ee506295f5b671b9fabad2e31f5f971e89ae2493a2df41410f9f58ad821aaafe45b780ea27e83407f0a9b6f54c00a8dc486ff74aca0358ec568ac6c73525b3f8ebe1b2bfb773b34f866df3662841be4a741713bde380fd6d663d3d78c7731c64edbc175eab125703ea747dd78cd1bbe52e5c8a5e40ec4b59be6d4e51b0ea41551e4dc4f4fc6ce48a5d8010dbf990785d4e7d5b243a5ae06611eba8af81b6ff2d339d1712201733fc69e95032f52def1a1eeb9940a9fc3e14fb3b96eea3349b76bb46bd2d4cf564d995574f23c62c84884c85177f51ce838875e49cb52a2446b3448fe1c0f1ef74c082fbecb8780f1947e321e44eb86bfac9d2f751fcd2c56b7c7239dc5a306254bd12079bdbcacfe5e5578b68a8637cc836ed894912517e8eeba4fed108fd43549696d893732c035c591014eb8846b2d4cd9ae5125e47e8ad627edd8f18d76dfd5de8f9a9d8cf61b0ff37baca86b344a3a94b0f462fe371cbe4a3f9bd47d9e3e2eda31007aa7dca4fbef69181e3ad979e47f15770d5fd929df56c7b335c898675711c341983773f472dee0ea280b5da8cfeb79b06f8b4efec638edf3cdce8e223363b95c9091b199c68feb0ea1bff0799d99cec3cd74f8b4dee73fe155ea42236fe61fcb2c9e3b5e36c8d563e7e96152f58b7a4ef84ab4c6fcec613a7cea69837efdbd0551c2b5af500eb532813c0f92d558a66bd2c96de2e874ac8873e2a885dbcec1b64d95a786bd60cf597640329ff1e51d65c0345c346d73d84999e54d9ee301eb8e65f1a7cdcec2099c852a5fc49e020a5f798ca7f1534cb87ee52bb3f8978943a7d1d2d9f129a7ee9e47d975c486b9a19bab6baf96d571f78ef2463b3cd573fae97940bb717422f75a168d539975fc1e5c896c2daf21d7e790a3163e27271347ac7cdea01d7b05796eca157775ff119ef09354d8f830df4deaf5caec6f5ca82f5d48e8e4d53c7af95891eb758ef71ab61195625e5cd77ddb70b60dc48ea3fa89d5865a6837bcb5748e4c11f8a9ccb990160d03077cdaa76f65a1429bb6b353c0e08c86ad2c6ee46d8e6251f0f97afc9df663bd0e1bcd5c6ed659d8f6773d8e7d1e519c6ed76e23a337a19bca2da304d7ebc6034b7dd8af02b36e2f39db7306eec78daff4d7782026086ea3c0ecd6e686d3ba1ecfb8e9176fcf1ddec9fc5a8e782d0bcc292f6134964bd64f69c74f69343a45cbedd76fee4f3263b79f1b6ea38334cc05d99e21e5ca7bf9190f765cf77bb21a4bec1a290dc30ee3296087cc96f5c685463256e40429b4c9cf859bb0c967cf5ad0add16e0676fb3156cb220f6afbb5a559277c6e4b07f558315b2ef44e77f88f59a1b987132f0cfe55db601f20957b997c6f95f20ccbd796da3f679772df6797ee2bff8a652af4b99b6d7ab34d6fb6e9c76dd39782e2c54e5ec355db32e7745ca5f0c0a7be3fb5e2f6ba6f936efeb4d2ccde66bfa357eb451ed7b0b3c0d374da7ec7afd12d69d59dea9cedf6edd7df96d165cf5d3f3e3dfdf9601d3bc6ba14540d03573c7e180fc69bc95c5a69c753af3aafc2833af533bdcd2f91eb3a2c90c95493f9d3595e48019bf6d44a9837ac36f3c5210e42975777eaa5adfd8615a8d9ed0c34cb5e69d5a17d0ef95df0e136ba95339fadb441afba4c8b5239c215fb1b576c45a0c078fbefa7bdcd648e579a393ea4ff659ebc9b1a942406c5b59ea48095cbd18bb66df39fedd9b77823c2cd2e6c57174bbb68afb74e274f4e08bbd3c4ae8ecc643e662edaf3a4bdae9c129e9ea6befefe3e7d575fbcd2e6eecbfaee4f3f076cbd96a71ec4e5f9c960fd6e78b58f90a317b56e3971ba93cd98dde0143044a114c75dff56bd6b756b18a2fcfd1ca1bd7a3cadf4cbba9d9e7a1ed25d69f34c67b102aa56076acbd50775df8f2fcb6de2b11cdb4dda5da91b832bb6a95f974e68e6857959a6f1817693569a155ea96f3b9e3a86c7e3788a7b4cc34ed9a43b9caef60ff57bc14ed97f7253394670b36ef7aed8b4d98b302fc67076608e6ccad2abde568b7bdbf36f52ab961d0c51d4b66163cbe1dd625ddb6b88a33b325285a34dd0afd0abe53f96134e5f23c52e51a6463eb4cb63990283f8c599ecd8c79cf11c4368da3cd317ae656fb598f5c850167cce18044319b83ccd1110759b2b1d9fda8c278b5b6f44b63a178d3c4b5d19c9666b2940d41800fc41b9d592ad110c25ceb2a98598c5e6995ff048114ac4a3d914c88c09b794d8c036987e6e31e1d64e7595ec98fed938af65447c641b3b69af0439cd5e14f5533dbf3885dfcb82d8852af507fd8507c9c25768e68d4ee6a3d58cf9a36ceae2b91c65543b4f1cae63d874b4f54c51233705c5848ba83f12298ed996fb5c91199f1f971e6c98c072947673f09d7150cf93b3efcd3a66b71424ed1a72b409710a32cfd1199c252b3f134b2fd3563eaf6613e6f89d086e37c819972d9fbc1111a55f4d20add705c683a8f13c98981f4a57eeeb37c98c2c88cfc6eadecec9c92869be057351a45b5235016e6dbff041c25ac402054a290f1803023e370d89a8565c167ea2cb001a1154080392e81931db5873d4916b4b9c97b01591c6820159596736dba982d650ca55c38a801ff7c50917725692a7062b6f269cbd35e786f8d3622ed742ee70daf7b93ecd111715f55869e4d83fdc772763b4e9a393eb2ff605b5664c9f0f46c88636502da08f5c5b35dc39581a92b19b71fd8da11839b0c90e3b6244464f3b94f40bd39a2db524326caeb47d1b40c0099038d442923cd46de0cc78d9022cb1c95cccddb9bbb3d3dcd439c39ea546f6665f5cacfdefaefb9f9d6bf5ba73ad5f1a7d268a7ca5e8e6feb8d6635ea4f132ad244a7f893a8fa7768d7aaad78fafca8893f1d47f91ce85c2ce33d91d19d14b2fa22b7aac56af4fdbbf3dde387985b9a4c4bc21f8b54e553197f528b5aa5ee7a51551c8c3b92cdeef7f502668f5c79da748ac668d4b40671b98249cc7e626928dc554a68299e19dcdb03184cc9a98e51443b49b39918c65f25393c574eae8dbe9a04fa796e104a3e82796c54930a48a3d97157f448744ea4343127eda66d1f333a3c036ea79409d3ff36316db52ffe7f9fa9920c7bdd0d93fac1bcf7d6ebbc671a34bd4edce74fdbf9dcc93f3fe3f1bc36055eb9157d79e8ed9b31e6f3fe7cc97f50aaf9effcab61e47ff3ff6feadbd515dd91e873fd0be7811987eda976d1b81899183d0017407c8bf601084c4c4063efdfb183b9d937370e239f7dacf7f5dad8e67568445a934aa6ad4286da1bff9bd3cb6e1267e7d765ef9aa3dae7985c5f6714e9fe8ad2ef8e13e8c1daca58ef76bd18d3bc1659d1ab85b05e6436aef71bdb94dcb747b3c437bdf745c771f87ec71d359980249bbb817b9daa456bd8c0c692307872cbfd912c3a5ccc1b6c7651c074db9b4449b386a22ec31484bb88934116205439ccfef4929670144b771d9cca275e3e2c2f552a2d692d506267014e90d6604ef044380920b628af2e5f939da49bfd8fb94d718b5647da4c39d18ced630f3acd99f4b1166bb27fbfaf380de60dbbff5947ec1d136b1c78ff81b1cf1f77fac3d9e3a47cfcedaeb98f770beba1fe3e037eb0e7e4d1f6ff6f7c450b3295927a7da71bdb3ec158b023269fbf7b210851f629b72345b5a68b6624af3b810ccc8484a611df46e4e355f5f1578bab4467d644c7a4cdd8954ee289da95f4493152ad22dd5b279a0d484cd6e460b1dfe5a680a604b4e888396ac741d71490c5c1eec67c1cd7d1c70f007c1deeebcf5b3197557c7ffdd3c531d2f041b3f2a17f7efe19437bfa7bf5eefa33b6d1fd78dfa9fdf692fd61cfcd3d11e865ccc821cd6f92a76f202b05b5297c744d51180ba6051cfa832e31ce180823c8558f701fde81d5d703fb32ced4099d8b0fae42cf547acf2d3b3741b855e23ca3613dd3e8e7c5a7f31e45bbe8e41bd006802baccd390c32bb70e946c44613aa26cb7c1ecc648a00032fff3555b574929879ae589fbfb295f908fc63f88e93ec46ba9c1768352b8e33547dff2897dd307145c204630dede077bff76e2791a14ecef883f676137ca6b1e57b2e096d2d0eccf885055fb219cf119de32daf402d00e8770828dbaf7d46417eb9a163128a2b26eae400d99c672d663220ab164ce5c93142c790932cf6626b22390d8d24bcb66ead930f2204489915e12bb3db3d7bf39afdd22fff3dcbffd4b76f43ad788bbe8336c361df2603fc666a7d7de9fdfe3e78e9b2f867cc7a83d2b86244c47005b98a85d02c5adac322c98f4b885a92c841e146e11ccc40e87a848caddde7f147e38d19290d9984d9480968643b745a1db630745573ad07daae91e99b8b16566a47743c4a25658e3eba4c08b95dde04bc69011aff52376d217b9b5c7abaff38d85e02e78b49d617f5ebe8f432ed7987482d3a7dcd1a97cacde6ea3126ed2473b24f3e7b587675843eecfb57a1e63a2f56becf8389b10947b7b88a77f6dbb3bf17c776907cc8883cd131eb5fa13bfd7c4dcac130eb548bf397e97c1a76baf9f71988a11fe690ebc08f0d815a3a54f676cd8a71f9d31356abde99097dccd9df6f77c361a0f7bb68fcdcfc4a77f73e1cfedfd2d3e7d7ad71fe576a6a3d77bf7ad33296cb6963cdde391e3ba9a36e0f7f372b045a2314338a24170321374a3053d0a281d75bcf03a5f29e6977024b576420bd4f212a0b8c2f672efdbe96d47cbf96ee54c78628f6d5a9a33a26123e5f54eeae624d1e11639139558a3513243415062ddd36570d978091c62a4213e1a75cfdfeb8b33cecd6ae0389c38c34ff5aaf9ff5c93e8fdf8a79a2811bad6cb67424884383b6187bd0c27c3c491b40347bcf866edfdef6d5367e0e764c9f415be7b619f5fc6d17feb488f369b96de09dc273789ee6689f3595ec83ac4e03fc77d55628fd7c354974edb3ef932ad3de40fcec314be92ae6fb05fab02ebd81ecf11c1cbc06a66a9ceac889b93d8a2bdaf336b8f6fb0b50384f93ab140c4eddb8e69e841cc14f37bb75f95f81e593024b6b813b65cfa058a086459a232111993a95f34d7144847ea17c514c7e94c42a5c663bde0cfc3723a6a7f6ebf37eff9cc5272b318a60fbd7d1e9096bbd77ea78a437c2bf9fc6198656aa0ddc00532dc7e61a03a29f16003699981b4bb048e798b87934f7396c733ffe3f80e0c3699845ee3adf7f7cefc2c5b4c35794f9d9b7b56d648da60820a1079b9dcfa04db7e2120b1c48cab5b8df6384a397308c866328f4612faf77139ef65b9d9d24a650190be0727343054286de0514ddb45eb261390511c8a75da431f7338f7aa8f6df182f7d990574aa7e02ed5c70f8bc7eed90abfb6e913b1e2eb9aeab77cc6bbeb1fe293f73084765cff9c7b50d3859ae45760aec53c3352f64727eb71168451277258117a334aac319750e2c01eb77e8fcda0175baa61ceca712e3998a4ba98a5bcbee7b6d9c64ca1d80648026f9b503627ce1f8395ec3671fc3ee53b3db1587d461ee6cb31c5f2dddc9d0049397018dfdea115eb92d7ef4497b5b43310adcd3cd1f77b3d19fa0dd2cadb0e5d6b8709515decb0fe6c2c55c25e0e7cc5711657517398fdab36c74ee5cff23997a889955188b4980b73a1c33b79b09dc3f4c7f53ea679fd99d61eb83367e1aa4a16e89a5173c71d14a685c29e666911cb66c4524554b69ee7602b257ee717e9d6539981f4f1282ad566c96f5a2f645bd95bbb5585895748804bf88b146e19976e97825b9094bbfb444d3688d716d5eb3bc43039654fe7c72fd1b979bb677b29b66925b3f4d05dff715c1a1c62e89fc7a5224b0d5c8baad88a72dc491d76c266c580319eff4cacb3724b87faa6d8926ea333cddf45ccfdb5b45d436875bc7426f7b191dda5446e177d3af24a843d7e6ba2199b333ddd25ba1b132edd8863c17ae48b30dd5de9f0e14adfb494ee8c804de2c0d27a61cf01d3229d803ffa6a86cd8482b7b5e6afdefbc19ff6fc3ae2d3dea58ebb5d394513715c7cc62b78cc7f5cf2ddbd5cff77b330265d6264e682c34238f3e6b8e659f7b2740a43ea2613d3b123186a0380675e516f5715daa03073a2d21c316e425c783ba28fba8551fb72fd7b1487992975b5a31c705e49c00cb1c4ba394d74a505b96bc46166b00a6e45252352b16c69dfea9c445d024fd50c3fe590bc7f7ef671f0db7332d86c6a0ffbf21057decb9af399be78b021ded6d17a5ca69dd9473a7c10c789a81fdcef43fd16fd3c267877fde1fc56de43aaa36c7f6fa56bedb8e659777aefe9699f5ae02aeed15af4ec81dbaeb7e89a1927c2f54a76859d3af6b959a399f245513f90192b859ef9cc961575c4544cc73b5c984468752f2c583163a2492a003260bbd058208bb1c0657b2b2be4310b2dfc4bc6b6c5e4c0a3b3d57aa18b7e51212d0afdc79aebee44aea9937cd41c7a9dda8de0bb279e5a30327f1c5b047f463fb52f69c3cf6a7627b88297b1adfdda7fedcac0999c6ac7b5cebad75dcedb795058bb486f356fdd70d1cb75a4a3f60ae05fb4c457b28ada25f7ba809aadaf509f68632f9dc13b41e428ae7087b4db0ead9b90c3b9e11560261cc196a1d5a60cff0a98b4449921b16e2c5a091c141bed8c7cc99771e27c7673ee3dffca16e591eff2095e5b8ff40be0b5536b6f17c1f05e8d88b7f7c3fdbe1ee9e7e59eb3695a8eb3b4173a7370882ce97288278185b798785d6c9b4bafd0c08a37956f4c42acbb805b19f608d331056d9acffbd49a1ba8a45b0cea9c8728f6b56c429c087876a389d95c4b790657b4e95025a7d21e1b97e52f0de76d13f3f92b5ff99e8f1ee280fd9ddb3ef1033ec8777dbdde7fb33c177b38af7308e3facd777c5bcbb81427ae8fb9590c98c5706f65e86de3d0dbdb539d76da6e915b67e7a396d4846c56b49e859711557e524a9114ad476d565d69e36a55c13e260a10821baabb5b469889aa3f23da336b5500ca0ad607aaeea250d6579abbc596c958e1665e816f830a62ce982d0b608952326f1675e424d678271ff5f5dce7b93ea15f95204b4bf42be29bed80f9a660e0e77f8a21078ec0cf3943be837e251c7691516771371eee854588eb84b30143bc7ca6631c771e9f280ae8bce3b6fb2b8078894aa5025e9701057cc9b30d2b514921ed50e575b28425671247a09e3390cd8991d51173634e991568cc10f6aef57215af780abc6953264071afac67c2c05dcad004557029a9492e8a21f658b264dd22c4db217f529a2afa9b731c62a20be41ccfb69b430f45373ee4754294c7363b28e47ccc89dd2df2f4023673ecf7d0eb3ed1474daaa35bc14136d8cb2197d4477aa6126e35c735cff20591918558419eea6c9a1071bda4722d7be8327d3e4a73714d7b7c1d43a4797ae6f3a2bdc705dc11bb464b882187eeb55f318cb57612ccdcda2b659cda2812563b0d4277c71d46b19dcd1110eb84c09adb6089b58f7dc15770da9bde9d8fceeea99e9eeff9e1473b18ee8721073bacafb52818f567fbe0e9789d9435e1853f42aa2e53cbedb1ddce02de2cb9a5f424686e5125eb254f8d2084de95de34b86cf01590ba24e82a2d612fb41626b6a8a92db7499ff1a523b8284d18930966ca6bbd52ae9359a1c533255230ecfb39f6feb73fe503fc7baa6fe567767ee86bdadf6fc3fa0bf2d8db74562cb563799607fad8f04bdcc7d43293d21df93c3510f1da548bba48c73e2fcc9af17115e9c2659c31ac6bf751c9ee1875e14277f598bbbf3cc39d7bbda829fb63460ade916edc13a3b625a026eac6c0ef59e31b6a7be158ea85ad0ddf6d7dfb3dbff5c5deaf8fdff19b9eae1fbde363af51f326af3f054795cdd1fefdbf79cec11686fade5977621b15a88ac104210d87cc41825279b79aa980390c63031971d0ac71e8efe210b5d87255d235b30044bb25a1fdaa82ae07f10e6928469aa8975ced842626a804390da18d2cf39a15a641bb71e955737d05d1ed85fb76de7d8f2b67a2d2520d758488ef1ab9c712c7fe44341d75a7b8ffefbe0303e58931510b0eb2a484d563dfd87b7fe758cf7fea170b5ef1f1f7bff35777c0cc9229e804f79ba86cb348df34d271d5dfbecb216ff4869fb149749ca57fb9197b3f903e7884bec923082ef77bb17be27bbce6fe0d3c629584e2796f447faa272f3598161f553f8fdc11e3dfe276bcc033d53e9e520f6ff819835a9fda1df76e9b0e31d77893d82c97b6d2c51bfef4a97ac97827b899277abb111c697128d45157e33d35db33380667d9f05f95dd673db5eff6763ef1bef7ef77f2fbff4d272b34e496fedcfc3f67773370913ed8d3d4662a7ddd63ab01256deb449de9755fe4abffbef7b9c6e451abe2157e79195b7e35fff45e8feddbded6b7f5e7a7f3f8518ec3df63a10bf4cd601555ac1af25387759b234fe82c0c24ec31943ad613827d5f670b646d7aaae0d253f5cc2b5cc1a89bad1ce9f9cc9da5ac6e08af359c671922f0ca53eeda73b21d2bdb2d56ee83af8d2d69c0bbd4910f3e1f67498f7782b7cba5bdeb6951173247155517ed93690efcaf43eec25bff382fa17fc0d3dc09ce3afcea990867da9b3864e0ab7dc6cdfdcfb3dffff227fe39fec4fbef25db89d0ad13ce1ea40d378bf0e9eefb5fc683a3d4665d7ce04fecb10390b6daa4070eef3bff4d7b7caeb3de67104aca662e27055e043378bb846e9cea0c05333c8b809aae72b1618e08126dec618781949a312fc73476441958ec96e82aa610ce1223bd47946d3cb0bfebb22b8f2b2bcd05e3b0367888a167a898f2fa36ba2cdffb6f2cfc2a17f0c4cd9dbeea29b920067cffef1c3eff7be7bce1e47d8809de7cfe84154fdade737d8926d5d1f64917837e88279edbfba3eec34ff3cb616eed0edc840326b9ce07cee0471cfc8fb86ec35e1c7cdb5bccf6fa7b0d9a70affce0fe7d0e1a9f763be8a2c9921e3972a7dfdd59d8e904367d81d52e17b33ec3899fe09bcbf03f3fd53b19385d8ffffe5e5c5ac4398c037eb345102e04653362cf3bb11ee358b906e1c0f2433797bad7317ddc313009126b3e62d4a4bc6c85479b1d83a28fd48d21088a798977b12d02d9cfcd88619b31b494544e974e6af219eb695f18ff525cda47fbf822004dc4cd4c3c6ac37cd70f741f9efb77dfd39bcf0dfcb767e1ac98f647f96677e5913f0f87586f1faffcf99f6b627de2673ee2beedcfece13b9c38d7aff7e6144ff644bc78e0ccbdb38f67e1d113feeb95eecfd11fef636038d25fc4711ff7299d857f5f7e977f85c7fe99df3ac1693fc4509f632def12dcd463cfc51e3f1d6337728805cfaa4173bcc5a12c64a969d4422ae8f1c2032e26b91bfbbd3be58c4da33033880503df807142c19db4a2d1dedf05b91b44f9649442b14934112405bac68e6ce36a622405dc46fcb796da6c43f26ce301f74a38512f807bd1fea7438c31f051867ade8f7be2d697ca359cee717fb9f69f01030c5a9a25dcbcd6747961ab5fae6bbf87df26595a2195fe374efb8f88d38e98b649387c1834f73ed3523a75bffda4e6f5853b7ec0436f9ef37b31d93268424e6b07db26f07bc525545e4adddb082040882c244981a8d48c766333b5bc51d4b30a0154c85eeeb0b6d348816954b2b9d7672a5093725528535868ce0bbc25babc4becf1886a70e2751b2d998e7fa59fd424bf1793bd8749be9b9f1775aaab83d68fceccd7b8e887f9e9d162885b1ef3a8430cd3bf886182430efbff5cbefa477ef0298efd5fcd871c9f637fc68e36d43cdacf59f77788efb96253a1611ce8581795372233df20366c57f6f82ed030bcd281cb38b85e95f81732e6f73268182278e369d28a01de61ee628fd63b4f47cb34841346944e189bf985d58a5269a9a66e13224d924ff4d54c9d717f7f35bebe19b4ea1e71e3015f7bcff1757bb0e5776b36ffb1f1f64fee88f7e39dffdd78f99de71aeafba7f33cdfbb3362cdb5e2107b0bdd35175ab6407a3af281f2d84c6681319948bd0d9636dea67a5632e3762466691be78591e4ec9e710b443a9c3343080fba3a660c46dcf4161a6bfda2defad45432cfa2a81b3794088f3832fa8cc7f27fe1cef846efffa12fb62a1e735d8366d35bad27d52fb8dc24fa8bbade9bfa70aab366ef4b8f779031c43aaf7bff2bdc3faf6b0f3dfae4231dddffe6e9fe2fd638dff313ff8d9bff1b37ffdf899bdf7caea52553277a959b4ff9e3ebcb708e930357bc493badfb069fb8c77ae3afa60d8f0ba025d4d209bbe9903e9e204b4c71c13c5ca098e7982098b582ca6b6e211de599c6a6cd5d94233deec6c18ac305037f7614e2c58a492da12d2164b2bed261c11886b2747b8f4d60446fba4f72d43fc9c5e97188ea83b66fa3569fe631fe056c54aa3e0ef1365d837b11aa03be7ffdd9b76a0b9a9618376daad70dd6327765d7105bee03a148639ab0638b75dcc10b9f4018f593deaf2660954fca94473d9d3695a7d53636145d39d91ae77ff4a85286678920059387a4745b34c379a02b3d98c945da5b5bcff1f48beaf4fdac26f0b716f87a2f2f5be7fbff741c9245e5fe2c445fe981bf844eef3aaa5c250ffdeec77f1ffb23ced30f7a484a6a2e3455d3607cbb2ad42d2762272cfc1015aeb6caa515ab090d0c5778b389bf306a9d42d4a070728dcb6683aa0c60c37512953d2c80d098652e45616a3e17f132f8ddd20aabd86efa95a266ca118d79b1fba41fee737fa6c3417f2ae2485bf0762b7479a236742207fb1a6f7f73df4facbdbf4fb2a8dadf6d309753b0497459eded7871e0349ea9a9e64e63e5525e65943ae256d0b18e75779aeaad4d81ba66bce9ae00baa30ebe4e2ad7a333af17eb86074c7aab92fda2e1248e0cc8452fef22823c64e329b7c1af55290d366d326f363763e58e109bcc6282ae245743dffa976c5c1f77c9e7baf517d1ac8b38daa6e5e8b0b7c3ba9a3168199d69df34543bcffedd2e74b014b64b490f7dd28bfbc06e0c6ab88d00b73bc2fc6d5ca0596a99b5d45d1617724b8b9126ec761a3bf04ada632c297ac074bc589592b24a561eacc398a22d0d0b9d1a1912dcc5acbc199dc17b5fc77c744a43384f0cf760b7a55b27ebbffbfe533eddeea8057516b63bbe8726aed0e89318035c28c6387e5f70971a37cfdefff07373e82d398f5719f4135fdada16cde475a00b4cabc99212f76aa18f5db2fedd53a6eaa017b604e9bda0f53aa0ed6daae3513c734366b54532ddf49efd7b14515930db6d10add7a2143b5c8889e8c6d59551d71ea5f77125aef66b26e5d7394d5fe5911cdfc3f1ae8d9ed78d8de775e3e5f44dccfe159f7a273f3bd7eb81affdf37ee061ad479d16ed51b7e4bcdc568e4a56b49554788bc8dc88b869f2505d114d524eeb35ee1a3d294dcc43013d5b030907f7510f69d0350f2b0bee52bb99110bb86436c9788e8ba86cb9af995b0cd06d6c6bf7b15143046bb6e2cd34d14085ec53eff3b3de3d91a586df88fdfbdd63dc9065c9f4a53ee22b9c3668492cf8b1afcdc05954b66a31c44c6a7fc6cbd52387627d5257e2553f1ed8df47c33df8977bf1564ff4c88b289a272d8a61d6cdfb5a7c5fab6b3cea8f7d8583f1be5699ce7689eeaab464bf625d3d9c8bc9920ad50b0e3731979ff5f45c4a1ff9c59acfe6276489adaa64ad1dd7396fce4e6aa10d2b9a965ba39e16729ad0a68e4a5c32a36e7d5068896ddee1906d495533c4fc5da2313bb545b1306e414aeb392b612779d3c51c5bc8ae01b17e775865280e25a361d62d996c698833cead1187aeb8282faa3ada6f078c9863ed9956e977fcd4a0af3fccf9d04727726147fdfd4147ffe6f378f6127a542fd71ceeabc106c2bd8db0d110af0667d6a508cc529bf94265c863ec9a1ad0f0ecdf66c095edf3b1ceaa5b9310463c8aabab1ed3b4c086288092c0d2d3e9b84b280082cf0d09651c2bab4dab1b8dd863d3a3b0f34b59250674525bb429c72e72dc6d72d66c96aff3f77f725edfd3b34bcab491ba2aa4fdd9fbf52ef37e8dd7f6fbbb79fbd951b3eebc73ad475ce432178b58893800a85ae57ff444d3b6c14c38d8723b3fc4bf968e286208b3589377b8503aa9dcb94f84e969d90ce7701670d35b050d268e3512105f5168b5d1ba5960c85a6c895cda4d4155aa219bb6173dd7256b12bdfe6be74f358bf7ea1f0224767bdc2f900f3dc3e171a6fbcb3cc4eb3eb5fd5eef167c38674fbcb9e0835eb17faaf7fd33ff63bc7ed68ff5df87feb7cbd8e7e39a7bfff3a8bb78384fe4b0ce59fe8762402baf155ab3f62bd813dab8bc6c3b510a237158b5b4c03cd6d1436ad73d62c24fe8aea516bcbdd2c1c4eb27ccb3304d0c5c6278bb133397b11045299c34d40688d05b9df5a9e16920f309babad2db75cce4c773baced6f51eeedc431fe4f479fdee02baefeb73e3a7e1590e1ac2d51772ac97c90f1dec74e875729fcf717a7c8ee658cf3c2f8e2ac79167c31dd6dd79c4d8955f981b5429fbcaf8a30705b439bbd5511e6d633b9b61ad59a2d0372915775151e30030b6d0d311a1e61a17782d4bd109ad896451b4349cc4a9ddfa44378d80ff3697bc8d161a9c24e7cc71fa87cffcd73085f7b6bfe21fc114e7cedad00c4a41240de562e0f78925d73e6dc288149d57b859da7b1d2fd35777c33f362fe8f85d90b61a7efe8adefacfb944afe6983ddbd3c7e738eaaf9f7787ff8a8ab99916e8ca677e9b96ee5dcc8415e5ee6d4a1b3bb04c419cac92f66644140b56f0b60f586de019b251616a2bdb8db882b3a434494ca0171b37f701c5dbd8c67e62899d97cf3b09c48458ea56b0fa8a3204bfa513fa66d6d1f338f287bddcffa06eede34cb157efeefff757cf36d7daf36d4f355188f3f8338dd3b731fa77edce3cce5438dadce3fadfd139060d2137c0cbdd5d0adc591ad6fcaa175e6c8f1b3e638630fe7488291e73f72e9e65619ccffb80b080da8d9f3a13c214ba5bd1c6f20aab4ba87b9530e94441b320b92cbdc2d78965de2e797def1748ad687b2f9dfaeeb2f3a6f67b32c4c2bf44007651886f3fd62898d4913e7e7a5f7f6df6dd3e8c7f4e434f875da467e6277984f6527984b444b7ab6156ef61dd733570bd40bb8ff47a4a7258129a1582644b14ba7311aa511c4ef2601f4f506bfc787e3ec430a1fb057e897589596d597aaca7a4657ac428de591805918c2c19b4529aeeb873d321a00c0a91b6e4e26a652b3d566a83665ec7293244819150b7f7a887811f4296aa5a895c7a69d1609e232fb0da6ba921822ce191c2dd25f00ff07a14af6637266248110dcd65f163fda62c2de5a12fe633eda6832ec825f045278e3d0d03360cddead0bb479bc735cee3f3fc06b41c9ba8c24bdc6342a6639be8cdcca7239d56f55dcce13d575e8798eb712aba48039ab4ea362a71b1b4dc302dcdc9952e9c554e8d988e00b5e73b544d74bf907a3263152593299a654550b67d02333d01979d259b1a936ef0b9ebbddf1eece97f0efb303fdb47a4253417217b78c4849fe9f05ec457546eb60a0048cafddf3ef88ce7cfb138ce1a3a2f06cc9c55986d09c082856a4688e825640a15ec4ae866812cb615a19c0444fe221c9729fd7d1f6bf22e29db38a1aeb55a8f739ab39dc8b36ea1a30041d9a27cd293e978e7596aef9b18a6cc97c0ebb126ba205467e86b7e199b9eab799b1deabbbb2fe2fd13b382bf771ef7eff5a809b48f598777f8ea33adfb4eee181918c91e9a12e248ced85d4a414ec09f7b02a026186d59c59641af84377381a4b51600aba546a42f791d51da2c44cff298bb9ed4e45562a4a35558c774da289f7bedd2620db1a41ff1dd2eaafef4a872f57f42eff65c7dd228446652a2fb387ccde17cfdfe86996717797f2b6ee6b1ae0eb3459fd66f0e35972f73b7db45780310a84bafbfd9ad883f4acbf17ac5b27be2d4162f9b8240af8ffbafd5eba53d6e62ee35a9de2a11fef99c9b7299bdd0121dd45107fa64a87d0db6fcea33adfd862ddf93627c871d38896772b79a4d22a699ee558f7154d5db98cdb789c2f781054352b1c2ab989e14752ba9df2e8c1b10110929ab51a0fc9dcfd1af946e76948f74a48fc502604a09f422c51611afe3d4f9d307449dd06efebadff9ce6cf028645a32e8009bdb4f7916d3a15ff8e7f1c98b35877705a43dce236e3e24faa839ae735eaf2194734cddab78a6d631800ac34cc4395c92993bf595521ce28cd8cd9a96caf43433468658d21cae5322756664733acb822b5dcd128a4dbf409ae4371db5c055cce406eb6d1d832cf3c23f3b0219e30451e17ca73e8b6e23dede7f187f94681307408bb8bb11c4fb3beb099dd0768bf4769b94f449cfff75cfe7b338fcaf1ed1d39c8053f5e03c2dc77dda813d3ed4e7cf6642bf7d4eb14d4bad11363cf47f1fe22470e26f0ef3300ffec96b627bbc8d0defb99eecdb798436ee163cdbdbce56186e96047f31d2f1b9dfe8d8df0a67dec4b6eaa53daed212368b70a2d2120df3f8079cc4c7eb78fd612dfba805fcd877fb6ccde9fe7bbda92bdf0e3cc852152f6a09ddeb7d3aeab8bc8c3d4fd71d4a5027a56af63eee69efe7277e6ffcb0e0a69253b0d9ffaee0a3e7bafd6f7b3c1c5749079b0bee9af26946f8e3eceed7f16f97e8728f09fb0fbf57e5aac16f86ae1ebd9c1bf0e67da6257bd2787e7fff0fbf63e0ee918f799831f3114fd4addff8acbdcdbff66953379321de463a7c48f67b57d6e7ce207af9ffffeedcfb0bcd413931f7fe1b357e4dc33334454a9668061704a80097b85f95c04a299861c3024c455b49c1c4cfe786a7d52eb1c1f5558fee7cdede2ee18d9652ac0907573e98f7a2cab4a86821096bb29acd3bcaf16d52e03ca804f02ada0a258cefcd1b7a91877bae0bf2d6ce4e6aae1d35982e52bb3b3b7fa3cb526d3f89c98ce18caf7f1e93c94ad4c9d02773587741d2815773de0ca32cf40a847c1dc411458dafa13ee0f02aa2ed6265c15fd491b6d7cb92db451b6872448ab12e38be4e6d56a75a5b24611627a5bbc1bad7c7ce64ce807a48e09ffb401bb315acfb28ac6fd10c85dc32e70264bba882a762b0cf7af58eb9aa0f67debceea53bf53b03ff297dfa3bfa89fbab959c01118026e6a84b0c9ca5fae6b9bfebcef625c37bfaaf7ee4e5f423ff3bf3f53b7ee9bf3d5167f6447d256f5dc24dc4cd5c70bf799a6bfd6fc4c06e96d8f021d259b1e0209336ba1df2026f9fe7986f3d233fc0d59a41778fe13ba4370f828a7b54ca05b2cd6b5a16edcaf1bba8ff208ff69538b484bd20d1c045fdbcde412fc1f95e47215228f7f77bb8b7c5e73feff7089ceb0b7ddaec22a636813d1ac91926ac74af030b9957fa1c5c69cd421822408ee852cd1fc9d2d5d3d2ad29ad77692fcb40c334d6eb7becb8262aebda735c1694f5ccb39b5f51612a6ab5c6aacadaa5adccd4fead792154ec6dfffb8b7e26fedcd7bcf529cffa9b1e6ba0af30fe3b7d4d42575aecb0f551ffa34fedf143aa8fbbb41b972274b7a9e1ad5ff4273ff78fd3b7fdcdcf38bcfb18a913fbb3f112dbbdc7e335a4913ea436d4d2926d93630d5794ac4b0cf40ce3bfaed9fd79db9ffa4cd72dd2c70fa9c136f2c039feda9e1cd7fc3b87f6e8d75f3dc3dfef147ee94ca8872874cd05672369b387e10c7ccae73931e3ff7bfea44e4ad8ad02a0560e56c9700798075ecfe9e73a6a449d97b7f198ba5bda37260d1a8cad08e0aabe25fbefde17f748b10769bb16a2e09e9622903acc9716de62ae99bc14cc57b78684b7003195632026ab822964bb51aa631c58ecfecaf04cda3323d5c60b56e238add29dfc47e6209d1b17b8db95cdbe32f3e112b59a756264ea90673bac3bf083cfe5e77136450ea34be63aab32ed121def309beb5ee94e25409e544c61cdbb67ba1bc4656daea8b8c5065a24a53792c69f6d42fedcc710f684319d71da0733977b960f6495ee92c22d480f6f7daddef2f2374868a3243d47b7e6cb71e49113ff920ffe3a071671a0121b65a9fe4cc3f635e61e726bd971a6dd5113e3442e2bd2db7ac1877d7f964f3991d37987b3fec8217c9d2b11a1db2c4254af5ee6ffdeac7ff0ada0144f39a5dd22bf79cb97ad642d6cd60f39256eaaa71ca57589796fa36ff5769c77f7bc9ed1f6ad33790213bfe0c17dde8f76c19e8e47eedd1397f2b12e07be51cb587322ca38a73a010c7b76c63cdadce1c2b468c8ae70c97ea5b429d2029ab8c4ae08c504dbaa4d959c4b80365109a6a400f374c6b2b8774b349bf809c9ae98254c42dc260db37bdc8b07a13773d25bad588f37fff8bcf22fdda1e391e0a7fa369e72f1ff428fce314fb7f7c18775cfe5531e7a34b0e569739de991e6d1e69a33d7160efa9550dc128a9c9430ced66340289c7a79da0785f212fafbded3eb4962df8cf80cb7d8c185b4e58ce6a85c39784d2c86560a8dbcdcc5c2ce1eb08dae64453b4960c92a7951cec3ffed5cdebbfe41257c7cf782fbfd41fcbc7c9b87fa56fc2c38d8c6e50bbeeeabe778ac079ee52310d56bb12a51488af1c4b399e1d36cb7ca2768e54c04ae84217a61c655d19222ed075c68c05f28f73556a0ed02b8bed0cdce0bc60e36fcfb987b7d4c6bba52d60887b46736461ec1240ae50353acc11ad53fe95dfec97ba9d30e9492b79b63efcede8e0a11805da20ffa84ff4aae3e0ebd46546c9338b2160ebe5d70b4bf179bd41e0ffa238719a21f3de7b7faf77ead386850d0802b03cd5280c215f5cd949a99e035f7346ccb329b053ada043aae574a65816220b0ac91075c2f2ee746a210c0ba59080bcdb111ed627b731f80c2f00b30491c140abad11867152a18472ac3ffd1befe4defd4e7daad9778f78fb5ac45787cf79df6f6b3ef60f1b066ab9c5de169a309036a92e23bc23323e02990547096a3423a305e860a07651bb352b4c82a765e305e2036c9e29cb1c0be3558a53a4ac757b2aa3309104fac6647747792da6e8967132866c20c4aefdee3eca2f7c02bdff5a4e572aa16fcf1f9f9107b0f7b1dfe690ef7ce114f7fac2ff7bf659b5fecdf8a2e932bfcb47f2b3a1f9b500864d1d054e19252539042e5d276038f6eb69c4a4a73cb4044382b8efc544f8d28576b0123133bac95e15c1346a447b469039865f12c32789eb909f30ca6b15f88411e69632db145e8556e8c4356c999b8e86cec93fd5bc1ff92ad546e16e9b41161b61b9eeb735ee74187875ca077e0c4da43fc71ea7372e01b9cd94f50fb06f3030bdbc270e77c26e75e256010fc062b67f2cb9bc95f54cba6de6c4253875529cf1a1e629e50708d72da2e6d3093cc45893616b86c0b4cdd8d67a7ed72268128c7bf840de702c84504941de5519b52595f763ef2db3cfbc73c19b44d4a94c92968a2810f37cc257fdd03f3159cd3451c7ddabb74c02d3fafcf1cdef741eff8efbf0f31cb79f5643e1f49aedd93190c5685d6330d9355256e1322aa20bc6d575cd0a87035a4144d6c04030deaa90e5a1fd431ae520d55b7ba978b0d2b6fcd3887266693d0ebd11cd19bfbc472710a6b4467f07e69efee519fcd2332b9685fa728d52699822ee266f5a86971989371e11ea62ff905560eb3b9b9e8125dfb9774bf5c204aa1d23528d372dc1cece1c57334472ed959795fc260ce2dc6a2022da4c5b648776f53ca7a9453ddb33253cc7014f1b1cecbf67aa16f4c96a3db580986d7e35f12a446a0b95c40b440b674e574bc5e55922c2958d39cb5893ebfc739bb93218a537dbee30c2ebc9ff74ce41147b782c375b2c71f256b2567fd6771045abfc9df7d93f303f3d866477d1657a52153a931c40fef3cd7a073736edc701de728f7a9f47d035e737563d0ea5647903dac88eb700a6352b63565a815a5aba8e3563eb35aa93593986722a18825959bf915be9256936330d756cead21b5e89ed8e32bbf6bfa5413b1ac22e097d25e52555db6d70b6d12dd3ceccfa15f4fbdf0cdafeb5ba554720a06cdeb886b2ffbfc5fe3d0fd3b9a82c35e07a0177c8f95701d19de877353639d99f2e37cf32631a44acb21dffc4c23fa5d9edcfe5c0e7a00ab92367f73a46aa4bdeded389ef9e35e24b6ba7f39eff7e73ab267fbb077ecf8ed7df7faddfc0bba062fd7dc9fad4a847e73d04186cdb7740db839c5ebc6f64277c29598c960bc43867bb72ae5e40aa835b2db92b3ac4bed9d1111c1135a778c6406ce95eb51b490eacf9686d227aa9e27c578237597c6a0d08523345ca85fb80064c5601415ed9641e8d3eab2f75feab0267d5f3fe73faa77f76f8f6ee56d535d3d0867b0812e76d8b97ccf777cea89593cf6d810a19b4721525fd3b4bd54ff4ebb953aeb221df62278d2ae3df13ccdd18f9c753f4b072eb9e312d4675b42c710f56849c26c812c8608843de56383e9d1282e9a6da2dd98a297236a439d2adff0662240a57b4fe9ad8e61d1319b1a3464f711ab7bc9db5144bc9d049611959b5d6a6b1ab7d5fc9fd15d3837c78bb2c46efb38c45fc1d997bad73789836a799c2df2e267e29ddf43c7fe8cfcb29ea420d3b9f2ee59a12c468bd6e3d9dc0710ca3cd538f37504148b09bb0a0ab1649a6ac96cdea3104d135e4768dab4ab994232149bb467b5acd412533397ce8d86aa0c1368f511c30013d9a73abcf87c916fe838bdaad97e72575c843f89b284b3cde1fc0d759d673f6b475dcab3b097e7e51961d6bc45fde4410249508e585ce10da663e8e97823209ca436bce2b0be275ad14a0a6c51d5a567b881641325b42c0b6cd6af385357408d68d08448219d1618b35cb0b4c4d702ba35cd2de019f2ea9fc8d99ead55f3b786fe6f68d41c6b6fdd5f9d876f69d2085bcd5725b60223cb59d0acfd10b1a81ccf099c400c612dfb498b39dda5dc3728502cc9d15ce8c84ea0aca202e7a2689dd490d701540a1bee3c306a6719deea8ca9d29bc162c9844db888577082bc308ba9fe9d5ea3a39e8b81cde4897bf00e463cade17fd0d6ba48fdbffddeaccd33f43a0efffb139d8e3cb6c7f731c7d967b3ddbc416fd8bb441fc736d6551185f3632fc7e3fa5a3fe8e67667f90f4b5a5a2f7a7927298a6898d94ca125b5cce98ab299b76e9601079a5fb1116550677a3b97dcdc058522888ef3349f6c70efed5089664813b398c81c536b27aaba5971d767546d9083477ea1b651b9698526afcfe8bbfd92bdae9ee7d3aa23f7e48daedbb33cd8d4fd9f13f9ae9bc71939432f57c91e8e3d6fff8382935c9a3aedc07e5fb3b42a9ad4868fdc9bfff1dec6ee8fbf3ffcfde3736aa7f5e7ded11da9ded31dd9c71cb8884377f7f47bf41267ef66391de6c6bd5b337f9a2fd35a5fd098ed45285452e1fef89c47fef6b97ebf68626e96c9e77cf30bf54c3dae37dcd5f582ab0751fefe163646215e208d69a9badd9175734d2c81a49d69291ddf215bb85e51ab28bf19f93d9ef9acf62599036261ceb88c827c32f1b4ba477082b001bb249f5c310243cf02b75e308e978e8c574af92b07b25465ca2fddad0f7e9ebb4aeca2196a505f894fd617b96b37710006ee617ad8f3673f6b070edc79f8c84436da128eccc496c4d7318fb97917533c956c3ea2169a79a5ebc59572982361c226eb2535e7743dc61135192a182320cb192cb6692f785c48846702128560c419e6349b713271482109e2754942e99fa15df93d7cf41f1afbee6d45da43ecfb19177f77212efe8b350ff8acad17e1418fdaebb4e33a67f5371a94a75db0b7dd19248baec19ec672c1552c21cc319c842b3b9bc8c235ae341688dc6a51eeeac84175acd59d2cc777846676ca326d09a1cbca2c5b42b60966aa1380eefc9285d4511acf8b2d736a91f2969db2974fe73ae9ee9d18663bc03ed59fb8a9eff03e4fe8d1fee57efe704efa1b9dc2e7eff4a9ffc8faaaf69bdb3fe55ebf733f3cf6b6ff1b738e8f79e383ddedd73d77de71bba069bfa4ed83c79b32b07fdf63581b94bac2a7a69d68a80ea0d52e67afe2e42fbf973f0fe7e7590fdf637f571e38b29fede5d08774b9bd7c96837fbeafcf9ee7d88774c61e9349b162d935d5e088d9225e18a24b2ce422800151d0454484e9477d48e7ce5ce3eaa065f2620f9fe9169ced57c760ff3c829bda1734282f53c7d5dbade458c93d0e76863ea757cfa11df0eb79fd775ac06511a97a92c20967b39b965af03ab6018b0c6b1450f33e75260dd3d924d5c024aefe74988a86f0b1887ac94478dbfa79d425444c848d47b8575b5628c61d352150163ec3daaa602a6208c59637f2746ffbbddef15a3f62d4e3cc07efcd6c00c98ffa0dd56874d44338f39c9dd0b9fc14cf5e80a7f166dd01630db1fb10c30febfa477c7b5e7e832a17fa60d2c7b9ac65301e4539db0640e5a926e6d498ec70613ea4faed1611f79a291c04fa5c5ba93f20d1cd4802617b46cd130e68a29939d185e377cd8c1678278acd96113a42b640a2f746bcc86611659be024befdb4d677fcae6696f0c3b9fc7f879af7bb7339bfee6fd3ef9defa17f173c441ca8aff075d00578e5cfd73cf8d9835d24256c44a01dd739eb6c17c428ee3d0d02d6a3ccabe43252f53c0819e2d58446babcc306f35830067eb1db4aeee6bc884c02b235b67f8f441969a4cf4c56fd017e19ed041764e9309800b545a1a5e1eac610b030892e310659e587080ffc9caff4d69ed2b2f958bbb0bd4c9ee6f5bacfce5af8983bf38f3c88f3b42353aea671d9eca20278a41bcfc92c1aad826613cf70eb4dc7d71e05312e6f3baa6e743e1d2f120a32af6baaa0f0fbd5ba09a556b4bcaaadc051bdace01c03af4fd81f3d09eb076aa3fb14668dece14340541e94b549dfce097a6726d49bef77e88d2cd577f453bea8456e5d481bedf0ecc7b8f3f8effd5938778623c8ae006b997da3c5ba8c45372689257551babfb095ed047001d2e084d27193843008acfa616567012fd42cd00463b3a28d2a97c796b994333af2351032a2fc5473d732473eb650cc68b6665506b0ade65e09b4b75cb5137353bf3d8bcb7a589273e79fa06dc2f731072b0e738158967c4933f4e612e7aed9db9be0cf6af0071ff7f6f38356ede83cceaac024c788960204259b8b5ce67ee94e09ad6d6e670baae1f6aa77effd618649dbd0c2d52343d898b0a99fc3392f9a484264fb0c59b18d37ab5cfd2240192bfb669458b8482ad1103a568b6e03221d6f313fa921fa99d64921789badf8abfdffab17faf37afc7cf69df862dc241ceef1d7eb79bfafef3afd90ebb9c45d079a68bf57c77cf9b39f1bb43ee421cff1bd8c482e1cf70a97e695d07f6b2bbbee0267425715ddad42774e2de9261cf709f54dc4ea8d008a600eef7c3eea82a2f985edcc6270e22c793365362b133a5e93996b2c74b312ac7e88797b7fa58df99222c7d37d83bdad719ff18ece9d2180b64938d92643fe1ba8842b4d7efeaedab79a60df7e57bb7d1c98547e2338a8a58355ba3efae313cf359cdfeedc5ab75b78065248c1e99581ae3d868d94d577a98e705ab12eb5981f7071ed4dc726e72689f948a7c1b8c333d41083698123585aa0496cd520ca51b7241340caf93dd518f12b063d0845a2cd4d0faa4294504b81fb711fc4d7cecd43a4436dc141967e865fa6178b159ead797c074f9ce4e6b8ce1971b8bb489c79eb75e3302e4581e8f881509cc515ab3cc6a602cefb0fe3f02fee932855951a789b7e9a07a2179ab5badf17510b036989e13ee2e9e7cfd11c7a02cef33311058bd471abb86722b6dce58ade748867774b473a7236bfc733da51236d31748320ac5bbf925e3a73454454834b209656e3cb4a68b2040f11c9c80a8a60496bc4737cbf2a8085f26ce9e5ae9ed83048ed46e14fb8aee7de3f89e137a9e36ed3a7be88d7fd5143cd2d2d612eb800c9149469f73c8ff9a63ed744bc510b8eebf4636e24484ad54a4e9b57ba80efcc6d1a309c5a705127366da2106f13aef20ff536abac101d18b45f84adbaa73af9cfe7537f430b3a4ff4f17dcc3fb3f74143f832f6ae37f591bf72fcf77166eb79b599581aae1d6bf26a0559e069cc4d40a691ae315941f525656ba4359b38ccd6116713a68b29a573532ad19372b44dba46c83e3285e68614202be887f3814989975786b4974e0d891df5c212cb643abe5fd90d7b8b93bf5e0ff5a6a3b3f94587f7c2eea270fe6fe5a40fef83d7d9df7bf3efcfdfd2cc42b26b3261a372a526a3084c54106c764c6f755ab9dda2471b0cc4b567bb16ea1959c11b7d39b3dac8c8483c83615465236464b15fc885c71997162e5185eaa5e3565ed9de268adda54078840a24cabd1f63c6cf7b7bd1e0736588eb640aea4f3979c1a572a6e34e0400485b6d165c1deb51af3e3bc41b5fee85f102a0891cb280cb360e859d12a8d2108f28051b9f63c6283622eefd74bff6b1902602d08910823874bf9487ba0436dfc725f22f575675479ff2e6791e7bc6cee350e33cd044e4e9f58367815dc0611497aa4fc0feec656ea0040c8c3a4b89fce5556e1c185979a50192e68ac63a6e021bf48ce0c62bdb9cd8e3bbb4bcdde222db2c6d708f9818110e841f34a584ee3d9dfeee13adf998d3f815fc620c3a584d14bad567738e4fe8577ecf6e5fac79d8ff41938ac34e18d1b9ba6f071e30855c04e3b5d0cc790227059d418e092671ff672489daf9f4d6487a385a1898d31047a8971485f52686ea5686f29a1998c76032c5219e0b47d888a316cd32be2ad90cf7acf6c27a896c8ca33edb49ad156935e4a7be64ebc3770bd12e0a3f9db56bbcd530feae9d0ffad87d6a432379bec7c7e7581c72c7fd79f6ad020c275701603e2bd812cf6411c0c9f5d271efa362fc409d89891d55451ab6259477a9cd4252a06a45b290cedc8edb68c4addd8839e89e960c2733719d16f30ef7e93da3751771d97ba1d5222a86ec3cee2fdb3b7be04c817b11164ffdd8a7343df44c45257c1083d6e52176ff04cfddc61cbdd4cc0e2ec1873a33d761b866eae0ed2274b3a4c4db64d030714f7035fe29ae3fea56e1444bbaa10fb14874ed2f1e1eeea6f79fef7bdcff1cee124b599e5198e97abca176a6c7f4b695861ba556ab568cb95883b1a7d09c28453187bb84a4dba5659949d1fa89a17456fde969b1d96236b1533e02b1c67e25950a055031a95020a11201936b49d351f056c7f07f81fb8fd52347efd3fbf2e7f991627f2f0e737d8feb1eefc533666d814914c29cd2b921ece6815161638e3ca103812876a242e62b3bfd525de56bbac3179a6d7c4277f8d84b715eff28b8197107faa8fbdd4644e5296f463c4cbb15cbfab4b780c8e73a299ad0af261687b0f0a6631074e30575604179368ad4245b92428b6df3575c22e829d1d27062a57a5b22420d2f477900268c6892241408ef2407fbdb31f541677798c774fecc0e61b321bf36f012ba3db63accafff7496577799b996efaf7fb4677ddca48eabf658e405dfe3b0fe19bab372c16c8ce212bb44633a2a6ad7d7b0884357435a5da5c4db920bde63e7f03dbee793fcb37d9208ff347bec7c98b1f06ff47bbf5873bb08f6be8aed167c8febe1e65bf83d54c5927bc0e7b84e99c8e9bab98a4b643006d74b8aef63abce97b659916abe231cde62ea3ab2c07550a5a3d46161c4e7dd8ad59b78da3cc43aec896ec674da400cf084ce4447ab3f5d50d557b155c7ab4a2c719e5d54af260e8f989a8327def3b1a718bdd17b50fd82e321167ae4f6bde8413e35a7fce53cf377feee781d972c978f71f0df1ede377af5dba8ac5564f82f7b894fcf7b39e89d387f1e52c7dd4a7b3c68022f4ab1d963c6f9cb1924ff386f35b1ebdb2874d767e6661eed73d0a2159fe7d42f32c3480c33a58edab8a5fffc9c1c9f43db2d06bd9ef37ac088968d023ace28544560b757b4c233ca851530114b5b180b839584dcdca74adca1dc3769a1e6ab12350b433812c0805b4243c5d84fa9b299811a4f659084ee32a04c6360ae2307098fb630d0fc4e16f0fa0c6d94af739ca76fea925ff675f1a7fcf4fd191af597f273f14187fef8ee54bf2087bf7f060eebbdd20caf7aab5b5af41e81098bbb2648b5ccbaea654e54f66ba5ac1fe675f6cf3a6944e8569fddf107edb29fe7c006fbb6814a4ba98e58ede9e78366d9793a30545c79805501c155c077f7d4cae284d03ed6cd5e3264a716bd4f0a4648383708c1fa92c15c687383f6511fe8b75ba4644bb8b229ad777ee18a550e7d39dde8a874e314fee92991de8ad31dd17f9b844d16276bed67f06d3df22d5c568a70de48fbf7c0cb4b067ffdef70944eaf7dc06383564b88b7032fb03487bbe13b5c25cf524458e65686682e554dbd82d5b86c63c1ea4960b94c2a344a68d34b20669847a318a6460064857b9c2d2dc07148b71e106b54b190f3f1af58afcdc451b3954d7741e1ba3173a71eaf399a3182fa49c84ecefa38abefa5105cd403efd871b7a9cd3a699fb8e3ffc177b2b7b74538e91263a2d20ad7e2afbf39f55c07bede797d7f5a4f425872dadc7965ebad4a8ca81e8d78a1621c8cf915a8c12a68a642f375915b3ab2e928e85d03e9b84aaac9c20fdd29b6598781da11e2eb015322d2eb8758c73e29c01db537a64f04c7c57c74d52312e86d74d9bebfbfb866d030788195c8cff549e6b3014b9d7d8ef7efed532c71a1bcedd37a8fe7f5c06d3a7b4e47a88457babf64894361b935d1184e9c894d0b19a319eb4535d97d182f7d6d6f3651a894f8b236cba5e69b6095d8d07ccd053bf13ce7ef1b41bfd2326ba2506957bdd7628adab4947d3ac37564b857c4c86ee3d77c8633ee12743e97b888b9283fc945696f358dbe978bdaaf75d84b558af577fa0134b0b4db666535c427784a2ae5add6cd3cb0005b95ed350e27953753365b374ae622269cf6b2a8ebd896c5caa9abc890f1128a2da6cc4f28f47c503b4bda3629173cd14c4468b3930e7639c31cf70260587c565bfc96aff00ef3afcec5ad75ba7eea07fe544bfce7b5b6220ee78dd0db6d34d41f9ed63feaf39d179b33799f2ab95b521920ab8944d1383cacaf890da8a492c70432a689521a5e8f7af9b0e42847846ea53dd7b1c3da158df4d4461851b88e6906f77f173b13b10c233dd121497337f2355c0b4b362494c5aa5097d5273ad41e9e66d9fcef71378a443fea0c7f9e87bbd0bd31ce0f797e3a608aa7f5bfa5196dd2aec188177d6cb925d2e434d67d2dd0d25144a4f20b73c934d32110673894066792c5bc7639d58c55e56e38c5c8b35c9b5bd95dac26610265ec31b7428065c2c6b1a0ca4a7861c645d407366863667567f4d77e0147b07ee00938de534fe4f452b3decef7df2f38531fc56bc1a572b263ed8033ff1c6ce1effa472d9af36c011392b59e515b82d051ec4096f2ba8b18bc4ec23af668eb063345188057cc6e61a0a139b29b2baf1c6359b471dccb2052309215b60871231c5abda8e43dcbd5cc37841eccb0e793c984ad9badd044ef175a77594ca94ecefbfdb7b5eef6ef24e6728f5f3ee361ec8e3db23fbe1b1203d742dfdbc4d1273cfddc78d3b37a5a0f1c692a1d0c6449750864883256d4b3ab3e2b0588ee8912baafb27b1fe086559191ea1b3d29c77718d6b1acd835a3a6c3c262c7cb8dc6c2c99c525fc714dfd17e72975aae116970268b1b4df071292bf5cb2f51804fced5fe7e9d25e666fd3487efaf56f8bb3d6251a95e730986fbf3b0878f78d5ad93f5f8e9b3337d830c271b11662acdbf94ebd22e809d416ab76a65b3ce1b7a629eff7ce80bf97a8f98d5205dce85952da4f67bb774c47ca1cff5b814b9afff1e453d9e106becfe306e3f6ba6c6418ff702f1fae733358e3c92b37ce94c6aae470be652223da994ede79370c55c5dea598be808a46c721bf5c227bcb650e90aa14b3bb10ac04365097d77ef39629412c603db4544132db15323b645b82a0158421ff01ce24417b709c36e6ca9133d44e7e61bd9839882ad587f3dc643d34bd8e99b750fefa0f49b448f5ef4faecd73b0be7060d903dac9342cd999ae044875cd2ecd7ff9fbd7f6b5355d7bec5e10ff4de10907a869703252025b1082481dc01711742404a51814fff3ea275768e2a6b38d75ebffffe5dcc67950e97c11c7afaa1f5d64825233e9db53143e85e453b31c5d365e18154a69ba0705ba1d60f94221268ee865a44c3c558450a5c07b950492f477375ec2c59e69229f5480e67f79ab12604ce44406faa5f96a87afe86bb55b93ebf4e776948ebb4fcb207a43bfa0be8efef22995427ccdf09bffa3afe3c98eddc6ea45e59437c0a4add4b73b745fed88aa5ab2c0bd9d330e35ca39c52c3734bd206c556e153011138c630526704e551c12731c56849a479df3b9a28954ef4d12685eb7da262e405222765f314dbc88bca56118af39016edbfa17df4a60ff245fbe806bc1d8fbb6b79f778e836111bf844b248f3becee1048f3b7702763ccc945bf4a47c187f38e76907b268d0c183b9980cb9d0d13cffdd24251d896be35a522894883e35cd83d08c98410183ca29bcc000bee5ec621b4b943ff6628a5a3af9d5d282cf160c466e890d440d8fa8914a680a7c338b784e673e03594a8d269659464bcae21efb18885d14ca6d42234d10785bdef9d01d72f9e931be635289432edfd5633fd59139484a34f078cd877e4defad46f927edc2d882ef73ad1f754ecb2c4b3bd02f1958256adb7f59c3660377eac0d7f3ee393f716e1f3fab4baec2e137cdc35aa6e5afb731db450d98f75a31977fd32b978edca59a214ffbfaf4f9c585ef7dfdfc336fef37bebbbcc4d3f3a9aefe8cbf7b5f57af70173320dfadcdc73e8e67dd1aa657f3ea18cfe1fd49c3513fc6f6c73b304bab0fffffbfb51ffeefc33cf7fe293e7aa729fcc12fbea4c95bc5215e0b36db45eab8996b276c50a239fd5c6d9f620b76d1dfd9aa0b5ce1ef3114ff01bc7b3de09e069ff078b7bd8eff237c4c606e086b60a4657560b51304385c12ae2c89532d022cdd69f6e085484d036151e2545e6890d41f6b6e251b4f69755fa92b0c8d7ec99c09263a13a6a9311361cc0464763627d67887bba61152fa4beb711f98f2b6f8180bf6f310e90973f6aff997ffdd9ba7bdf98adb492a7478c603fd798f3ede0263fa8a03627a9f5acff5e0cfcf73dcb38b6bf59e58ed721bc34099b56ee0940170c032348c253bec51603022b9e315b2a0123e1040290670b62cd6cad27482a894ca620aef4809bb652e6c6a651b4c78bc0ca01fa994a752f00818b957708f8462b624307799b8e27efdbf8e493afa324ad281c3d166c721aec5973dace68d7817693fd4fa43e378d7d4c292ea099779e97da5fd010f23f694f136b144ec5738a3ec979e30c9bd12b99e9a11cae02c28eb7b9c238f856e4b4b59e0a930842a619cc30d0bb339a790441a763d46ef3c329e215acf49f178e0bde37060ec50d1685e8e1d3acd6a52195f6944fe203778c957f9c8c7f3532cdfd90e4e6eabb3f1a98efddfb6df5594a51669b83acebec181f5d167fa610c81f2e8e85731b18fc2730cf1ee39ce7d92d7f1468ee61a7562cbb1ddc099a66aadbb450d692fcc4568cca2ca9111e519e9c60fa939ea970ced96218709c485501490e4dc66010f51493a9f1a32615cc5a096948096e5d298f7c84e898c0326e649e1acbd30dd5f91fbfef772d5cf7319be68653e6343bf53df07b7b05b910a0ffc4defcac9e7cf0e436dfa9f9fef5cef27d7703576be09594c044ec968ef56ce9308e59d50a4b164190aac4c21b7d734389ceff56bd7657bdcab5ff7b7cd6e836b3d8f779ef3d3df41ba73afc6b22a0ac961cda953a260b68fc33a6705d13cd6bacb80a882c8996f62974e538585f59d5b48d52d0f6aace08c851c8a408eee3581bc9c16ac801d2d0e2302a4cd20e23477b8c752cd35794e7bca11d36dace8ce4db5a40a631531472693717e5c9339e3dd33afdb2c4f776e30fba8b778fcdedf2f73a6d23eb1e44ed8ce33ffc0b9affee39d019f9ef5a1d0eaccd3fd211e7cd548f8679da9e7decf54333271b6b38356f6474ecfd35e3ef7fbbc7cdfa718f44d6df98f1aab9ce9a77edf70f61ac3771fecc190cf38cf4b88f2447ba9d583cb1cefe7b99b9cfaaddfe8615de2c495a9dad649e535a2947d1ce27dba7a8725bbdc5b58d23eb51df946d3afbf10c7cb548380878efe7aef7b17bfeb62edf9e31c9472cbfda187a05bfacf5a626f75693f8d7f8c6ff267feaf21c69c805562c13cee80929654fed91f11db449d35a9053b7eb621a739bf341fc7cf3ad99bf8ad3fe1d73ff93855728c2ffc97fcc7619e479f38f293f0c489c787bbe0f18f7b286600a4e5f1bf2c7bfdec85dad7b31ef0807d793bfea73df19476408f18d8be727f9897d6f72955c7bbe39d123167fb7af7889a57452354a9c4d6188809183e1733aeff79be5b29cad1cbf37fe2e838c6b6d6b888c2979e56659e9b47dbfdf9734ceee2f7faa2fde5be103d1336ed22766886beabe35a7fa8137cec0f79e67216af3a1f87795e7cfe3d95d125aa38c69e7f3e4bd529f791dabfbfe8ffa58d38d71f4eda2217f298d5473de4e3f75dd03d7ea3ef1c57689fac4e3dc52fdcba274e994bf6e2bcd66fcf9df7e933439efbcc3ffe3a47b30bbf3d1a0db8ead03871ce0cfa76e4ad1de8afac353fdbb357bec5e7bb64a23fa5dddfe19ac2dc3c9cb8707f3ffe1ffbf03868b3fc191f716d8e659f0eb9a2638c48f3539c798a335e7c99ab638b937d7fe6623ac6b03cc44accbeac658d6ec467f6c76778e72bb13387d410fb5365c0751f638aeb3138130e6a10401a70d2dc89b275e780d3b87adc3336d31653c148305389243d57c49317a03a265ce5363acc7b671530ce7c2a2895bf3561d52361d5816b918d0f7f2bee54e6c46a3d51e81bc2dafd32cfa68b00ca2bf058ffc019fa726fe789aa97314b873e5061e3fad93f38ed67b48dfd3fece5ca903c74bea145f23cde5ff1f6beac6d6ab5e07886aed85ffd677fe0eff6d7a56778b7bf42632b98a893d5bbfdd5ff80db946273aba6454d50211744e579a0fe02684a9f62061f8432d3dc29041e918abb1a1724176152709c28624acb433b57284a193682c26904a0591a428ca63463b6d1a500db4b8932b797ae1f406f1952dfabb2d14df17ed59bf961ed90a74c5760cd597b38c6a7b3f79adc7f8b0555fff83d3fdeafe4f2bdf6e1cc1c6df4c97ff9471b7de08c76f8031e2a6054893e6251dffae2176dd5a7cfbfd77f987cc091bc3b67dfc6223cdb893e52c7872f7bda3ef7aefe5d6c7b8e41de9fabf37b01f941fdc6592c6db1c2abf19ae5c63cb5e88191d12152f455d2355690f32851b61a56e12c8170cdb5c77d6cca3899721605c60ae71e20123e049a5807a6d417568bb1e5004f951987c8f51467e74f9d2996f2186b29883937e56fe121ea3843207dd54b563edf9be738c776b2930d2437c730fc8ded7e8dbfbee466bb412fcac7f8f4945f7fffde39f7789d4dd616012e0895fb28a4ba285b33eabd9e59baede5d996062816d3b47535bef0d4ac12530ca926d6cc849e2bb38d57f11db7f808e786c115d9facaf8210ad11331a5b72cd7ba5fc14aa88d161588e3e9ef3dcd517c5bfded973950e310d562e0e7ff545bbf018fc23fead4dcb01e08f454c375a44285b36b7b423eee85cfbac1af7687d7a92a95449bbdf6ebffb9e7ec3678f17f1cffdd5efeb88ecd79fcebf4d28ab5e616a311257a86a651275473ef2bfc01dbde9e98ebdea74475213253d3ed09cda62ec99ea21e4e18cc0ebc38745e2f7de437060dc4536c9103ceb94d0adad202ac915903e1370b168851b2daaadc92074aff0d3ea16bb93bfe7416fea336eae3f8e73ac9e59cd980cdbb567338303aa202dfabea882bf8ce0f91894a6073b3ae78c8efb84aeffc80f4c84432cda93bd7b81ed0c743ac647774327e8ac94c71d5da8f2d4f67946e03227800a1ee56f5212df42601de2865b0f714a130bfc11169aeb8ff7ea8517a456e7eae7eba97b2a442f537312917f2713f8a21de8d39f0829d3087cfd865f0839ea0150b7819e7440d00c5ae955197344fb8d04d12d27b5cd2bb9434455a401d97d8e12137b025db548a9900681b9560121460964e6916f74e89a6869704d93d35b91e044e9386d906f77cc7d56616f466cb57e3edbfa149fc835ad83fad6bc19903f8d7da4d1f738d3fed0b5e09969efbc58fe32aca0f74a58b44a11ab77983a031e564abf83df2091975ac703b4f4aea95702494d620056a5909505c616b71b4dd64dd91727658da064bacb1454a7d1a28584b597d10aa6e242adc23db9089391a2553e4fb25565d55f8b7ede501fd3b5edd9bf4735d13c721c4439c5dd863bd088d43a2394ada9d71bdffd1d8e9b34f917cef6eb901373118387193a33f709d4ede49f346111b623f6e68592361010315207273b1f7026c79058781c9a74cae15d2e32865d40e403615793412d0dbc4e5ac17e5764f2a99f940782e3488afc95058c0258a7288564dc6212538e4abb4871e6670e6567fee29ba22cef88cefd23ee6abff34ff17f2d83f99fff7631eedc350b74827e074079c7b16afc34b43208a86a4129784e83c28642e2cc777c976cf882024373514707bc99097aaa916e572c561a4639bb6229c295c8bd48834ad0fb32c9e461acb3327a1ae46157a872864913256128b876ee5c438a49598de9683f4fd5df7c253ff7fa7efef9fef8fe7753ad59d18da276f38c5fe9c67bc096ef51fc73f9ee77faea728fd0f70342a97467e0f664acc322da5bfd56035cefc30ea780eab803c8e1273cc0414d8b7c6add763ddeff99e2898d1729c0b068c54e5d394d51b66e96d4c258a2d800470f709a1b3c0feadd192ae13dbeb5376501393d6ffbaeff0dfa9d72b53cde8f8979a01e9ceed6e832f3cd5cd4f71e2e96f45fb815fa2ba4a3d0d0a04518e41c21a2bb5c00617a25d4a3e4f9531716dbc7069dddd6b54a6a48d796530978c570b8b6c3c8556048aec5e198f3c756cfb53a42465562704cc7d062749809bb9c6335219f773b5e948b5ee6e9beb8079a239bbd75ae6255cc0e9337356f76f6cd2659cc19f310ced276dca7faff6f72d1fe4b4eeff9bd7f87f31af71ea4932bfb0371770453fb737c7f14e790b6dc02f670307ddb53d618cda82704bf482a616ceeed55449270df66dbea3bde12f298ee600314eea0936953d57901210e807bd910736256e91e598343b0a0d35b66a864a68f310769e32dba7aab348b4df075f437749603ca52a0c6980afc0ac3b75f2397e58f18157dee9cf788555cc46fbd7f7861aeae71c7d09b7f109b7fc0e43f0e6fd5d5cb97fed175dcdab15a25630da2dbfd60ffc885bf9a92d388f77beab422ad3aa68cedf7f9d869382cc384407aa794014d94cd802b1c0e1690131b2e40a978d114c333f2a1e01236292c87a12f5c52160e3ada87819ab0d8e94ba4bba71c64a69104ab724402dd71c4e7a6ea22a1a61d505b8a75312a27c11de9407411ee7270a87797e8fbdfbfbdae8f14eb9be6e73c6d55df0913f3deb9f73671f31393facbfbf19f35c1754d2120e368dfbca799cebf01b4bcb5960452c92e0685b1c2e242d7cdb708416e93e15779c283a33d1362ac623a18e0d6a538b9b6388400d512566c1a4999180928595ed89a96c9645a626a4b95b5608a62cab968161a7d2046c6af611e3f5bf8123ff0177994c354746da738df08b3ba2bb4dae3b2d692e86b53a9ff597d7e79cd9756b374f189f0753b44245ba213253c9345bb821ef5c805b9735ee5c1d4f7129766ea173665225a5bf4773e5d0a76693a5901ac84c4791c259c4c6960b1075fb59ef299ec26c7920ab71c94bb9f72db01156a1ce01ce6e5d87fb5ca725bba3af77030ef39f60d85feacbff7bdeffbf78debfbd7e177005ffcafafde0cc2bfd82e93b5fe525d5d6a3a5396a3d49f66ee96a0b36d29362a6fb26be4b7a63175349d3f0515ddab2a54cd71305ee482875aa190fd4c23166b4f654b45e98ce4404a445a1a708edb7ce4a50d192b3d81ae99838872bf050fff2fa512566ed5739a8ee461a4a2fe39dd7ed0d5ee26a6e9d0dad509ed26c83ccf1349d462302d6076e3515260d8b8368bfb0e493dbff3ef88a1352b36edddef1e62ae69c0a4234314753182e291e45ac5db88cfa093101cb25a5fed865536922858744056c4191c1c247f5dfc8311de3989f605fcedcf35febb67cec45f8d91d7be6b51feed7678efbfe7aae5050c615045e4ff448f1344f9321aa6817c86cee9a7c2218dfb012ed6322ecc5d4d0a84d3dc1ea0805c521526680da789be4b3030e1ceae53898036110c9db18662597f5d62dda0507ee86035810533a3153f65facd937625e9e45a17b9c8b26ade84e58b2f992e37132d26e52032c619676c7d7a0134c5762064ef6eed2fbc1ef1deaaee549713a9ffe5668880b4f193f2404656c32dee3d0b002f0bb43d071a2526e22822624c89c98c112c97a87026f73afea1b6a4a7519f0d9926677c2dff62844236423cccd9922facc4636f57001ef02cd58530a9fa2a2be14137f15bfe4b105b7f13b4dd94fb8fe3cb1c6e0185fbfed0138f5877cd29f7dab1dfeda6370a167815b3413d6e37bfcd2a7be1ed80b4b964bffa5efe0632e6ba8031eed69628d333e0187b41c2b9c9df85adef6207fee2f78e16951871e8d7f8cd7fe217f70619fbce1b0cb13abf8980bf8d6794835af39e90061390f6977e2367ad1fcfe4ecfe80d72435f3ec77eee8fcb2844ca9c0dba4405f70148cbe2dc2b33def1a1bfd1fc096fee9c2b4dc87b2a6998a944d6b600e90857bc8c4a38430a8c88fad845ca61e3aa6bc00b602f25459e96855eb1ee398cfa2810e132cf74b78cf6829a071ea00992e238cfa6ab8e0314e0270a4ddd879cf8e4c4d9f18d7be1e5f77e5f3bc8bd91a6c6cb7a0cda286948b364b82f2ebd7fae295d77df97ae06f1828df132904f6e01d75e49f6fe5432af2f5aa1b48daf38530f903d57f04352340b8f4a1bb1ac17ca2fcd2bda799cffd67dcb053e948b652e73ac149b7b2ddba6269efa4c9811930aaddc83ab4042f24765f0b1bfa3a176b40113f01ddeeef64631ccf33ad7bc8cdeeef3e3ebc63d69745f95e35a9a35488007ee9583bea0d996e59922545a44d429510147aec415a17c244a110740ee89d9b4aca26542ea3aca0d25983ac775f3bc621c47393cd042af7c966d5382b75e60c8a0377257131321619e84f5087dc1f5f9fdbd3ef4397ebdc757b7e8533fefe517feedb7af8f7b7ab643d7d5493b6c632b52054179a6c514933814b15b660b6ed665a4648b58253a33c7655289c6934ec8acace1a4410bdbb15c886da182e91c4025e9518080b3674573400cd509ac574bbb7e404c9240629c2aeb0d66d4bc719ff47016124baee62aefe71552a2d0fb631fac670debb88dd96ccf2b7727d4d7bbfdb46fdd4fdaf203bf7968646949cffd13432ded921f70d2c90966af77f6c71cd3a9bf324fcb711385388f277ff4150ef150277fcb213b3b71b5fc3de6fd47f7eeb93edf0b0bae12eb551bffb93ff5cf31dc4df42bcfe7aeee13753470924565fbcacda01e7da1d7b3f1a7e7fd11de94b56b3e196b78d5b8715f8c7c58efa9899404f22e2299c2cb47c0a0ace3423e45ac8d2275aba52aa4c2a6592291b9242d5a5afa2c8628c204dfa7241be1a96852301be1a9013c15b489d5687181d8c2ce54a164da7577efcbbc5cb12ee90efd3dbee31fc73fc70cfd732ff3fbb552cee35f7517334f6d7950365ed20b6549ebce351d944a274c4b680614df0bb59ea1123b11c9f2b93adb7ba534105c7741688c52b389bd8a2888c10da37ce55af88156024745d4b9554d0306d6dc4a5baad61d65f59d474617ebf75fe3826af5d57f362fd98b41fb2b61b4e36f7b5a569fed565af2227a67a73e7dd72b77892a9b98b5d99b7bf66c5fcc1b700199871fe9869ed67fcb432e930aad85453fc70c9fb97a3ef6f7ff348ebd30f6ab8d484e715b1fdb58c66c74d62d8ebecfe9420d9e5a284ed454c5154441086de2376b9267b108618118f5a38f1a2ed76adf9c7e43c719fe0667aa7bd318272d691131a4bc39c7cfcfd19cf424ccab7cbd18c84392633ed7789698ae1e30dcf91455682a14568c0f8c388b04e0c857055910c199c90fbe39dac7525a69d76cf1f1dcabb2677ee3468af3802d3ca705e08b801bd4aed5658542b16a20e97e29be0a00ff8cc1fc7e4ef35a4ebed3fcf411e31feea4efecf5f4567bfdc2f8affb3d5561f9916fe23cfe75fcfc216e50818aa5f436a8ca7a6c6dbb24c80254517701f96c69ea9a1ff07bc1661b1ec805a338f718e8dd3c238b293e50cbec1011f784467a9c1b5316180b3774d0c2cae6c87e54b9e61c70ee4c088b366e05355a98dfd4e73ffe4e7cfc5d5f9f9320ba05b671b8fbdedd75434e668833d56bcf0757d036a299e78174134c792328d2b1e2c4943ab6a762e99bc0401a06b868574180ee3c50ef7821252bc6bb58e5d398d46d2285b70c69ebad7eed7d06a7b817b3c46c54a13a88da74ce2b5c45017a12ecd0217809dbf3a5effdfa9b55f8244e98cd437cf445566ff9e73edd53bf5fe7677c48cbf168e9838c5bb87bcb357201cf36706e0c7688b57bae8a33fef19fb97ba390ab31fbf5ca47f4117ffe9c3fbbe897bcf0fe800b7ef9eb6f67b44bcbb75c26977a575ff6632354d8250387d8f9fb2717eff232667a3167409f87227b7f877ffe6c6241e53837b30ffa751f3eb78d99588b0968963ee87808010f5f380595cbfc22469dbcf023479f39224f362ae36f7c6bce60f3ba8e177089955372eb5d4fe6279e9d541deae7f2c597b4e09b5af2e5b5feccefe27ee67fae709d544593d80e78fddc4d7af4dbe37d8b5657d7512eeea33f6bb5b8b7b557e771dfdb2d20d3cad9a72be5f0036cedde53f921d2909994b84a0accb82a1da43a1a2e1a43b051c7cd5f1b643d8e90cd2789d5842910bbe56afc40c95627252d794e292ec756329d296e989198b4d287229a6b9c2ec27a83218f522ae9d2aa1f8492e557e5c94ebf4f8b426777a157f7c27cdf2e5f36cc7728b2b4d48fb6eb256ff6e1fde66c13aeeb6be921244c00af4af78b102a510f0f7320080bb04c031906d4713c8236f1aa99510b3df864dbc66ca404340211e11921aece0ae488a951f8b938a4395df92c5212681c7c9b1b02feee96a1385053afd25eacd31346ecbb7771fb755ef2537cf473ffc7365fe6361d786687efbe0e5fabd07c59b923ae480fdb0e3bfa3898353d234e2e42a30d4239224a1631db99054aeb932aa3ee6a6cc60cb1c5341d2d08f03de9f88b49338b7a0750ada622341ed21e73d2e3fb65e1345e953d1de37cafcaccb97a291ff9150f89234588ce7ece0beff5b51c47e5f1ce9e33ba1bf62d4359a4665f6129d41be9095e1cfb648b2ef1d59db950aecb716a5833fa39c8c22503abc0da7684b4dceff162591928d01c1e1760cd4d3962367544557484387d601235b16a90a8782e4abca19abb8f3443f78b75ef01eed0ca98b9e6b87649a6f21eee45e9a065d116b87026b7c553f16d147a1fb8bdfeac23f5bd1ca0b31c74a683a37d337efd9fc9efffdf4360763f8bede53699802e62fad71ae1dd27aec11f9ef3b7630eb14d9d5887262de18eaba4413f884b5332de2f48b4e126a00971bbc0422b643a2b5af19dafd4230a8d274f5536443a071ee00adbd44eab7a134c458329dfce55fcc428026e312e48e07851e01edc62a4241adc1035d5e370a6c62574a9b2ee28452cbde877ff1867ab242fba006fd6e2a517edef733f57f7a21dfddc93bfa945e157b1987723ee015e0f9a4de1e06b9fe3b177cfd19c6bf8576ad139e622c0889bbfd448716a54101d81cc702d3ef102b9131ad4eeb5cc46e1634ba174889965c2767b571530f6c79ba0823a529cd03761b89c66d8371126d4096840c9d2720f7e29cd85a5df45a5d92f9850838bfd165fda8a6fd4c6ff59fbe3b98ec8193dcc196d05836f392c3febb45428e32579d647e9feccd388641272990eb9f8570ecf93eeeddff749bac1b57d441fedea97f9b41b688cbd1b73f0518eb1dbcbbd77d2d0bd4e5b8ce16611ba80d8a9e697ee016b1c31e6f4b1395297255a7b8aa99352e0c4aeef30ad2357e37a0267ba1f428b4b77c42c5447654b99399e7399aa4495c0cf0de906486228e304d40c85a2484baa22f0bb0f2a7153fd0e5eb699b0f1b3cff04fbc995dcc8e362d7a7bfffd653ffe2defbfe36f40caa71efc8b9aede60df070c77d847b61cf5ef6d0f18e7cc6925ca99fad2ca531c2b65c7b9aac83dcd17c0215a2b40e2a45be98cef698d52d2bdd3651750799e06eae1e0e29149dc7da9ea89cfb935f1d2b644efd46baead8702b610ad5b9f3a958f89ac8dc1c590bdb59a3556312293603f6f45bf1da9bbdf1674de3db70b4bd8c37f813c73956062dfcd3f75f876728e0dea3b0160cebf7da0c108def8896f6be52eb888dfbb93af67d2967cbcab98b4b732f4cc74c432716a6bea6613a8a2a4f5d06d98357d588aae8896ab3cdc26a6b9a6730cab91ea899b6802246805b2ca7f1b2f8b32ff19d3820d1660d67f05493fe33beb0bf89e66539eee68c6691fa78dac72fe39ff30ed7e1739e522acbc0fead25ec972e0aa913168d96ac09dd2ad23c7fdb0539c67149a79c14e05ec1770b9a7511930f2e9355923fb642ad6b7f2aac28972a51c6a190b00c2adc10d554fca9e3270092b472a238e405a575735b0de97fd60671bb6bedd1b84b7c50449fb9432ed47ec94de2b844739a935e89795ecb97d7cd29877addf94982591be4280c540031a53e57b7aa974b3b30c710410750656cf17c360aac6cbd08a1cd185d24a66811e4268374eb574527acc72e55db4920c9086bbf4738acb7099071a0ca152bd69a98521929b2c3123dd18be7e7cb3eec7e79f4c755a9ccdef2ec7fcaffa27d32e8e2d1e29463a659e2bfcd917fe2306f064c6d88f5d4a26ff8afcd21affbf735dcdf1fbfe73bfed23e2d417dcef57e474fe816f7dcdb315ff655ccce988fe034ce75d8c968c495b6b9efbdd6f77f8d6255001278fba487a60b1cc7874e134369e11e1f9242d7135557053337686a74294330a19e720f22cd0d65c672344153a22d2d67c515d47b2a7f22c0a8514ec11ca4aa28b62dbd4a8bf55a5e87663f67bc9e1ff7973f5604d37791daec3df5e85f8f079c711ca2615dd26b6d48e5ee867d6a1b670cf29798da5bc46efdbc7264c4da4314e2f510bbbd7f8eb3decab763b7764e38261abe270a6071d11cbc60768c85d60b1b4d08751a1af0cd62fa97b5f90a4951d29df81e07e82db0aefd09cb70e24e7933fe9913c9bdcad67a21d516cc54bc306ba966640b22282fd73dea8d49408dbb65257791ca271e71c28509b22817130cc48411fc844cd973cddc440a9e0bfbf110071c2c589db3a93c108277a926fa88c1076a09921013a4267d129763db8e339409eb3c0ff2b022562ba310c9994d0fdc820af70d25e98ca35f2653cd7b1483de87b14f57867ab403e164f6cd739665a92277a9868ff76d10694e9ddadec5bc4ba219034efe8c63bef0efc39a27efed3dced24ad4c91bec40f823ce8cc7537d7a884f8c215e196a4c76fb6b363dc6bce64f786b5f753d56e0e84f15dfc8cddfc447f838ee69efd25da4e1a36fd944439e4669afe7fb01bacfc6aa17d6884d3d3d55a2116307b0b078e001718f42a412a50511932b62671121b515586012a80e110475ae094a973435b1c607ac287a504a2b2e25f70a34f430b8055fa3d2e93835558fe88c9ac5e1ef75ce5f3573237618303673e66c238636f3107f8353e7667d0c5f3dc770ef7ea505736d1f83eb035b68f04e484e91d2542eab1b6e3639b6d62ad7d0d62759b564ee5fceb19062f25d1df95be51fdf8d799cbb8a87de1bfd78ef7acc2911280a3d0593357083a88d15a9bb452645d16ed31c6f05d19fbc52a8095b2b6e80e6118506526b05c168e4e5d8c7362a5333db2020f082089632ce97a11c2dcc7130570e2a2a9afd72d274be7416b1daba7e2f6eca8f96dab4495ff33b37e145bb1a97f5acdbf3e7da447b13bce10b3effa48174fedeabeee4c016d9d2163acbd32eb0b69a90b513547811548e2ec0e38155d45dd2632c814d61c115673cf615c811ad6dbfcc98b044b12cf5ada08e4cb56c9150a316263910053edc2bbf3a54a1909a99f40172dc4a20ef8bfcc195b58832edf4e37edfa61654e2c91ff1407552f23336e5ede73ee9e2d44999c9e35c9dfaeb669fb03cdfd72d1aefa2173cc9658cfee9b9417dd685df273655b8fffe77fcd51e5eadff033ce2f2e87be557fbfec3fe05872874bed14f476ec4ebf95e2f6cf00dde3f4773eab9b88eefd323638703843d951e625273017ef71e7576587bdc20ca77d4269d6f3a9cdbf50a83df0a62d4153d54d31cdd79395259d1ca25a3851ba2e98265bba8440f515fec89e6a025510091064ecbc65ee63823bd8c13eda6dc39c7fd37f49fbce2b486bafbdfe2951e7f643f8f773fc3755a7d23ceb9896f72d6859b80220e9dfe654fbc3ec719b77a5d6e0991aca5212c62ab8189c69fdc625cce55d0bb8a94a41b43ce9a3ce889b20cf18c142d43d0802c70ba183a5a5a645100e113a71c62ea1e022bdb448131128a6e0a53f0242723a1c929b25d70af8059aa8c1fd06d6d6b9d94c55bdb05fef3bd406ff5fafee8a3f637d2131fce40f4ccdb70de0369a7b46e371a5d8d952a32859ba67a0f0cd32be4132754f582a24d2ba35d16548dbbf1c6edc63552a80c24acd34ad654a3f7fed498895ee6a92def030215b7ac95a8801a65d0e75666def74473c1a322a4d05021f3b868bc2844f5e21aeebc6fd4f99783ee303fc6c0af7a850317c25fdb85d13feea5eae8e39d71ab1ff692089dedc733cd55a9c4365d9d73537d6a8d77a93aeed26edc1f63bfc1afd29cb508afedff7ed97b17f890b13ee82f97b4ff52077a32ea6ec24df16ecc5fcdfbd7ca619e9f308457f97e25d970429434ffbd8fa9d8a5261ce1e92370ab75eff9cdc2351d05516731efc68bb8a835527a1d2df80c33d02d4331e2395553506fe329f651d9d64beba07aab465bae7e8df8a469228a038f350b977027568a3eb80687f26d9b62fe33dfd37fd75e5a7dd99b718a6d6f90b77b1eef393638feadb4277ff2ba9c1d2f7991b0711f17e6c89d0a1d75cdd60be022088c274c5a8348deb0906ee77ddaa230ab7dd2c2b8fcd5c7a6e31288f338742a42f41d33e934c969e5aa4021794602a59dd2d2d9f08a662ec90e9c8d3ae48fa3e8223ef1c7362c4b2b275bfa0024e5739ee91f35768b389cbdd35d753f63c85e30f9affdd82f5aa09f702e3113c7f578c745f8394600322d85745f7b192ef16af48905fbf8c6b1ed072ccbbf131b68a84e4a3cdcc56999811fc508e5450ec59aabc738f8abfcd510378cfefe4c3d6b021fcfd4f3dfcab0a68b2b39d482d028f15478a92521b58d4932191b48baca22c8261191f748167b8f38641120482d67b50c9c924c7f1f448e615471cf935988d9382339a49e34e6698f6a92933e356b8e14aab0720b7c054efd80687100e9bfc1c1359b5ecba92bf65fdd950b7f741b7d77757c8eebc6ca3c28865cf675b5bb99c6a9380898010ce448a8f229ed0d49578deaaabfd47b90cd5c225b5a6c47dcac1f30a339619c24acd9455aaa7b3452b885b4b982d74bab18050c6f536a28b19d8d5258eb7158a36525ab05744842688fbbe68adaddd77930cffe78e6c675fada07d4a20b7d2d9e8dee1206bb48abb3b81b0fbef23cc475c268f70e23f0b1d7a53c61cacedad21ffb7dd4cb3d56034fcda09b3ae8b997f47cd7bec11d5fc895709b1e128b8e7838eb5febe0976ceac77cec8b86df678e046bacf1d0c9a310c94f3a6e97b4ad996c6276e9992f7f3e9d803c627aced947bcc525ec22decfc3e333bfe51af858c3ff74371cedf173ef52935870f4a1bfedaf7df5791e5d7bd6bb8821c92bba9d33fe15e7ded013866e10bba525cc39e3209980f2c485fefe39869cf8ea4adc23154f3e30167e11690b8615bf802c29254d4c615325e3585b77b114233ae52c36477b64296d50e24d24d75d528c7b4ca24da4142d66b84ad9012c0be4c7b6bba715c28c3a6a2ab35cd8d946401e3149377198fd3927fe8d3b33b6e05773dede88e7701d9db4d68effdbfcc8bfcc9d4214bf0e54123550e91302ce862ab59d96741d97ce5d40e013ae7e8339e07362ff0602e203552443663df3613d77fdf164693916a97079f435bcc00928c0d29dca3c22b8a115e62cac434ce4ca93aeb2fc4227e7dafcf3a51ae78badbc41fe6cc0e95ead5d90656907b25493bba803eb441d6fbea14df0d1b6fce8ee3deebd393be195e62cdb276a33e4522ebe7fae2b5f771ea5e542ee61b5de2ced99e6855227142e96ac8916763d47d0508549cd14d07b8f1aadd0c801496a2d73b88d720e45510057435e3ca5339735e1d24a4781cc1c44da9e4b67caf20cb0a95cc4409aac705673157c9717653803bc6cb36f68a7dd70aef9363ae9a7bd195f517ea0830797acb9a793317649f344a1c8856d1cb8220daef220e80dc5071c30499f624ba03437b558834430809229377815f598c820b128451a8c6958ef99892d6ac21935f11499fa43a2a47b5665d455a89a98c0fbccedfbb3fcd177d726d5641395e3edf7cec2dfe37c87f509919e30679fd8af76f2f53994f6fa3e33e00516ea130d82fbae2912421d56cc36a8c27b61ea96af997ba4e0fd3d581f4480f7746adcf9caf83e280f7d02e51c55dc169a006e993df9b6bb4179f68069bda2565d5342f4a8140f1e71a248fede638d77a437e6ff061fec6c3ad4cbfec13ede4e7728b1ea75143aab9fec972583dd37b8636ed24f7ada2b324bcbd1cb3e398dff238d659a12c74f59a1c415d1e8a42129110b6e4323e80d2fa288610d9958a9a927a11af752522a161838dc25c8c20abe632c73a93a4648a93166b449ca56a52552e740c284b99d50f470613a5337c73091b4ff3762cc6bfbc0620b7773961de777cf35274bfce3fc7e79d63ff222fc70fd2e8d7df441b3225d81751c222519fc5165e0d8fd0977613c3538b5c6f7ae4ab5344419cbd10e4b4ca280178139369186dae5a4815cc55334691e2265ad071ad196b23613e81d529005c4cc66698ef225a33b12222f0de18a16999dacc67b2c0b7559d625264d84357e97fca837ccc95295a868729efb7fe6913a44acd9bf8b87aecc0d5d98f3c33196e30307ecf11c837d54aeff4335c4cfeb9c5ab48bd4814bf9f8bc4da23a4f275fe85bcffda39a23218e1a493c22566b0b257b727bee90226a91ccdc04481849aa222ae192fcea1753ba89a97bf0a9db2fa66ecb4b1450538f289c698b2965c2e416cb9d2c8685e6f6e8ceb51a7d61d62ab23cd567a30dd1dc8d003fd92317cfc4db38fa5aace1295ff1dcdf16229930789cf7fcabf37f8167f967e7fff899c973ff38e839035952e13ad24ef7fe3f3fdfd157bbdabee751e878b1dae6943d6aa41887a4d86a9e167508389eb0f09ab18ca62add46fe18f080ece3a2b98b4b5ad18a47d886c82da48b0389ddc2b1935cdeb3a25ebb2c1d21151d50c07be18f2d0e60b02c5148fa33f7c55f61e48e67e8f7394f41bb39abbf8a510f43cfc80d62d4532ecbc8d20ac974f562973f3dcfc02dee8ffaabe291d0d362ab56398bf68864d0ef854f012e685833cab2edc2ae3738249bc06a331c180e0beb2208a91a4964c6a131f2a47308d4914259a62d60ad638260143c1e169664749a459e5adf253d1f25542ac8447500ebef7224af97a121d3527e85bbbd155fe6cb78838db3e5d1a6d57cf223ff25272adcc476b6a221cafc90b671c95551222a42be9d2b7cebf65ee7e711585ac20da0ec589805449be92903f77385defb5d132c2cd4919e373e6b319f8c33a4161b6211054f0dc401ea04acbdc0aee5bd0aa797fc97aff2ac22a4f59b7ed28f7a5e436e4e30593cefbdd97b0ef4ebeeba97f9fcac47f8f21c7fee5dbc89ded869ac5fcd5ca3203ef52c5ead33e65b7580a1a3a152c438a0f7011355a4e19957a2275ac28d3b7ddcf80a6531444e4cf01d2e75b2a0ae1e315a25e1ef11a2ee3e928ef42427518e313579460afd20ccb51e6b9447445f27a5b3c064bc898a663557bed307606c39833df70d905ac73b09cbd964e80378f517a6e963a2cd1e634b56b145bbf9eaf763a0b6050f678f2f67aa721f1306f5994d8fdf8586fe92cac99212ef13ffb19e597237b3904c2b9cc56cf418a9b28b343af0cb262592697778146a5647eae3631cba8fb1aaef853a7a14d6afc7a8248fa9edeca3b23dde1f4accdcdd6c62049c91c7376ba72e267ac1c3e8f8b93def06fedff53c7c7e06a33cfe066e512562729b76a3777b222ae5ee52cdefb88f67af9cfaa7d7d7ddd1dfacd70d9a87eabf54af1bf62aba4ecb235f126efa9ad346dd98730b85b8d46bbfcceefcc0ebee157847baa60a2ad1d0b07e200acf4981300b857e8cbcbcc2d1e74af324c22c0ce07a8f8b0cfa538e12cd6c8352de05643ca19a2491168d821e3fb042a27f27debeb65ef73c6760b5f441c119cf046b956fe595ffbe87e379af34515534dca26514d2ed807bf987e7fa415f4010848612697c85d55feac2846d14c03962e322cd3d2566742ed4ed5ffa3cb249ad712726a03cdada2ffb9d3f6b6afccc176560d0ec9f337e9cfba1bfedd37bc1a9c6769dafc325a3724d98b9c15388bda2b94b2abea6241b4579564661b64d2b41932aeb39c14654c0039a120d078616987a9df4ce2a00689e9435c75686e255c363025b94c3515a003b8670b36032a2e516e0aaae0801b7ed0f78c6fcb2f3ddf9e7badacbbe3dce59a2bea9234e6ea13117fdd7632f5ef74c9b2dbfe4389ddda8afe5e5cc6ca3b0d6dfefdde139cebd87d7f4663a6142c61ea5991397bfda7b558f03b39d308a77bc125b218d4df0ed7df6ed1cf5b5fc687512d2eef85ffc8cf5f933aeb0fdd0bbf0535b01d2f2f85f96a5277e840fcfa19c6becdfbd33cd2656b31a85a88bd5f13e2ee588588820d5ec5c9aad960450ea37fbdbe3007fef169351bbf0afdde37a991cfd39fb5b7a3eb7f04b76bc6c6bae66ca696fbf8c7fae9f5ec3078e562eab11b7380e20d4fc8adf63d2401fa62a0722749953c67fe203bfd27e26aa9ebfb19997706a5a5ac2437abe37dcebd7627d8c71bed5df7c139e24b93bfaf17178ea6f7e33fe39f7e65d979fedc62a56618426639e58664fb55a0f085229840f0c4ae9934c4dc9782e2cbdf54a0c9612cf52bb3e105adf7921daf80a58b3dc99df2b74e795320802798701dafb84cb2034225fcb326461ce69ed9010ca73eeed3b7ec82efe5a8fba9fe78f37b0277a7d9ecb7af0c9bad1e8ba1ec49acd350938883a11d621621211896a56401ddb18f349b35bda9826652d03db3b440c2db89dea0bab9907b6a30aeab025998d5c1bf7a4a00f3810ba2804e32adcc670ad92428f3c1540df6aa8af38f3a545ff1e6f111a03aff4bcfc32a77581b3ec67fe716ac182dbb35d5c0df9c5b7afcf7bf7ba989cf444f1a7b2f1d9fa9096ce8814524f0b8c704801a6b3112ada22b104e5bdb4884ae38585016133d503d4764be9a785d9a302702ae184684647cd68cf4a6a088deb24a00d3605082aee1053397885dcba9ffb97aed286b8f66e1df010a50009fb0e7f82792bfbd2cf19ecb8469b935edf10bf7c78ef5403fefefd3ac4a423623d1e48099485a94394d33ea86a7549694355e1b821be7355304f8354494c61b816701766cb5989f67e58cf03ad36e3299f25a1c39300156e906d506eec7c8b765e9f190bd2340babe12278d496250f70a9bb5ff4a1dfa606fcadb3e60efdfb51e8e8f3f03b9c2137f34bfbf9c0ad03bba50f5e78432e3ccfb5fee970fe5801209152a63d3f605b16cb90da31c33d0fc443aa642361390e0282714a61a2d515598d2ba439856b673466800765ab32e9c0b9b2ed0226626ad5e132483b4464c959eb72ca734c141da9a011d0b1d917ba6457e2a08e7b354b8fb17a982983c6c9890be6196f7f13bcfad5f5e0e3daa8709bfc47b984def36bbdec91d7e738d77eafebd5e1968ed2101d444e7734406ea252cdef9dc55c2b345f6995a58db358e34430384d01d1b124c09d8c31b6401115d962e9ff52e64a0d4885916f439f06b32ee9517b0fd2d1824a9c94186346a7b412f3fb1eb5e935bd84dff5d1fddf43bff5bfdf8fdc3ec516eca22b7b4f4febf48d38f7261c44c33ea95ff747f1a37b9b317e4fa7a28b35037bb901520bf7dccc5c0c4427ca6ce2973ce755bd084aa83182177e283133eb3bd7942c26a2443d7d58987442cc26e036d7dccab1ee95d6f634142193c70b1be7698e566e20dd08d4ed577a86576bdefaa04e4abeffc0e9fa0fb8a0cbfaafafeb76ca5f0f7ed8f5fe41118558ced978159734ffb2afcfffa4a3f7337f39749b13e710d847652d23cd3bf9739f9ee78c15bb2e774d89da9a744a3a648b3d097e8f22368e7155afdd6e1ca312ad17b4d8632a224c323c5760468ad181a8cd3c0db0e216b5e6ca59e7f6ae2e208a9250005a8e39525a37319d69548c9dc47eec92507a73e50096e5f6f0ff2056ecb8567269e397fef92f6bad37c88fbf1df3d9860c77ef49a3b3bb8edbc86c5222350f9096d3d9c8eb05e14596c5369529cdf28525eeee15e0fc1b399b811bf707f73aafe836b145cd6dbc9e33b4e71669526b5c7fcd23714bfbcd4162b55accb0124fc0990bdb38c6becacb9afcf3735e6befdb39fba505a4897090c5319088aab44d03fa70dfa72a9a163d0235fdc431f7edb5b8ba3ed47f4f93d6bb11beea65bc67fb78dafb8177bdae75406dd7c673613a0417b209346826453b71cbcc468573702b98fb0ab5b84df7c8c6b10824a293f10c153a16ab71155b99eef6c61e0514f012964b73bd0f2c3c43bd7403dbed7c957749fe08a8d9ce97c4d43c496fca65fdfeacbfed69fd7beefd81d7f97afcd5713deaa4424ac4da2d6767ade0126e13fb2b7feaf7ceed6ee577bf70ed493e01cf5c0edb531ff49ffefdcc037cddddaab13c1bb9acee912233d76a64047eef3d2543f31e195ed91849489fd85484c4e638ee391001b212bbd8076cab20dbd08946b7243476be992aa818a3b8c86c66c2834ff41dcd318e61d113207698a007b75a83dbea7dbce73c79e77ff91ffbe964ff1cdbc6436c87e5bb1eb3bfef73f91fc00771dc3fbae42a54e290cb7958cb74d02cfb4fdd359fc67eb6833bce44262ca9721fdcf1d0d90f7ac357f4d5b83ed8d2623cf29963a24aec63fb77974e05a52a7502866990e33556c87f4dfee738375ff714de28cfda815d6a292f739d5a4a73eedfb92a4e5b041c7a8a2ce3a91c09139b0934f4c4d43d6665777185f458c9fa80d4b11b6406d18c8c6a355e12a74350fad4422c96545d96701685d2f4080ddc724ce73d9aa756fb149b198d2b1c9042afb12d6ad78c0e31bb224efbd7f87b867d0b12e6c8af340b5077a39ea8617fd0262a69f7ec83bdbc0ed2ebfbcd02aff55459c66aaaf220234bd606a985156a1b32801ca5210fbc82b2a5c48a30331553c744bdd7de6bc68ee5991154d1c19dfe5602eab8688ab00f0c3331b77aa40835a87eab81ac4326e924b11c9b41395a5afa15bec2b7edeba007717d1fe171fdc6abf85bfac9375abb678cfcf3df57dab2b3564997126cbb2a5a455a3d5a9af49e94e30766a187b8c2453a85f773b5d5d3296c827274585af02e914ebf98348d20ce9a0398a7a5be3ac686cb298d10e30fa2376649017651c9cd65c5779800286c686252c3a4ffa267f70677e2377db0535efae8e7a8b2f84a23ebc423729b1cc6338f6152a19a9f38d42f3c8fd25f9fc350f6aea43681a84a42dc0af5571b6b78b43075d3b76a406c115315cc62f3d786abeb03cf8b1eb3661d9833404a112ea813f390878ccaadcf9a0055b52496abd2c00953735c102a1da1647241e5149938c4c461ff460ee327b9ebb3ded1776a55e0263e4678bc07e9e8f9fc9dc73fe312c855f79d28db39ed4d8d287a8ba6782fb4087814faae825ad7723031e96a3169363847d407eb8e97320e8a7128ec5a6184803830a6cb02c54b939b42f905163634022094a5852744f2873988006172e786e2c9d3a0c56ecb7db68edef340f47f8df7fa1f90fb7eee4bfd0f71071ced43bf646095a887677bf1fcfa475c028126eab8cc32225195867c9df8bf0eacc44604b205ab3c3d81b2f0157e888063d229a501a480d1cc4b80a72d024c83625c50bfa952e8a9a4aaf7489d29347766941df689f65bc51ae48b69a178b4d6442ecbe8f67bee7d8ff20b36f1efe3faff0139d4816f905bb04b4ba87f6b0fdec6bf7f37eeb3ed13b63c7086cffc61e7dcfb15183844b29d4f901597dcf42ae4bb2a3ea4107a892520afea8c68c61f3170df9c333d0a9ddd292f768ce5bfa3a7741b3fedd49bfc9c437939bf1f9ee79c57b90edbc0628964b41a6f7d0b6c124d160bdbd109e48eaff1074f1d29780a3789025ae6376a1acaa758d232ead168491a854c71c1c87814049e9282ba4b2a88895607dc76fba52d1f52494900f174415ae6015e05965e7dd1bbfc2d3f390a9dee6bedc95be997bc8c779a77f5bc77afe4d3707d0010d10ba2f02ad5e83a22609228fa3dcd39f38151450091a5f9c7b8ff5b73c3c32f757e6f878b52e9e8dcf3318c7b7d2e445189cdefb8a98f6839dbc794cad8c479aaf05c4079b7b0dd4d6c9a7f3927753f0ff13e56e9ee1bfda9b789ad2ab711d678c3997ec23abe7d7dcaa15fc9c3e214bea4656221e8aa882e8ba60e4288b986a622f8ad62698005a5854fea07d77224638e179bd902595b350a8dcaaf70cd4bb4f7344c16ccc997e6f8c088a3a4a6d7c50a4248a2d5b24c154f852005e99e985f70a47dc7c7a906bbd57c6927bb8123ed06358b7ae074484ef6f169b08f0c6c87de8b419fe13abdfb580133a48c2366ae35163a8b0519f88303663b3b11e09a4da51ea8db8d9bd35d4a1f959881c02df58308396104374937c698d6fb3414710c64e613bc71d59a89c279a0e6d8c14cc0d8826ea0c99d275dfdb6f966d871ed631fe4ef1dfaa8f55ad23eb59d3a61e6b7fa2dfea15fed65aedff4acbdcefff5f880a7541defe6cc01bce45fe6b2dc5be5b22a34f04a09c64b1ece4e7be8dd739ce3e92bfc12aa3d8e10a3ea726ab649497454b4770b136f78f9b889a811a7a4aefed22f393d6388f2d8a24de403252de1700f7e998f18b8ae6ec0bb739ab73e52339930b311b6939dee1bf23a87179f4f39e9ea5d772e4751e94cfd292d3c2029a2de28b0108cad0cc45331f3f3c7910f33407bd4a64ad1b3c0b80b406df92a8f31c9f2148ada8764ef57d95ddc47dd82385daac2d55c052826191656a10b0578f7fda382a8e3f1009df213dfd0357d9e0771c69d1de72a1ee255aecfc3c187df8bd06b86cf95b2fc929ff856bc48573fd7f13eaffb441d0d7db2afdc8872c7d5e3bf03ed180f271a55e6ecf839bde655718e21bfcd9fd1ce99bee201dcfa2554885ddfddf799964ea1e5f586126ba26366bdc57f7b07a954175fdb8fdb70520c631de7ae91cb303aebcb5e59b708e5c65ffd5290448b792fe7c454f6a92af3d8ae3152c62ab3a58da19c6380336cb5f38088a9c7daca9574be301b7f19e0a728378a858daca8db1ea8ed1d18953b6a65ed023e7644d695a7a61a828eb7b4447e591ff3c731f567bb3d997de6c5fcc6ba25165478889479f876adbee41dbe81afdf66c2a2bd988097ef3ffa6f179ee7ac5b72ddfa0a95927b6d768801de10090b4fc5dc5374255680464186a90960aa89795af049ac2a4aa4363850008badac8d4d89fc00523a75d6015b6f5c266baec83507284e025a510b74446693a01cdb94898cc2a25d9a375ddf43c4d02662429ecefde8ec334427fed8ffb85e452b45f9d5bef8bdbb8d6f398c75bccfb63ce4bb81bbe45a1c8cdface8d401fe1443445a1b07623d57473d0f794eba714f587bcf4c74f0c3dfea9229a300887bc42843abad8a14dca7ecb00f2c98d1a968fdc231c4d4e99625df47fe2f4088637b6536c2961cb90c2331753684dc96e738b51d99d8b4e03ed8bee79afac4d97ed6b2406bced0e6747fbf68e8fe2d76e1d19d0cda20d7ee95530f2003fa3c74641ad2b3cec69fb15437da3b97c61ef6d2491f0b34cb375ccec7f8f0eabd45b81948c7724bc0e30aaf7dea8438100f0bcbdbb3a93096051e216bac10926dd1648c99e50017987b2c1dcd2b78ced5d986956333a2b44024d3829cf482c22830612dfa544d34b4b8073c734d1d46641ca2cab9b4b7bed40788abe8d56604b34bfcd6fb446dea97bec7c9459e974113e0ecbf6469a99f73a967cd94d505ddaf9266fc8dffc3196c5e3135d1056e6824c580311c6f62465e788b5e713bdeeeda7ecbc41a175178d230fb3396c2d4e6f9ec16fb6ecf879ee2a34ff2fcb7f2f2fdd77111445dac60c803a22516cda94db711c18e203a2176d193aa50b8d2da7ece6397fcfaffb3f765eb8df25cd617f49f203079ca87858dc0c4c84168009d0172078320c4263670f5ffe321a94c95c429d7db6f777f6789e35858c3d61ed65e6b9025ed12c3ab396c16598df0b5d639cc963356e73ca9504c5dbf435a7717ab86639d95016df405cc133fc27a5230472af4715dfe8cf99e576893eaa6120e53d927b9083419814bf882ef8ffd7c1dcc2275c60f826325a29fed69dcaffbce04df2f26e3071cb681ac023db41b9296de64e9e471aaa955ea36377faa7ffcf41d6adc4b6e1671843fcb2b6a8773b1fae3bce226d5719ee9b70ffb674d2b94cb638dfbbdd7f773a79dd1dfd3cd99bc67d4dc129b8564c08b6be36e3b07a2a646b9669ab9ca084e3ee427f8dadc6d33c75369f5e9793f68df5d2017bb49f5f12eaef6f7f7ed69ae9e7e3f97ffb29b735ce301053e47d7a2cc03df6ebaa062baafcb5c4eda5d58c6db77f6d767f67f24f73ec689c3eb986bb5cfbdc7b752677dacc34184602d22f535eef53fef01d8a486545985f24ca7ed3ed63bf697be7d9e73b9718ef777d613e74ef7231c63c7e4b8143709c939aff0700dd096f246a3d41f8423b789d696d8cefa94e1d68ff6f7ba067cdb64a1eddd70852612401cbacaf461dcf9a5bd0b157691a30aa11a1c4eda1175d5dd020aeb2fe19e5ef71e7e654d7b193e72397e629f2f847d4a5d0f3cf143eee3bbe7bf1fb4b9cfd5f26db6a8c2d7fe144f5386ee65d43c48ad2174403bc65994f2601b4ead4a28bc49401e0b432649d8aa8c4016e8a0a3919c26935611170902d45482d25c10d8f8a5c89329bef3a907094523e4429ad87295e9eabdf5fbecfc9931ef36c92fbd10ed429a15ddd9f13d876b118232893eeb67f02f14d7833cd1692b1c75c0293e1bff5b791a312047b09fbd6f770ba9e71671665b54a22b54e212d9719f56f24a10eb7e59482dae9b1e4f3d2360f13a1d9423a8391304f764d29ae1e0b5626a5dcf75d1503dee32ddee028aefb80b1b14b65b56cb1b128e15beacfee82038d04534fbe58b5f8463e9f65fcfb1f46cdddfd119442a8d3eaf37a0d565eafa99ce5a79c2cd3efd4ce2f379c2f86c58303c89192642c5fa927a7d1c596c31553bc4c55cf016fa95b625b57cc0ceb82040f49241870ef656560c091d5f496615693946fe80112a91b184d928296fb7a99bc398b03ea8c6b660cc9084cd4288cfc05fbedf43faf87d9fd58b1ef7e443529fdb2b703adb91d7a7c667f6e4c09172015ea11763eefdad36e6ad9a73d667d5b83f71b1e8e7c558fe88f17c432a6a4865cd531de0c4f6bb8c0a95da609b18b32dd5fd21e07211d768ebeb2303398053db0604e244eaed6441cd0d77628d432b4f69370a4b3a4aa6569d4cb3212b3513b9b92e8147fd12f1909b7fccc59272f870c8077e951be222780c90a715acc5335e8857cf717eaf1f51e85a631ce96d8b0caa653c33707de0eb67b2cc5759d525f1f0251ee0fd9ea805f97c1f5e26b7f4a867b8f7451f7fd6baf3eb6ada282392632e51a8322d2c722dd605a76e3912c34f9354084bd094712d1d1cc13b118e235eb5db306aeed3d58f81d9d29606be0980d2b82d470141370b1707cbda2a96259a6247ead7e0674fa7ccf4a7561296e39bbfd3bb7c6e0e1928e9e45bf1158e9a8be8a13f8d77b01922c277a98e8f31c33e46fb3a9688531dac7d6e268cd21dd2d18882a665d578119781c6b8bd2543f0777a88cec4baa65c155975e0c52d3ee3d93bc6847fceb3f772ccc3d96862c3dbdb096d1f0f9fc6394f5f1a7aedb2ceb61cb24282dccdecc08c696966e18f1db7c706b14d53e80d64f6dd6849ac3c1d2c43b87097d5de15766c8d7373441c74857481a96afa852bb6c934e73eb1d658cfada0f216b196f3646046e8c8485e569b7575d06b7bc259fbefebe739aa4875904be798b738e63a672fb522fe315dbb176bf68ebf66357bfff02bfbca5fedbf87ffe73edbb3f939f86dcf7f3fe4b3cfe4b3a7ed0ed3ee5ed4b20834cce2420582ab9ab97e9f52ef7aa97246ddc692ec679f02ab0848395ad05c2da0a709f273cd19b3923aeb422594b0f19d64784e9d76962824962558f8bab90b06b5910cdf61a060a8e3bfd1eff47a6dff12d6bed9a6352a12a76bd2aa55597d6e0f3d6852fe392f117a5d3ff89e9ddf8f75b0f109076a6fdfcfd6458d6e77ac1a8d32c3f2ae0d09c202de20e51b4237573183f5025aa3648a17a4cc57486b4948cd1633394f980511f4e6c4b036b252f7e9aa5d243a102907a1003ff585030a3458f77ec956826187d6a8cf0c99537e4edffcfb7e7dca557baadd14a953bef6e5bf75e79cdbb37a7c0650c69fe13ec291f6469bf5fb6bdd0a67f66bbd395e1dd67c1a9c89c7d6b6a41c5351767d06ac09abd80c01a56165d5191091ac1820938d46f5e69e47794e091c495beb420d38492167c2cd3741d58d44a416c46dee96b4e1cba9ec91eb25586b2cbefaa1a74e3b0f74a551dddf920abcc32173562d563f13db779c9f089b99f366eddfe76f29b24bf803fb3d71a84b1ff3b6c7353bf41d44fe89436e669c99f3f312173e043a1c42a24c3c6949a6837516b15950e7946a0cf00a633e6513c9e0031d3c1e0f722719c434dc8c965c05884281221625ae55ca020b32c59c1056a04a6d12ae0403561daec60fa1827e3695efc56b9fddfb4ffbf1c9be4d2f5687ffceda37710f7a111dedfaa718c50b61e0ded1117e3cabaf9ee75b1a81f788b2423ae63a9cca3ce582cf0d1b848e6c531d6e7c9ef594e64ea8bc3ea6632d8d6e77616d79196f4789eddd85e178132ab4f1b98932686b88e73c8e3c83948c127d1c61aedab4c2098270ee436fb674d9e8137da07fcace3e24fc97aff8c1391e8e9c9b7f5c8369136e368ffee071fd9e7e6f8f38e0f37cfa256d664c4198b8aaa376c79823b5059d8d7c60c59288c837bc11b2812ecb5ca780e9cc196f856119a9266d0218be36949da9d92e84de564e5a9368a80cb41f8624f88e4fd18ee94243551b05a55764fc76c7e845f158479f3e046ae95a79faecdc44c778d5f8c39ceefdf9e77bbf1e6af8029f5b3f2fe825cef57e0f36273ccdb3f1b5435d159d778e1d42d403514c64ca9b0494f95c41ea1bb9e2ca36440510d1bc1a5566442a701d025c08035d0b0efdccc0c11cb01b0cc50e1ba847747cc79dfc8e3b992e566d27edbb91e42ab906165b3aadcd7454872cf7e517b1c5e91b7bfcd7726b877e95343a9bd7b89b33512711eb452d2d590123b361b9e0a2c55aac2515b359b51b898ff8d1bf62732aa8c9e8c0a3b38fbb7671e47d8649e84eb8b33fb53d0f71844156c1cd9ca36d1a5979561dee90f75e6ff7bee57973877ab4fa614807b3d055465a7b4166587a5c8b90db6517d75610fff1dc8d4bc1c1f60b1aabbb8b9ccda7f1f6fed6c156b4a93e3aedabf3fadbd16a7c9f453891655326c34fd3af2d9e96411f5035f3899a53a25cca1a2bd4c609abcbed92059de4cc4715dcb255eb2da732f779c7b9421a771b1df3db9d503fb56549359f629be9dd9a55e359a2663ad3bbedf20c5c74e2c021e4e6201db849212ab24aed8ef6ef3b7d3be8ee807f7360ff0b9ff61e4e0eabb866f5f3f7a037eff9bda6d09306e81bee29d0a495fa9553396aadbdcec91db0c0471c1d7dc82ad62e7fe91474f397fefa3bf546fa80fa77724f06db1db4485cbf8df5f1e658cb39bdff750d787fce9d3188f5db5ff9acf7de73b83fc51073a15e706ebdee83aad9eec40bfa901ab811953ae1d70f3895ee033ee555c25f63909feec6f6f14c1d78527f9d818bc4c58b77b8e3becce5b58f7b8e6bb6cd0e98dff12675f63eacd2c5eb3df16e4ffa78ef9b14a9de6d0447479eac2307d8e119d3fdbd749eeff0f47fa7797afeb752700f7ca6f3eef7fbb58dffd86e0987ade451e3fd34ae763a5f67f912ade0bb7552c57b5bae61be03d4197534bad550dd5854e573ec5a93b81657226a0641e40e695d1752b315ced84b863ce0ec27a086227194c394291d299cf8766362da5a3ecf874053252ab19738d2632e8ede8b0932d753b10eb5c7ef8f8fdfed857ede4d71fc7efee4e78fe31c66b7ffe5ee6e0f9a3ad39d76e8290fadbb38126ae6d8b7a93336e61152fbcf387c6fe829ec8c8799ebede36495198735b9957aaed29505329d95471d3efb961c7c4bf33eeb2d95d6a2c9aaf1c341236032ba0da3e0a0c197556c7fb7b747df37b85df23198b96c270c2f170e3d68f33d3e676acc6ed1a1cfde7e984df2df7226c84a1d7ca594b332e1f6d31a27111a2467c37cc84cd49797d36e79cab31ff8f0bb0b9e85036f85a8bafc0be7e1327d910e1ce65c6ce2e3997836fef9fd90d2c12123688a41d327b489522e1658179b54bb1d21bde3328a7797e7513b374ffc64a7dfd61c74f0b59cd59f6360db539e6a38d415cea80d1e73c7c84d8035ba06e29e44b80d88407c3a3352cdd670e93998764e009a04415fe32e54581bc78111eb0b17d36bbd59f98658cf8167c6b48de8d40a98dd9accc02d8108f9ce6c1d73cc98cdf4b8f63b6ab33c9c7a7f8e2578f217df6aae3ec78b7c30f7605e6497c07a3efa2bfbfdfef8738bc29171ae3e78a64310535ccd81950828eaacec28516a466bbce38edd25cc6b421de5827b4d08ec2e289b328370c3b4db3eb5912ea21c0b780b50841ea82dcc709078595b40b8701568e52e63b923ca719e6979b9a4a68ddfd5077ffffcfca697fb85af76f05b7ee1a2cecb0f7db49eeffa7a1ff7f7bdf101bf13df1a0864aeb5cd6a3c1ce235677cc45fbd7d9efd7a9f83c93feafaf08627b52cb9ad3434fd392254354104a77c8ab78cb68300b4c711b4b0d10cbeb276871e3f06455c35ed356820d358c1064c442916cc9d69928205af40ee3bcc444e0c5247fa59d54e7c07c63e8428bd2c2ef0e5ddf2e4fbffb996c8d9b9c56abcfb9a26807d819c87b9cddc43fee82135ac276dd373eeb5b80a76892b486ae498bb8cc4fa6860555e255c1bf9407968b5d12eb84e795ceded5afc56f7ed2b35bac7b93dc62ea7b9defb647f5613b83edf3ef429879b246abe881ff32f94e3dafb35204f1d75f50243f6f6794e39e5f36c00aa58920dcccf0614491b35999647d95411bf946c49f232e3ed0eeba5162841960572e308369808b5acd9ca9fd2ce2f1959d6386691644121a6a854f358c135275e9056b36d4a038d01b54d4a144a1d19e49c1edfbfac15f0720e4f71e3a7fd5617a8efbc19f798737ab6ce20ab76a73eabf3eef0056349a0893084b024b55731d772c570bbf6a95a843c337d6da62f4bba8b598e5829d6728011aea54e064c52d89812503da65d8de8b8f26db89b03ab8e758fc801fba4ce75c2644c3803c2902800b7bbe09c1ac15febad7ed44101f93e9e139ff6df07c738e78fcfe69b71f776f951aba58d2334245c3e1c3894c2b3f4a73dca81b69cb284f3dbd15c83317105a311eac32836b2c19b62eddb75f06ff6bd3c7dd726add14e70f405bdefec12b9eca7f94cb83964cefe19f6e7e5edf31c300c67e3d16d23b3d94c38b7ddd26ebd804bba6488615dfa24badd2e5d69f31aad490199980a258012a44050402f42b041d43621868ce2557b278db227904daf356f730d9049606e91ca3496abf1fd92df6eb3886921f84453f2dfc5bdf86bee3fade91c6a78c305cf54738c299fffae758778b53f2bb7a5894875c4150e331a3f316c10146a9d90dc614a5a0bf2b36794857e0dd74b079401c10fc489d7526f6e880d2361e45701900929d128b371b7a040c7244729cf2352cfd621c90d5ff31668aaf872eaeb9c88f8b2dc5858894a3deceffeac1aef44e4698f7ed6312f6ebfcd0f576c9873b8dadf3d3147cf72e8f6685efc6cd38a8de4e4659ee77f236f6daa7bf707bbc05bb5fcdafebde49d70ecafdcfb6a2f9fa33dd61dcebbd749cd2ccc102380a1acea3c6e8fabd06eaff054ac326801dfc0424ed14856cd4240cfa361eb0816ec52db5c217b33626066f836cab19bdf496ad692f93db7b335d69bf592028318cd400a962406f6522eeefe8a9ff676bf9c71ef98ff4d77bbf9deddfef0ddbbfdc88f28e85c47a334ba054b0eb72144370c22332b91293465e30a6dafc1fe3b79c22f4de43bb6462b0c052bb7c86eeb8cb32ba9092d1ca0991588a1428e38cfbb50a14dc050ebd7d63cb13bbe54d6bd5f753d72bc33fa673fcf170b8755fbf59e47569f1a96ca6adc88e79cd8afef81fdff447e1b736f7fbfe7b111fc7a2fb97df027e04144f97bdc191ff21ebf7aefafbbead0effcbcc6f7bf9e23799baef67318b4a9a306e9b0d7b9b2777cb38be47ddf8c7bb477a3fd1da3cd79b78f7f54ba3adddbe7d5a44c9fe6218fca51d68fc3d44113596226b536a63a58130d23e1de6a2140208cc426d5d00365eada2fbb3228bda9cfe1c0099e4947dc71572a1fb028d14d3fe6adc56063a7957795b8411ff2c6f035adc31174fe005b6a1e711bd68fff9a58cbc564647ec3ce3dc4fa17f0de17c9291cc63ad8b3b44247bcf779dcc01176519e4d51c4b49c65c0bbc9b4d84c4b314545067c90e70bfa654da0cf7da05af67164ed8e77e2ecdcfad436737193ea662e9df16739f9ddbc282f91937f31e6e14c1896b65fc738c2db6ca59dc6390b6b6d20e86d38614ea09b7719c1f7b4ce3963d61c3b309486c789ca51162137d355844a782d071c87437e9746b8f5896504836566b0991037032155bbc5942d7809fa05b1d7190f3a5a0b1d53d31083bc4f94e77cc27d7dbe1f1bfd3cc51127eea3f7ee890a0e72023622122aadd19d74d8312ff8a4151dbfb6fb078eb3938f7be2e87c8d09b07ac13b201cdaa6eeb37b6af516d771c41a8022715891f41ff23a19a9e195f368bf377f3effcc0be941dc9e9fcf3284caaa6e1bf3a0cd5c6f2b8f1889cf31546f79d1be97d7faedf887386e6fcb36a90ecba3df80556ce00337e169fcb3fce198aa1b61d80677e44638ed844c55914dd97da2d9db948b4510b12619ac05af058fa9b7c9ece68e82602d2ab6cb083238856d0a6098d9cdbd28333d60259086a4a926b78c5903aa58405d5989eab6cb087eb8d6def3873fe53506d2191731371f7e615ddfe169dbafff2b0e9e63bc363b7b0f6413b01faf10fca831fe253fe0cf7334bb83ae7985d449c77c7fb7bc7eed14f79c979fce866ce06e7ec30b7c95b94127384e386bae649577b8b27519091c0f509780e5bebdd90515d642d6d494022baceecc907b2a2e6fd761d5d621688a05bf5d07c54f40ed7646ec314da7384fcaac0b2ab0c89448d27334acbf9ccf3cb397d0b0f2586f73a1d323cfede71c0f17e101cb1c5824faa157fdc88d7ae8197cf51a890fb5cdf3726c9b21ae70eb57a31e4578bd8cf2225168be2c676039cdd74289516a8352186845ddd90eeb6d121b729669dd2eae6c3dd6bcfb8c22cda7ed26d6d05da8317d69e75e0cf0c4a782938819a9aeee7931d3970e1b210a2eca2529f4f1630ec57c9f7fefd9b9e0fb337f7be2cf1fbde4297fcbf3f7e89fb54f7a95ea58c77d8fe3ef89ef63e22dd1a147f4cf6b9de76a4fbdd90f6f313fcf6af21ff9b2271ed63faf919fe6e547fbeb674dff86b6c8ca1f140d2a48a92e38aad524abe08e915b339bb22ad4d91a13af9d6ba69196781b6b639ed50c63e577734328c265b9ac5910ebe60d21be4688984a238f164e339bebdd08731b64a5b7c50e63d2a020b4737a867ff53e6ef3e59e38d4479fb859cee7b1dfc5bcdd7e899f8cfcb9af9039709df6fb35b3f244fff1c8c77da65633be23f66c44dd525baaa610840dc855e582e557a9617512087d6e28975439f7a9b759d8264d29ea7c92e9be96ab7098ad71243973e375ea3057d05de76bf821997a86a8bc2e3524a7309f86f4c76e59602d66ea90bbffd25c469e4aeba07d7ced1fe27d7b33eec986f7829bda9c9fcef1f7fac65c4a3cc880b7a32c1ecdf51feb20ca463c829a504d421db1a04a269cb7ab8463b8e01b90d5d666aee753df105a68e71351cad62f559510d13110af637d6c63bded196d9320caa1af755b3965ebd84061eadcae2f9b474779ea74431261955d1a2f72665efa510f31eb411eefef779769ff546fe1fb631fcfe141c3f994a74bf50ec8a3cf761e4f3e8d7792a13cb44d4ed4cff5c261038a662673ad3cad722d06b7dd875c9fff2497dfe377d6d9679a6207ccee65ce27be3bd4019ecfb9cecc83eecbb979643ebe4f395bf82e2caf8d7297d4e80a4778cb4930ca0a2b10910d842b11e6ad97dae8461281118f359f7755622083bb6c2ea1ea13476e996bf969adbc58cb5bbfc02c71e1e87a6034e35a1f729348adbbc3449ce157fd352dd3e31c46bff4623eb3abe8cff39c2fc63cd9d4fd39dadbdba73edc3331f72ed5c10d9b7a302ef33ea4e644148ad0424eb1cd7ca977d70b1b42526d06ca4706d1d53a1cf00356ca9204dd4887f6d75a2388127a62581666b0f5fb3125b609c352d873234fc2aab95a4679ed6bed8469e3ab3fd6323bedd7a77e8c7f409bea34cf478ef65ff37efcfd3bda545cdaa13e1bc5ac41d861f6dcc009337c934ee37546aceb050546a2e30daa73c48a9c2695e9d229ea4225aefda958091bd489ee4d52bb630b5b95a21c0f61849c65e14dd8007ba204f5410e48c9360bb7098248fc1bf47f7709478fdc349ff766ae2ec01df582efe660eb9efdae1d797ace3b2f9d6f6bdb056749e8366d565896e45dbc6496412a91243536f86a1c06aad9c4e568080734c591c7b36a037c18f40143222472b2e4748723a1124d085f53814f4dcd2ff14c12ab1761cb7dd5ccc2c84289c1a2bfa3f5fb9287e0cb3d508ff1e1b3b917bad21297ad4ebd4c27ae80719ff5e3fb54378758cf370937d722f2b4f3f78bf9592ca01ffcf5cbf0143d9c628126ad7eb46835eafcf04c6e228e7beae22ed15b220a0b88fab6173a54314134ab9593506f266cd313309f8b82f9a4b0ee98ad8d7c85e290e0112b952e886710572ec450f68240c4a6a2f5f5c6a25a0790123748672e27f13ae5c01591fa0ebfc5410be0a0a5ecc0424e5efaa1efe906cc23948beaa50ed2f3dec0b71a696213477890eeecb94671f7a627b33ece7566e0721e219555ea883d8cbce1579fe6ebdce0feff2048385acfb938e015e50480fdbe8f75b87b5cf353bee34d6e3fd3c70f09f7dbb81a6fd3f0792d77765ebfe2f1d97f61febf11ebeef7f73c429a988041445e13f3ae59eef7f797faf62e71afedf73c18a413b499cefae48407cdea03d7de07cff7d8ff7696ed8419bbd53257dad4f5345f038068d062d4438c583419d89aaec622d610425c2ca8cdae84866efcbab94634aff8d4d2e34acd16345f8595dca4b55234428b0511f36565e68208c4b4404386950405cba5c2fd5775c8dee8b4fc03758a97631eeccef3fad0b7ea11b26a0b0cad9eaa66eb339810c77b40ccf331b076a21f4729551815ac4b818c1207b9a11e6fe382a9cce9d6890e7b3eb5da457437ca5c6b1a478196f2ee26636c608665929a09a1fd1898f2cc4ca919359a18f1bf90a7fe66dd693f9f871cea041c7ce9cf7bce2ea2e7bacbaaa3bd9df3fd9df8f3706e5ebdf60d6e554128b174a4f22e29bd07dfce1773c02ce1e0493ae4352fbceb0fb90dbee7cf9d7d3f6715d3a4a33ed79bbc14ffb3eb29e9e2e6d467f66cfcbd2f7776ae75cd5d7c835c7f47dcbb2d86d936a47726e5384a6c58a17ebc4899155196af713ddb66ab719480d9206be55d0f96be7060cb6c3c4a38c454ebaeb2215f0455674a47f80cdc6e91c130a3c063436c2043f9a1bed3fe3cd76af522c25ac29ff3408367f3f0e73d29476efa51f75a9fecbcfd003687798f666de2b04de67ce14e0b2f14abfdda236dea1cce573fe7b94a5debe95efbf839cfd5523fc6d171b9e963f0d34c6b2fa700315ca885af728345b21375b309a8d8106a0ace776baae7700ee27538cdf345c416e964bc65119cf851d663ba03c86eee7c7bbc59328f88691e0a254558a0220582208843027ef697c545883c33825638aa12abe798b5dffa4467e425dfe437bf12e31ff6f93204abe563aef4a3383f1ce917dc3be69c7ba6dc3fc73ed67ffd1aa1e7f35252e1c8e1e7b060b8cd4aafc3e56694727b8bb4b1ef1bc85eaec67c19e152da4def4f036d0e200b6b3cf35d395ff06eb5e08d9f11a585b5f296901912c2ebd095795678932cc24d4070130049a4fec30ccb6ebd2cc55b5ecaefd589ff959a0499eb6d639d0d597fc46c1e6301d80be34b9c4f7f8ecb35ac3ed591ca0cff8863775491f420cf2af9b8677ef77c275fe03cbfced7c780d1f18ef25c1386b722badd21edceb836d88800bc0b19164c872e9d66db80e75b5af8eb20dc6c7d4ecd4c6ffb65c536582fb702e65798295356de48720fe2424469e199998b0a66b74da8350eae465dfc895ff7b5bb605c1fb8033fb3fb87f9b840fcee7adb2397c6a38d7f1c5f3bf1d79c8773a38e9a49bbdba453e60bc79c8714183ef9b90bc3cd686937312d58cd060f4b204502023da18d1e136bc51da5f1b2cde7204799422be180da37663d77cc3ce1f86ac1204879b063caca49e425a91d9bac5043f0868be49cba43f00d7f196959c5d4bcf6541a955fe94b185de0dcec7d682542b3171c98c7b3f2e2394ef89cdbf3fa470769f35a8e2807a3503781afc31091a067611b2f6c6166b6791557e2fa5af30187d04e060498de444b67a4fb84763155081bf88e011572883b368510f1f1b5acb275ea34794cbc9bb02ad7ac127aa08df1e2137cce57ce87e4e0b31865b8548cb21feb38d7accd26e772901cfc1b5f82c6bc367e0e541383cf2c533ac13651aa90536c646eac2d68de708a3a315561eaf8802b512683c5af875c2ceb584fd40c0455b7f6010e5366f93e171a2a145dc29fbb9082046b776b062c87116f82abdcb8ac7f73880bb762050efb2fe6daf33e8137989854370bf12b37349cadb9665820ad55f1e8077dca7d72819a9ee4a619ebfb7bfc904b781affc48572666f481e66c0bb174ebc4e0ad6a693d69c0fc20db53ce095d7e3d58f5136f584d0ed5da82c4db89086acecb94341aae7d7d40ecc4c877658363e75c56e11b60baa79bb4c095d44a2e4b031e3cabcf72ba42fec311453eb6d6fc8dfc3b581ccb1ff293f613fd6e13e9291951fd6e25c9d3b9ec3b0bcdd65431e70bb13731d95dcb9d5518d17984137adb09d956a4e6ab80806364a23cfcc4063fa7a0982016d311ffb69651b9cc29b98076b64d0ce2fe87a59de76a16dc68c0317f3b64f9cd9100f1ecfaa7775d2be8f5b8b50111fb48de5368e825f1c4f97d7cffac2dac3cfb888f479515e8277b73be6f4e03027f1c3221c69e7c50b769768a20b1db60e0046484757becbca540782f1b1204ade07155b858eb64591bc62e138ce226f424b6fc174564828663e845e42476b52b28217962d1d0a12575c85ae5c65c5ed9a43d80a8305897da7331dbfada99fc17bf0027bf2efea49ea24674084a04d38ea5303e799bef9dcd7595da087d88040444ccdf95193433a70488e7be29dd78fdcbb67f6142f24870baadbbaa8ba399bb2eb982141a3e63ad5373b643757ccde758166eb319577b260bd28bbc807569d517b4d88374d5c2ba1dcb48221bf5b38a5c64bb10e943fe2531666bcb58332b79031d31287ddfbdac67ceba3be58dff4f9fabe8c0ff77388cdece4b33ed60c5fddbbdfe8c9152aabc6c3f3f8f1952db97db5776f1fb5d68f7369e57b7f601f8bbcac7bfd667f1ad290bdb98b23dc0b3e7e38d53c2b1179dbcc78c64ff9fa1c4c5eedfd977c92c5fefb48de6987d8fa6b73f238e62b8ea6e0e533044f67457eedac1ce2d82a35bc368e8256eecfbf8ef2cc39eefb8f758c5f73847ecf6e7ef40c071f36624dac6f5a71e42fd1e6117b78bc63c441abfbdc580fa098eeb6a901effca9d72636db22ae81b0f07a69204ea6b3218cb29eda2cc740cc04087a590a6d61432b3366bbd4113aa53610ae15a783a2d4a5bbacbe33244413015920f47615736d97acc65552b08490dcfc725daafa42bff8ea127199571ce6b67aac3b9d177f2d095a615d76a17e3750ea954bbb5b11a7dda6bcdb264eab679a3d123ab612c6700ad124accc49e288876bcd0b964ea6c595affb5530620e9ab0c10652873a76442da27c2a7454c47a7b1783465f46d2a44c05e4b21c5ea5e06c37e7ec85d6b23f7993533cded9d5f1aefeafa32ee2dbd8e117bffaf37eacb7b87b03f749f4f3d45b011ef93bb5132ef4ff9df24467d6a4bde2b8e6689384af6a015fc909fc46f3ffe318f5752fc2b7cefd7eac32e6de46844f31dade6f7eeff5f6a01379660f4fa04413baa541ec5631f74e4b35f321d1911faeda0d53c847b5d82554283e8db7628ab654bb1d2d4b1421c04674ea6dd30add257dab335b4e7c120c4b97394999135fc78a39721deae398bbaae52e3453ae3cf12e77c16771aa7a489c0347ecf031f732d2b24a3d08302e05477b3bdebfe0e278cb47ac257cd7eecf4256b1275dfa679cd67f5a33ba3d1b7f7cd86bb8c9ea9f9f72985d86c770bf77709944de3117f26bfcfd7e3a9bb730d6c09d24b2980f792f9c7c1dc23cca40b94e0db4b76d6449aceb84b74666e7f3f940d70907db6baddb090e0766c7a3d460302bf33e856a2d41b0bbeedb87a452a6a4588f0779835509d81481c410c9c2852d5617d5c17885c53bc564ab0bf0b190db6ff1a0edd74d44f96e5e1ffa32b747ffc8ac5207d65fa81d5ea6befce133ec7df7bdfd62a36c62eeb26aaca5c6c1a77d38f03f1a87bb7338771ff9ab16fbb60fc450029f8e379c77d7cb429892d02d21fe1072346086fcd4eeaacc505e4cbbeb98661a2eed3e2bb049a739924aa050314627e38a95de9a1ad62aaebc24853e10867a884b161147ed12aee2845d741f95828b26ade8a1d73673587fa8abbee0bdf05fdfa1ea84fbd7b2ea19fe2c1c7507de2c6eaaa51b5cc426f99391f60fe01c374995e759353b3317f1e15e7a8747f92d9fd2273db5c6fc023a60af3853f677f2abf5d31ec73a6bdfb3d2dbcc75f9202a748db4b1ca2a340f8842ac824a00390465ee242ad616c41b961400e1a007ca1a5d4ec6b61c72b5acad8268b9e02acfe7da9d89ca1f2359dfaec58047a86022d4f31131a4cdf8adeeeb909c8555fa7cdfefe7404b7bb0cb2ad526116e64453fece9dfefb7c75ef3787f774f5e72c3bcc339f31c3bf906c778e0188f9099726ffb824fe09dbeee433f8d0e37a71ee8e7cfd9bff7dea31dbc7d9e237fdb2bfec427a51e32c352cff97416eff499bee5c1fac2675770c87455a72f7425deccd57e6f3669953d1cfbfdc7475c7e8dfb84039556c18773f388697d65f3f7fed5de07cef731f58bffff5fce57f6f11df89697fae57ef927b8cdd470c02eeb6cb4f7e39e8dff2d4e333f6c71a2b162e9283fb567062b99896b6c0655662287ee16f6d8ca0cd1214db0a0925606713737b27ec9c194b86a1e56d2a62e32e3d28344092d20320e00844263f1d26e835437dd6b1de89c79a36432f6c3cbdaa10fb9a9fe14bbf32fe79bdadf596ae9fe7c79ee2bb189b91cdee9097f87c3f353bf727409bff21d5bf982a3f5d7f368dd11fb7a9e962271b086e978e213bb17e5389491da0591dacc07ba63cae321f53c010526003146250edde61ab9f984ea5e23a7b7dd52797956df1918e0bb44630eafcb8e5648f1c88b384741ac790e85d0085d65c503acdfe6817f5b9bfdd7d8b3ecb3b5ee8f9a45978a21b2c9b378c13dc49867f38ef072ec2dab60b46462a00c5a48bf1b610d91145a2e77658d9855a5d4eed2c8eb7cbb099063ba89730b90dde5a1361a960ece9370ac8790d992645a66b7062bf29ba58b1461be8e22da9352b5a981700c90edc3bfcea3fc97f6063033033747dd9e736bf51ff1667cc2f17809ddebdf8f7fca7f3dee3390cb43ff27de263a3b723e9e8b43643fd7299457d4f506a18bc5356030b331f1011d050cce453f66896a6254014cb50608d6dcfb1a9b5f1b628119da66d42399ed313c45751a51edc0b7668f8744e55152c69dcf310e01eb0407956f0895117846dfe1e7b5e4633efcc9771dfd79ae227e5387fee2bdf3b826a77dfab10ec71b8cc99fee9347bef637af69e0d82f7516d66d14732438cc69482c2b015047cab388de40df1037315531af5aba88e416d9dd0daebc490814c6943da4255804b535cf38665959ea74c00b36b5e6d456db39905c967740da74cba7ccc7ab31a58c55bec3d617c5f63ce6bc4f5c558b3fd7693eb7afb517fc88339715dcfc435c572fc63ce5330fe73eab459e4e4e5c9767e87110e2cdb2bebd5f726070dada44b3071a51c0ca6c8468d0216d5cdc3ce6643eb1a759c49aaca2ada8bd6d7accdbbfe327be8bb9b940cfef6fc73fdad3088224f2d49c8b3ed5b5a79ec61336e73ccd289657be6346828830d3d955420592616b6553b54ab862710576a96beb7428b7d96463c8410a0e7f6ec3d29b25aec7b08d59e2cafcda1016a915886bd609d544cc158a853fb6182a8e0d64e34186a1b6dbcaf21cdef6bfcd5bf1b8369ff385fae4221cfc4fff73daef47df2c7ccc3f9de75b25dc5f23ad11098b47ac2afb65d460ac8988e86dc3cb00f0425d21ed47cfabbc5db01cc50c8f84ddc0a5dde699ae142e517f6da898afc651caf221d6db5942db8d4fbc3c2b2c13a9bce1361ef9baa6d1327ff0a38bc67d6ff8271e6b39ff622cceaff53b9ebdcffdab4bf0ccfedaa7277b70bc375fbe76c20d9c1777ede2d518710ee2ccc05662a8819662b470ad869465276de910053d5cda83ac5ae86bb24336030181252e441dba3fb7d786a8790d874093d77164e94b922f7c60af91f3c3c0b5d4b3880561851e7821431e95dadfe002385767ea80a93fe4bed926e1edd738a5fe9cfb64ff3f077f5ff0ae498ebcc1af5f3bf104cdbede67c95b11eb99b1acf17d688b2430441d33cb8909da6476661267acbede67f9058d4b676c88c82be208a93779d0eff8a1110229ff54e36f77211cf9d3788ff65772a08e3cc2e7695a2e1c76ef43a52895049563250c7bb498a2694641c3a6d68c17707d415ba925aeb7955c1e394debd1a157f41bfbfeb39acbeeadeef477e73938edefa03df8245fdfd3479d0662ad7ca0221af9062d50b220b6c180879704ce42db3682ca36f034bf93aaa991621071e02f797bbd849063e2dd4b6279dcf1dcd481330aad4d02ca35d34686d444706d484658de06a5b07c0772540bf18e86e2dfb43f5a72d8775fe92bba483ee734def1de908e6a45343bb7a7fbb02ea1d6c59cdc02a6b730231ef72b6f2ea2db2db1c7373e130d87e2c12f5b9773aa51a8cc4c8325e7f83e8dbc9c53c53220d6dca52332e03c0d37a3eb81b1b88239d6775dc6f32d726017501884b689912d495c1d7c8e2ff97232428da8bfd00734196997b8934fe39df6391b122ecc938ee079586946cdb4bc1d2d1c7b1095bf15bc9de2026efcc998d129f452033592aafb25c37748cf2752e59cd05c08200a514a5d4e6f4d04f25af2bb9ed1b18f1de621eab97ea5197383194b0e7da6025d549e1618922ea3e6ad0ffe41be21e1e3fb635e7ef6ff6e88fd2e07eb2574e4b24a94f13f8693d88f75380f9570be877b608577971aa25c966245f4d240fd388a7993530dc4c9e0dd10475b2f6dd3130c9684021014b289f53b23ae36fab22a7b5ce42ed6e028e1b2484bec6476338b4bd32415aa97b4b113f673bd70cc9b4c9520068d9b95f657cf42b33f6fe233fbd21f3963fe7c2e559b55b03adea9a79f897f7e2c4a9b24d11ac4abd6c29a7028fcd9f308c65ce5415c820da15e9d19f91526b9475c5f4b6de0f1c98f3e1d2c7fc1d8440eea660eca211d8481eb6c9b10258803773160d7cc905d5c9543a2e351c8ac3218e29ed917ee13d1bb6dfc58e7ed8fb89133b18fbfd6edf89e87a4feed675c30f7ac8698c3e26cac65cd1e0ef15b0537a9c3be90379a5dc487937cd4660eec63de6d04df1decefabd74e18e033353cf94e63b54a6871ab1378b74d6d3ce20a87a86a3a32cd2d5cd29e0e9687cb0ed1e94c0fb8779f691d0f281e850ebe0b56e3c2b725cbb4dbf592f826e3629a10542eebbb11d13b2c99d5a615bc261ad8623bc7417946ade239d6076ebe8acb7f5cf3aff5067c102f8b8af5a9819ef143bdde8f1ff74b640ed4b28aedf7c2e6cdf3be8355928634e6bf7a1b8e7bf64f7b252ab4ff3e20758f3984afcdc9e398275bf7a8193d79f90c4fdf096a67e67edfeba579aa81f7aff82bbe60fb8f3c6771cd2af125edf4d945b4d3632ed49c7b40544f1ce22f9e634ee80153749e9ebdb7f301dafa53398f75dca6b45de17d7c4bcd1165e83a2be40a034158b50174503023d0b936ac5dacbc2d1a7eae39673976f3b51c982da6f982daa335d6023dae9a07ceb59ed52c9014c56964011e893600f9db1eb2ff9cbbff29e7eecb67e384b5f9ec6c5c8a5feb78364e781fffd9d9787c8e53defecc3aa89533869c0cb09c9426080db90e2a759f6afbd809ced16aac08113c893c7dc9ac288577465042bc24d8bed6f3a9ac6eb5a0109b9066eb545965e2788e28d58a4eda9ad972121b5e9969e39c45fe0eafda2428c7ef71167f96b7d8c7ffa75e939fc75af379f9a1417004b2ea51bfe39127f8d3b8f9b5ced0f7fc5a9d15f250676986543ffa17d9316ff79be7d2fa238fc55939588cd8dd7641e4435c8e17280ab664321ec2a96839f160cc519528e14ac39bc600358806435ce3900c9ecb8b7c270a38f7195b2070678653768d88bc4b9460be82574b77d62ded1f6b5c8149628f75ccdbab4003ed977bb74e1a089f9c13e3908bbac01d72d2bb38cdefe1e716f5fbb88c9ee5c75167acb0d688649acfc2014f98fd631b13454521123c205df01fdb80c884d548640a59a8bc1ba57569a6d56c080ac8b3da5a4b3a5a2f0b75830933444941361533647745025592e9ac4e18ace3b2b1170427eff7357cd627d3f5320445ccd1dd234fc33b3c5317d5aef81ebec0fec6993daedd1317d7a798a50b70513e7e678e1b51c52ff6d0f139b413f7fc799c687c6a79cbc9781a5668b6a4b3513c603331ac19d69425cbce2486bc49754f23e18f9198b494f2d612d3db6eae7b30a96410ba5e1557b6e633b11311ea91dec4732318317ebba605827caa54c07c1057749d28282eaad5f056eb66f86fd1ba79b536efdccbbf9ef3637da6cbe47e1e9fa7d77efd4c8e3a3ae7f15acc8605c39398612254ac2fa9d7c791c51653b5435ccc056fa15f695b52cb07ec8c0b02442f1974e8606f65c590d0f1956456919663e40f18a112194b988d92f2769bba398c09eb836a6c0bc60c49d82c84f88cdab9d7bcd1bb3a7007ffb2e9c7f73c9d93d7b986aff853a775038374c6fda7f7f2e4c2eb17212d353cf5621d1f5f233fcf5f4f860b5e0b9750602e22b1153673a881943f581ba6ab8744bf5b8795bc096a11a4456ed05269198421d5a19938fe1ab968c0ae3ff8030389dead452d30a54d4d26e348566046a0b8475015b2f00604e09452507f5107671051d0c6fa789be84a3dd6ccbf503fd0e6c5ed25e65b9b73b44df5b611e1c9d779bca7df7daea31fb438cf0f52027ab3850326a1c622a284c74a3017bc59a435bb5e3a9dca988273d010e120ba988c17826be65c076d6aa0914fbc5d6ce07231b506bf1c9bfed49a13d55c65d5b826ac2188835cd24d3f37544ba67025ab4effba1f94abb8820fa23ff638c7dcfc8c4be062b143e2b055cccdfa30ff1ce46975a8abbdf7fab7ea3989968fb2c2bbe2b525a483dbac1c7519c5f759edc57370d7656ad6255a36c2eeed5ae8ed2e1ca08b1c16a791883343b6b146bb04e2285052b0a8d964151472b0b74bd6ec905200c3d2404069b2f216be835b7c8e1efae7f1c5af7938c557bf38d75fd51ffe191cddbbcff30ff0a3bd19f768139ff6edb1cfe05bbc699a71ddb725ae722d366e077fa083a45e9e91dcc670a6919a8d828a6941dd4c116830d1f39641e8a5650ec554aca8e1c5c2517019355359663b04ee3404991076471228d992e51aa2da76c9f3ab85c3d6b13eebcec0e6ff459f45d569053773ce46c92186fdb8bffb4d7fdbf734f81aa19b793a016ae928edb8862f9ea33dd66cfcf3ea548a5da3a9728221673e1d8f2468fca5ad560ce21ebbc24fab788b14b6859127b1b61949230f176e33f8048d32f7d6583a9e8b0aeb41d8de26b1cd1e57658f290058795b41f1362c7f18d2c07754eb3a34f560f2495efb2be72875e0907cdeef7099fab8dee5997e7bb0abc771bfc52f582f98dd250e54715d0ea81c136a60232ef083b4918b35998706ca9942f794c423517aa314c042467883b8207e240027f6289c22831ac19094c2c435ee13e3761d1a773b564077316516b28119706c135ef6f45f714eba26d6e9fe4e1c927f4acbe8c598877cda26e148cd397cc8f4b23d8d739e3e2e0553c2c51d273f35df413c848176e08b2a85290c2862c502ac9a79688f6ba46d0c5f071a83f29a56b351e6aac0d7c59528b0b77402408da6c4b4c1a80421e3d99669de03d1ba91d0f344daed5c461e2497e542c8d31a357bdf7779383f4fbda6efe9a1e4c7feebddab1ed9d9bb75fd24f25b51b34deaca46b8f86e7ee0eaa06de68c9bf4a9afd4bf10179efdfbcff8b35ef72271e02639d8155588101ce6ebe6a9063a1bbfe8d53f7bdfbfdf53faf1bc7d7a9ffc396e5457c39c0b903a9d9170ac251370e4d38cacedde8e3df69e7ef09ca7fbe6bcb3b4ac559b12ba96613b040622cc50f622828b98b37b56201bd7e22ed0da22b5db32891a11d386499a5b8b290a89d3ac906e1249e58370f034b4a5ee3bf9fa5a6b05d23c14f06e603a9b23c8941804648588e9dfd0f0389b97116dd34a1573ee6d3fc705db6fb5cbbfe72f3c1ff3787fe96613f76095eae3764e8ee39c87c1e8c2d0b9dd0624d7329819594d470bdef5a9d33264c361a972cde7782501ba674ad692ca3ee5dd0813a9c591e429c593d42e3b6a2b9ff0360ea2fc9ab9b24b1c3960ce68e836f7fe206c44511b3a12a7d47ccbf3fe057b279d719b70bfcdf44e89e8e74b0cea6bde82aacba58bb46cf5a2b7b83fd7b74f0dd6efcf7ccae167bcc7bb03a7d40572e2cfc73cfa83639055fbbb0ee4d9443b8d73969fc2924ae699cb5aa6772bc2f37550c92b369522d17dc059ced834d0716135a1414754937146ac556cc800717c35d76f77d4e9ee51c51ec21ade2f0b98c4b5dda75316c5111469edf1b8961101122d693ce02230fe06e6fba0ef713edef8e57c46bf38073f3eaf3f1f5038ea16975ecf5fe31fcfeefb7f6bfdc908cc0bdb3c2f9725b769a519cb723c0d69731594120b7bb6964e3e5007f6bed30a4991b7544a5fc2c6486d2f5f4ca5998463249c46470037d9d42b964cac887307d2c12ab0b216c8663c311895fa6cc01ab6978c8dfc12bb69292fda27f9841b78eab3f8fdf97e79265e72df9d69c377d9e15e8bf736f62b38d24bc47ccfc73cec83cc3dac6b35dfef9b23def2cb1a7e7e08264487242e3c91ea1d65ca0a840d7948b158d6cc890dab4aa2ec0ff54bdfe76efb18fbe55f24cf71ec8393ff251c76f0654e589337cf7398b7b3f3f9f99aaadb1123304acac611d3dccf347cedd70acf0d193123cf53c3829906278cc058542d5ad8f63a297eae1753761d50b9cbdca04315ea7d26efc420e621f756c819af191128e33b3d28c7f7d70603d9646c843a7b0f7ff869ceeb25d6e6c8b5888e78b773f7fb71de7a30241c34a9039fee8bcf78522fc02ffdd8d3d866ba6a13dee5475ff2d97abe7aae934eed79d8ea70dccd871c23dbdb20d8cc0366dd27451e89c8f382b28902dacd131d06b412bdacf20a17f97aaecd7a5f2fb5b46efa147af7fe6a5ca7036c17c4f2d2423ee0fec7c06d4ce272bcf527ed4e1211ca12514254883580bf9ad37ffcfe5257a574bea0277b09ee995f737b8a095eccf7e935adff46adf481187086882a0545dd82a13074ba5146a025875b1056a686dc4c0f0de187068c58a5d6a81a5b0bd6ac5398fba45437a90b6b64c7fd32f2a84f018f19be0f22a8b35a96a26209323223a6480fcbc0905cbedb83fdd9bdf2b578f6fd58f891eff429d7f12cc6fed39aead93d241f703e7d0987fbe73d3e1f70561d63910ffe7ec2e79ed7131417cccc2a6fe36b5e1cf2661647d4a4aeb74680eea8f2440c9810f648939a24ac825daa79980e74176808fa5a3b914c311f62414b33c0250a900e79aa99884f6f8dd06e69e2604495f0e814d509479b50bf3447efe578061793673c837f5ee7f897f30c3edaa7973c8387fdc54f7cc79feaf25d0063f2c1993b6865eee3b3cfde73f4e7ce8ec9a99b3b8c432a5dabe311a2829af3988a1b39a01039de288c9a88e8e68a92db01015805b5daa4437e1f46b916ebde7caed9db4c031c017b4d34c8e78688d27e6364c30c64f618fac49a7386ee63866efce93bda6b7fd217e1b02ae1a69a47fb39b15456e3135ee5893fef0d37e02bcec65fef25d903fa2dafe67f7b7ff8673c7effe1c4fc0f27e67f3831ffc389f9fc7bfe331c729fdd4b6fb9069bec0937f0e9fd7a110ce7b33dbab747cfc63f71019d158f68dd35806bccd128a1dd262824c79172a4ab26622835417e8e88060759db06566c2234b863aebd958367a614f94bda5e0b0d0799a15641c916acc61602f994525663968f42606dd3325ba79110b4ceefe65ae75d14bbb9f7937a302c3958a57a375c9aebfe7fb6bff7b6def6beddfa387ff7c69e7dabc6365e25152be40434698d768767e8b5f79ea73d71719e87cf2abb52daec2628ecceafc40dad9999d9d04c273f800f45c84a350939e6948e0963cca534bf0a0b3c0a145a255130f2a3268c23ef0a6992264e0bb16a4c9f798560aa674015d44113ac2c2cb5dc0cb8df09ed9b3d89ffb67d12212d8ebc2ff8533f2f52a7f9e0ae1aa4037bf922cff2fbe7fd567cc0f211af466b1a597a567a9e4fc54dac67bab0d56e095920809c52972db82b109e667dcc611833866501159e623507d05c38e536b10515c49a300e6c5458bb398016aabc3b9f433d8d58c01cb1486ac819f02e9aebff4f7cf07c9fbcb56d6fbfebe75c65e8cf75ac5ec5033fdad7b1ca61af1ec63a2b4fc8836ab715ba59c5da9d4174d6c75a6b2d28e031673533d024b4c53d2b02d3af91492256c6ba89792db4b9868d85c3ae3207dd845025dcb1b76151ea64c8f5e5a4ad917bab23a6e6899bdf480db3641a0f31f3c165ef6536cc23bcddefd58483463a4a7fa6b3dabfe3c7ee7dbf423a7b9b03f6f3527ea87373b8f79fd7a9dfe4843ee4cb7eadf594f5a08879b739ea0fbdec2b7ee7bdbffcbddfc730ef73501fdfff9a6bfae5fb7566becc77fdf6b31fe2080d09970fa7b9d2ded704fa425ee8f773f385b3f87f8a8bfc5bb6e93fdcf9ffe1ceff9fb45fff1327fc9f8d1376277cf03fc4d9f962cca77a583639624f4fb5ec2fe313fc107498331c466c88a3ac4ff8b8608e5a7102af9328c7dc658b74b83dbb1e7aac65bebaf7fbffc69ae6eff4243fe5c9bb507de7ddf19f62b7dd231740ac8fdbbd8f215dffd477f5e57ba79b33cb21acc192b79ed4c16661e38194ec8e47721b97b9290cab4ebfccd9f9b7399211c81cd6c75caaafe0961797c1443d1ff37876224b6515acf7eb3127c771ceaba1499f46d827146d315573e4305b16e2061b784df431215130e049bbcd8865fa3a1e9636003c62b6ace0824502b069ae70e901e2808a1656c399ba0a6dbf1324bfcbdc668a54332c1d0fd0a9b0430e37848a8b728bedf7dbde0e1ebe3f676d12614d44b30ff5591ffb32930a3e6a6bf66fb9db8fe3c735ab7ff5cebdf79e57dab26f7b6f0eb14e6a78ed9ce35c3af62f2c45ff4edde4a07daccab771c99bcf6c4584ef521d0f1fc74da049f9af1ac81b7cf5de263ce514e2039ef3cddf7fa31d7b9c37ff83bcc2191aa3dfc0acbed8fb6ff3f4efe9cb7e8e25ea47c685f448f3b8ead47cfff78ae58fdcd46f5fd78e73785eae00c655be5dd81b2d29d52ab4e128add92821728ba6de4da69a1aafc609b3cd2203cd3daacc3034144b797b476cd12d6c340b23bc9bebc244558e79cd9294fddca6053279a178a0d82a9be2abe56adcf2697e9732155c54d7a142dbaca2ad8c70934e40f3a48b1cbe7b769ab4cad5feae78a99ffc26fe6f321df659054f7375aa09bc3eafb5d5a73a5299e1b7e9e1ec1e34c9f3ac92c32f0ee1f7feef2d7fd8ac1e810fe3efd71abef5991abef53b758d2ff90b6c27222f173a7b78cfd7cf74588910ac2417d5d1567eaa717201ed8657bc6707ccfe8be768d1ff67efcdba1bd5b5edf10f741ffe204c46f9b188119818390835a03740bec1200815131bf8f4ffe126ad9dc629ef7dee18bff370c6a964130bab595acd5c73867b9d8f73fc7b0c829eb1e63a2cf103773a8134b90cebbcca343a9a011384a06598d10e0ffe281ee090d011a0ec3788890ad844a194e6d7735b3e662e2a28d051a8d01a17b94f34d5cb49ae8bebb1415dbc4e6a35203b03375f609f2e60b74e6079ff9d3ae3532d340258c5605c3e71191cbfcf4fea8efae34c47f7692dec84082774bc25ab0448226f7da3cb7552296751c70fd990236aebd3a04257ac6281506c83edc69760ecb389752f277085a03282122d13926fc212024119148ef910ba2a58301ccc807e452b714e7fc57738633e3eff67fbf3bbf3a989e84b5c8b76218efdfd9eabb1ca8c577ee3fee7435fe879e7cea79e15d7a2277a3360cd1e38c31366c065caef3a646f369cb2ceb7991b5214cf80799d56e241287193169264758e59013ddfb010e70d599499b9087f195cd19e15aa64063433beeaa93d36164eb7f427aa9497d5363eed3bbde702acdffbf8fb9ece9d2fff9fd1a7daaedb26353c2ddb716e74eb2fb981fa23dff187b6e1c033e8fadb186f951ad3a77df4ee7d3463cf677b966de8321b595279ab79843449c75359b159064646e89845a83c200bbaf123e8c51ccd160aae48ffeb81b872140fe583efdabdd43a5316d816b5d0e693df6b0cad47bfb63aa2794358613be1e39adb329c87edadac65f8238cb403871917ab986787bd105ca8bff7dc9ecabd0ff985ed00b322bb440d57dbfbd05bfff5e0bb92f871c7e37c562db67125d734a4ab0695ed2dd1848d49defac574904ea0fb006ac9c4536999179c7635d1d01f6c4cf5b492fadcf1ca90c290f21548e9682d750fc9029b847945e898130acc695c229838b69681f1924677fa82c98b623563de8083ad181dd7c677bc756bb1e348308b74178fe257fd97c136ae3ac68839e3328ed0fdacdede47e68bdfb7abeb04a7ecd1eb7efeb77bf0239c57b4c7f3bf7cee7baee9677f75f3f6738fedd34f7bd78f3867be7147ca7dbc7902170affc82f6cdefcfa323c97db35dffaa9bbff27778fe85c2e5222319e782bb46c678142be04f103d2749df371112b09a8b24a6250e0f7632d539e6276a7fb65eb48d0d6b1811f259f7671c4d678d90a9f4911036d33a78812223b19b12136bcab8ceb1605d00f6d7f1d0ef81417e9cff107151ce4b55e0ace3633ce3ac9f71a78cfb990a33370e00305e85e703d9f45b88fa3dddabcd1b13ade7f9fe9ca3df79d1c613765e43533de0c6ff6f68f34b25e78819f72ec27c63a271faf3267bc1491a71655dba46762123fd9fb3b1e8fefd515e985b812de8cb9bdf30f9c1a875a23a1e773f4724fa04afc4144dc32666f1248bb10340e293196b47144d47421c07d102947d84ac912da49047ba6e50605dd32a5de9cd07c83387cf0ab58f3a1d5ceed86e25a21bfd2bb85d3baa832eb44cb6f7d02ab19e8ceb80bfe310eacc33d7a02c7c2f575527d775def2eb4aeac4d41d3bcae19bf7b8f76fe03be18c2d01f1e3505d3ccdb80584a6a709ab9f71b12e51b4e059020030bde983e355ddfc835c1c7dda2883504c524edc72175e46356d86bac49ed06a8c207ea86b90d9edb4cf7755c12626b1440235582a55442f4f79c4a1faecb7fb94afe5fe32a39f8b7c739993f19183fce2254240e6be350d7b20aeed6fb4b6ecfe39ce6cf30e0fbdadb10835ca5dc6ea5ebe57b7f7fc7bbfdc9fb69dd0f38bbe684dcade9443dfa7afe873bb9c7ab5197dadd7da2893cd8fa203a0b29cbff309073647bd64cf71e89118f16aea8b30877990de33955b7c8d1431ae564318161eafcd2a40baf440497be8b6e53d7d3633a367d80bfc2a2fdcdda9dd94f1c1cf789fc73fdc4079fe5acb58983b259b2099a23bbb967356bb94d37828f7d46941d80a688696cfa65eb931ad2948a495a665de6c423e132b6b0852b0d1ca012daa8321f923a3363823ce1a850da9b0113cff0b5c64e285d2f9c7290e5589dc13bf81d9ce09b7be74d4c75545bfbdcf6bde3b4fc17639a8bd99537d887afe3f9cb7062bec15b3cf5663ef76f6be007f6c292919831d7a342c139a7a6171b78490b389be9ca6570daa181026ca882baa846606ac615e6738af52c623d722440159c65348f637e07907e3f0ab94e902ee1a2609855e8563a5dc506afe725d3851180cbd6a3defbd5dbbd42ff637b651f8b7c61a388ffe8ff3d96598b236bc7132d1db8113bad5c7b389747d3bf1e0bbfb002a97b1ee32d8e753ca1a0d4020a49d6b7b70135135ecb8eda6d9e44961b68ccc826f646408892c8e252a144ea8c05a0dcf8ac5c13d0ae422acdd06e9dc45645528d8ba46fed1098d7a2ec2c5c5fbafffc5d7cfb519daec24a6ced377fd2eef88057cb196b0997db7be0a98eb739995faec43a5bea2ae6e8fee5b9f7ebfa14bb226dbbfe33bebdcb5e8d7fa25eff4a6fed7ff67a6bf187fd96fffb51bf2537ef45b48ddd9e9e9b1eeb439ee89f3c7c9e7e94ebe2ea31e17a9319afde7d79e2b90ffa2cb7cfa3fe449eeb592bfcb986dc7df49c7cd216dd3e779a03f2336e86d7ef7d34e7d2c9fbd4607572fd5ca31e66c5dd999a154f67fff732aed4e3932d38d37ea8acd2da0ca8ab6fe8c15ca436201dd6a7a13e245173b025af7e26d31d06e7bcfc800d3283b5d8e9ae1634e7a192cbf9752b5220048238f289dde3416cfc524ca8cd2c5cad1e105175c8d45416280ea1779f12b59250e0396f5709c1f7444945a96750c352730785a498ea8b891512833d123afe27b4f747ff421fe19070b3dcad99e1ddcbe85c9d02ac166ed0cae73ee9cfb9de8eb0543ff28bdf8cb98d5d3411e5da2c7aaa2dfc3e6bbff8a15ef944ae43128380b15a947022cbaea2604c33fdf7e806740581f6dfc616f75935d605f80617513f1a5d608e9ec6dbcdcf93c6f5ee2cf5a3d11973630b886f6683e8e6b619a78e1ce20a3d601677371a5ec7bcd484a27f3b374dcad9ab7ced67f3135f0843fc66ccfd1c6d6dfb53cde3505b3d4f534fa2d8c03dd3823e844d425ce6a50eba4f9d16fa15aeb8dddc23edbe0f35eccd2936d2eb551f732fe03cdba4113228cd2ba24193b26c48caa6f6234b20262ae96212523391b42db833bef635e12e228b27a03bc641fe733e6593d665bb8db7bf88318c1d87d9dfe30db4849be68c77bddcd70d9fc79f91ec71c74178d6da34734e7f6d4243d469c17aee3651666f360b82423afc36334d9fa1422a0c204e8a72e44fd89fd45e99db3b8202588ada6b9883ae166537c52acf67465eb001b721f3aa9477d7739a9b34fcf54081f47d1877929fb80fbe5fd73f776dd6db58f81817f8efe495a4f3ab3d85efdcdfe31ffcb783d6f5793863d5f9058b833a008b32d0d3da0a12a7f399ca5d5c8e861990262da6eb8c8eed586be7a45694f0409395d7fa839a320e6f130a118216ca88a5081393998e1f16eefd03af9a3203be8e78662e227575a3abce9f5867d4c2be7da7837373fee973efa0dec7dcacbff2c9d08538990e6bb7cbe367157c14fb3ce189f7d1f47d3dfb2c0e0980d86f2389ee019f301347d32e3664210c81178eb70ca3cc607c35086d6c228e3de1e204b99e2d2be6673cef85dd04375ad7ccb47c846a6c868335c77cfae09772b2e0a60a34fd26a1b2cb4a68073a9a27433e9cc1e9ff8d785f0d336eea29f75e34c02ed4db313f1fd3a3a5062bbea1e9d05de6bc8ff5f8e057ecc73de8bf9d97ef8982fa6ec4a2526776a7111d85d256dd8da66dfc7e3c841aeeb98dfcd0cd0deca04e3214f895aff95aa7fc89bf9e474865558383525d49a70917857012ad518b42d93390af44a42c0ef135d63a43ea0d93835a5d360769ae33f74d0cdf7dcc15775a2f6c67c723bc964fb1fb5e336cb7170e73fc03dd30bcdd97077bf3991f555e88f3f279bcdd7ec87a7df7fe33b2fffc33396283d40d0c5ec209661ec620def89ad623824c6977c207781a97728e0dcfca88ea429a478c9526b773914ee01532a4482b49b202dd52c24669c49ab9f3ab0f381c65da78beb0d55552c18a40d630cd5bfbf4b25c6c71e4d56f7aaa8f72d1687bf76922d47b11413d893cf5063b78dc3bd2882a7e8dd139e67de2f04184baca6a6ffd8a83fd24e7d3c7fcdcdbcfdff370a3f779a35abdd422c38fb99ce26affdc3bbbf6bc1ff6fb09379911ac777989aa39ca1749d76ff77e903ec486d73c9d2fe1a8415e8f9709dfe142fa24b2b42ffe5edbde579961355b9f2305e6ea906f2cb77b7806b6e7eccd33bb73f66ebeb6effef57b70ac32d75331809ae0c1fbf3fa33fef56dfcfa49de387398cacaaff7e38e872a424556a9cdbedf7eeb5b4e1f517f2696c445ab847f85f1b71f7d125c042bb8d3ffd8714fe32175d472cf85119c8b158fd3aa1c1035678baaa949e419221266a6e534d0602fedcecea005169c8e162a5efb36d570a4445a04039d646b64404023192413758d413b15915c9288ad58656a71a5ea94238a0cafe413744daa5fa6d4bd9b0bd41fb7dff751ee6a546695f0acddee2de9e2e6eb1e8bed1cdd5da2b6b39bffb4de690f3e8a4ad5b3c8ea4584b584ef7b2ef6fbc1dceb1656a2113b4e3fa6ed3857f7b8feb37bac17d032e6ccaa89b27c3ca026d4bd514a570686b2bfd1583ed3d155568b2a74f11f5c073ab1bd152a609d0c1e0bca6c8deda9996828a655036e8cdc0c19ed32c5b4b482267118624cdc0415427c92273e918fd8f97efeff43dbf6d93c71742f387a7875af1789c38aa437ffbcd67aff61af9bf6233ca48b74e9a8d5973dbffda8f7df634d7fe81becfab35c7fef1b184c4b7837cc88ffe89fef2fb6a1ddce7ca018b7370fbece1c54e73ee2ab0db5d97da86ff7411b042502b3be0d138ddd664e1332231f2d265323d4da30a8f43620f126206a23b43193a5decc6d394ba087a8cddaa4f442ea3683af32830cf0f6a2fe62bdb7652ff7fddd45b8e6d04758c5da5222f2ec6fbc979939eccd3d775b68fdeefdaead5fff7bfdfb7f6ec3dfc31ef3ab6fcfc8ddffba9bbb1dcfdd4e3ffc77bbf399dceed774321a4f27fe1ee3cab773f5faefe9a9bf0727ff7eb9fd7b4f49c77efdac71f2d9fef9d973fd643373681b835cc560f5b546c965728eafc7dc9d895d6de8602b66e4f7f9f86096af0463eb7850bad4649cf126927a9e33869380eb57842387177484488e03e20159df752c9aea0b5b154994c721fbfd30b7bb475ce29ad6d68a117f23231f488775c2e9864413950cdb5c103c4383ba4d01bb283fd9f67e4b5db6f5d95e73acf497e258f9492cbd5f13a1b22ff94b769f7f89186ab72f44c5863d97ddeb9fb5cdde569c955bd184e35d8551d3c9aad1045008459ee1f3959e956c2a6dcf2265db0a9795892dcda06479528e363e1770c1f33ca0ea3e03e319a94bb020d9434847a6afa92ab38526f5d24c22d820d0da37466e8420c79966defc5fd015ddf9bb1ce759ede58b70c735fccdfed45d6ca35f661d5919475e1f47652b9d5f6f7a553f79bf769f9ba1e7f94c15d6e73047a4645b3b3f0bf5e90387ea96db9053174792979bd42d37a4c6eb046e6d7cf6c0b89e878eb2981e8c12d7e37ee4f5b37e3c452a7ef06d0cc25dec6c9b74288d39d536a9037da1ee4659a58dfccbea2a3659afefce9a705ef55cbfe0fbcf5ffbd7b1cee75a99fdac08fe3e0ff666cca773fb7c97b68771cee3f85eb64a569d0861f348799b2f8a9cd2d2d317105b73e299bcf482d4c03da2770f0ce41801cff6419e306e968b09d3b036ce7d2ef400484541330aa206f9cc6b48c1bc452d7261ab9841a144cd74a937135a5dc20ff65fe30d86f8288780870cb0fe9d36be96194865f54e67e702fef0f4fc3db3db9f62a7f9f3454d6bdfcffff758297deb8b897d1ff0f6fe7ffdf381ebe63cdc545a7b31afa5c15dcf9ee9c13a54b95a707993713c2183987375df91490c42d71b91709c20a07b19f1d6d4818fa936dae0023e12f76e485d7943220a8248de70129b89839b85031d4ac77aaaab81f006a2703cf1bfc0ca9f8f9bf274f174ef2f7fa2b3b4f32faa3d0fc089be08872d25ffaaa63cddfa9ce6dfe3ecf75c2fbb3e88fdb8db3505b3a23c4f8ba5f40dccbb5ed84d1e5666109730b819204c0d2c640d930c4c07c1d10a45b241a55725445c870ab35833d7d2f80d62430c99936d12955fa5caa3a186ffa4e118220d964213d7ac62168502910acdb081a6845eb62f7aefc73debf49f7b269b2c62871ae6097ccb497eaa0bd4348ec6ddda73f6984450172fbd6487337a5e6e435233175cf5985920834d4481bc92060ab081995f379ceab84f97bf4664c2ba99a6d402366d38b15438112420d91000dd0a0863c89606d13dba80d0e2b56f22862d6e77f38c333fdd3e52fed285de54ecb2da3a4556abcdbe16081f85336edfaccdfedc5ea8ee75e65e89ac328eb09a71732d1d5525fc4badbc7d5efe02763c73702e1ddaa6d5584bb8680e3c17a77edfee3518ceb3eb9c772552f71b5aab09a7f21a55e821e44d254a794bb5711bc2fc8fcf2512941a31f36e170546b86f63c2db3689f26b3ec17f1837ebac943151ea0a19320835af95ced846b6fe1854761f705347ba4742906bb3733807bfde33cbd4c8d52b0d8a53dc5307dde84f39af0e7950394867dc3f71599da86f3ff3752e38ec9fc6f59747f5ce7d2c1dedb53f53075e2dc2cf9fcd7abd48c2b7fbfcc4334d5a232de6dd4af0a0dd61672bb84addf2b9b6728aa72b89fc767b7fbcd48c3ee85f88549e55a3e7cf3d3cbf39d67ddcf590e7d2d9c68dfadb3b4e8df40fb88cf4ec359fd8296e2fc05ab9d30b7d5d8ff24fe286170eae67dccb33c0cae49943ed1fe138b8a006885229d0f37479f2fcfe7fcf7caa85d69d994b3869278e7b72d17dccbb872f6cd7891e951fd9aec3b9fbd53e8dbbcbc79edd978e6d5f9b020662cda7ed2d679e235c749552dc118adc8c30ce96639d5078ed17d91096ca4fe9af071f3456eadc8df80477d8c5a574e48416a85ab878496c86160a8dfcc2c3c2c91fb1836e644d7b4960c5ea4b7331ecb83907e9aad50b1f7ef07894f7def1201cf1961c9ecff6cfffebfd1dac4fc2adeff2659c7b110e83a71ef95d0ee3e9df24383f5749a79b05f3e842a9925134490bf578a3c5da8d26ef91ab3cec624439cac31ab59c7a76a6638287bc9e69639594ed750ab04f89e7858e98fbc04308342cd3bd38adf03a8381413415338045c6fd4e544dcb8a93f5fdafeeae8de4a6b9e3ae7a77379cbb46e9b5be8977fd93fa2afeb227fb42bdbec7e3eefd926ad3660eec3340b7f7dee8dc33ef87ba93a97c36d3601517412f5ce42e1c3dc105aa9302ae02224c697caa7d7c66bdc4eaf7cf04ed6e8f5e5fd6d73c973ff7c033b87def5e70b4b5e9dfd1b0be400fe831afdffe1c1ebd4fbbc7737e9b83ab9b310ffbd434456d193e3051aa1490caef42adbd113a73638ad17cf22dbd5d5d72557e717f8d76fecadfe3037663ede78035e25a3b7cee59b54487003dcc96ad933209439a8d24cf135988895f7954688c73174d93e1f728d1a891326b9595de1273fa100fa89f47d69f18304e1da967b6aa48a9eee3019b8b09d5c3496c123db748edb198215d12a5426ece8eb101a73161fbeff41eab7298df337d8fdd3c4556fec49df285f6e1257c8b3763beacd1933d3a70fe9d57f7bd158e1e2f6c7b949578a0448acc36795cb624acdaf94261c32fcb073ab028031ec28e3991b68aa80ef3d440f380a348da420fc3b108074893ba6121118f71d5d64904e182df8d842e1f0510852c722b0381b9ab65dc7dc3261477ed9e3b58ad44a8173147f7dfe8971a2e72279f1cfb573b33e2d10e9711edb14f318045e2ec728bc3b9798b7492af028db5c4413e67cd3d72cca5e4e69cd702075a53a0c802a86fc3c090f9dcb5d7c4c16c31c97504ba811922c076db66ceb80c4b78436af910f0fc26e87fad852d049ae43349154c79a389090e59a5ececef79388cc4515fe3607777c8f4efd700e4cd01077b1857dbe7bcceebc5bf2676393067d331980dd4152b34582bdf509daf970039e5431cc98dd4f32ed3e43567f2213120928eb9e48eec090d1e16fcdec8aa3cf29d56c7148f1665937396bb49c922c4c7751c593352ea30d44c94546a79591cac1a4494ab172ee7df9f68267f82830df597b5dbf736aedffdfeafb11267e797802ac5d606f3ae49abafee7bff3876f8d17d2f1bb18fdf573bddaead0d7dfb1e875ae1999c3a356a533dcf531745acc4081b6cb380f73a2d7e8f12609ba2ea92a46a1ae28a292b61c4e978261d352324d7931a27cc989ab1ee55a2820f3706239804a31b6dbc9cdbe365ccbb3873a529186b1614db4841475c360779827fe33fc99df86e8d8e3919def05b7d71f79ec8cbfce8ee7dcba9b5e39c7bad3f71e8d138efee5d7222aaa4a080e80cfb4ece7cdafec1a569d388dde08a5d65b42db3129ab8c29e8884851dd5654a4ea58e5671a55f93529f661396278357a18915a424bf61b63009f1da2cca1ff0201e0568a764b03bb11cafcee0dbfde7f2ca6fcfdb295de923fe91cffdde8bacaf4af9f8cfcb7aee34e3def26f91bb1ff454e92451ea2ad6e59c68f64644d20a5debcab7f5510695236b59a35afd591038c7031a4987adb3e81ea009e601f8b5a6caaad37adacd34e9caebb68907d4840a5f519243491015b6d6218872094cceb8ee62f28576c345d6e76bce977f21cfd664bd5e49dead0e36abdde714f44d0ad4e35ef3ef0b5eae9fe4e5a2c64cb9a6df18f421d3d0407569e289ea480555a2e201db0224369ac5a09b09475d710e6f58c4a601b91b68d9fd890bf9480de6a6152e032d776561dd277d3be3445e130a57992e553860267806308b0187f0ff022fde76fe763cd4a9a31e4fd5814f71997e5e277acf71fa57daa54ff7d62b2ef4e7df1d702267e2a515bb42b4b16f0c5c6711d6b1d3a0c4959e18988e95e03ec05ac6eecd058337296cb8a86d2d24bfbb99b6d2a903ff20c6a64921f922f230d11ab0a8a04175b10a0deb362ee126ae84eddbac44b5ba89fb55272eac05ffd696ed733bf3d37c1a5f9ca34feb4747dc485335029ffba8ffe13dfacca1f4456ef74275efb763bed662daf319a11fd4bb83888150c73d7304264acd438eb4584dbbb01f0bace3d027998e4a69c6ba3588412ee7dc2b59a16c19413d2b702d0b9187069c7207dea34226735bb57490118eee75ca44410cbc122aeb33d540c9a5862ecbe573e4bbbdaa9dfdeb7b2635bc7216c93edef1407f916f5c5e421f4aaeb32a68a5e1e5d90ed3f6fa676da7ade19fa733335d2cc76d569a4612e139adeed6216496b4b53553c11a3131bd31548d27c266856c396d9320c2536278cb6cc819021da0d0070b2736306d6684c61bc9b22ed49a493ab1a668f8dd890125d860c30dd0754c1838a3cff7fb3d59bbfeceb3b1c44656c14de67ea58b77a95cf1769f589bc5ee1c3ffdfbc0ddf8ed9c84dd4a88f09c375748f3ba44e52352b502d7c2f2219c4baacfa4fb7bf4b7799aaddd10a15e25bc53330eb514e84dfc755fca7bcd9e9fe56db67ed30e5fbdcb9de5d219b709dff5a87cf05edade273c6fdf5bb2cc8b05bbd7c3ca24a2b6b7eb4d16bce983aa9dce231521473382483dccaf7f99242ad7d80ecc14983311d1f59ce04a1a1e4a015229fdd5530a6f7009576965da64d92618fa0fbc6a2c5a303d26f69ac2787de1fef65646def67ff77184ee5f3007f6233a895178837d7ed14e3bc52b0f549d567035e36c94442f9a1827f9b93fc5743fe310f433cfe54838591b5770101c375fea5f1cfb253fda77efb011dbfdf6ee3d9efabaceda6701d5cc7b4c1b5bf026e12c369209dd04d5f89e4c7e9b389a9aac829ee0a2f7cb0e053c1e88c6dacc460f49396efc012b1e29cc298c19c37f30831a2f1b1a02e4f836ed196d6972ddae330dfb1990f3846be63f615fcf8dd117ee76ef7ed59f115cc8aee6dad66798f5dad3b83fd2bb21762b18814dc0f21b0e591db0fc71ce5898544abfd1f4287115e3763ec84a6c10d00bc9543be79830dacefcebf124a971cf22e904516ecf27d3754a5114d7d8cf34f907972a1713cb0823b416137c95296ce163bd9b73ee3bedcc3365c6bc5b25dfd523fafbd8ea79bcddba70b84a77fdd93f3943da200176138e934564ebd49e6ee6131c139b11c4f086e8280c083212955ba9ad22c2733d25de03ad10980d4147c1a8175cc7be83cd5887117259c2ed4e25b59cc92a03384220aef08a959b07ac148c8dc0f86e8d6971c4f17732ef7c811e24f5b89fc7d121bf7c9ed6378beeb405972e3390ee57be9144c861808e78443bce3b3dacf48e55f928a3ab3ed6ba982868210a8b604058549e4b6a0b2120741f96a37839bef289d870bb7bc4759ef0484489130ca2caaf39513671f4093aa717e5ef78976e5ef6fda7f7e63270bc3caed86a06f6dce9a2f6f2bd6ee667eb973dfa64fae893bfe7ebf960fced3db3cf2b71d1c75c573bfeacfd98e76152eba05bf07119d4771de3c84c380b08430f0c980c397990f1dcc888bcc7a0ecd352f83eed544010647cf39011cfa7d15d874adda340def8d7ed1502f831e512d089c2d2562b1131c86c799bd0f1d4675e1146df8febb28a7592abfea42f535acb987b2abd1edf275cdea78eaa133778c17091775aecc7f7cfefb8824bc137ebc461abcc61fd2c1279eaa8328ef03a5bea8d70d8e33731c8c6acb02f82cb7a59ef5ca5aea5b2a50e62de35c2815a6a4cdb846395d6b8119552d9f257fbbde7b4a7f73beffc1748cb06794518d211efaa24921186225a28cfc69a9adf80ee31d018130e8c85817968373571a65d56ca3c20e20f893c2d28144c2935c8c41e896a1c87a58273c81e679abd4e26621e56c2a5d1efb520f006d967d68a3fdc035f9dcde01277d5abfda3eac4e91a01f2bdeec2eb9fc9d37867f97f826ae8561a396050c190ea0403784df9544f346c671a5a67362e13c6dccc809b38c21b1f88dbd42eb59bc19bd2edf97574c8947c64353329c0563030c834d4515d46cc8d37099f025ff7fed04296ccf6ca336a34cf3c37a76cef79fbf79963ab3beac5dee931e779eaac5ee3988f9e496abf95cef84170737887b9fe20aff3131ce93bdb73b2be303de685feb1bed49bf15f69eb206db1f3cbb4c378477beaeb33ad820d2f4b90e84d2820be9f4365867536504d5f72aead65d8ce332e8620ca6106e5ad0fad6a1ea16e7e3d567382a3859bdf66d09a2d26caa1057452574da43de6d8366f69b81aa5355e65548c12e61537c654cf8efa909e7376a7eb095fefb1c37744ebd419f73b5ccc2eb60b9ee3d3f91bfcee5bfb7fb8ffdf73389dc26a9fce572c777a52c773fea3deb20356bbd7d687bdde1e3effd84eefe7e5b39a9f96846d35e7dd262ccd426ab126a1e4f3ebf16da6309576dc09bd696e403cc2355c2d282c77dc51bc2bb0920e65d2f197ed5c68684a41fe27d1d0f246534e5076dd9c7b3aaf25f4a3bc4874c8906b296ab0f73c8a5fd88d6fdce9fbeff86eaf3fd702fae3fe90c35e8a50b1e3ab7fee613ad420dcdfaf7316ef39c50febf6c4998587dd5e72c6fd4b7ed87f6347def890d7bfdf63130ebd2dddd6772852606eef9df771d3e93d158ecc63ddea1fefa9f7e7e2e02bbe7daf19d99d93e1b80ef9e5dd84450999748207598a3288b043399acc6d345930a5f95c0866e424a3b00907afa05a001625be9edba32136ac0153cf92ca1b651375453459a3325b532d9f864a596c72379a017835d3948e6d691117cd59e5b94777d3e77ee3cbdcedb4e34ec5c54ff7cb0ef7dfa6156c0ff14277e825fbc99a3f6efdf06fae7777f9f5365fc5052fefb3e3d93a7b9ded369ba86b569566c2119615e3becebc05bf1f285528362c2a4bc4beb4eb9fdadc3ccf7abd4a1d78a2bfe7a33cf1fb5ae04fe7ec65ecbdbff6acdffab126d627f6d70f754d408ff91a7279ed35a192ad284d5754dd3a9cdc192914ba2c7e7fb9875fcfcfff86dfe957f9d22fd1f71c3d97f14bced0fa3d8c7bbe7f4279c3935a96dc561a9afc1e11aa9a2082133ec16b46db41e8b4c711b4b0d10cbeb23609d0b4984111574d7ba3379069ac600326a21473e64e3549f539aff4dc7798899c584f1de967557bed3b30f62144a9f13e1ebd947ff2767fbfd223fad4b67c86590b1c76e0921bab3d4f19eebfacafecfa852e91873835f60eafb4ffbdeb1507aea3f3f841090348c736266a9342712feb1c0b267d6e632a4b01c2d22bc389d8e0089569b5d9c65d6510595a1a3107334b09686b38f23a14790376517c037410500df8c4f212dbccc9e04588c59db0c7b76989670ba7fd3efff3a77788972775fca21f45a6276a287bee8037fca147da316cc85c4f3df7c1f64758f2ed5875eaec3099cfbae41ff5b60ab05d2ffa1a4b098e355cf4dd799d71b18d7bef5ff6e78918a66a76bdaa29dfbcd466c8fb9e8fed737a9356aa8d23fc84f73de037828ff01b7b6dbaad9fc2f56d4c384cdf6ac8fe387e3bcd0f71d23e6ac7fd2b3f3f238771b736f1c081a1691ff4b17c6907853386126090121c0480cd90bd1aa882735f3513bff404a35ebe70a51f306f92b1a625bcd170b13d53f0c657ded277f30dabba3556de63a08d6d69c03f992b1f033eced3016f04efe6736733d0b22965816a7a947bbd941dd487273e0e3f1cf5e7c5657295022f4fdd6fc5e0dd3e76ba948ff03cf6763d9fcfdf6c6bb38a93f99c2fd73450d20b0c76b52831c0ce788a089e87763bc900b3636e5a894d8700307b3b3eb6373a610120b61e73e7be671a7a1413c582c11b16157e40368c8823fe0847ce8312c504b23c55b9880deb3a28db5baa4b571ee1b52fb4a6f56b2eb3c359bf1e8ddef0bbbdbfcf4ef834e9f7722bfd498dac1f9ed1749f4f69b35e3b7ceef9eb9869f281ba770fac6a9074740b957aec17721d10ec04a580c41613aeee353ae038e3cc257a3e91453c92307848aae920abd59ad62a0f7519f8d0a2a1a122e9e83ed5b44dbc6c730119c5915866030c308753ff080b75a6affdac79b8d7e18ec1b84d397b94df3b57a735bdff129b76d02d2d52a0b7829b5ad6bfc6a91dbde7c7f5ab2ffd0b5151c77fa0056e1257767422e633003d597895cf250a27f98ae842633a9ca6069c2057cd503526180a9e02a4a7140ea2445d52b5715ac38653fd3ea5ba41fb718b69ee6713c905cf577282ba74225698abf7d8d9e77beb8837f85b3e9fc8330337a22ef77af3cf7d605fd6242ed5fff77ba7f7eea86a118eb73ecf4b8fda1eeff0fe77ed3ebe3dafd6200c31213a9b67301f98e17994200b39300eb4ce138eb722134bc3aeadf9a5e7ce062f96835c2f1caf4927eade27504f8dacf3dd46a383e74a2af245695e8baa5966354a10375737c00cd209fb8321fa93148cd2e35e964ff3dadbb97fc19a6eef80cff55c5eaf9ba8c6bd04b0170efbaa9ff6840efe5faf59951a9e11475e29f82e17f4fae7437ff19975a16a7c7b3388084fac9cd6f7a3b89675a8ee4799d33e2c9ca643e0d71a0d777dacdb5d52941aa27924066b1dab06094de502aac8d72d2587df0f311f3d2403c464223d0a9b2921a88c0b16e142dcd289182157b5072eab4fe73873bdf5c22ddb98e3f22beccf895cc20f63a28fc6dfda32ab4f8ddc9c71580a77fa23ad6de99686042613d7635730d4853a9ef865b35ed46885a2dc8d2b73c4b80971e96f0818f533a309e4f2d72889725302b5a15ce7bc963a33c41c03f33a054a0b0bcf48a2dc60355c8b5ac6a466f9dcb9079cc47d0a8fea6f5fd47a3edee3af381fdfe3ca36fb3932ff641f734d9d58eb1d366595f0e95ad4fe6306509e565fe3bcf671d2dff3427e3cfe360616c3ac4645cccd32d9dabffd98e769a50ea8f60d0b85d56a88ab4c4f55be24d7bf1e02bd0421f15458e22b5ec2c784042675c44d5a6e7451c97b0a712d740b0455b0ce6c31a740de64005b42971be9324712d965e118d25adc722a56892b0602f1243c831bea8b3afc0edfb2e3f4dfcf83161ff07ffb753d8aff7ac9473bde8a3db7d2e625471f8ecc4ff1491f8ef585f6de7b7dd29fc403dac9b177f634ebcd413a50dbe9f05d8fb433f5af446ae73701b18ad40dfa1b5dd40878456cd80fcc6d4261374016b6190f9e476a784d0db4265ab7f179a39091ff91eed4088b29b8d1654c8bac27149552513323b0636ee3310d5789ad57371a0ea58237e1803fcf7f9cc049ecf034bc6be2e5eebb1adfe035da61ca2fa0177772ec1d1763ed3f4a005749af1dc63a0b1b360a6a6f1d473e900a6b6cc06ec8721ad0dc4e353af855fe480a0fa1483d080d6d98269792e5534a6c5d960c65d1b4f70deb1a0d42cd3499c4ba1a7889a601ed0022d68374821eb9f01e476a9615c2086abc3e4397fa0b9bfb891d3cc44ac779a89d9dee5eec72fc1587e3ef0ca847e1eece499fb8fbfebb2fd67c73310c8c8b9ab4c2bbfd9255b99eedfaee0ebd75e4f70ff0149a494a46e7c4de60dbcc43663d0a5d3d12bb0b04cf1e08905759849a79c410727412576386a21264939c208aaf08c31c47e886d75e2e41f91054639b28c683caeeb193df640c0a460520145742a71b5478fe1778dae3fbcd455729877d6c3479d28f77676316edf42cbfe7e75fe0ac6546d3c691572c2af830035b9bf8bb958e6a0f7efe9b773ad495fa3379edbda0f0e2b86ea6cc1e8184332fa98447586c264ec763200246a6201b3c107321980e0b5ee611b7f3db85a372aa1a81299ee14896e9c4eee7ac31c540373740ac398bfba444b574bd8e6a36c8a8a913853eef4bfd7eaeb7145ca86cb9c3aa1729301f05df63629ffd9cf0f3f3b4e795f6d787b8778841ae526e7f8d55ba1e1917b8bb769cdc593fdee75c2354240e6be3707ba6f6b17606d0bde07a7ed0e134ced3f84223a609cc6aa4824a0364506e5c675dc8e472ee4e01d17d8d809cc809baa7b0f1134d5899ddfd2124a798e521d13c9d52e907f4ae4f8857f3da2ab883fda0547d06739dd9f83e9c481e575a97b0bc25a53cb7dff879fe9fb1a19ff98c843efaefb5c2ff6edef7fa69bd76185feb50783e77cbfc7abc4cab86f0321821d55499ed0dd8e926216fe7dc56200ddb7b54cb66ce33238ca07f03da16572dbed1259004dd64151c84d6c1d4110d75e43a1d723e7705179509136261a6fcceafe4329d945a325122d33f88bbdc3d27fa930ef997787df29ed3f267f6e9690da503377b5e9cddf83b2ed65d7c7556ddc9e27307cd52435e0b173501518f719d5b62c8747f80032ebc42402b2195622990852815138cb969d82e056f5850d2755c8b26aeef87acbc1b50a5309da825e5cdedcc40b78b52188c94c6cc6013c4f5c9828f2f658b8ef7f2f5f4cf177ef37e1f3eeb9bbdafe5056de674ba00475cf0a77aa82f74c7bfe5d517d1417feaa99e78ad6f5297d5091f6def9ea3f79c6d7d80d379f8cfb02b5d5ca23ad12d84341c3117094ae59fc54485cc65181bc848c27689a3609344a8c3b6a7d2be9d847abc99133a2c6ae8f9106f908612a48966ced54668c242955ed0083ac8366f59691ab41f577e3d050b88ee2fe6f77d3c5fa3cc617db2afa1e5e9b5fea207757abd5eeda1279d03fd697ed71940ebed994a397c8cb93c60343ffc9c375cef7b4ee4230edf4a72b3908e5aeffac3224f896b7d993ab0487a5dcb2aa6dedda3efb96fd7c281c3534d713bc60e2ffafeb97adfdb9b3d63be4e702fbee2bd3d8c69ecea73ef6b0bf5b3c6d5ab9a67f6df9ae47f6b92cf7ffb0d9c6877399ca8bee3694d23ff905bfa013e34426ea25ba31b5dfc21116e0322109f4c8d54b3355c7a0ea69d13e84d82a0af71172aac8de3c088c1dcc5f406344bdf100f33dd3363da46746205cc6e4d66e09640847c67fa1073cc98cd405cfb1db5591e4ebcf79a521fc7416feead0ff27f3fb17f5fe8c55c44ff4bfbf86e5db896ca2ab5ab6fc57cd3bed2cdfbe8bfb54fef75660ec96030e85969daa176d725933ce4355284de69014022a8ef410a31a0d5f896d85897119c73d5ac99930351e630b1c70d57160ec0d8b819184c272890ae1a85056cb03b058ce589d495860932b9827f12077d5f2fec9bbecc715c74e8e3b91e1d69c27eb8170c54a486a5665ccfd30ad64ffdc427d7fad3cfd9fffed97f2ddef78b7cea531dfd5e3ee37b3ebc475ffc9bfdfd7bf8fef4e41df6fc9ed15e7bf1439ebe0fe3a013f7fe8e47f83b5a0bffb0ff67ec79460f3594c3bfb5a771cfab293af71d2fd5fd6cc038040c065ab7f4ab784d79134a4d6fb10dfbd89085afe43a5332a055773d876cce60b3e204ce32887906bc18013a70d594999357b4cefa3987142b4648cddca0c88d39bbd333dd37d11196f0c739f58ff6d61083f146847a1b73331787f5faf11efda18f78f47b03f782d34fcfda8bfff3ccc9fea1eef4591a4347f7fb89f8f358a7e1a731e861dc5fedb32e10d97ffe0f70f465aa3143b8a245d09a08bad2c20185948e7a5efa7da0140b2a38925a67d11275bcd251526367bedddbf4bea7d574b3702d9e3a638756e68468d8c878b391c0b45200d7c8b5546a8f46e904856185810f64789493fc7c8f7ec37eefbf637ae0da7ff279fe8b01fa3f8101fad93d702afefbcffa5147366feb0b1fbfe7cfee8879d8469c362e764c3d18149750f919f5ee631de984c852924c17b59ad07e6c66b63f8a0756231d9572901bac6d3452621a576cea0fb90a95552d4a650a1b4d7989d704c83fa9331e510d5a7ebfd2d2ebf15576b9baeb3f63db2b3524fbfee70711a9f73ed08ff6d4c1c7fb3a4f787487fd4d9ef0c3f778d6e8cdfa9fed19e9b409a35e8d219c095754d990fb6822fd3882a31434336cd387942a96d2f19570ef8d6cd9ea373ad591b319b0861f986bc158d95d58ff1e62cdec320ad93c128851741d105825111e429eb7c85073df15a3f931e7c7577dd1e7fba6ffd933fec17b1deb6f8a5d8f1f533fccff3d04256ea4bd59c775b90eed9521867cc269471180b3cc86460aa723e18c87c411d1a2c84b34c03f73221f116f594c5811d33c92aadcd07a6ba1599e969b358ee075588d2d523130877931033a4665e74b3d77cfe0e5fe59feefef62159044a891bbfeb1562d0ef7f8593edcfb67767a56deb3eeab7f5ad7abc97a7d87a97ed3b37d94d3432a8dc4eb3ef1e138a7e23d6bd0bfea1f303ed19afe064fd64bdfc657791e74bd1bef42799e63adc9c3e79f9fefe1788d2359ca4ad3a88d5438e099af7b98145e120cde3567ec3a8e7283d8300c0c98a454ff23ed78b43d2761e18571618d322856a926c2b444b7d8955d525b465ac275cc7f6999c356a4c857beeedd08371e84eefd53fdc0afb427773ee039bd99ede91ce0098c5078c453f6d3fba7dd6315f46187073a5923ffd24e0d18b4c1e2bae549a96b29b50161773d02630bd9e21a97ccc7254a788109827927a8bce53602a8c83576ddfe890b04927e1c2e389c31fdf786423c5b30a9a5b4238458cb1b004bc630949537f8cc8231bdeb8fea141fde336fefff33eb4d27eccd7fd82778e7efecb8f9dfffee47778da6a5c65d9781a6c55aee2d9c0662db7b2414694c134e62b39ebb78161008e3c11a82dad2178555653c1ee8755bfb5ae36043d1859b2f71f11bc4b5327c5b84996e3da695d7a1092e42a0403891b36cb0d7beeb838b7178fccd5d533dd7ef4ede2dcf3c1e9ff290c1655c7b8777ffa44e1f1ed59b7ec8b7e16dff0eecf9f50fffdee35bceeb65e4e6a320e53ae40acf407e15f25ca0da2ab1632e831a5f210dffd99ec54c951b1ffe5e2f6a1150a0e9993d7612b0010b97b959291fb9335ab31a53529a15a9b125d4bd391b60281d769f18e88a11d5c53a6e12629d8be5cbe35d2f082ce4b5be4a81ac4fe82b9ed6c9fe7b8da793631fe67cfb7c1eef7894c7f58e77b73fe8ae9ca501a5f541d5840c3623062d9038ec56967219d46885151244670fd9b22589b23402cc9ec0df830fe20756aa88b88d5a28b8e115ea58951949650f6482cb40e5eda26e6aa9070f31f9ddcf79132e262c08403984356b3ee07ccb6330ee8f7451defb0efd657a73638ed659b5ab931fc6d58c5d8fda79fa598f34521bdff9d5cd803e178e47c90003328887d0690d6a78add0ef378405eba44493cc361b093c9694724dcb91269cee3a71e18d74c65852f488e978b6a82465b5ac7dd84409456b1a95801a3912dcc3acba1b7de11b1fd5800edfb34d6af40dfd8d8be8921de653ff931977afe677f773bbc7f09cc7b7160e56201d6d8d26f2360402d3da9a53e2ddccc0d823cb5f0365aa0907e1483d7b10b45986b4bbcf001e25132f627657a6d7abc1777e8d622a4be6782da2cd525462834b61897e5cdf184de353fa90d4e2663b665afd3c277d22c63ff43c7f76671f7aa1ff1e8fb81debb9bf082d773dcfe03c7b7c3f08257c61089a0eb447003e2e9832c372ec32a86ee2327b9095f948990298582de27a9b00bf63f6ea21ad732b73ad8740eb5048379b98dd6bc2f156ac44f354932471f2f606b45798e08445ea21a8c6480cf84837e153ff7687cb0d5ae130956d7d9288e5e94beff4492c45bcd3c83860f60c9cc755f7c27b0354b5f85cd7f81dfe4fdfdae3ddfa3deb621ef305dcedf576cb6d9cf212fb2d5fd7cd4fdee13baef91df717f806dfe525f20be0cd982fbc591cae122e1f7fa4bdc19a4d003a1e1a3026050ab1e6b521504be1886851c309277895560d947c3c5f28aab389b5c6546c4415ac1705ebc232e771e4e989e135c20eb4a4663e193c87db7a23758617eed46406c4d2812226794c95ba546df5037d25ff737da51f70e97f23463ec155f0776bbcfdef62af83fa562389ecf57ecf8fb9b42e8e2c451d11130219d15127076b3da7aac1255c4b25aee654d3e9006dd1af34e67ab6040289486254ff5e67958e24674b64e088570df6236f84ec6ebd20d0ca4aaf1660dc61c3aab2089621c17d0acc63cebdaf62ae234e984ff54f4efbccfd05d7c278e6db3a68dd3cf7f0befa9d367ca00ff9e55d292b58c5460c42d0705eb64418f71b548dd14cbb0358c3d75909b5459103e1e438e6ad9b94c293a5d987b60d16044d032dee024d3d12b77ca0b4ebe60ea6a1b2b0cfa70fa1865946b1131bf841402f4213acfc236ed22fcedfd7b1d4534c74a42db5c79e9dc8791decd1b7f4514edaf8577be3b5eec85e63ffade6f11bdbfdc91efb48bfe4a42da7dbbbe17deef0a73ec01bad975ddde7cdfb68fa5ed3e7fcbd855d166603ac43e05d671142a1a692d4f52a51cb95e4d988d0fc2106e626a97d9d29ab25131804fcee21a5f6e043bac110afa5236c5e58a5af18cbf47c431d3d48a98ec2424468c806c2a1e56bf70fa9e335eca8ee73a9bdf5c61ebed53cff1cd7f6592de7706feeb9c5be81a5ba501cbee3bddc7348d5af782f9fdf433b70e89c15d7dca4fadd268e2c372ef39cd1e69a541bb0a0f143361137011582173140cbf17d622337d446ba9c288cab66192a38638caec5902352790e763c206aaf0ef51c8404e20c369b145ab7692dbd7428cd14dead030adbf3e39ad79a7eff4eeff2db317fb5efeed573fb95bb199198b0dc5850e5b2095a61e059a12ef33999f64105077ff012319cd29d3e8c6b6033758efc8dd3d8d88be92a3e714cbefafe87f738e03aced5695b0685ea03adb1d804f671d534acc44bbfcabb501353a294bf70a4960cf99c316fc40be4f15adabe160352e351acf28452f4982ad4f8b47b585cb71e76c6f7025a2b5cffeefdc2335809fd90e78a970da61a3b33def88833759793ebbef2e7175ccfa583bed2593bc117f2d3357ae293daafcfd3f83b3ffeecdc9c8ee613dafbb535d012750b153fa0b2bb4f811ea348d6d964aa73269ab86aeee750fef10be421e605896e6d328838058d196a411f10af0dcaa6659acc6fb4768e40dce389f049756726557b1d006612a7d51655f37d0dbdcffdf8adafb58b6916156d33076ac9e7fa689b64c7a905b518dcbd5edf2fb41f601f83dcfc97f829f2ac42f73b4d23b01f77976f3d2336f343ed2106cd35296045685e0a92cf51e44d45a446496415a126ff606a9fcccd65d57b1cfe89ba437801dd2d00fb3d566cfbff87bbeb2cbd214d9f43dfa4147778b0e2c5646af04806d4084c5136a324127f38df68fee089c09015b6f58a2f5786cf3c2b63ace715ab90d6f5a10e135feba6c41e1b81ee6bb8ece6416dade8840ebede8ce69352a780dd065a0ecebebb22afde6347bfea03dbad6f7799bd230fdaf387b93de0440f7ba83b1313b046cc5b2f88d048996954dbac71397e08343847cabb4a2a95277a43fc8285042a27ab10922ebec9b8578a497ecd0cef3108db0a1bf73a026a8e98b5f42762234bcf95d54617babd098a6024ec6695812e96d5985eaa4e931956bffb5e4bfd894be37ff6f5f6e9a75c1a073da75672f3e0577cc19f70090d6c00fbac82e62c628fdbcfdee5fddfbec7a1b7e13c2c4e684b73e18c6f19546c41114235d218a700d3a64eab40c37caca4063d64344838a2237dfb8041f398c2a60d4a7c350328449155cddde93ad6a71a336ce0bbc89f19bf37216f8b4431889965d001b9b8f6bcc517fa1527eceaaeb6915e7fd3bfbb900664bccb091efaad9eb4a3dfff6ecf5771663eecde90b66ef891d218cc35c49b8e70744bafdb5b1a61c508e4929ab3392b377ecdf4b0c6334a2091456c262ac7a1d6d688a3262e3b036bcd5a0eb9b9504d700398150ff60873ddc7ba95a7136b994d7c90d5e2ec1a5766a8c718b48dfc6aaeaf8ff8027f3ad7665aa18764cf07f26a7c6df30157e087bccb8b093578150ff38965a249dea7c033b9d3fa8b122709c03e1dd0c3a99edc38c2eb94ab6216a195e06cf36fdde3079dbd36039d12d1efddf77ff7bb1f714c259a799b94b80bf89d91b9771b0ee53c0c571ae5de550a543803264db4dc629aa98b89a7cbcabcc92266fbe17884b86d600613421beadbb058d470e643f8880ab9e6e198326877c4f15808e01f5e5b1b5f2b4d094ff73ac711d3d21dc786b9feb29e77bdd3a1bdc07e7a3de6ee8ed3a5332e626e3e6eede4619cb3e63383728aa977934cd432d1a1c230174901e764e25d074a290e714e9c76492b65fa9a992043cc69019719918019f9944ef2f006a8494ab119944893fcaea7b67e9330b9c2a06b123dcffde8f78640c6384154b867f2abbdd1fa38ddbb1983ae9945fb9a87df3fd72bf413f58a2275c68fe2a51672a217ef99b7fd99bffaa50ff5144f2fea53030d33bef537e24fb5104535eed3502fe308e72fbd39f4c467ee38a2f7f6a2d7ef53307e78e6c40a4ffaf6f7c29db689a306e98cebac82ed8c37c3ebf73ee67ec9cb6ca9df6fefe414c83ee65a9b39ac8fc14edb682522bf4d81f7e75d0fd1fbcfd871813cf508bd1a73b3fb5eeff3ec556eee7bf2dec497477d5c4fd8ed5964e52ff589d33a2f29578f09d79bcc78d1f93891675c6ecf475ab19d8e7c6660952e9fe7f3543d6d93554c936ed9c6b5d2c43346e504ffc3f62cbbde5a189eca0cffd3ef95556c777f66b578a9e78527f99a7bf18ae3e5c3f9af77cf3cd5735e38a7ffae8e53240e5c25dfc2c79d3c8f3fbd330ee36eedda41ffe4c3badc97f1918627e81a2959a1099c115d85b8c2c3a2d2ed8cea136cd83a53f15a52dd0a8aa9e16b8d471cfdf666407f02deddcfe19d9651ac0917d7813e1d449d6b71d9411235643199f694e3fbb4c445580bddaf692794303ea8d97c3f4ffb2acff5cc097ecccfbfafdf1df1eabfe8257d99c7ff0c9f5741202bb5fec2473076b9f50bd4f1652d9a741f07efc6dd71cc2ccfe60e8afc12a100e8494c511b68680839bc8969375bd8f08abad2f1075971a7ec424d8e48390682e3dbcc614da675651ae5495a792b0cfc2171ad29d3d5630a7f3f84da982d6033c451738f2628e2b639157abe896b785487fd3cb7f6923ff998fbf03d1ffca9674e70751de1a2a12e22a6665c6f62c35b4b070e49ffdace4cff8b7dfebf807dfe6fefdcffa5deb96f730dc4155cc5dc2c040fda973cea97b9ad0be448bc3c75e0630c58397bca756fe3f6e3f73937a6ea665c2d19f4da38423d02eda3a0e2015572861cf3965665b770833e1ece8ab3977184142a82032ee8f3f94197d0b3055e9e010ad0f5763f6eef93d73f6bdddec73e4fcf3d34ac9cf36e9a16b98620e271399e0646f91017f421d4da5aaaa9266b6fc0931cc4b5e8e34ae1b0b60604c40c43fc9054ad9dd52548aa729329769394fe26319a25a958405c79b570ed5112a94d3a045dc659f4015e74fb8e795697ad8876bad4bbb9fbaaee7a4203e467f166a51ee3c833679c8da4c31e77b6635f7ffde0bd0e67ff3c3c7cc7f9fd2899287ca3431b17cc595439cafa71310f578071538bcb4027bc0d85f28c98fb23ec8c614afe7ff6dead3b51de0d1bff4a0948d778382a01a9c42164033903e23b088152a58a7cfaff72d34e37b6d63efe7f27ef7bf0ac3576f918c8e6cebdb9eeebd289d47c2c0a0544c1a010d8e525ba23828158e7bd44684ac47a95f59ae248f514b442a266a7fa11b8968331ae860379519b39f81877fc6c2f6f160e3fe6418fe31eb83faee6386053a07860b152ddc9dedb4877845811efe2d23319e80c2eb81becda28d6de63526b8b54b99b81f629ee73331b0f5b7fdc3eb008631e492e299efa3ade920937543f7a0a2af2c717f924ac8649daf33634380c2ff4225ee12fbdc3077e15f7a3568aaed8db9be96b6dbe8f31fa8b8ee32bbda5f7df5927215ca666ae5ff14fefcec4669fe0e7828ff9f0fd9debf07dccdf2751a3ffc572677cfb2fb433de8d6f2682e8ec8089d7ff7219ef7dffabfdbbf77891ef68889d99c7ff9f7007f8b37beda2cfe7495cc9474ce51fceed6d8258171a8d434b42146b1c19355d68905d106947da5aab12d94984761ce42633ba65cabc3965f9160bb4f2ab18f868d4ceed86915a63bf82ddc2695d5c597502f23f3e45d5cce8aed679789f7ffa7ff1f7cde2efffae05f941f3f7d3b37efacd4f7543cdd3b9bfa64f51a762f8f82906e8ec9ef87bcb3df16efc83aedb1bcce28cfefde11e8198198d5c5438a2e570e43bdc0c58be5d1423bc704792d4fb35955652971d2db37ee1129d9ae80e1701e025decca01748c3daf9e1d02566b04a84df27ac610b6d0f48c47aee10ec5342e3483d71cd5b02d8c71af6993df2555c95447e2b6bbe4edd23ae76bfbed2616de60c9bb47ecf377fd6669ebf7b7e68332f3ccfde4fbb801705a7e7b93e565bd4ba4d295ba9b0ed0313536e6a7b1ea1792cf8232fb04d6af91080b648edb64ca246c6ace18ae5a3f90487d46996d8b0a862ea493a6412dacaf09d7c750f5a89818703d1f5dce0338cb896bd44bc90311337d13a7a853ffe2647d08d31abaffc86a346e6dbbf7deeeb5dbae7a2862f0a7e4fc62d9026028a91472a72331419544c0a5ee052b92899479a845597f04a76d82eb77e389c613eca9382f3d0793079ad778c0def55dde40a6291daed961ade2873bc8a4c46484ea41556feca171f3066e7eeb99ff4757fb479636f311f7f8e69be7c2e3ff5215fef8ded4c1c7c8e4ff2e8279bf02d3dade7dfb9680f8c5bda83b718e8d7ba59475f0a2f7fe843310455d9b24c938a314bd25217caf1429fad378229c60adbc454ba0b8183ccc8ccb8d04b89628bb8bc53d11448333662d67621caf364129ba2c8bd94fb2607fc0e7324623004a92323bff61212f15a4de47738227fb2b73ef4a81c6386ffa6bf1ad75e1e1b6c1f0b6fe3532cfc2d6e7e7a036cf499b10fb1e3b9bf9f7a97afcc853481c983d0268e34bda998a8a95f4b1486bfe0c21dddf91375c7403ef6272396b9bcce44de8a888894c13fb860dddc8113c53d9c82a124555712e6ad7d27ebe613056535bc930e9a4aa86631d44e5cc45dc654732b6e94f3f9bacfebb3b1317c8a0d046602e6d9f859bbe22287ff32ab507199c7e8607f7637c80fec62814fd8e4e77f9feef1abb44ee072eef2f61e6c3b5637d887ca666663240e3024d0777ea42bee78633591923b5d41583b52356e338613514a134fe41d2ea6468ae4e35c3c740bc603defb7d38e1d37ba31bb3689450febb4bfa7c7ddf6783d0b1b7b75a5759e9753a86bb5858f52b7ddced3b6e9733e79457b2e2bb9990bbd4009773b7b7c94d42591d3422aaac1ab6c7b3f9e6394eba78d7f50b538e0a61731e9778a66cbec186f79031dee38219be9d5b7242e2580c0d51757f66c6dae2057e48b4e46439bc53303343e00989f00c3bca53e3e172512b3a6770c90adea5c674450afea8229c64c6742b389af9e5955c5315ce6323d7b1f0d6727f974708cae8a88df1855d346ea44d58c4023f488196e9de0f38dc0bbc5787f8e5fc73cd68fc497fe057f7e2f0d137f088c0d12463c3444c54b82862c08565f9a592016fe6a9a309335115573cc82a3562149921404d82741b40fe945568acec068406765941068b429964d9fa296826f726ee896e0c55f0b104b1150a752becf80907b37f7fbc4d0deb5f9fef0927fa5e675a46417be4f344edbf7bf34c1eeb8409890d5424fbb937f8de1f0189c0fdd7f5cd562fa2f8cb7c5fea0c4d1979877cdf59ee90f7dfaf86bb54a07512357a16f15d3a7ecd477f0e73719a0bd13589c15edf15bbff80a7f8307717eba7e1b9bce38ff58ab51ac3036f5a2cc041b3f8f5f3cce8b12fef07f1fb5350c62b52a05dc01b11986c934dd42ea99b3a085b1917642db58eb37ab4c6866df00ade679a0dd47e1f5334094d19cc2032996d25a163fd495db5e44e2b71450c654b6f514acc4c4d84e3f929248421efe3fd71c60efd24c793b9bccddef54e5c556f3dbb2fbf537fbd9def7fe619f66bbd4e4da5b30ae799c1dac4e056f6cc9ff293be5b17cd85eb51dce71bca8608f7784ea37c866d8e29423d1343931bf12029db4d0afe5ab25703e62083e9c0f42732c495b762ecc120a8dc7187992ce2ab9837bd12dd20a6fe5641db8cabf5367300108e9ea6ec1bbd91dfef5d2c62d1ad33e319cf75c157bb09b61de7a9d3f549444efedaebcf9ff63f7f75e682b9ed3d06118e956ee83d941e41dcf3297a086d4c48149b1869860b25b9286158360ed5cacbd876e7f7bc0f2af82826c12a8bfe5a34e246eafa3089a4454b3e8f4d32c0133960ac23be81f6519d999938bfba56f6ae26f33fe06229620175ea1cf6f87ecfbffefc232e163a990e1824639f66dbb45611ebe39e8b06a436ff43282e538790201ae5a1ce93040c3d3fe29854f24e1678c76a1e48a1a631cb75666a2dc3562e90bde2bda44a7b36e3b1c123afa40609133eed30c56678818be58c6ff5f00dad4570a37ebb337581e0077d76a409dda624763b88215bc525eab9f036a1dd0584119244d936635cfb2e2a31c4928b411f3aaa20551749c3b36343fac4c42605b9944ced42bbbd23bdbec39a4b59fceee4440b52c24ad47940291a088dafec81bc028777458eff9c1d4a9ce12a1124ff861e319815fe7fcf1118f9263174191ff5fa5e8dbfb741c195bd67d05636e865af1e15c3318b72876b3c67b6355e303ef197ed3c141004351f308e0c6e745325ac6d586a8ad9b0c88ad19af4fe16577882819c24541584d95b5937ed427801677a8d5d32084abd89ab752781fa73c1065da1d56d59aff300ffe768e73f70951e7327a73d509feac51fb0ccb29791d4694d9ebf771e4f55a9756a4c0f1869292c70faee27beb3ee67c26bd20aed1621dcc6d191bbe3e5b7cf7efff0fba7f7098efdba5ffac1ff30d5ffe7332da48ae7d2214d56ff7ef91e0e2f71f3e16626f493ac7e7d4777f71677ebf378c73d1dc226ade4e647bd4b9483b05748b95ee2db8315059d4323f2a05cf42729481552ef5e8ae9606efb200028612edb61d6d95cf35ad80fdb80e2fbac270165aacbaac136d4ace3fd0827137b238adc147523999b773cf262c9bc650af0b5bd4b45ea94ed010f72d17799eefdf91be42d5ee3210eb6ffd5e7bd0f39bd16536561076fa8c056ea281a184424c27a4c18192b3e1d301b4ffccaf3935abbdc5528e5a3e59c5953b61c9298591c979c5398171c959bac97222915261389a8c628169c08964f041db9b454148ba6a2910a2e68ac9df15ddef5917cdd23f6bebfe487b6f9f5982ff30c0ef909eab7a771aef25f3044b55f363b19fdeed8eed78a518c628337a226240624e066fe104472ac762d6255dcf934dea982f48968efb35a6e92124e498d6235c949c8e5434c739eda7fadac52dcb73dcde1c852e8c19a41722722b4e61f7b1f2ff4f4ece312ef4d7fca47bb395c26152fd418e699895f6181cee36cce711ebd606dbecedffeeb09ba88a99bde62bd376975f4538fe37e8a97fdb41790f4be459d419718729aee5a5bd48a045a8f68293781a1a78cda83b33d6bc7b1dbfd7367cef0e99bbdd937c859e3756a587ab6df0fe66893d6f8a0797ae6794ef8d5333a669ff28b8cca05cfff308006dc91c9cc94bbd4c61e8604528d3c4c65947d855ffd7eceac4d046ce2dd6739b3df5fe79e8d6ea304d1aae24fcafd06bff1ade6dde4e5b39ff23ce7af9ea33d688a7d7fbe8f79005bd7d2f192201a055c07039f8f46d4c85b2e7037b7f53c3147db942b1d441807a2d9fa257752063742f82617fcce6753c3af801108522eeccc4aa1f438cfad807591b411536e83a440948a7c329fe062665c695f44639cfc266356d8bb773ef481b750095d9ebe333871c77c6d238e3d81456a58fbb5ba94c7be1537ee87718f6bb8b79fd33636864ffb71d5f8279cb83064259f30173f6243c399992fb118ce84c03d29739ab9238756569f2c7f41bf1c0a8ebc595c903b36e19b54e7262fe37ea1659b72b2a115fe234b35b9073824eea80a77438ee95f204b58fb7d9e8436ce89e8661ffcf84b39eae3bb3fede3f9d35a3df7327e67ad5efebf4b75587c837ac3eb315faf515aa15686e034ce55eb5352b35cf90041dee3dcafd53cd6cd348c3816f588c5867a2426f779388441b9dd28e115a28c2d0af325717e0d641503dae716af7fc3a08ab752483a77394aa1dee0c806a4fe6b4a545ad45084c0bc0e224c3ec1a09fed87bd58dbdedd6c4e5fc67d3daf99c9b79933dceffdee7afe14d825cc7b4cccd192b2eecf0ce43e2e72ebdee81eb06b6f67e0574779e32485178a898c67a06da9b0fb7b43dd9309bebb87ca0c294a1625992e226c642c77598f5b3691eda2b282d868b7c281a62f2c6f2ef07d52ebf0804ffc6c6ebfd327719b98e9c49776f0339fb9d3baebb8080ef397df43de71e72f480c95c8dd90a6b63264e5dd113bdf4ae8410cd088b1619b46280cede669e1e4a128f5240492f349d9c5b52712db9aab091b0400469cea2003de52153820364e38cb97bcce2171f4d4af20f8583b1e6e9fb583bf8c9b0cb87f0f2dffd540bee3f30c6e32d787589e97471e5e9ea7e169de3ffc1d1cfa02e7d7ad81c3d80050ee558a353a74623306de3228e13dd1f94308b19d85eb5d020e3ca3eb947b63556183940c06e5b40b5133132ea1a44494387999ba0fd6a21c4a65e60f73a7b3a5631929837f64f86b85052e53c03ff2927e6dbf4b29ba7c215ebfe76b2e9a4bfed2f0a0e1259d8bda93c63116bd85bd39688995f294277bf5b9c5cb632c718d9fc4a912d2f5ee4965dd4be3175838cd2e74476c51b3ed22f2a6cc565e2a489fb2c0c2bc594ba82911e83110835d58b677c4c96d8e46ee5cb463eef02a65c3259d78e6ccb06ac99ba74474ab7b301473865ddf084cce3ee1aa3086eddebf96c20233c1db2422e0a8817ae11cbcef75ffe93988469b74ef6f8ea14e8506ca396ab57df25cfb18a0bfb6df8555419f19cc606cbacac0af8ebbaa1355d3c710ed54e46d091f79b2fcb59d995aa61a376921c9ccf46cdf807f5444a64af35d00d04358f3a56f4e2ddfe5f378d952c2f15831b6655c6f82a2dc0a41aa38223dbb3e67bf492b9cab316ce3e8f785b9fffd318ff7d3b9ff37e6694f5b451c1df050db193d8e7305b7da2e34ba9d4ffd0d379a4a4ef89fb484762c1a287bc4838a84bee95f9973193ec94ad79949365975291e65379c17d9481383d4f49efdb5d7cf71ea37b9eebcc70cce32d7ab939ecbc4f6e60bf6778745fe387795ab26d31599b01d33b38e202f0ca3a60b6ae567134fc654b7a482726eb781aa2550157c8a694e17488673d6605190d5a284362ef2b95f7846eaa030735a4d2e6072be5ffb201b3586dbac1a6eff613ba667f2cdea803793355fcf847c5b23f990bf817962b0563a7af765df55cd9f92084179e8b178cd63711ed3a1f67bf2d027a5d73284cf9c425fe246160ea967c2cb338397c949fb393ac6d89772da9bd4689b8bb9a18fdcf83fcc0d0d3789a19ff7e3f1dff4f713bee28c9eb8e9cdac942b029a01e7d39e30bd112ef9736f6a41686c11313543a36b168e974b8622597a2428b4c16b3c4f97c3cd3dd4262e741d68451920b3f9640a1384e6d21eac1488078b92fbb2c02529adf5cc680709e4a33ff41c87eb69fe4473b9d675b3fcda71de920aed5ecfe3e1f3a7ba5b5f61bca0796fa03236e41d73f38239dcbbef4751eaca30aba71bdfe85c5efedac66560628e0762120f7c8a8a05c20f3e57cb85fbd75ca0664cc0ba935c02e2c446669483acca76a9933f71d1f4bcec302961156bcf53911a5d5d1bd8dbb083e6f7b64d2ed6076e96d33bd8c9833efd1836cf31c5dbbf1dfdda6b729bca893bce749d096d90daee6484c002219cdaa8e49cdbca40c595f7ee4e0a049eb17e49e47d2b27700b7f72eff3aa17fca1de1d79293f3ecfcf34a548110219fb46f3e4db701b0a142795ee53b85fefdc0bb544a1d9e41955777eed25a19957f700d2acd02c31481b3ab0e794b47ed515d4193e66d5c38694f97aeec015e67240059441d8560a792b36fed5a7a0bdba669555c3fec0635529e37fc43bf766ccc3f937bd4d66fa6d1c79b55a9ef6e37571160cb8d433c3ab6999af9943029f4b84115ef9931ccea3d1282cd4c68ffe6e149244a1bf2686015c54dd831039546018292457ccf690b2f35295318c4d1bcc91bc930cbb5894dda21c0089503177472645faa8b9772657707ab73e7390f90d0da9ed4db003a7f9cbcc51ae8eda29ef9e031cf50aaecbbf34ac244158b69c2189681998d2ce03dae7bbc4f0fea47ab45d30624903dba42651528f3407d6449ae580c3dfbb4ce7c502e5fe1c913e819e66626b50d31bfb6566de437e9f55a8ce7ad4f9943b4a900283ccb8500bfc3eb7ea816719ae6454fef339ced5a38c5cc7157a92078ea6631cf93597977a48047e78f39d0b75abacd65be5fc6ab3fd38ceb07dd1fbb9cc0f711b2e51d3b332976c669197a715d9a4ff7cb8e33ef9f4f93ec5207eb5670c3f1aad4316f40baa7733a30b1257366181cc4ce75bea708b33ed06fc61c7403e179ca0381ab578f76b1050fd44d168b388a4c826380c7743c46cd9a5055f91a8795a70550bdecc33e801c1b5c70d0f923e9f5dcb792c1d7ec2565cec2bb8415c4d741c9187132fd27edc531fc115dc2f0ce599c024285499181627a54431e8ea949790d86a490c3c38cfcd7f960bea3cdffb7fb7e9a5141e3cf2659fb8a08e3cefd762f5e339ca3b36c936beb0add844ab05d2a65feb3833fd0e8b78874b6bc681b725282772f27ba3d87a13c25127117a58385e10d3d2c24efeb4a89a82504f641c6d898bd7b26010f7d33e066dc0d9d06506c4827ec49ffdb4eef84fe7f6f7a53a5529c521dfb29fe7fe75bdf5f25add443fe1d3f14ffb746f0bb7877aef9b3a2a388dff7d3f518296491b3e4a5bff21516c84a59e10a49bac0eccb0529dbf1be2dbc4c6b039f2e7be9dcb575c6e17d6836f6762fffbc73cf5ffc0ef7c33e669de5fe9c89dea25576277e4441798a132899088e17415564da1202771a1edc4c8efe33e7f92c0daf936cc139b8f8929ed8435e6dc1d416ea0a55feb2475feaed2aacd33307c12faf78a30c502fedbc8b4b7f5cbe62eacf27b5137062de3c1adb8d093e8e4fb09f80fab775abb8f9ca8ba9f0972f0d953c37b940283376bfd815746f7ef7a493ff9dd172c4bf396c7f503b7cb26ae1a1d9bc109abff2547e9b13fdafdfd94b9de463947adfc5925d7b150afde73fadd3d7ae0789297b9b16fc265fcbc270fbc0ed581abe0dd7380ed81e3f03a1fc1a7201f846c9833a4cbd0e9ee594d264c483be432518e346726af28fdbbcab47cc44560b1524f17156e67a6741544a1b025c0e530c89876b8895b5fe78846de3c641c703835b08ba5cf3a148260a74af4e7073ec2febd9b8b1c5e871ea5ffeebfff1bef787fcae877bb3f13a7dfffbeaf10f9bb54672b9f4e07245c9b0cf1d53df4fad00e56d8c073e13677ecbaf8f0b0dea9e03b79118774d295bc81cf24a3512b23af3ec6e2af3f0370e435bdae061716984b500209f4fa1e8ea6a202d037daa7cce494d423746f588801b8c300005568121b6a8ca16ff8a07d9cf532ca186c8846f799ed8d45f4d0313758e1422e453d0a7c689bd4d5dab7879b398341f85c83fb181b96521c7a4c417a8837aca767dbf53fa8d39f1dfb74ef54329ab6fb182036864fe9c106fea45e0fb621c725ad863003b92174b023423b296ab428d134d0dc6066de8626367989912cf207deab1937948b1d7b40b9442afcd5f36a6a28ae646a36aba4d6eb05c3034947f741a91b564ebb44c70073dff49112d7f6bdecdf3511969e45a35d6a8e745693333c5b6763811be8c9102df7715578cce1cbc80389e0fdf31a9c79ae53acf0edf37fa86ff8007652eb5952786bea3625e5b89aa3c61325dbf0659ba8a85c0595b2711577b8207a6eaf77aa57a534ac6d08d02e2889ce4a25331b005c6a29047e4cabb664b685133d5acd996df0528ee7e375cf40bb16e856f58d97fbf7a0dbffe64ea75f6ba23ccfdfc57bf1232ffb4fedf569bc937ddaafab08aee7f58cb4f42bef4e552492b6d750c049ea8e1c56aa044f782febd1965e6dafcfd4f3ff3773b28e23fd1ac371f217de3fcfb5f93dbbf5cd669738305f44c1caef110a4cb49326de62471759d9fc5938f9595d0de9e84a5ed67d78df4bfdc3f7df8f75d80f8dace21f613631cdd76994cf18b041505a16751f56a19d631e356b0af856f6bf2da2e3958c62439450fba6bc4f445e4b37bf93063645918b1470c41c38a2364e48affd344215af86737aa87b121072cd7899198a11893fe85a5ecad393265bc23a7586cbcbb1ea4db09565124d5b69749bf834b7cfe39f78efaeacb9a955a6d576ce5488ed369665eb8aa8f9431dc8145322a18873202b65fa3deed5d35ce00253b651ced4202eef162c36320713ccd0326139daff2e7147721ec5466a209a155e1c00d2485bb53452e5a2d45fd789be9f5f38f419cda203ffe415b551b2898f98fb6fe4166e92db2f53e3943f3cfa6e2fe3ff48bf3bd2f41eda30a1f821a86293006f25276446fa3cc7061fd3d28a68a97cee20a44c2539e44d526a49a9bacbaa4e121b6c8352c6a1d33c32a4d61c3e74acca4c2e502951a34346da84ea4752e0691aa18651ef56fadd3a33394844d7bfc9152fbf8ef1523368f7716276e11e3bf6cbdec2660fc1d1e738e04e5e8d0fe075b99e839f4d28cd3bdf6c6c49d9207111cf44b38b39fa93464de2b3ce0b279a7288eeb9b38fcdf0143bedbd5f0d892abb24e955186b14ab9ad8947a3189ec5ed66ac50b3d094c698413e2077434e2cb762381ec8312ec6ed573989cd751b9b056a49186f50d3cccef433dfb06fee34639ba4ef7e7ec74b6fe7d06dbebfa530eebc509502e37248d230e330389b0f4577347d67cd9ce792dc7c26927dc814215aa4f7af9941a8d2d74632836e4b4547c414749d2139ed93921138988d350df69b641ad8a80e1fd9ae9d490c6226ac631f4ec5bd5774e7a322f7aa6cfb8950b98f35245a3b58c729d15977cfec39a811bac19cc9c4e2f1cbe3bf68dbdfe7c5cb3efe3cded161b6a2aed7ca6c0afeddc95d3993135924a1681f16b10f76444eda177dd7dfe51dbfc6b4d91dfb78845bfc1579a1db479aeab1d603328bb90304d30e80cc1e4d847ca62b53413d786b4e01d73f202eb114ecac088b5ae2590eb9072b960a44ec7ebadaaf30e73398d4bf887d4c897bd7a905adda5111bf0094f7c8e36b2ca5b6eeb873022d76240745a056d6ac49ff1cc9c89fd835bf43d7c18f710730aab9c8961f5d62f0faeec7f002b15655d222c2f4432606298f39a4f17dab38413ec7ca10b1ab6455a0720301b1b475e740fac891fa9470a39e5f6b0bf87446320ffa8428d127b602aed5b8bf1701346fa81a2df90a169178edb6d82d0287419bc95cd4f0dab78d51b062e619da5b04eb1eb254ceef4c9df0d8cff6e3bf8d3c9bfd89dd6eb79fcd65feeed5d7c556cb110cd3cd5a39ddfdb7006e423ebc95d1861be40ba565c73867eef2445f3b0272506cc14e5d04f222d03032f49e935dc8656c882955f2b23a59e8997ed562c871b69c31136709818cd430647cbd42566500e77d4f91a7b7b35d7fcdb7e54f08d9e519ded601e1ff83e5171514f321c7407fe5261e9851bdc22767937fec1cef533810e7db0b1c0e080293a7033c32719e5e05a2c6b48092726de06746466a88939e0f3ac2223dfe5d3b8b21e94c38cf90403df446cd62341cabf56ccffeea46d438646541692f09e4f43945798e55e2a50c71cf8281c2424972b8c3c971b56be105dcb0b05830f5c3f3f5d53decf22b2d9fb9e89808d72b4f1ea2ceeced4512a25ace2d04bb23cf48a94d32ff5fef2fc6d0de7436fe1431cf96d66ea36ae86eb0bf59e26dbc1032fd1918feef5737ee060db7ff7490a951fdf09dec9c8db7c8929395b9f3af74effea53698db76feb5e7fcffcee67f9b4af7edb3ad7c7fd81abe2a58fbbdec70e64a35cbd95a1b58ffb5af9666dced4e35e389ead6d560d416a1e62daa7032625c2208ebcf7f5bc7f673c7c6bf733873f49873fc586fed4afbf422be1fcdcfc07deefd3d8cf1cdf277fe7d3daeec5f3ee872d49002f168ef6537b6af2925ba4265650651676d8766e0f4799293b0c240f2a35ca10e96666b65b0838a1ae9e8595b2998badb8f410d5120454c5014448021e2fec36480dcbbd37a021b83748c6433ffc0e9f77f8133dbd837666bf1070991a5dffd97abfb98bc7bfcf71efffabc50aabcf1cfed1ce9fbda3eda7f9edf8f7cf3cc3ded67f3caf7b7b3fff190fff237508206c38f6a9bd93e5305491de06915ecf7ab6e5da1321f33c8924a11073ce1409dde61ebbf998195ea3267fbb85f6f2ac7e3009240f09e08ea8cb8e55588bc88b84c0410c3c87216486ae1ec53daaafe6e1ff52b3f0137bfff57dfcfe1ef8598e23f20fb5ad6c6f5f840649248f3897737fa7075dd22b738a68428d6e2d6173af1cc4d35eb709d7e318749304111eb37c9e948de3c391cc7a2412416c0c909930fee88b562eec56334e0a6577231935230afe4251b6613819d57ea96be60c8cd054636c6b36777498b9f25639c5cfeeb57d1c70ee5e2be388e89978ded717efccd3f9de7ecad1796e9fc406daca10d6a981bed1bf7f132c8ece0c9c1f747d8c61feeca7bd7e8e534fc275fb82fedd28a61fe232ebfc12f7495deec2924718045666e707fe265e213a03c32d2db0151b96a54abee60e3129e54fb85412ebcc90d4f398c35b594b57549cd3082573666f7ca0ba90375882f629a8f291da0dafc57ebfbcf73f5e96a31f7229ff785c737683b3898b381ae97f9853f88c97d9df995f3cdfb18684bf8d8fb25bd27bd380cb8640d4d1e5af5d563570113566c89095d8d04f5c42aecc9df4a9a39f2ec5157837d8e19b688e3d8f77dc9fc77f0373564cafd613c768da258287b260bb99a1ef62d8200cd09aba25c435f7423bb7290a4c8cf4dda2f03c55786b5cb576ccb54122662dc6ad49d9144ad48c322dfd39c292c09c0a1eef044335ee474e0c3328287f2240cd3ffa113f8c1bcad132169e4ec7c32235f6b648ee5e78278aecc9df9f53fac116fd96115eeff7c5cbbcb95e71f2398e1aff1ffc61f4a89ef57a9783ee3c0ffd6bcdf3e03c57fd5b5cfee9bbd9c7de9ee3595d2a91bdfebd0f7eb77486c511bbcdbeeca57b9bab38f5e9ed06f0c3f79ee725c2456a8e5ee9b39d8b119ef71c84cad1eb57fa6be7789a7566744d5a07adaa749f4464932ddfc4219fc442bccf5c4fbfe28b3fa351ebe9cc445046de2bbddee0ec6f1d7a9cdc37fcd31fe7fdd8a3a8d37a6f9fe091933c7c59fb7377dbbf58b442eb834d1ac365eaa022d94190555c7f8d473cc335f84fdfe2cc77bdfcdf3bd8fd116ff721863cd5015eb8b3b7b322fe7027a7d16893d5412b0ff6e7ef977b28111066d5febf3cfff7dd3379f1676d97438df6f5f81ff6c463b683562ce0fa5fcede3eb7be8f99317cdadf0927fef753bf826a645db6cad0207186508de1e17b8990d6d7f3dd69550d5e9e1f9fe35e7486651cbdd412c0acb0f776f5e3f73eaf3bbc1bd3ca95cb77b1d8b6c7fe79b47b9f6b7c1fc7642e6952c3cad53f9ed2edac28cfc4cfa35d6aa80376fbeb5e95d35de9febed003c3dbbd5f357de1467dcfd370417be75c6e20fadd2635dea4cb635fcd7e9fbfd88bdd597b015efba0c773f7c10705871cd98987efdf1c9de981aee3c1ec88716f52873df3dcbfd5fdff3957fc077d9a6f70c59fd745fa911ff0467371ef27bd799e0357fccf62cca5a0b24a0a6650c889efe4dc67ed23292d9b45fc9e54fc2e636d9995c82215f1642447c4d15da6d55441bc8e2b38a6259c66139e27bd57e1c92848697ecf6d6951eab55994af482f9fa4d14e696f7772395c7f470ff04d8c197e76675ecced80b39aa33fc73aedc73de19b3c2877e0f4fbd7e774a43344ca20464a4910187c86ed75cf349afbba99f8a52739f3f285abfc807b938c372d150d20c53ec640f7bef696be9b6f79d56d88f69e0230b495891e33573d056298a73dd94ad1cde7ceb6676553aa02d74c7f83affd47391dd8bfd43fc2d771de69edbed2e43afdbf97ced199fef3ff708ee0017b99467e7bfadd1fe8b9613781a3c13d948f34226d40251693a999021b90d27308eb9c003609463e102ed2040ce3c08c8db94bd8bdd12c7d53ae66d0b362d6466c320ab8dd5adc242d4518fbce74150bc2b9cd8db8f63b66f33c9c7cc0a79ce6efdbbaa587bb341bc383cdf896edfad887f8f3397fab75f6a2adf7fc3c077d979fd9ae918ae48cbb1e931acd05b3bcd8244b56a0d90c6a97a369877b66105317ccc53536a6565c113167046611df614719b842b38ce5712cfe1a183e0c420129860a2d0a4e7885ff28a7ab78efed44c9a134838fbdaa676cd77fd0327da3ab87df73319dd6f62bdbf8e53dfc1dcdda8f79ff9fe6579ed7f8e8d7edefe5539fcffefc7dfe9c27ed851fd8545cc920deb52176f483325180cbc12666daf0abb893004ee74ef787d724622cdf64cc070bb63652886daee52636791b44b80a4cf498c0fc29135a5291b7345274664014dadd1643a913a703be89d6b8ea5072bdeee5d775cb53ecf4cc77333bf4ea1190888b3c5b831bf5087ef90cc7fce9297614279e9edda167102847eb6c09063fc08f8d256c20459c4ad6dea9aaf36750f2a4febb11626ace274a303a359866bd04ea31a0b8499834a48bb7b3de5b522145c815e7fab7a99c66a00e5824b60ad16fe04f74c19c2e50a5b562a2db2c8a7c32a748ff1c8fd49ecd5d9ee2e36deaf23a1183761fcb2a9734973103fe8db803bf7c86534eedb8ae99d34169e8a737eb4a8fcf715dfe9bdb612f77a10e8c90595456f84fda338045d3c46c680645b6f5233e0aa36037334888a17a221a6d08c0229dd81bc260276d340f2a687281ba8cdb000b1467aed7735bdd31c3eee7acf37c3eb214f7c60b37bf1546f3d57e8587bd2ca3699b387c9d397cf7b6267c011b72268ff2b5a6caadf2d6a7b534f02673d8dbf53dfeadc53fd0adf34b6ba00ccf991979e2dbed564623498b51412b6f730fe41ceb7c13f6ca8d59be6622af17e3e143c89b35d632f71dcfc1131e3236fca38cdc0fa372902264c7359f2402950c7493a0b2a67e891d713853018ceb5b6145789f55bc5091d7bfca85bcc7ca9e7248641747075f475f852979ce6bbde4962e60816ec223f03ef7f63a07fcfcb71347f97536d79c535232ae3771c42d557576dc07bd702c3728f235a7385193acf34d390f8cbc561382b8a91e848d025fe7aba0964fd29103528c4612e82e04c33f71841f99ad8345f5608535aa95d19a71892599fcdef00227b7ea19fe77e66493191aa4e6f44c3fee9b73fb6e7f8d745a119d56f84c0fd81b7b6e24116e9433dc5da11bd67dbc87ff43bcf9e9bbbed907ef9ff3738ec64b369dca7bdc7bf339e2f39806865fab7c065a870202667074ef03cd7131a2c41d4d7c88e2a047d3a4f2bb40e771e648df2f7d8b156c1570662655ae7d3b3608f450c6254e26e45e456c4575692e9cc10a57a4c9107f5fbbba18d77ccf1e9fd91b17f9cd6e80abffe97a2dafe20639da6ad7a3e9fe5ed4794ddcc6cb4060a44c9561a5b4aa9b5a468d87a90f0283ef30db6e54adb1988c56a1dbb099d1344111f489f61ee4444b2e3a4ca0f65954ee16f568472bb8e193bc8b233c212691f710e5a1792da7e6ab9cfed775b2f7b9e09fcefdfe5e3fd5f84fffa6d9d321ef7855ef49dc87259e078019d8e56d02e43615ad434c74c7cbb6a730d82a7bd0897aba52827714355586e28e1ad3810cdb09112ae086bda2663e49819afa26794a1cdd52d67a31f35aec808daa5098d90f9bc4f4c245e1dd8a8b248f8de12e5dbed450cee59b4fdf818f99f99cdb678739fabc46f4a99dedff9f9dfdbfd6ce6eb34ab7f1a5b33dfe5047fb0f677b3fde713d8ed81dfbd46b799d8f2b9982a49426867c2b1d7b257bb2bd8768aa2a2bf2916771f477c3a0d461e9d9341cd6814970c0bd3fbe837dc5835de860141a1663ae7c48746cc44ce92cf226c172d8c7a5b5c926a3596636adef347dcc15c7f6b5bd96bccf22aeb3bafc1ff1cebf8c778c234e35d619b5af8f09059e1047f719520047721abac4a4bcdc89c81b314a9ab894ab806d07acf2a6986b37a8ac24a87ccbb7e13e063264d5ae98c0f759f56b13f3a60938e229b2fb4ca89de0be4126d298dbaac02c8301447ddceb1bf6ed7d880be007bdc02b71a8f2806f418775fb700f9e5dd3a3deef8df26f6fdee9742fbe7a1e70e211be3ecf16d4f99296caa515d8b25a8722925cdaf9368c9431673a5a541ccf793e491defcfc2559b8013482af2875095102acdd0deae4264433ec91f5238c2f7663355159c2deaa627117a9066b925a64730ffdbf906aa127e53ad599d999e8ecdfd7df20d6e939bf0acbf8e4f4f36ece5f3a986745dfc364b859cd1095ee2325b319d1b6c92cffd48ee7c483a5fb4fecc184e48a59efcd292c2e620e3bf0733b0ed33bbcd33c447d8ce063190221643c78798fbfdb40f400084abb76c39ac64a537a10357ca298d1924f90de3b7b767e298e7defd575f42b95e7ef411deafe959ffe13c87f6cfefa757ef745cdf57cfd39edeef7a3f817983b8b45c02ac767f3731ad0d2ec834b3b5a90aed71b3d194ea3830ba25357333058829264b7ae8e3618602b97f0f72827930489c6140c3f62e74651b9acd5d06789738caf26db56394c73ec5b9acf4adfd84cfeddf475fe136bdcd97d6627cbd7e81dfeba7b46c2ba9d5dddccde73ef3f8acf70adceba7b9b0c67396db8bead736adb4e4111ae03ab732ce9f1662384a35b2165c6d2924a528b94e182e92493e0e6a067dca0176d576ce9b564259f12a7f9a333ecedceb63ad6fe7a5c6b7e0b47919efe4331c7bde4ffa9ed7f56f8a566406ee84b30614e02d2e722a8a5199180a85503678f96b908887de9f8c6681562cacedded7bf371269cd21a10aac81cf95c5dd3c4fed4127b9d706942773cef90c74f19c0526d18aa63cb618407231915fc75b67ee8b130fda655df29b70773f73ac1df6ee33df5a7f1d57f7e18ea8921ac1a067560c02333075846bbea33a9ff9b61c2b2157a2c29b8429773e1999dce581124d8c69b98dc1147297acd362ba25d4e34141e80caa11d3b24b505e49ddacfdb29b4be8af244425b3b59708b0b970477cb40f15cab3ddfeecc29d1216482e6b826d6745768b1c7a150bd4cff69f230fa635695271c8a39ffb7beb8f8fdad1d7d88ca0f63c36215c396442c1b00d0c14cf8c21ca6cf9874da680957a9988360f8047e6b66e62111ba21a403c5eafd2aa6561242d5ce696701b78dffb3033ff820ca232288839b733a0f8c809a2e64fe6e49c8966197ed49bb8a0f3f90ec77a0623f65117f105a3fa014ff95e1368aa0ffa7e67308b476edc377d691fbe23f3cc248dac5ff138bff7c3c6bf97a9297556759b581cf92b94c34fbd826f73c1ef7220dd730e032f07d6c51a4f857a358607ee54e9b056455e73c2989d7473be8399bf410c7cf139f6f6623f6f417be472257a16f15d121e6aebdbd4b0745a3f73555da99504da3a84aac682f3852b43512a93f7b9a32ab98cd95f33e0394d265e41c7eb3e29784599bae30c4e16488dc30297bcc03986fbbbb3dcc9e510323ad23e981adc801b69077d0a7d889d8631aaa75c13ef841bff622dbecddbdadf8847af8a230c66e2c8d1b83f57b1d81eedc5c7bfb747ace375fc6db2c01da37ac3a2d24a0a6f94d89e9e81bf162f7dcb8f949fb2761c00cc6786b2a961cd688924e9f94366aa3f18787e683c6ce72c2f30cb25ad1fac1828ef7ed70e5277640740d7c4418d42b2f72778c4d17480d1793daae7394e84ac2ef314bcf7a1ffd3dc36b28a5fcfe9814fcbffcc77feaae7dd6e600a03780fb6d69ce76b51e44019bc8cb957e1120d7c4d6ac6e540552aa1506f98dd76a2e655ca9a262e46804ebcfd9d1a04e530890bb4e5a55587225f678cac033ad2b41f15bea9c64aa3228d9a01beda5f3b9dd367ecf457f663b77fff1bf4dc1cd7f5c8a1b5036f3f53ffc95f0ee0757d4e9ead6c594818187357351c9146c1875d625b6558c922b4ad95a43aa6867c52061c33ade2c4813a04609095f196dbca4c99bf6111d9f8d03759354c42f3378c0dbd1695375894bf60c2c99c23d487cb1649466e9527ff9d56077eba265e0eab6c67f5ca41e01d5fd3fa5dffc9d3de9ea68e5ece0cd9cf6af5eaee3cf40ef61ff2e787b585db38f2f676f75faefdcc3d7be259ddfdbb13cfe4b62bd8c4a6b7490502f10b2efffc5d9c397a6ff35fe3d54f9af05fd6b84fe7aee95363d066e6116ffdd2a365e86af12d1dee1bc470c7bdf9553fc02b3bf1d5f3fea836be4e9c60a340bca2ceda9adb79924232514e27b20a4d95231f30cf65221a2fa9d05a3878854d9cf388c0585894b8daa751fe143a391536b7c31a4d177660a6110ee776b0550cb799e856ca6826bcc807aa56d34f3445debfdfa117eeb9efe1ebfec8ec09dfc247fe64fc57f6e3658ddece7976458fde61ce45607492566d90f60a2c78b3f36d0f67da8bb20ad994937b6534535c112f66793133a69ba0d2238c1e76341a0d32bb4d829a012cd04a70b9f41df287d78ac465bcf3eb8653011fa49375dc68765c3477011becaed4cbcc933afed7ff40cffbb5fff88a5f3028e7b82276b222c53b0ef04fb812609f08d8a40efa376707bcca45fd91d3da7507df3d337220857ebabc6f7e3fe1e5adf6cddbb15fed99f551f31c3f288737e9129cc6fd7e4f27437a1bc366237be9640ce28c29726fe4e11c3530130194dcbb5287ea781f67152fe3cbdcccb7e2b83cce53e469e93cf3c4bc7d8e1f715d8a5666ce00887068c4a29bcc192cb35253d907a642cd9f0ce931ad864cd86dcd27da153c77323b9fcf8c4692da5fa5b65c3167d864b05c51078f292065082516b434024eee54ddf4dc8c5784fb1b6cb7ad12d23caf2f777a170355ef6cf7777254e67fcfa37c3afebfbb23c2b9acd85bdb76cc6199576221414ae544ba0dbbefe5200364e55760c07a09e92417a19bcf15288db0e6cb7b8359546b1603d466fd74c0277f418648ee17dc0d351273f1b00d60b9a505da519a3f843d19e04aed323bde051a55f7bdd729283fd1f47b1d375fc855d1f8667bf8cd9de01cee807ddc655c5d9b05781df33c0860b6a213d92a8e2d02bc8473cf0d0ca2431b8eb0492029bb25a5f82e80cd932cb516e5f02931e424614d976a152c22de05cb5f9b50a009e9d534b55b43191ee62e9fc99ad431c58f4a6c77f82387f5973993c07999df4d2c1ae35faf19df4ddfea8ebcf71fffcd9339daa5666ecd042aa53bfdb217331687be8d3c3683367586b5344efa51c7fedb73bd96b9aa6593ee5e302067fa66bef62b8ebe223ba319faf2eefb3b6e979ad37fbda1677233fff60234e3c87bda8ff165ef5e259b035f5d54b6ca406fefba8fdf5dc711e9d5cbfc1d3826ba8fcfdc35d2c8c14c40eba01113719d99c13fdff963ad75ef3b3fa5fff243e738a97652a0f2954f7ad22d3faee3879afcc1079665bcfb9267a39702c3ac62cffd10fbb8e1a53ef6c95af75240e35faff701ebf42116508e7e5a84709dd5ec751ffa05fee0736b7d8137f33d86e8c736fbcdb82fb6fa707604df65d57077d046be16d7258613598f8a0c9027e9a82782649db0d28c6be58400c1b4f04aba5b8364f217a8d25b2750f5dcb0ee6660c8c35e8752c80a73eea440aefd22e8168834d4e1530eff6e9466d6a26a6daef34e703e48caa1193a985cb0d1fb7dbe4bbfa309373ed6476f1257bd3b936fedf6abbfefe778792d6fb3df118e6ac53c73d6eb4e397e978d8711472590916d7100c390a149623cac42440a0af4cc17fa09db5060819c98a3c99c3793300ab6d27e3033770ae35257d8e982ccce8d2022815f6b3343642e4ddf4c5cf485ef41bacbf92bfb76f1aa6bbfecd5ecc0a9695f8de9c480178bda1f48a003e27a62a18315116d2f9857a868d4d1480f18c863e17a530aba90d539f797433b1158cc27d960ce6018682f9c8fdb69dc7b909b0d57d1e84fd613c97a72bf28bd36a8f3c7a4c422a8737b667cc85b7dadaf5871983de7015e7a24820bf9f34f7816beaa057fe45ff8e1ba9c1bfbe0671ffac30ffd6675f9dc27de9ec6bd72cdd436db0d636eea362ebb95af912fd81ad0bad95236dc09d1e0c421de02e5308ca4e56b34ce408770d53d2a312c4353967b5b3333f076c19a7b1f601172b90d27a33f09455355655d6aca258d1a5fda721c5cd0b6ff7ecfc4fe0e0ddef5c81ffc1070e16e6852677bd48dbc889fc96ea409ff66ccc3394b44b73e6a5b2a7de20dbe12e78bfea4bd76ee0d82b98013bfec8ab820e3584b232ddbfb05224152e2f61e7a61e630200181c4f4ee12b03553c6453a1e9689d65451ef8f44f68e3976ef4fbc3976865d02713d177a87ab26a748ddfb9a535e8fbee669fa7efe12a42f9c8270170bab7e85a3399c9b0be7f1498e617bb4f597e2843375c19faedf2bdfee78e7bc798ef6a0a37ea5bde4ccb3e7946069ff3262e035b8641686f9c877e438a0fa4999c8bc377317477f3b8eb4c7ec3c57aedffb864249385cd11a5918785168a36831c9496863c2b84739e56ce1f8dbb0d2f6dcb1eee2caeee74219f4030eed02d6e93bb5c3cfb9d4ced5965e737a7cc8399f62dde3de984cbfd4ea7fe6ff984518a4a6f78a57c3bfc4815fa50e023381f3d8c8bfa52f71032eeb37631ef74f97abf1b34d07a771aeca399629d53de6231383a6f0edfdfaeabd7d98e3ba29121b8fe6dcab99e8ee16254fc4041b0bd18573a63b52493a477991086fcd79fe27346484356e147bd84a6af7921129aa61c20b6e4ad7d3aa50810f2cf36618bafdbbbbe479fe3ee356d925626f1fe2d7b6fd020fdfebb8eaa24efdbb78ebe7ebbabfbb5fd6d4c5207bd602a757eae8b84db0b08995d8d84ad860a7801e2984fd90ca3aeeffee66803f66bc297c317c0a29c18be570edbba3282bd13a83b812ecefc6d78d1743b692146f02ea99c455cb45a9235ab6664ca73d29f25d328957047951627e56a77eb53e5fd7f6de6b47fed0cf791eefe0dbecd7101c74a976d7f7802e4ab409386a9420d6bd3985cc944fccccfa10341616c37e660cc350ebe9a2f6ee92cade28dbb3b3c84b946d3df0281bc475602c68fe27a81bcc0dfcc8cde96aee740d2f721417d2a2466ece914a30948e2878b2f8885bb994abdd644ba8e3931ef7d75821ff26b5ffd49cb652a02239ceefcbf8a738f44abc5bd30921fd6ca2dab4d7461869228bdc4a60b653851addf7de1c23f42819d621652be23e58c2f5f284fdea12a19ee6136426959e622097f348520a95c1849c2b07d29892a9afbd0de36497e9bc5115e1a282b7c2c87fc11bea5ff03986bb343cf088e6976b10ec2679c9d4f4daa35eec312e7bf5b93dd4baaf3c17299d76b4c0113520229c87d2581b41a15d6a0f11461ee460e8c8623aa04efe308f902b049fa7b6ea3092b6407c1dd6e54e397f7799d18da9660362fe1e90a859a75027d4d04b513e986ac2750cf48e68fcc8afc57345d84a2bbc4aa2e035e7d9194cd7b08d4fba75aff5285ef4713fe4d0e0010377e0fa8e5e71ea8507fbffb59f607a6d22fef1765dc492dce23e7935e6f14e19ee52a14ff93ad0fd404754cc1de5a7e11af8acdccc9db656dc0633e3574726380c591ea62297a4cc40e658f385183ea99ae7f77db0cd6a541001191eb702f7c88af9431f1401c466be8c2b35c900ae128d8384c65085c308d772e6f38b5a171fcf57ed3f1db43cdcd1f734ee6fd23724fb59ede95874db17adfbb7cf71bd2e22938499e49e012892b2dd0674ba4d0deb61eee231e35ecba95ccd27576177abcce0c659fe9bb3d8851b68fad6f8192f79b03bffc63f6111aed25685231565564cc968e1a228736c8b405e25856ffab68799dbdc2d8455c8d21b053a1b50819618782e079e24ce0308235c67615b10bb058bc9a8c135b3920ac7f368448863f5cac479cc864c42d206946f8968aed15979e12e4cc75fed4dfe149bfbef0d8e76e71b7a1c37f1893e8c7bb8bb615a61b03f0b33e11d6252ff073c190ba637aa447794ff05f3083b73a4d798e61503380a0bde2b8d7d255013ebd14020744fcaae0dcae192bb7c9215232c0b344bf86893d90acf99d590aa6904f3267125f3987a4e3291fb7726b84473ae89e75fdd43f8ef3d63b13dd49367c25bc702af66d1dee65fcadbd8b7cadb5c7a8ec319b9c4ab7ae067bf22bfe387d05526ba535a720cdada174d2bedb620ce83214dbc0e595e2f847f9d8d3538f8aeb6ea2997f1dff7f09b31f7fb5769f54f67f54739130260ae26048505eb7081566154ee42871bd4e976d8e920ad9ab134659b1441e7833667cc36933a00bcc8c718797666c86de8ac4d0ef7b64876526b6b11fd1d50e86fe82436426338b837bd7b565aabd4ee66f8026fc0b7f395f508a6d1efb7f5d22f63d903dfeee5fc64780bcda6c358fbbd7cc2531e7ff73a1db3ce8ca3dc5cf007d32fbb15366512320bd0d2da2d2215fba881d4d554b95e49dcbd7fc32b51b62341794240f3c06b524bb7794a5d1eca080f6805832422c847784477ed1fbf903d87642a594b43ea999479b7d213a8b29db5f723d7998340327ecb9ff4818bb892eb44a887b7b9af8fba036995ebfdfe3d62f5a71fea9adfe7e41d3ec506fb57273e53ab3e3e376c4eba4d9bd4e5408657f0407dc07a7eb5e7d88d7421dff2491ffcafb7cf71e280ba2e8712b0a127212681c1b7096ba482bffb807b4fc4fcbbc25c3e7197ed42db93d26d9604fe0658705ff5c8c80a7c1714d81065a71782977e842773913fc515fe13f7e586991e5e3000991e91ac6add454172d6eb24bd957da8743f13cf67fe1597fa451be1e5e9189649e4bddfdb67f17137884d0f36627f1f4a47ef8e1c136f9fe38441ba5277824f33ce3be9e42b22864652787fe472d8663df624f73744f0550c7e41ec6a1022cfe70509082f77599587caf4a6c2ee4852714118a7bedd3d2486bd5db86a4e5ce20a3180735759414f7a1cb63874f11fdadf4e8f24adcad7e7137e6bcd2ef63adafd477dacffb25e5dff72c62ab4ce76a0f37783c1b5f76f56e640dab6710f477650ea47c9b811d0b2cbea51b728b991ec862b7f376c30e09a6ad464b56eb8c9efc3c968aa7a5d64aebea70c01bf6a405c22930b144a27b7ef7b66faf02f505a99b8d44552b6411ce166feb166f1c3fbf7a0d7d5ca8af72fb67b3cd8bdcf295fc9a90d16d148cf843ce1722ef66d6f67c5f4bd6efbcf6da8f9fa9d7eb56f3f83e7b17ed0b76de97b8323ec4eb7334347693d1a2dec6080a977e7037b458bd1584d784897bf36b46aee15f44a5f4b27b4799bd5da5c383154354e52e72f60855c2751bec6e574a5cc87cddc0956a9408c01b4a2057242d17a3ee86edbb77dd8e3de259c79774663ef877eee71bc7fe7ebc03f72ac015c172f57b2226d6ae2c780fedd62b334ef8d6ee4330bfb4e83a88d425e41a9fe3fdebead3b51de7dfb03bd270948d778382a0151e210b2819c01f12d424046a9229ffebfdcb4d3693bb5f671fd0e9ef5a8634db893dcb9b7d725f63bdcdb70e9688fdafc77dae375507601777093558ad0ca8a09c34f58647d1a917081c82f6a6311576da584dd85ee48a7c514ce615edc2ba71347de218eca5609ebc58f883ec2113c9d2b7df8fbaef33fe60d79d5e3f38a7be103ae84373c121fd7a89d6bdbe9f4735bcae8f2771c13dfd70fffe0dafe703f9e62ba8b3b613a24421d75c42986f8f29a9e6cb7c13770aac7341a5564a282ccd188bba3713a1e8eb0f6c182e6e398e919d6e52e601e5b508cb8e3ad96d4abd8e4e75e1504c5b50c029d47440c7356201ee8d13ceb71c30ad667762331e040545b180234092933138af85770aa5fcfff731e37b5bbd6e7ba38fa3b77f17987175b7608e6b47cc2b7d6a0f1a929b9da2b944302f54019fa77d68f345fb5866ffc3066309ffa4c77bcdc0ea4ddfc2282174c48968af62936332be031900e36e780ac974e39a0826c333e02899b0f32d45849d4e065adeb05f258ca784f0eedbdea3a7e66867e92eee91e3b242eefe7c60b6fce7e5ed81fe1b9fdcccca68d23af58566833378e77decf5639bafd53176abff7374e790054240ebff44cbdad8dfd98e3e3dc577cc27bee4fbc9611dea786f5a74ef5f021e6ea1bfef57ff3c9bc8bb19c7b683eca6d6f5353e9acc27966b0b7b8741fd552b489804dfcd19c3ffefe7e2e709e5658a70e5aa50e7b5d67fc4e2e273ec18ae7f2fcdd0ff32aef7b7cf8211d3fd7f9c26d1cfd5b677e701e0fb1c05ad67c3b17f29adf028e36cc1d6a30eaac42851412a663585dfc96bfe631a7a79a6a70db7955bf43385a84656c2e04016189445a699edacae52097c45c1f12ad067c2245620f76d8011dadc826d6eb435a0e7bc2e24d0cca8e085267620f97250e13d7dff11a13c13d23d379a1dc7ca3908c85e69b24ba8223fd3e87b08edfd9c31fc64bef80ab92e767b91eff0fbe65fff81531683f129cca5f52ac4d56b55158aa8314f9efb86e70201a279bb01d2fdb209b70c0dd5114f21884653e15e5b69b036f109732544ebccb0c3df2358eb8c3f60b8173e240a190964bad5028bc31ebc9c3f7b1d4dfd4b47c942778c92f7f5ed39638a89f0bd42f8555cc45be4b8df6da99f8e04c7eeb4c9cf8a4cfb957bf4d9ce12e314f799f8f3ebf351f76f217058bf75c8fdca46a0759a146cb4813c62c2b818f8365b905cc958030d273d68c988b4c457f1a9cc9075f742b5c7223a4accfe0688dd963974035907dbe107609a98b2b56e264e1f278c1ac8d602409aae92e8d3eae6939cb586ee377bc3b1fd40cde25bf78e20aae52079d6ad45f8d7fc17dbc31ee1de94da8831da3689e6812c526d9678ef202a12a067eec95dd0ac51b9e54794da369878db6e32e6fa9d81b8190860fb8c78c4e73aa3aa1f9430a739b68320a11b1839e2ca83174e7b019708a91aa3accfe81af707a8ee3be10deee0b318c3be561fee65d7e91e79f797c0b1784d95d9119c34e85db8d74200a79339ef512a4265990b2ede6bdb2d3439bf82e03290cf6cbb2fd1596d6d6373a19f6d220a63215f5d64999f7b33e1e50c0935893df09e76821bc9a0234168e17cc813232edefc3f7f5ea57f260a7e7b6e2c8fb42efebdb9edeefeb83a5408774f5acc7cfe35fb8646fe558e802ed750925bf15556c0649478055660cfdf2d1286750ba19206ea8f9984572b3109c7360b94c975d00a44bdc46267617a50098a146480af894ba52c466bc138cb771ef99546783a0f40fd8e64f3cc237df8dd29db689a37be59cec83762e9a2fe8debbe0867c38f6796f93c35ce447ff62274d2f4fc3a37f71a9fdb8ad4674ed23cd52b0ee65a4bacc40896f580e4724c715f12908cccc448319e0b5b47d3003c3222cf42f45d58328c9964f46bd403808edfce01bd892c222191c7599f04468aba7b9317404950f492551087357d54dfb2efffeb9cfb08a23ac71111ccffa6b3c8a8f721c9bf42f1bf9f39aad0f64b8979157c8134e57a7b303dcc5d5fa2bbdbcf7d05f65b682ebe3bfa5279b13b499c30fb1c19f94a3b732f2dbd4f07eff63ed3f9a77eb7fa3d78331cf88351930a77315c87ffbbdf458197758e77e0a358a353730d768c97ef48b09df24dcdf87dcef1713bf9315a6dcb6628ea6e662c285b2a5230a2f4f5069fa3d7ef09dd65ad88d819dc008c560c34c7fa3e06d35601feffbafe7b14efef94b4d35eca580795a932636afdd53f7ea1338fbafcffd3899c1dbf8b46ef87caeff3dbf6fe5c263031d98d36e63c8d7187abf38f4e61860c32f54c85c522648af7974f401ed9d120cce8d66beac1a2da134844d3a4a3d8fdacc62d41b13636085ba992513542f26aac826ccc84cb6239522cc6c0a0efd41fc7e3dafdd5f2779640e3a64063f7c41b7ee4ff593ffbde6f5f49d7934cab31aeb6c75dc47a7fbecdd7ce6f4e7130e6fac818d0233711a438a7887598ec25e851c9292478de022df2edc664322b6a14e97133af244d49434e246acb19d44a341a0bd3d3506808bdc5ca0c6220ca3983eee178e167c92c781d13ca4bd1ca45c036ce386a2a6feb84f30b78e7a2411d772b6f7e2737919efe4232ca391ce2a5d7ecb361098c6a25d2f1d8f6706f254847ecb5a1a31e45055fb1da9f63d9e78335cf081049d2f224f2e11a659a1bb94ad778435f3d9714f9a1ec515f45284cab9619b49d8069212dbb761cd4c0f083df29715dbc4ecbd6df079be88c344049ff645ab883772fca6d7f9bff2b7bc8c7b355edc7fc81ffdcdb8e5f9597eb473f3347eeb9ff917be913bca7f334042d5cb5a940c8625aca58141687b45a2659ef43f0733d0225ee53414da5e96f2894f345d08a4a501f78b09a773c30b25f30477a68071e2c4dc5b642e992d440b85408bc4b156b4e4bf12c39bc7abe12b2c899f5f8805bfca155cc5fe8fff733cf8e338fcc9c7bcadbe46608b94649ed5a898435dc6503969a56789db787832dd04514367865a2803f26539a4a4c261009154a6a68a79e3a02e77a1d1c02552be580d9dd0e6535cc25d46d122891a4c81172d39295491ffc2f6300919bc1567f639d7d1c675d94a875771c4b7ff2b7cc917d90acf3af59c5508a6ee494ffd635e97f8d497719eec9601b8570e36e252ed70918f32617761cf77d29d02ec681d9a6a73dbfda8dbcc191ed41856c7674eaef7dbdc05633a11709f9a1e980b79bc5bd7e7bdf9e6337ac62cbded5e945a70bd66c2de90092241d93ea4b55c73960fe222afe228df66b5e2699df79291515ca23d9e3093d091496dab497b6f45219ea755238993e364d5ca84a10e17689095d04d10da2c848e79b585a46e6ac6eed61bf25273948a61a944a73f8f7d3fdf9dac95b5b74bc3bff9e33fb5515fe4dce5cbaf6009dde5de7ed967db386aacbfd7fb348f5b399cba39f3a2940d03ce732fa97e7433c34aa8dd8d05274fb2565ba5471b7aa3fe48237e38fe9738e8fa5918bfcbf17ef72cc0ac3afe97e79971e2257f330f70f2b3bede9b69b789913738c287c418ee924a0f98831936ec83cff3d59241cec37677a39e7892172c98afc485ef8081f6aacef16837ff19ff52cbfce5bbcb0f218d0bf49b0a5231d611051a232cf99cb03cc2958a788f56b2dade25069f1a56f1ca0efb2897676615da6797f95dc1a0fbbb86f3f3de8bb735a0dfdc8bd65a4647f9f9e77df832fe0563eeb6d8cf666e4a37e68f600ef536a6385ad61a07a6648c0d6321b817bab2a3a005698dc6d2e50fdccef7cb7a4444dd8c32a39d5391277eb9dd10618d138ef1226a5c660c3d52719ca17cbe746c2091d6a2d42413dc3cc57edee3405eeae3aec4890f83c11df4dc53129ef76b72ea95f29f16b7c96cc657434b0925fc9a3ff09e37947b34e1cd68c9086022d8a4750eb8b07e4bd601df4105ad88b9a0f92604dd41d53ce4b51e2f262390410f51c0cc65245d5ea93c75f2046b6f216cdc12966f386bc7a1995fe3f27d7f7f44a35c3ae430afaefad2873be5889acc39617d3d25f5795fbe7a7f8943dd16b7603d03e144b7a158efb3ca1bb0525b5949308938247c3ac06557a68ee2b2d70e3378b2700864626a0490bb7ea5c3acb47b5c42c9351a337374e076bc13151f29535a8cf296d80ad25a7acc06fba0d45bff1f7dcec929c7e5d5eac2ebfd25dd7a0f791e609e550aa6e2a5cfeaed67977c46705b5f0f1aad7de4b56a922f088d6106ac07556b9e72558714816581dbd0b44dec746e40472d9de4bee04d9102fd1082e103711e8dd0810721402f27f620e9e37d5ae63a2bfd4140f53ca5f946446c80cda662403ed19bfb7a747fee5b42876508f7cf38faff83bcc651bec7739f6775d99eebe54f7ae2dd7cbe97e76830e19e94916f6436b1a4ab2131749919cca4269e2e5db20aa98a78c53911c30709a73bd9ab839c8c065ce856306bab7413927038f74b580b4d7e73b334fd827bb2e25bea7011038e1754b569444202efc625fd221319e5400aeba493b337187d9fdab3c73364a0ed9f3a932b7a7e758fde81e3bae13c75ba973ed937f3b8e0aedfd63b201d0b6711deab823f718afdd4e066d87b8bb9599a21e8c0d22579624aa6049a6490594433e88f878438b08ccb7cb10c7f80396820ab090e5d14723a3da43dee66301b2cb826694508117cc26b359ff5b8cb6ec60e383d77f33fd3fb07585ceed3d3b897bafe1bcf86ae421d9859d5ee199bee55342a33834ca9ada2ac96eba06caad8900fb4b47205b54d4b6d319ecf96c5c8e39576659141dae728d0a3393388a17aef4056ad4f00eec58438a2c8416c4efbb8b02deae024a3e45e67a3484278b483777f61ab7f8e2d739459194744cfc5709554bcf85afc63fadf6dc7c86fa583800ce12eae1a1d9bc1f3bdf2663e97b8c76d3de49c199dcd27ec805db563f4e72016c384d4cdda3f0c135ce1f582973bc2554c584ee600e5ac1cec99d1ce334a805f36a6afa707bff72d85709c460af26a2831e8fcd4f6267139f452f7f190463a98833d5c56dbfdad5c3ca7e73feab0af7012aceed3a3fbf798cfe7840f9473ee6dba8cf3759f3a429e0298fb82870bdb37b923a7b1c8a18c501cf779bd5cb538bcd1a7ce0eb052a2db2a4397ca796c636358ca10ee53435fe77e798fdbf97d39d57c9bbaaa912e59cf2f785299336cd2fa659f7e324f70397b5ff7c1d35ee110e668819a8d60309211ea30fbb1c17d0c16d4378566837fd9845fd943f7e286fd33def3fe39ef9def70c36296ed95dd8240132714f057c6c813b5a787c4ce8ca0fe79c8049e13264b257e00851ab86090cdc1a3413532e6865a276ed9fbce0f88235ec5420ec2d5d097f6a3b9609d9ff5de5cd6ded362c219b55b2ba06accc53d7bdf5ececd5f181d9fd7911eff4e3f652639da025a5e7a0562d16daf723d9c78f4eea3771371e2e0d8a60e2fcfebe71de7633ddb25fffcf733fecee1b618ab4a16ee6397d4be190a7b9f18bc60e3e124b4c1ce07689c00d49e78d0a00a94461b5c73e803b95d86439cf401c85c4d95e848e65853d2070605f07768ab3888461ead2c81115a0b8a29372c14801f8765c1efc55bf2a66ff0b58df9ae7ef9a80fcef6f8717d0d5dbeaad1be8a117894795af13a8e48a32ad62e2b7e48bf14c3b98fae7b3ff6f3d9b6b434104822a9e751a3b3eac7adfe7337179da066eec565602863b8ce26de1e431e49a6b1447c819ddc25b7df114f9903fe4775912739ecd317bbf2f81a80dbf4fbd12601162ef9241472bd8872406cb265aede523d8a13b7f99d997a13ba18877add2d6c443307454b8daca09e02c13d1643f99b47f2216679be646444b87f4821dbf9a0dda74eb30e11ffad100e69a56d65947b528c9aefd82469cddbb83ae3ab7f62b39b77b4d99f94802b194d9fefd5e7f72d3edc1eabc113344984dcc85eea0522568af05eba84650ef779093ba5f19870f9c05d024257225606269ed89bccb192858d16aaf8b9f72704b3720f7c88e6cc26dbb0d70531e5229bc885d02ae1ccdbc6a58a45940fd22bf8b01fdf01c35572dde6bbdff97eaed57a7efd1dbf489043c688eb1b78159bcd6069f319ab86bf84837f253529b3099acd8dceca26a8a5d560bf74d043aabd7e316e5bc5bcb584a8c82a6b9599a3dd72c2632ce42fd58fa669099fe24adacb5a3e11069172914d5883d2fee6be818f75f0e7f9c9bbf932cf9806698d1be9b0e7bdfc663edfe115053b5f7397215ca711e994f1a34b4c3258d8961d3a0d64ae4ab801a789fd63238df55e16654f44bba6f614b24a450bee25329291e07a1b8a96e2bad1ccf10d4ebd28b38725e3da5320d70bae27d82611619ef88ede38ea4f197d090b0bde452747479dc207cffbfa32fe250ec96ed219aaeae6bcb74d06ac0e4fc84e99310c380a7d803bdff108b3f96a316e37a4c03c84eb83ac7442cb61a4dc0608c660424793658993a52d6d057ec0858b46142ab074c89869f96b0e63c8847ef223f53b309123eed5237eaab7bea1c6f4282753b77135bcc6e378e985b98b7ebfd4c1ef9fcfc4f3fbcb5addc6db484dd524559e338deb2c92eb34fcb1171519c5305f883ab052a4cb10c87d0c3d9b4f38a78843c1f3208581b9a084d37258f2b0ad331418ac6e76d898025e78532ef6bbd4fc691013c9c5a404016f4c55e82abeeb5afde909f82b5f7f25af971de0a96f5f3ae89055e86a9ff81defe6bfc67d3e6b276c4241f2acf6f2657889cfdce0eb62963f850c3b4925eda0c6a16f907d8650903a0ac9bac99939ba35dfdccf239d67d5a07dc68bf81256e97d6474ee3778f6939ee3f46fe673f19d6e8c45cadfcce0abb9d14d53d1ee96221864b50e78a9e7aa1c4ed282d8be687734427266ca6e299adf5cc8c237732b3449801d22a999633c21bda8bda78c23bad4b8cc7a3c58b2e18173e273dbb72892135e293fadd4ed77aef13fde93c6ebbd88bfbd0715e50b89b0234d0c1307e1a01a2e421d1bbc6c036960cadd1cddba076574159ffb7eb16e830fe4c527398e7bab4de787c060ae7c90b635e0d5749770ae139b1419908542fa61e1fa9bc4b66fb3036abf55ce702385f5851ed9bbc8e1f75147a546abd373aef7f5fb6ff5adb18accb890db18b03e86fc213434ce38aa3380a13f910e7399c505f1c2f2c73eaeb88cf5681dda0390f432cf1c35538eae6263385128b0e20a0fa83992414df664e26d02000c66780fb2279338e23d3f0c83f0e61af5e6a45bd21336fd35ceb1e01ef849bf4f3a4ec0ede9ccd5a77eab363d71e4dbe0665c5fa3c5e144fd12289f61a80fb4d0bf92dedf31981fd29a81843f5a4b36dcccfa294c6b146347b7acf79e32971b1c693b153f768cf124359129aa56c64cdb498f7ff35a8e2924bf42c66b22f29cda432b2d3dbab85bcc0f1da479aecfff0bbff7f016db83f799eb35a9b05fe3625de92f3f7383c535afe475dfbbbfdbd9314eb89c50565267a778eedff3b8f021dea05360b49c3c4219c9814fd193a4a541ddf580386d958cdb9ca1a60babec469d72e2e7ea6323d7a9b05be57af9591ed772b7273ce63bf4425d78db0cbc9602e6f3881ce2e8e4479ef3b8ff9e5feb8f07379f8fa5e3ad02f008a58d25a79c2decae20225f2bf16886f67ab0b0f358f1accf22ecf9b0dc2fcb6142cab612259fc6e6284a58cee7a0192cabade1177a9cd5388f57c3960a3d6511691691c26cbc1de0090f99c37a5efda3d6e4f25cea15c6c20b6763a41ae5e43b150567feb4ea0b5cc5f7aa9bbe795e7ff6f5c79cc5d04c22b24e4d7ee1e8b34e5c6137f6e7767361ad2445dbb04280b9cdc3accfcd6c829ca01f81c454076137db1be39c1b1969e3ba2eb84bbdc969acd37e36b8a556a0bf9dc719584bd1cee67d603030d82d581bd070d82702af97da36a929e32553b660adcb1d64a7768b09c0a3d4c90e9c6d0721f42cec342bdf0906471b64d68f989a8ca410164b5c7b20265e282a35917d06981e0da48145f075ece4cffbf8ce7b6aa584ac9e715cceb1a1cf6b4952070179e2357dbdd7af6251de2126dde5cae1bd1ac397df3faedd07f3b96052de66032983b39939dd27906c984665601019000b24009a1ce684db1065a69a67a51c270600b1d1120aa0489cbc4b6c8d438a389f786b2ad61b5fe84602bd96102729e53577e081e97c4caba1cb85ca392abbe595baac1b306bf3d86873693cf33abef04af6d7d7921be9b598ec599fff671d761eeba8973aadaac1b7ee8999e131bfe6536c33486d85b0f1b84b0bac5585e9dcc424b59b3830475e3691564af35f1caca1e4b131eb6393b8b84bc7433f16886113cd821201bff61e6435cce73d2741a9c6899bdb49f4d8491b02bf6ac9353bf586353a48d141e9b0f68cc7f0d243fd0e4fed146708619138bc48ce71aeff7796d5b5b5d475e29ef9afce73b960287e9e1fbfd3da7e34f669ad3fe2466df137d69e9464c1caf89072fd5b39b9c7b44218fc18c8f130c6003d10f711a42621a1b3077388e2b8663d0b870eabd59854b88e576d9202927311c0d0550b4c31643cf703a14ddccb5d06061b5ed97b5af29cc2ccc8f48ddc18a2312e36b2312fec8f38d98bd4186e12c13ee5ceb899d3f6c48ff0fa8eff836be51fdee1a53d9e385d4f9c7cc35d6268fda7fff625d70baee56e536758c6d1556e9ce3ef98f3627a077bb4dbc9539fc7694f5d5e8397dfbf2d371f1f124090a4cc4c1d5e70976f63463cc52cc6dcb267750924e8dcb09089cf7ef4aa645d627ab540cd22ab319981cee1b69af23a17498563e6fa1d06dd3ad68d20062f03d6180b94277e448ca4e08ed2f8d61ebd6d6a903c331e9f62a3dba5152fa5e0fbebb266f7b0893e1cfb7ccf9ed77c5ee16d6a585a3a5c67a73560b7c5419df5606e58680647869cc869a8f153507a8304e5bb5078db65f963705b6ce0793f58c77f7f8a0d04bed0370aee91037b91497db4bdace254c3f75a56af3fa7c1f1bc7fb98ee4e857269a2f52d02156fe0074d51ee72224c4d60caa455cdb4094b7e5ac5267b8cb1c4fa7d5d5b37b2ffc946d6a0cf771755c9753dfd6ebf797fadf5bea2a484d7a1cf802cf649907bedd7441c50ddf50b91ab7fbb08c776fb95b3ebf974ff5d4e5f4350ff8e779898f3101ff073e60ea0c4d1979451c613d17ad5e46fe599eefe6736bcfeca976d4f5cbee372e10103679e2a574a8510eb86ecaecd0d214a2df0aa1896f903a35dab9b489eb5790a51481e584b4988e169ce5630a1b1ad48a30965b4b3a123ef546bedd30d293263664c2d8e36689465632c9aff931eff7aeebc12ff2411a778a156db39a3de3849c64fdeafd85c7f7361f23ac7e18d25eefb18d5b663470595966a831f5cd11975cb5723c9cfa8eacb8d36d04ca6b059b6666f0cee77c9246882880d73383fb19d4bf04c3a6a0a5e58bf2402ab4c6ce6317941c07e623c8385913c3eb13769b0db314689b3afa057bfb2bbdb2a9401b19c23289aef160f877f203619e18ec549f76d2b57fc6bf7011deb626b2c78ee43f0fbedd2d94918fa833dde1123fe09294d88e0f69a51e241dfd5e160ac475732013cf0c78bc497bed48664d2525073a6eadb0f75a3919cde6866c98117799617701236be1a20687ed8ed7ea170d879adc8dab04ebf4e8f3fef1f7deaed58d9816af7eefef7df1c15ac61fe1327ff79cf5521c7dfa532dd4f3ebf6e2bfde8e6d21a6fd829371cc09953a3696cc3bc4d1882f267a8f859c4bd122bf023b5aab27e20c0b0ae54171e4b0dedea98a63699007c547455a0eb1df138c4b6c2e513648cac75deae628a6fc1054435b726e2acaa7217ad7cbf06f7d36fe791517fdb29f75567bbb776bf1fe6ee9ef817ff1f798471bfb72c622ef909ad3f632ce6d1c047dce13a75b48aa0c66b7bb94a375d0a38e547c4bc57093ad8634eef148026b95193ffab4c840ca651050ee73d49809985ab4ea6259909839a8a56e3e23345ffb8e5ae31e1f282dc1d29526d3c12180d24beb5b6bd2609e56a8965fee71bbcb9dd2c6c23ac56afef4b7fd3d8f6fe4342d1ab688176a935205b18b6a0ce403671ee1919cc6b5b71595ff51cfef2bacf5cfeb97ee9353803aab94f6cffbebf2fa68ab0437da2a60905125885038d419088b1cc48614cc2d07b2ff69d10a13059b32ae954322b496e1301255bb0ba3e677bafad1735bd9ca24bf02a881b0d520a0f8d7c225c1b21e15cb124f88a38c19fc7960136ef993511296c35fb7d686a58283c419965fb00dbbbbf8212fe39d65ab9c7c27cffda9b770f374732e692ab65daa1b4ee84f3336732a2a285260adc884f0381cfec2b77123b689c087d4f8c3a1742d3f7e87deddbfc63cdb08bac8aa611b47a438c70d6eeed3dfb30a3ea8c330e6029bc2567b32d179487537ef473135954f6b5d27256761915bbe8376beabca2c1a1db2bab1634a645ae77e6cae4da95128eae94055c3f502c59defb46e62a3715c5a4588e406476a2aa1ba1b8f775c7b796cf0fe357fd53b6e867ad49c385b4ff27989031dded4d6dd684fbcf9cdab36c5f4c95fbde39bffee1ed827021fef3570f13b5fbf6f2fcff60ddcac764f58f75bd6aa0800e171a1032974cd5dff90326fb6d439676e3352fce72185a322a0e560c172bd401e90f4e746703e4aeaac0bb5d4d2266bc5c99c39ed34d1582e4bb8f00d6b1ff47aab8ef63bd42834c8dbd8d17fb42d747bb53ef84e1c0be7b14efae8c4ed7bf9dddbf2c29391488bbccfec72a34c3ef3d90f83f5aa4e2b2f67221b30375f63db5a84ced40c21f6680511076dc36c0658d9feca9cce4844f33403d626e5ba4db957b3493c48856ffacefa4084a7b92dc3ccf47a652022afd44d7c60439c9e4d3a5fb843276f71e0beabdba09e0bb2bae8b5f6e8fbc4e77bf4632cb84fe43b07d62fee483fab711068a9c38992ca968134b1e0a6d48aed3718e1df89d68398dbddd225d8672d26d5da0c1d32486d6fbb74b845cbee2171f58cd78f6656908328d52ce0eb1daeba4d0870a3102ee6c06a33e7e3bcfbe5394e75975fe3d09d9a77b0475e734e1f75c459b611b13287f7178c8103be0d1b7f168abc4b4b9c67a0b4962cd83013b7898960687b038e3052bc29197f8441cd49aafd03af7c33733961dcde2c5cddb0091f09ca2137f2bd746320d81ef012c0b8974deae846701548b0dea56543a8fbd37c874df2797fd7cbfe79b32f3f8b797dcc6bf1bf887909dd26e254e7de67cef02933d8f33abd99cfb7625ebf31e38572ac4d3851792aa4989b360c1dd5a606dafa223b30963ba1f60e311b82347adc87f5c8cb443b486c6f1d86c36da8f1d61716ce900db0c8451c79262d39a3c6302242b76945128cd0dc47de74e9f2c1ad9cdb6ff927afd547ddc776b29a57f7e6ebf7edb93ee046bc13d64cb946287175c7ec8e734781059b0e7c388a1595916f7a036c434395b9c12037b833dc497364a640d914723233b59de9e93e44de4e8d5b8b025c06e087a928598b09de7343025cb551507a45261ef7fc7dcceb9bb56fde8977642ef82073d0d31f593fe3876657e262a7b56bde73ce7d88b77187fe10d8a4956e8fff76b91b9ec7bfc4d96feb0f2125b0d2d2e222f2c2a04488a286f0091e48de106cc896b2e158f6f28903ab0dcb96c586eac38ae7d4c5808d879c0222325bf559c17f25285f2728af71156fb288cc162e6fc4aa0d78946f085285043aa6ee3fee86abbc28d33bf53cc213fe731add8c9774f49bea24e20759ab91aaa099d9a85c08d9121083a4e236aff603d9dfe4373dc511815985b6f3a3dd1a8df2f7fc641ffae9779083952b971f62b16f8ff6fb89fbf564c77df4f9c57fbf21ffc7cca931ef1590884f97917acaf4a8cf5cb952da8b438a56191a15b7d960d64e3abcbd5e8734bd531fd6cb7847fdf8941a44a762f87489dbc0dbf854e35d5223206a3993ce76bfa0de9e5796ed97c80b27b6159ef8af5112b0f697d0d29a9b9af911d77422f314c69b307a34638ab65c3754a1fc41957ced3b32c06e83f004d904a96d02e52e749a106bb54dcde65e7caa45e20c378920f94bddc061f051cd43298507e5e1f577e2777de4ffc4a4fd946bebe55e7acd69f58eef2b73f199dfbdf6741a95aff9caccf7bc82bc55975ae4a91ec0f989bbfbadaf8c61e68e76594dfad3d97486afbeff36077fe234dd29f19a3ffa6dede2094ffae9f8dc9981aa971efad53bdecbe373c3cc21b972589b56439008d9fce160bbe0e37f9f07f1cf5a5df5d5fde39d65dcc957bf8c7bd43144c735af4f35d8ab8ff02bafda74ad14fb4d52c5665a7b80883d64cea063d123c07533623a9f1377348e6bf920a3a69754ed31e8ba9059ad74865ed2e781e03f2133358da31ca55c1b5893c4b71b8bb076e48bbc0f802e7149bcc4511e7749f4cea6fbdce6f8c2d97a7def7d84b1f1b79dfee6bebce8c43fbc461ffefe873dc16feb84eecfa9e4ffabb7fd133de9871048e4711f6057d45e136ad5cad27265d5edc2c9a399220955f1f3361ecaf00dcffb47f6dfbf70ee3ed88fdff26d2e3ee71937d4fea83ffaaa8d9601b561eee386570d560e1ce112c67ea17601254e504a446d39117a0d584fe24c7097c27ca28a78a050b049aa69afaaed8ed53a0fa10a7c3462a1a923e5409f01b08f576d2e11672492abac47011168eabfcbb1fcdb96f9705fde9463644ff8f0ae3ef2be39c670607e588778edde8e70ae04b2e56a18888a08697a3eb72d19220f6428cf7da1c384b5452cf82a612df1993793ee88a4484dfdaa9ba88a0f982031a6bc4ff5c859b2adc9a266af04e9e2127bbe8b6252c95f7184a7d2d50b62ab9bb997dfd6fca96874c292ce0eb0488dee7d6ef15f6bf09e1bf8db6bf07e0e3fdab9f9fe3e9dd3f3b8dfd0ff24d1f2b732481c4601f027390e851e650cc7d819f2d0c435a71eca187297b57f60ee6893529233ae57490536a2e4111138c20857a4b4585610489995a4c2decba804b2e05b09ba4302a6fb983fee1983bbaf70e07e47ffffcd85f71167e787f7c067719ca7d41c7d099bdaa77788ff56c3fdb906d8da656ef0dc5b724b5fd54a4e466ba5f16e8950ac382ed2028bc4914d4a1f7bc14a63d607f7c99108eff88cc6c58ffadcafaf868754a06d1235a7da59e55cc37ff0efe49f1ee50af3d4d10f2fb9e2a3bffa7e3effbe673fc390a97892f5dccf7a1c291b3719c8a36ca2a95f2abea4799989764f8c12045ad26581dd38420da1522f6bbef227acf34b4e97358979a47850c8092ef53cd66823a817a4d57497b20070a8774989436560f3765cdabf9e1f66d5b55ed0e0a843ee90b77e37eed9ef33bd36165db3ac58ab226f7baaef0c07b7d52253cd45891d56e644dad6416ab227463698f5c8a3a5ae17148f71dd20df4131e5d249ccace3409aaafc0198d125cb48715c215ff6fc972c46a36c3c0ca48157cccc00b5ad812a61246ca89550266538f66df4b9fff75e673ce354b67184fb44a86b1c87e03df7fbb7ee8a77e39ef6bae1fd960283b9407d66e83a5d81cb785f8f3f841cb5ca7d8442ebf5623c1c09bb3338477d566a039bfe21000a7f18877a195b3f65e6e838b7ebf198b73552dfda7fcf98a0279c9dfd690e7fc9e2653e471d6bdecc4f46d59eb0bc4c266810023d9290580c7257820e2fc7c3810224c98c76e1735ee28ad782eb850f78c974064409035a729b73e2cc8cdc5c52cfe7ccdf04d57ec34ced0b1b2dd25a3dcc8dc64ac6c34e4564cea35b736c7f9eff6bf514fe7fbfbbfec8b67f23ebfec4ad70331719d1cb08f9aa94d1b2ec3619e5e385689b852d0507b6e54f3c4ef8f4908976900a32c28ee5cb556b26e5d00fb8aa976e33e1b0590466be27ae6dd148a2850ddb04a945b66abd859bf54139000b2e077e2f25d6f9bdf0004b29649356accd5c6f9739fca01cad5fe1efbc95f7f16f747680795c639055a87815c7e916e3c17e2e2cbd74836b75d62fe7ff8b35d677c18afdb3ce2ff5d56fe601badbf4cdc9265d28861083fc1767f090da3aa6869c866663e3cadb3397f50a69e09bb9919456c94a4d66406a3e196d693505619f47acc8f68181eca593435a29c87a2f2687d64daad6a291fab5acf102f366a36cddca2af76faead7e7eeeea59af5eed9fb8afbc5fc63dda8bcfe7ddca331337d2185c78176feb17e33ad8c566de2e27dc8ac570cac09031531f0253d721234e6cfcd8b01a37b12e0fb404fb989250da5c8bf007080dd5c9a831494de67ea40f3e6406367399b868c68c6ec40c70c8ec764d917c60cefa90ba53105fc109ff7ade896859e9a7a38d9755c3bd8c3cf01caf3be32fd86f30aacef80b7381564719c7028357df1dcc8b9f6d5af181faa0d7ec3d4ff42536fab6deefaffbef74365ec751afe0bf0e9f8e675e8de1f678bf49712d4e7ffacd3be0cfbf1bf7749ed3157c9251d09eeadc1dfe74d1e737e2bb965d883cb9a4793f87de36069e4110374398d354b4bf880dcbe584cc99c93d5575bbc0b08860eb0375c83828fd2e8eb0c4760e6495c7ca603de76a93965d9e00c444499ee2ba59ab89e72575d6538a50c6e43fb825874ff1554c887be5854e639d6558617d941bbe112783b838cf2638e220e719f47e6520b6d2524e7091411fe6f982b1bbf873caf4f2cc1d595ff2e7cc1138ca2a8ec8f57aebf1c0ba8bdefb6bcc93cedb2b47efd20a8153bdf5799cdbfcb79e84292a2129f153e2da20d1de806b1e8480e4ac56075e5a318d504f4cdcf05e8ec23a03c2de0e12078294da7b05fcfd321a2541d99998692f9b3c42aa1b9c1565373351e973cf50255f28233393aa09c9957aeb9bf45df4b34d5e74cacf937df5615fec186e6524755ae3b5727893ae5ee74adee5958edf7dfad33bfb1617e83ff7652f9ffbb2dff257a5a657ce237588a39faf7fb3bfa2278fe7769b1aa89c47a3436a121d9be40bf80a1fccf77be7fb5fe39fcefcd1cf4b9d612ec7a77b091cef821306033d8f7f1bae2af2a8a13a0cf33a75c82628f7566cfe8449d58ee606ac68896022b67baa1b8357689cbaa35982309b195267aedd2ba847a91812568f6649255d5c228923657267e8a69007592f354323535672ed47364857ed3bbff70aee1154ceb08885f5f47cf6a322785f07ff414fe5f9de9d5eaba9da9fb8512aacbfccc9728fde29f3c47bfd141b7c1b0b6f7bcaebbffbec62e3de561fdde31ec74b7b9860b7d9ab09d2123552d48d91b8c889a9844aa3c28fa4c985bd0ffbd158bac413952294a15952682faef82a1cb7b3c4507351f956326ec7fee4a8bf729f42b2c50efa4d7a344e9975e0bad9decac99539a8488c539fc50903ea7a0fe15dfaa9f7b1c09b58287dc6d9399da5b79fb5783580b7faed498f57d20187b49842e5b4d6d2c1bf19681f82820f164e5bf13adf5241eaccf082ac18b9096c0a05f29ebaa3554c6511544d179841171a5d1118f99c447210dabae0f6b4235a6215a95d229ac42fe440468f90de0d1354ed9e7dc2c5fb5ae3b39c5fee4d98ab88ace711d925067ffaab4ff7031c84973588f8217dee610c3fca6d7acf39a0cbd98e8f3aecbfe4ce5ffdded53ca2f11e87f3fbb6c473cdc2fc00febca6f13f7037af9ee395df6b16548831430a5ceb7156a13da78f5636e15568f00da15e3b07969996641783a1c86a4e88f6bbb9293515aa5cd63c880deb17a53ea0544e9499470ba799ce8d6e40840db3d2db118773653218da39fb4afee4afdced67bcd1f5284f8c1f5fc163eeee10a3dcc7a2dd9de4eea04dfadc774d6fb4db9cdc0f8a3c5852f2202aac71e483a5082ce136bbcc4526afe3dd92a94582e22ea8f603aa491b987687fbb80f1d3ef7572d525032b56ab792294d27764f1c6bedd7aa8a6bb4535006c2c61eed470fd825b9883eaeb33bd573090bcc05dc49976fff5735beefc73dde49a33cabf8931ac3363508bc7085ddccb542a07d205c85194262311eee6600990ba43be5c844e85145b51709ad3771a54b42f50647de3e1d0fd7418f0d65e7d3a0926e4a3d4f56a59171256606de115b6d32cde7a2440342b19f9a014c0cdcb3aa5bcf8c7bd9c427deb43e89c89f58db17b0b99ef1d82ff1b75deaf2ab5818775cc70fc63eafa5721edb13f79bf08ebf0bd5edebd9cd59bc571ce7a16d09aa7f6e160eef7134b5b83bcad32a07317cecde623f5cc96d5c70ea5b7d15c7ef709f78d745461b1995673be065fc0bf6dc6d71c55d52414d8b5127c7ade53b4dbf2c3948610916ee74cf1cde61414ccaf82614dd849acc6094577882b6b26a7b0573189a4466555ea790eca96359a1c0d3944e011779b71c6f217751eb97fa8999ca4fece3dfdf6c731d9f771f47de177b06fe7b2ff3df63fed97f473d73c2a73c8f73a31ec12d85c181086f9a957a1154b1c5e0d40c0041d455dbb0c84784591b1fa2270c864d02b6202da50c22d65393687fd5ce04b384aada7dc03849a9bfe376b720ac71c878381065f37b59eb81ecf13cd0ead7f2d65ee6fafc8c671ff52b9c58ff3dbf7f91f3a967e77207fe794f836f706d283b34a68398379838dc9e9b24e1a66fb149bcc9e868b660d04c0cb2c5758e7991b3a4b25c36c15da8e5cc9fc895b4619d18de38b53bbeb07529cb611f46d85916de98f7e840b5643ecc212df976e1364110c95b71bf5ff7105eaf35be0787a6f9ba87f2b4975fbd0727eecc1b39023bdf06bb85e049e8366d568c464a74f1928f4c5ac924a9892956c330d0cd362e077dd8e309893c91555be8a3e010702c43aac64bc1f624923a0152fa40073eb3805f92a9a2a3830c5be1eb661a46239c983cbab5773a73f4d3351e28bc3ada6f6f6244df946f5afdb8f4875abb93dd4ced27ffb69eaf32d323908976c38c78af841cf895caa5b07bee7a16a9f43874c82214240e8d18527bb04f10c18b8947855d8225929eaad84181cea45566f915eb280f8c94e2df01c7bea252d05e69024b6366c09618dcbab1e7ab8a4ff8989e96ceab7cdc87359fcfdfc5b9acfec6999dbee2d77c8fff2cb771447ae54effca21bcab95ac4ff23efe6e398fb0ce2a7daeab88bcfef3fa680413813773214fb5186a0c615af13e36d0fe59675d30a7dfc50d8fbe7e22fc36ae86bb347c5d533ebd624b1df721ec9513b499c10fc9a5c626abaff5a3f8675ff23e7bf343599df5ed3fe7d79eebec6f8b279008c5d81d99048d0e6a82b162c351c0f99872b6e7ce162670ba13024f28e515d523b4acd484f6de4358f0a9d48f7b55794d38d1d3b86cead4b12cc9514f8bd208cde62916cca05cd978a2f6a29cc238922cfb070673e67a3a75792943b8fd42def77017bbecaf314f7af6755cf8d23f759befa1aab638ca92e966e7739450c77bc2dcf3091cede56118a54c135cf02e852a4a1cec8646bc8b0bae33a7db24063a88c9a85d44eb41e68e267114805474bf32ce7b6e8e2c5a7329c18f9e6bcfcab49e32b389f1adbdcbf5e870eee10fda938cfe473ca34759670e7f926378f2b14f7bf9ed67dfe17580f65e1532ce44334e8bd194ae863c10a40caa1f0309d787b0f26fbb875c4f2b9734ef633a1fdcf5f7a8f339eeb98880445c62397fc66ffd7f61217d161f8439a03de97dbb7b980312cd819e2d382ab9918f6491ed6805030e519c0079989bd31d37dad037a51586dbbd2af23ce5c45e3a3a671cfbcbda1fd0d2db2e235251a4e279af20e31c873c3370af2c6ab75bec7e67ff5d9e5774a775cd56702d45b77fbe0ffe07dc2afbace2e054d3b282dbd31d1f4ddbc4e1dbcce187175df0c93c4ff98f5b6d5da65661ef156ca29fb20a5106b9b360838370155726aa965537225587a9d6321db734b1d98eafdae9c2b12dc5aceddc18f28c4d3bd57b884e1808abc73d353a8b695c2e905771a867be81775cfb8023ef179b78f7e2db3edb078234b28a5fd7001c3ecd6d5dd67a19c2d5f239a6f1997d77270c8acb19b2e6c2b394c3fb57e7eacf67943d9db0d36e5a3fe9a8fe67bfe0a4cd4aaf23e576900a7b87c1d0f74d6c2f5743b18c48a9ece6e04f02308788873599faae9a2f44b75a88c6cfa80661adbd25e2a6426816ba2acf0a6f9c45a409286902a8a8327e5861d96d96e53ff2fff5e8901a5867a67faef17074911c609e55eadaf939bcc781f9eef9191632c2fdb9ae8b34b1b16de3c8ab9fcfcebfe677d1f137d6cbe29de2fc5786d05a39ea1097c3dca76a860f2d5cda4396d99a09ae72027f9a7380d6299cf633606fe63dd28b086fb2bad1a9ad9ab941e265c9e53292aba5cb5784c5063706876534ea6348e6096b67a4944fbe40b762f71ee5519ff00abec465fbdf6b1533d7db49d33bcaf8e4c7fc19ffc2c77d932f034ce6e8a9b2bb6d3ae1be74ac79c8a0e9d39ffb30dc0e967613b382d7bcf788824a26303012d618311dad84a38128db7c0e739c69bc920eac7d737a108e9527823c2c3882a908f65c8f721a79496ac7162f747faa557b8f4db63f3eab14ec29ab78fb059e8d6e5e3cde41967ff58a9ee5f9d73cceb9d1c56d1c1126062451664ed2289fa735eb633e8578e2f1197c1c905aef69ddac64b9de043d8f19231bdfe451a2d5202de20e5394870cbacac923c1bd98bb88f98cc11434863cb4dba442b95f0e6749d80a59cb0985f6e0e6dca8cbdbabf6df7b7ff19b323e8e75d20d308d7e7eab5781ba2a5986edde87d8c97a141c75eddc68646c06409923034ff434e17a9289c062555760de08e96cf77cb51d88a83170d5849879dba4c78c5530a01354a9496c71370f7c5b6351aad90caa806876084ab956f7c2ecac4e36ee4eaee05197ea5880d777e8bbfabcd4b00af9c767edafe1b2672e7f5a9e79fbafdbacf7e88d38ae61ad8bd438e35ebf1abf3de3f4dce63309e4f5ac6a4ab96a7f6301b733b3dce152cd43344ae2da73e67dbef7b5ae633a9a31979419279ea05e2c29df2576139089ee63466661d905aafe69cd8045837a74e0b5d4aa22b1a8f52aadd687d88c0714f0d23ff7a07c24c77d7c4de7bce744ffee79d8c7e73835cc1cfb823d719bdc129bcfc2c9a85fa0514c51b98b0d122793d850b68518534fd2268790b58b8c59131ce56d56eb5ed4659f503ef18d214a41f71453250336cce5786b2a6a1f70d83e841334a53ae729532831bd755ce0c2d7f2f001aef077cfc3398613c23a3510781d63ba523fd35db52157036b5e04ff7d7dce75e05d7600c6bc286fc50d1cf9a2753296eb046046a92a96c5084a67d80ace77825951527a3a2ef376de7373a9d94eb8e810686f4cb5d2b1494438199150e8c50c582886eb3d7189c6223796656ec6f574308339498582ccc96758ab927d7c9f764a70284378c64634499e19dbafd495dd21c68aa08cb89e0bd8c4a6b7530eea93936df8d1e7e05c3b755bfc75a1045a30c33664d5cdf984cf628e258b9a596a6cf7d86e1eb8bdef02601b31536b55f0832cbbc887a33a63f686526f92b8a384096b14f4f97ae19440947213687f20263ccc446b07653ec2e614240effed83adf50f9be5b8cf8ff66d75ea0d8b8256094b6706ce33e72cafabdc90ff9d7bf8d3399c7474c44f36ba3cf70d8279c49f64848b381a6979c1c6bc51fe3866fb5d6aa2b53ff18eba6887058061e11d9489059d4cfb30ca0ecce63981722a617050a5040b1b8d3273ba4f1d69306643e98ee2b4d78cb96c9fd56b53213c968807d26857b100fb6435ac92822794e6d629a7f05efe87f84bf1c23bd889d549271ce2cb7ebdcd1e84966f78ae34d13c2930092a32a08ee727c6b04d9de13a31651fd0bc96366a38475b06bc595a7a6b590d36811e0d644f56711f1fe4246731f0229f72338ea42d2ba59736ae630317899117a296963235117cf4eb8a3df8e5baea33e7073cfa793aad823f3c366fe3dde7e76fcecf7dea117a1fd3affee055bda99b7c8b1900b24aef9f6be5e2a39c047f52977addff7fc6f5f9bc07e15f1c399fdbbbf78941543c97af78fba440ede91c7ef439f5bf118bf044c2720b836e2e3979c0ce7091566d41edf5264592d2893432473b923f1a7323e85388a70bb799f05ef125fa7938da9889b3dd284ddca0b0816fe69054cd94f5b8949cd409687702e556caf36e2960130a72632dad7e4a1c7e3c07fd5ff7fbdb1c527de12784c3529e6cc8171c9eee7d4fe90933072462df4a87efb38a9f3856a65fe7173fcabb948e3e7cc1ef81f7db07a4c9ea9f27ddf1677cd0dfc6a173d221051539c486bf5bb85e9938ed5420d58bb0dd65c05b4b8d2ddf6e9ac454fbd0deee70d836a9f8b1a1ee48c71166a4c8778af143e87a5b215a934f7e6e6686f53b893424ae2c30183a8272e69b7ca3f47a9009e85ca9fdf8b20ec99ca3bff007d3f0bc1fa65f582fa597eecfa7cc3dda0ac3739d4125b7b1b81aebfa40ff7ceb6efd740e97335dcb28dfcfeb53fdfcee5c8f619db070cebd83feadfc928719b4f741cfeb05651d353a99dacd03ae35c4e110fb3df662132306ba2d7564bf643aa77693939e3801f50ed8d5c1c286062fe18c731ecc8f3bb66a69e678ab58375bd6f37a29ac15e1ca4fa25193f0bcb9d73a4b875789b0f4b99760a4b39a5c70a25ffcddf73d1e971a31e57af9b9bffaf25d9a3df963f824a3fc2d37d96d98d41ff4c95dc5460a071d3ebcc30afbee1e7ad31bfba39d1b7fcfe9944fa0d9d307b8b357fd405e7adbb9a19e648567180c7556e1794035e615d212aa3e287327d1315850af5f3208a5839f186f0c351edaaacff5b21e1514e452e83c9f83b585cb1f03553f6e644f06b8e03234f2013595cdc5a3e11b88becf397e10230d3f92db3ff7cd9f758ac8eeb87712011be568e3551ce46dcef7cfb8357fbaf4acb4f1f12e19bfee53fef86f1207f57fdd1b6fefa5f39cd771e4b799a9dbb81a6e5ff53f7f804d77f9dde35e36d0f64f7fc74b1fd0e1fd5e3a73e99f6a340c3ef8f4de3bcfe74f5fb2b0facce1affbac071f62795debe1fc704eef7a715f63cd7dfc37cff7f8c13af509a526b132873da9133f387fbd26ff94dd73ddc91b3d7afcdd139f7156077ff7aade848df6b79cbf72fe3f9ce7b77aacfe8c7dc2468b4ed8c6b58c1e2f5c0ddfc0a2a2f6868916c566de50a71b6328d19249b0645ebda044fb93fc57106123a3cae1ccab8368c4b27068fab56e03d05921686a8246fd527863c22ca16cdb143626442824dc7cce9ce11339b4add23a5c3a8f3b6aebaf60d27fd4dbf06f1bf10b67ecefefbfc2b9ff08cfed2a56c7bfec84c7bbf5657c3087bff1045ece2db88c7bbbbe4fcaae5436ff151476e757f217abb995d9c84ac73fa08f64c84b3d0e05118c0d29e7dc652c7f080b3208345e255130f0a3268c23ef0103c512a745443796cfbd42727de05017ccc163a2474481dc0a84df49f036eef781beff3a1ed5c59e1a5de3b6bc17dff7cb78af6db5b3fd7d73bf5b42817e9093dce235268cd96652e46e00f196d92a5646069923db80a236abed7da87f82b454eb64c20075d09c1678201dd4cc4d39e58c40dc937d682ab1b08783cce098f53154d45b8402ee32880a0682fdcdb5d77f74501b47fc549b9b1aadfe02b6c3e14efece3fc6ffd1feb54602c153edb233dc4871c27ab8b9768d8ddb2d379b20ab712dcbc186b3ff63ef6d9f54d595ffd17fe557f3f6bbce1e02b2ce7257dd17cb115046e210480239756a1710960801194545be75fef75ba2f3a8a3e36ccfae7b7fb55fccc84343421e3add9dee4f9335d2ad86b8490fe3aa1801f248c5440e89ee3a0511349f35082fe63c53752c776b5bc0b52d8866c9bce22e6a502a16ae021fa9ce1f51aad54cd747c4d34548fd86e7a4b6ce60d87c3e879b99beb67d8c4fdbbc5fc7c57d02ffea4a79d795f77175effaafbd26812fe4ceeff81432aa27d8717bbd00e8321466cf954bdd52d8838f854ff30a8f3dbe825afd8072f3ce0102214c966106c676d11b45149128cb64dca031e9f7465813ab11e0946733c035bca27d62a16917634272cb20f36bd9c1a2fc4dac78e79ced69e75764ca3e3dd767d78af37d53e6deded0ce9f0dcff5c51ef3e212ec06686549732f976ae871e648e8c17621e22ea1a89900d4d714573e9a63ecb91d47946d42597af629fe947fcaf40a3cff83f2f76bc06e6e3a208ff26eb5b30d6e65d7bdefc465bef53e4b7b4b2263191750c4b9305c0fcf6defa7eae7a224d4ac22a3aea1b0d491f2730e9548a124b1475279e718c98660a4119a28be53c93656554e4d10511610806446f06a24214632de202d527056592385e917eff33ff1f14ff8535c05bb4c797a06efc6e0beff9e74dc0bd7dcd2df2c14478892a4090d5c538d853e40823f04b208509f04636fa6b88d190486a4520d246490644e463a8eac37012586ad0ce731498211e0151dc0349092d291d7b595eb1b6b90c9d4103e1a4c9ad0458e6374eaabf18bf77150cf72ad7f7a3fffb9bf76e3f3537b48d790939efa693767def6dd7e1eede3882ecb09690c572e11dbb6976c5aa911308db89fac03ac9a9687062853918359cf52d81cb97010b948e758ab99e6cb4c4ad6a34d253350d69104074eaeaf799175dc14a2fb06ada0c4145ee8006b651a8a99828550a171a94faa2922a5b70a0b284243cc3f17b3f6e7f3f7bde4b7218b805662cf9bde5edbf9995e923f7c4e292ca0524a41961834833293751be55a130e7a8331ae578c9ef489fef4f83e929bfab57ebe3eb73e460aa9cefb59ffbc0e8eaaf25cded3b80621259b91fbf3529ff30ea3b335a5042160c9ae4c8ac89d742c09d62e15d8d292c0a28bebe01919c9265448b1cfcdf73f3b7f70fb1cef3887f5bbdec58f5d835fd8fbb6b4ab768c7e3ee7e4ce9fcbed4d2d203cec590a4e61307635850013c5ae3e74344db1734d41fd64c64559404174488115d3ea3ed6758a5cf391bb3d931ae62034f421d67b8b0064732275142e31fb5ee1c425496567ac67193a850563087ce0f7931329a0e0109ffcbf150bf15cde4ea6e686a8f6fefe97e716976a9fba1340e44a8f5c935ab93962de64e56add078bb092ea6c6965d580522c615da891a46794a2c7d033138a0589009bd301eeb80d4a4267d1b96f08f1733d41f2ba8e68b282865edb58b71d4d4550e3aeff51fc4e4e40248bfc133e9bebabf8e73c97b76f430f96acc8f671be97e5aa22ae583afd49c77761ee6fba2290a061d1f57a04886d61b18a64011c5aaac498288166ca5467d0d145417298238549e37ea65083832035892bd51ac319b0b36813bad18a7b5cf5714d499fe57e81fa1c20751fe77ba40d59f6095f86e63a63705b56db763933ac7daee7cbc61e49cd59a8b02cced8d49533056eba9e4fcb044bc00f1af3c135a479aca926237ae66200ec9497be3c53fc7c21c779b64169324092de09284fc30c1991560efd4c55dd1c16312eb580fc9c8f0df5211219f0413988b28fe6afa8a25ccf3f932bed1a7c2fa060e353bfe57dfbe3bd3feb65fccf11e5dcc9401048fa0065ccc67d93452409a8de9bbab48676ce9b7850ea634d585183162e16fea8315796b65609369531feb1a22e5cc1821b7cd32dc74458bed74b092e3daee8d3c0857336484c6ca03e4c4dec5ccd7f8f2f42f929e633daede99d5eeb41386de5e024346a119edb7b77ae648b2ac872d4e6d0d217a14116ad7cf5feda0ec7ec32df0b972ca0ce542a861d98d5c148aeb5582f314ed96384d71d1b33dd12d6dac1cc72c9cf0dccf46950408b64ba166b491668c395dff406c483c37b256bc684e4b69c356c507e1f6bdd05f6881d523571b22e0c2534c4d8bc56fea60ffc015fed519decc75d7cb05f909cedf3259d986f60bfbfff67e75be3d3adfe610296b3fd9af9b61e23175f8e45e7996b0bc095d5e7235f465588ab295258e163b58309bc8f523e4580b9245f00dc083d7275e35ee9ad7d61ae60f3734e2949d02099f38668ac9f8cb1d69923c996fdbc5c522a6d48416c8ea11f7a3d403d56d92041c76379f631d7bbfda0736d7aad7cf4bb36ddef4959afdaf4a91e97c662b66d4a7a0921d0880049dc4c058ec2e7762e1e43692b3fe82338ed0ad76534f04c39263d2fd4678a9de9287691762f277d9e4f243b650b0747f350f4b2c0300d968929beab0aa2f13b5f31b348ea26c4b3d6685a0576d67d9f1fe59cdd55f027597a6fef3e294bcb24e5ad0d69e783b6c71239eb637f15dc55050a5f219b27dcba96671550ecf1be8ed56b2b3f5e9c0b18bb2418359912e6e6839b126924ad5791349143926d10d553969714297c63cbd00d5ca259b229e1ecc70681592732fcda6974e2a63c18e3097052ac044649896ba2b8483696973cdc4bacb2f3e48167641e671086f403d9e7550eb613e35f19a5d6125e81a71ccd0bb4e93497e6cbc4465720a964413f193a0dba23da8f95ef0acc5216a006ca8cfe58d92e0f48015924600f66b34e58646a980f1b3bd56954f4e61c77e6712a1e904b14966110f5d9106a751ae82288645204442ffcacd4c62e0a903858c34febe803138c284c7c3979f293933fe167ffdc26cc10393ba7175d0b27e909c76e1767faa66f76f5f8125ed280f67b667cd7ed3b391cc678d8f11ba4064a6f8824d1e359adba0a7f086553729d1f1d7657614cab1eeb4fea916cea41ce6d6760e67eae4916616be6c10d944b7fa4d81d4227739c429df685b08905fc1ccf03a1b36be5f07f9797f0093ff0a5df9cb765b4b1f40659fab238fbbe73fe0f707aa067fc295eb6cbffd5ae33fb6349fec02feeec9cf3534b259a99101de62465aa5d9849a4e3ced8fb0958568940c29bd0e98eb9ac6aa10c1f4861028c996b395d996150b04109b00197ae24355093645be11dd2248fce5d77116b24819e79174a48108f038893213988713f22837d7efffb794c470a5a9dcfeffaf34a38034fed0e1a6e7477b95d0fae49ebcb7d1501f641292309c0d8157228231d09d830d75a873a2fc3bc7abc97cac2954c191b9d0e07a6c9073d84054c629aa4f70d6a2209355663014eab4520331913fd9e49eb155158e568350d52c47cc5df440d4736d0e10771000df3ecca97bbab4016e269bdfc844d47ba4a6c804ca4368f995c95bb3c4ddbfaecd797a3f59236a3d4be34864030dd1c8e0d70e748c47305334906468c96e3b020f7b1518b88087d044a9719108fefba6346257524832a5460c772cdb5afa06cdcef3556d655ad7e6fe48af27b94770b97942ea420e178b11929a272fbfa94e7b5fc515b070699fa542dda6fa620d9c505fc05f99a153863d44cc23cdac704e84bd6ee4d1fbbbedfcfbbac8de7ce20d958451944ba909801366eaad7c828379198ac68aa6f70aacf519368f15d55044a6f64e1486224a9b8481a2e8314b9fa8ce8fc8e0041e2bcdef8442896d35569f153a61ed1a81b29d443b29f75d6cc00da99bc1d17ac1789f0737dc93660e7f372770186e4b167ff8ab8e08372dff6e5b39fdc57729b6d1673a6b119376067cb5f2c85dcf99ed6411a72a0a682583305d7ccef76c3038cbbb39020e4507588a82dfb026ea8814ae489efb6c206569f07b08f08a5c8c272e2114ff8bc4fe04811b3384d4420c3a975c6be7244f72b99ac26e11d10b121ced9ed9b2bc58ab579b57cbaae9897947cd7de6fead1e6e1bdbb30d71161c4496d15655687b8fa433ce0813b484c5f201c6548760d351f350c238377680e47e301efe034f91e355a130f7a1da82453d4f8eb304777a1918ca38c95564620c7cc0965a28552f900152e053ab422d7de207a26a7f591753734f426f8cbc6759d44f2a4e5ffbb72a5e60bbca81813ad0e0c5df845d6c0aceb6205297e8a965c830324f1c4516042047cc4aedf6199d909819e720f2d2065aee531405dade3f4a18215bb0932a6a2026d0265327794d99aa4fa60dc273da801d5a6487369b6b9d8df4cae4b5fc6954fd526f8ab3028df94d98edf4540a118517d19c9d9d7f6a831e8bb94cda8fb53b20c481ddd96da98cf8ca94cd1992f888d443972b46e01a58562c940223abfc7f9b0130d846dc9ec3b4b91191b36c04a99215c22980187d068452473e94a7587c949c0b56ac43d53770ff5b82fda6277df1c29480d8de77c41c7b1d273bd8db108efdead0f87fb5aed5c8f3620e7b45e705964dc986cd7d56c2bdb84b258bec713fc7a6c8668469481d0a895802229b8033b5c01afb7dace8b4ff96a5f358ff5e9fa3cf96fb3822cc2012fd900cd467bec83c8e89661617f29dff5ce2659aa2195c0bd82e791041b0cb88afaa276735d04c26f90c6e44083235fae47cc10df29d5ef894786b63b6970563ffa295f62850cc21c65b6940c78da9b059b6a445d7ee7627d11012e9c0611462319115fa6fa01cecdc773fe8d4df82319e21de6e2691bbf741d9bc1eb325b5eb00a73918ea8b90a65a9da9773d9beb46e0e83bb6e6f3c406bd2f00d77276a38301701c092edc1ef7460d7cc30152c9794c81c20c5acc241a24305251cb00a69e6c27175dbc1350c40d28bb51273459f3105ea8ca0619ccf1a98d9c096c19001bd72f3037f95d3796b3db40aa948471e5c304ad66fe2580ee6fc87189d2775d450219b2d8f0da97ece4fbbc555be869dff75993b3b671744f996af8324ba93f6e55cb47e9220e74934201591eba94b93b99df3efa4cf59205b80928490be2da3b4573a0aee6089fb91db9bfa0ab72145df47f2648d8dfa11e664e914fa639cea815f689bb04f3cdfd3595898d42fb8e7020e63ec3728b5958b716fdf7c2378ce957dbecdf1d272b36bcc9fa3e51fb6ffab7beecf36e7edf8b2bef04259ada0523ed892b88f33738029babb57d02c02bd244a7b73ea91bee3958c1749c0e5face77274a4cb3954bd1234f390ebc9f1b5f11d4cfea47487fac7d89d96e8a749257800cf8d492b8860682c47d5343b23ab8961fdff33ed3ce07eead8fd321eeecab367bce17259fd5bf94dea66dbbe9b66f3ee34371050cb13765b6bc731db57cd1dfae877b5f0aeb02ac7ef3c127706a09b10a7544b1decb6cc24ca48bef1cb3343258c99bcb64f6367e2ce7bf9841da75f8ac3de75afe117b7f614f46a2957bf6b69cc3fa7c25be17cc0260fa631dd7442eef516e77dc01d49cd454b1d35508e01d9f76d7c8833d5be09a1a6ceeba49ef5e9eadef9b0970327d100d7a92e5b2344a752f3022d991c4d44fd12a0058763d7d0133f3219856807b3f575caac4818de1f43ef1bb3dd7dd9e19743eb167f6e467edc132a462e17b4f72cee99cddd65d47ba826d68efc70d9a80823234f4b6ed5b5e76bc5e7b5de1327fa191a2adc6ba26d9f95aa259d5c346f938d6b9883271e708de73b56aee939ec30a530e0c668c8dc5ca4e874de0a2655c980b9ccf362399af2c2aa9962696505607a306fa48875357feb1be577a000a53b6018263620ef639984eb4f54e0e3dbf777c951cddfb3910557bbde0d5bc78bef6251cb030ebd64e1fabcc20fdc8152ece92453cd06adb8b3a10974bde470acc2ad9d5aa9a0056060d5bd9ae0802b9f65d4d355db9ae59830cab101bd2d721c9751c647acd055398c1044db90265bdcfb352830a2982437cb793ebc019b97fbf2e1cb1733ef595f7f3454fbe33e3277df853f3e9484cec79fc83abf8793ef5ed5bfc83625b2fe975df1fbbbfc7d0becc2fca4f891ae5e6c2924cdfa1e5d0f7b08a07e61c02bcc6c2643e208c691d894bdc25b95e8792897083d7b604754baaee3811c4d211c3996aa30cda50d66928a990f6278aa355383010c48299b80f8b80c28573b5fc3dffc51cbea7fd72cec75eff15b9804e8c5546d5ec0d1ffe8866e7ef7e992f0fae1d3c480c4275cc07bd9a7a1033ac8e7ccc1e78031d68981dc72b3d5756a7d89d3410e8b95d8845d8248f8e9748be6c8e4692b68a244021d0e6aea4d391c2bc70b350a2660822adab5b6e6f44097cf4097cb0faecff9379d6e1a603fe442ebbc3f71e60341c895b6b312bae133bfd0e0764cb5bded5a9c56155466974b96d85b0bbf0ae5b84394b9d943f30cf4c1d49535dc21246b91749e610e52585fd6c132902728ad250e8012fec151a441de6956b5fea0e29297ddfe9de8f5df6301eb0cebd1c4971df071457b358eb2a48273398c20437e4bf152fbf6d1329dc6c798ca8020f953cc7a772d83ed9014098ef73b7d22dbfb63f810391246fe3f1df8fc5fdbaf8f97ce24fbcbf69f3a01a758bcdf50607ec306fe1932df2adcdf204b6c7711c805d9dc6876bf3be4e4f981760ce3cd15c80c5b1f43dd8eea9bcd85e3f7ce6c45a09c49b3ef9a8ed4ef17a0f4abe674a1fe161bd91310e79c4613b7f66fe1f1d3b5f92335e95fda37a8399b18b5b3db2269cd3b3a4fa1ee873446127c0f5c24e39459e30f840dcb1269398fbb3e34a7ac30b4d4182dc31495f9381b6e28da986185a31aeee9984ec4811533b236352a01e04491f63522092741cd05b8559340f3dc67091cc46526d1ed87f4ecb139f58233e31c72ec241791ee76558c035fb3c1ed2717c99afe59c3ea8c3563638326fab7db997f37b5a5a6c8074571ad6966be62e3041ecf57a315dafa0dba35bf9cfce444684fe80012108e8c3389b49b166ba7e2ea4715fff8e737d13a77c408c648e300b6257777c99b04870e6835e6a67ccc61e1fc6584f2dcadfef471ee3f79fb7a57f0a0be77cbed3ebe9d41ff39b7372ddbebe5fcae5490749104e2b140dd8c6ceb21a65dd94352c73bc5e87905e41246873acfa3c031a6cccc4276642882e5b9468d0c02bec659dc0e9ce9040c2d24c12625bb6063f57186bb29f4f6adf6315273dcc32f53122ccc3d7cc6f7f3d5d4019a5f86ffcb3bff1cffec63ffb1bffec6ffcb3bff1cf76fdfd37fed9ff1ff1cf5a1d30ba034958c0f22fc2f67853e6b3bcf66c8fdee3bf7f7a0f4bab224c04c60244b2ae58b958f90095bec86a27171d4c12e0e63f3a17f934b4f5f882dfeafe3b8202aec229484319548caad2e7f2305dc9e679b4fc763ff5230cf34bf37dd423d2335c52224e2b93cb6031d650e36664463dbef2b344654aaf082fdd5bf57a22caf5821dfa591df13d9d5cc5f7f47599bb7148b6b271c264b2e4ad8fe4e4d23c040357d7255703fd5022a6d3208106beec4a5c0aa4ee0a4b40b2247b1e2ada3a7661162909e4a4c5bb4e5c41644eec0ec3ec8ee3ba6262b80e88607196f42d8a3bc1a0f7dd6e581029c994939f32d244126ac0b896bff6763c444677d9b6052555e021698787f22c331dec233dc51104b9be79c1d13e923b3747c22f487132bf6e9b9bed956cf2416ee05031ab11450937b4973daecd811c34dde59610994fcdc55bb9f5e09d15f3d02c94d1693b5b0eca90bec890f0d026368d9ee539bff54939b87f046fffa5ddda58c2afc7537df0eeb3b2551b5b155d29b6ea588e831d26c6e17569f7cd5fd0b110356761938ca0519a7e96f4624305b1912961636f5cc50c98e4afa840635f814190b225ce2a9550300fb4da88dca4ef68428aeeba79ecb2192625a039b04772a789c94c259949fce2a71417b35548269dc0000c7f26e6ea4b3a165c4539aeb887caf00e947b79eb7f76f2d671fd21a0ea8cb5fe026f724fbcc7317f96b37dcfdcf85eb6a73dea27b4efefd3791c8745e748bcf7f3b77ee4a3f1a1ce77c4a7e5a58e1fea351fe45b28be645f3eacf3591b33dee519bd8e1de2735802ce31bcadf3eb10eb9b8466e63d322a3fd43305c9e67d6cb006b9935558b05100884e5c7d6035496a79b0745386709f2563d2c3630c2a471b7690acae2319ba2106f758ee1a63ad7e703c531a0f483652b8cd8dee63ec59126afcf9676ccda7f485e3e3e133fac251fdfc2ff0b33a1afb7b967785d3ae1b18aa8c8c4c465932f505cb792e36e1a6f242b92c5151caf78ad571490f3a9a99c682096c301269e8de1df095abdbeb6060d7611f312e997d3fcf3a9156f6784e7444d1329012150f04c677dd2a1666ce0ffc09aec4bb8ee06f0c8bce1e83f5f43c3c2d43b73298c4bc03dbe0717de41a3e255e9b1b42443bfdf0f5f9de27eb329f110b9b3dbf601b17940d92b48612d4278a3e0de9a486da7a4d31a92d8d0c1c0cfd91acde85399b33c1eec394bb51912092eaa6a5f420a5a51b67911a3b3f142af086a422238aae4674b1c15a57898d7a6af545c6c9b5e23780e046b26203eb6d5ee503ffa1d772f2b3bcd619a5d619fd88ac23a3bbd9ea1cbedc5d84ca39bcbde850eefcdabe018806bd5554a0a68d1135ba9b2779ff5d7d2ab8b91cfb39f27a7ddb634ed8df8e2ff2e00c987014b88452b2f4a5d2e1850facbe5e3b544f1da544a1f663752fd54a6c58ea7dd3abad825bb1e74bc86032ef4fd62309d9616aae23dcbd8ba43243865831900c709acd5d852947f6054efb8a197a33a26ce1d3e8c57678d68f073def879f9883f2a8c55cfad37350dac9e9db35702f27bafe126e2ef4bd21e580534982409430ab1e5c8969c84d2a2b1d36dcb08125eb52d03745982529c575e14af011294310e61c8c0d3373b0ee60ba9043dc597160429e22d52566ea186a1fcbead0cfa01e189a14c9dd29f6262026fc5abe3749503ce5329f1cdb6f9f864637f33d381be57011caaad8e5417bf6dd7b9f1f6afbce4528a3249227cb6d5dc21c26fcd9066e6ff597c379fd3e7eee955fe07bd9e99d8fe5cbb83aa2271ef5379cfed9582dfd917f4a669b1c62e07c7d9c6efb69bb466c7fabf1dd071837e7c6a9cb11ea9b0b38ad46b6801697fd399400a0b49bfa82cb58f43257c1b2b5e94a913005d16a606595c1e5aaf015b4e47458fb1e59a169c52cc2992f4beb316e737bd6dc238daf98df230a7a58d62d47b3564e83de6313eddbf04fdb8b9f72f10be6fdacb63c68872fbe1d0bd6893d8d3d56900c678c8264e4a18defb57aa938193ff48ed71dc3f37eceed76dc77074479b65d175e8fd7cd657b17fb18c7dd9ec1676454f0c1b77c49467d6b9bfc518de437f5a9a0f3c5783f6a3298b347e8b20742b475a0e3da914bc3cd10e2b8349857d68e8c36b6270ca609c1335d0b3c7d43a444c1723d0db1397671b286549f5bb92f597aaf1a6b25468580560eead8a80630578b404a1e2c57cf47727d71bcdf7bdfc390761fdfd8693fc10b8eebbf5fdb477e5b7ebb8f5c6d65f8175fa1c907b8653fcfe96f10cb258b73e8b959b7671944b171b28ed31e8c073d860aa6b086a94191d56e16356d2e4c45ff0e535b22195c8d80693359dd584e7780147b1e50ab09708963a17590871b622068b9c8f53dbe24825448c2f2811df142fdedbc3ffad979d25c739e9ca9cf96879f8929fe3046feac3c1817a20a5d3ce74ed5d80a748922b4b1a78f7d4a1e490a3554b0992d5569a85559e095ccc725e138e98dfbd0718d720a65d5e5982f9981fa8ec665cb48e6f752c5a064429bd60d91c908ea44b086e924653efe8c0fc0499e769a1f7f627ff68a31cf1fd7a5ddafdded6d34be9c88906a151f98c96e1ce1bd4fcf17781f56e1f8ae6b8f69a7a146e9079a08c2545fb8463247b9deb3017a20c444d428bd40f7253bd35638571f789a7478ce6b3ed0d73699a80efe2185c444b10e3b1631176183a4c82b454487eb48ea2ea28224ae92356cf0297fdc93b6ab43f9ebecfc923ef069fd73fef5fb789fb7714dfb6bee6e7dfd02fff3edac9c923e1c43ad9c91825454c36b46bb16718566cb65ea635fb5b2ca720b1d8798f5c32caa23c3efb00121b1c6065c4136cc740de6ea3c2822d577a1c90ce1706ddd20d7542ca9d4028c57b191353ceb1ec6a41de17f5ff1956414ac82fcb5bcf02ce37fe0fb7b1e8360b787f2b12df6fd9eee319cbd3d1f383bc63ed81b3eca07e051ec863fe5ebb7dee3683cdbe19ef78d5dffab6b6b8f7b6c44062666421f53ac9abe82a638d547232006441fd6b0c13252448a07b080f250f57344c71881c8231b687019e6fa28c289efd3890cc1ace350e042c0f5382588e4f0811b754e1a734333029862cb07b1bf571a5bc7f6a9f7f2df695f0dfbb4de1f19e770e0eca5e55ad7d883957cafd7f2756ee86bd6eefd6bcd0571be3b7bdb5d975969cfe6c03409ad900f501fcb996463dd8d36d5838dd58016bcc65a95045e6f604b4489fada9ae93a0cbc1ee502061c1062cbd9da22d9ca95ab8583b9ea68951168220df26e1a6c2acd91d53b96d53d744dbfcc777ad307fb1fcfb96cd9dda93d22330b15543259dd63f96ddff7f3a80d8fe5ddcd8892c497272f749b23f9708ffbf3fdcf719f2cb3088dee746f0b5646a9b684efe7e64b1cc7ff1c8fe3d8ae6b89d8f6f333ddf400a7ff581cc6fe7df8607f37a06a1952d1f017bacd11ba8ffcf9b6f4ca91b67e1eef2f7b50da47746d7e8f3dddfa28ef3ee5b3e7bcaef7419b4bc1c05c71ca672ffb74d6b93c6e12f3cc6ae4c1323e8bf938bc920d16892897aa4816dff776be57e7d22efff66571eb092c2008315ac4851892acf4fc7432a7b49b531761d268b5954572d4370d1bf4741bb3f97d83552609e60cfc866a891318921a0e10c5ae98874626059aea31a2df7100d7cc4d529c7536d09bac71d60561061e2ecd75c50dd2e177407af64138e50374a59c876fcbdcb5733cb02bbef70db02ecb6d588fa85f43b96bc294f508e5b98da1ec1acc0d016a707f320f0d68e1cbb0cfde8cd7d331e2ed38fed36bcc5379bb75e6298f8db47fffe7fdcc9081b033fd21476e32a6465d44b2990612a1965369a1ac97d060e432cc3d5486943cc9f267e6a17f25ccca37656ee5aa5dfe9727d9fd43b9ea14561487be823644b2378e5e06ee8098a10167a151e9568e72aa953328cd368e84cc31464a78b7d8f8d4b4298dd6a107158c93dc95741593a809b2b2b0bc1e8384e57c805c07ab01c7554a8dee9d25b141ecf56820d7bde3f8f5a80c8bac0a0726388fddfdf3dddaf4c5b145557544eb0ddfcdb5e7f2476d6eb98e7c593b96638a7fac1d8515614a3674507a91b65ec72e7470f3538d243082291748d65190661dab4f1e436da1a286adb1ac67ac304b62c0ef71560f9148929192a4a4419543cc3ca4f5dd18272a767eccb1cc2d4bf76b4ebbca07edb81a79c77c763e13bb7d0d1ef6a33ae6cfb49bbf1fdcdbc56a5f366eb1a8ad94f87661cb716683b0e8d981515b44240394759a91cc559c0e5711ee6abe548ddd426097da12cfcdca6ac49050fd21c03a847a0f466e4fb884f54700cde3c16c4ef3328b640b401aa9b127bedf03515bfdde418e8073bc327c9671c0c6a76a716e1d81578a9fdfb7736b538e727dc9e4367fe291fa483bfbf645f84b920cc94f25f06632ed131579c3da5778ca148662c39c3a5ea410ba6898d4552145261ba0000e4c8de7c48a68b2615a69df4b753992920e2c90ea34bd31a2c3b995f17e4c55614be03ec0bc8e325db3011c074dd29cc192bc0877232c48e5bf60a12b9fc0b0974285a49fc0fbacaf337fbac0dfe17deecbfd527e69cf2e261de2658068b5e402e8704dd4f792b4b636ddc691d0866ad0720689820c5873026d2bb7244baa85d5b756630f8a282f919d89efdc289d3865462095224e8536929305f3448feae80e49b5c24149782316d7f2650df3ee9abfd109b4737bddcd88aa2b7656efcd0e75b3afadc14fe5b57d146dc0b2b5f1b8d907b1c5a7f66d123b1cd80acdf43e222642b2bfb62469035da872ad66968c867ec6c748317b912b6a07271e21994ab584857dfd3b54380b73ee46297cc02ee9841e29c7c68f8d4df54e2475c7b126be07b99ebb3a298964ae2c7c35bc8924caa3d7b14c87fec58a297c0fb5b96176efc1affd520ee89ff3433cef5b1fe84a954f2b31a26413e5ddcd497fdf02aeb867a6cc0195effdac9e7d455e70d4c056df7b5f8798becd4371ca1f860fe022a0e77c60b4a5e5da57f1b168f7f75b3f43d4848698eee21ced4b710cfd30cf1a88d5519c9785eb990af3981a4909b6257dc3b55a8bf49e1c53dc8985bfb2342c214fb030b51bdc8f5650d165ec713be88b3b245743e6f1a9eb9105c955c9cf45115288a16266b40fefdcfc87ca81797f298ee1ae5dd51d067ece4ad6e25310a9c533398fd9561fe0327c718e878658f2d67eabe6018daa68600a3e40e5deafb0ed8fb068f1f8972c17c5c8eb6d9887a4a0cd05baed9ba33149a7faa68307918a0d3ec65a3db06431c24552390dd788329c23aaadb0526e78ce86dc280dde27969daf658bf2b925c81dda74353b15731b244e50f8f378204ce2ea1be2a1a5ef098b61404856def912f0c7faac86b2aa7da16f0037c4e26c4ccca6b3b94e1e72d4b4fed5036bd7e60a91025a372daef8e56b62e568d5c89205a1da7a6e0162c022b1205dacb146660e30899d55b69d4179b4a99c40220f91513a44493a717fa83852e5d839a86cd75fdbae5833a94b7806cab1c647816e42ac912ac84c070fcac61291e236fac3b5d6c4175ef38c3d529f5913d5c8c0952f27c26ff3b29dce0b729d3c536fca6cfbabc524a170c6289cb7589f17e7014b168c9095df08c025ee47b4f438481242506053f0dda5d0a029ee403741b66bcabc98d4c41b82581369e025be437ecec75abd44192a70d15b10d75a73cf92b9416a66d44d20b19c3b55c25c34828d780865a25c697ddcf2ac05a7488c68ddbcc1a5714ecb9abb3663223a88b93cecb7f155701976fdc672d2ec30fc5f9f4beb368eea32fd406286f9ddf1ca9ae7a5c46401a1672a165d80282343ae993d37ab2a362059a071d5ce4812649db545991ed324b1b198457277e416991cbbd1dcc11dd592441e694ce22053034f2fa15c69f74aa23872822249bd3f33cf8ef031b1661425516126b1d362204d3965f9f91cd2ad5f14b84e9b936c1fdf516df5b5e7b881ad9efc71fdaa9d6c72596eb1384760ac27d0cd88c6bcdec801c339d5c503d5748a07c8e3345b87836ced166815e8a4f195684e28481c43f408b03bc1c0a496676e469bee100a7f6e6948765a995353719329632cad4343b7989874a25cea5857c3a417cdc87bd35617e4056f9f6b7cc52ca3c1b9b9d4ee755f0137f44d99cf3c3092e126f07ad27e4f5dba8c07fa73e6b105c549100a7dee7bb30ed1cd3bee25d876b34d4cca3b6c74a52825c37bc067d8e553d487332ac8920d26806bfcc177f59c635830021f634dffeebaba13e00e70bc52f62932a98e28a30c708f0736304feb08873c0b8439126c1753f099dc3dcd9f6fe7369e2e8f643ddfd9c95f9fef73f55c16fbb98c44127085fb5166afc85df79e1a44655259330d3ec04c0d68aa5b3065c3a848e008cc94108bdacabbb64fd5959bf60c8baa56dc870b2e9590bbacc7a592c154cc98213a3e66c855c88a7a1006190623c9da5c4b36600699f267dff0fd7ecfd7b1fb32464dc08ec68d1cc94f39eda857f2c7db97fba31ac9bb78d391bb7bff177c04a676c3f57060664eaedf87a237b5c9cfb985c98aeb428e48d9f82914bebc065cce643b6725cccc7ba293d4cdbb4ad467292fe09a35bd473a289758a01132ca6a2461c5a6a840994919d66d9281b12f5583484ae07fcbff24dcc7a45aeffdaddff0bcb7b2c4715e489681a703e6804fee575c2bc7d641b95b9e08c25cd49ce2ea65dfe20b39623d32f62929a38cd8bce80504c0222e7883352e11d7fc4e04c451de598db535889caec9bc2408f164cdf044c692a65812ac6cac01e2a20197ba0e1924c82665337609b64962b9852e5ca36b634d7d8094074c5c2d5e208d0ab1ded968f52533bad5ce462f966cf3368fca49fb83d7cb5afb0a5557dc107940cfe63c950eb1a2be34574164a0841bb80af3ae1450f6a4131fbb5ec1bb167bf432ac2e5a6750ccd6b8107d8af91dcce1dca165ce32fe80a56ee5e8c9a3453964182b3e311fe21441b4a97c975655e02577b48f1e09558b28e3be2bc477a870db91cc8a1b5d0d6a6069e7dac6a62a80c0741d39914607b81c5f9557cc556c9057f88dc323b1f270e6d37a7ed2172cdfdb3e1428858af9e457bfb7d51ff3c900aaef99cbd371fca2dad9c0c0c2f74af50c6d33a2cffe67c763875b1ab18c14d4e6626777a0f51ff169bd889d673b5b73c48e57461bb08c0ce96d3cd3f4d02739a6fa269c3ebdf72936e1481ecb36c6466fe30e47de5b5b8497e2e338da03b2f69dd7f3eda09e87b96b77b172c77c673acc882a3fd71b4651194d3fc4e5be304ee665acfcb5b98b76e56e75115f4e92d0587c3d17918b344b1aca44f6250b570f9498061bc0ef2146b58be120720925d32e70b17e67a551e364c20af18fb92597bdd09874681fd56880326ef03e4e611e0fd0d4d5088c05ec58a98998912c9101ef798137dcd573521cf0e933f2d527e6f5ee1b77be8b1e94625a3f632beff8dbf178ffe33193db3119ed6ce0a763574ed9095ec5c29cd66bae63db219bc079caedf1742c49a376ee5e2467df5903e19041c9984efab6dc51c36965c0bb6a10f491ea6024b9444f7d5c3621117768003196a20edb741f182d4776decd5c5ddb3838c9dd144e5d973f120f3ad450b350e96128754daaf38c7a7a6a51f618125f3eb0719eb1db70aaaabb588267de509f5f8bcdc5735e755a277f55cecbc37277fd13deedf3c63a5b5e7f71cecb7a84d9866a8b954dd914f6cd2c92782724a561c9fcd1a2750f164239997fe5323b59ab938ce8761cfe7c9bfbe0a47e7f1c4fe2741e83abc49cb736f01145221a98c2977569af831ed467efd770c487fe38bfb41ce060571fc794ad7903972e55192f986be16ae4e49c2059d75c77722c8f2ee0546467bebfd3e697f9f37b516d59ad9dca2325bb93f6efbd880f18ae0c9c685a1921e1ba83a30ea749c053d6b772133389503a80c3a0f9d90924ac84a4b78832738a289efb0ddc8cbddea32f138a0d0e224de46e26667e83d4b88f81d3f75517243db730894f20e0ae100e55471fe41fde7dcb7e0e9d1f3fef65a53fd17e4ff3f6b91d9fe6ec1e9fe232befac00ce0c79ad68932d46097b34853a99f55ae9357e35820c5cab2396e8817c9264486dae79af030d0935081639b428f6b0c384e97398d8e83a2248ecb967e5e1581a7eb319d7418e04b26b394a7492f926db5d5790fdb531eb77b66601dd05a8c284c7c3939d7ae9b7d3efa3fdbae47cb6edb376de3c3aac8100be680d4a770c6f6184617b6f3626cd47d4481e54b35a3f9440a731384991a70a1f79ddc02d1c057ee81d9e7b2d6899caec574d2190fb0120ea0c7454f7364b00e65746fe372cce5aa1768657fb4e9664864d258ab80834915142883ba49038cced9890ed7223929777ee167f5fbcd9f970bf82ca070e79bb92b778f477719e6869dd5a605d0c222c8b3404f0efbd13aec4335722183292aef655d8906dc8f3c38b085f002b9aa5d0f2d7d91145106b47b453c42c59c91a637e79868f1a0bcf789f0915ceaa4212b26eb6b475221c2d5d8a565e967d7b34f332f11eff4a453729b12d01d36496888e559bfe26bf914c9226b75235a9761defaadbcabc7977c8cc6910c56d468f38152a48101f77a1d9a12c7ea2773df1579a8978f412e2c9e25d4269cb9522505b882e30179e47ae945a94871ce729f2ee69c401df62773571e765cd94c423d5973450842858a345bc6981567f6ab3f9fdffc48beab57b96e5ffaef421cb783989ecf60525d11df60a79fbce0e3beadcfded7ef0b31b1bec86496cf00ccba04bbbd1971f55190b131d275e0644cc4853e6203b31763963994c8364665e4999e33e06e6898959da9d019fc043e5d6c586aafb121751c818c184b9bd0d33b8114c961cee78ef6a3b6a8bf0a8d3f1b13fb3696fb33faf3f82856c657f5e777b1e41b69f52e96b01a7f945bfa9c3e8d811b08f1dd077cec4ada9a79bce70c7adf2d0d74225d18bce0052cc463ecea63d4c00e37c82af26632ec236acb3f5658f48ab018d623890ff85d55fa0d2c1d81be6337d1b90b31d3a41aea30e1b24a090503e4b28bf3115c9cfff9ec3cb1ae394fced4679f33e454eee65d5efbafc42f7e8f29a8a053817b05f62300bd18db6a84d584d1925a1232789ef41d192e1c1995b1108923087034ad6301d30af2a1120a0890ac664c8343a4f8ebc058cc1d902976067a5b1983e1854428296046281409ba16b6db07b9018fce2578180ff327648ce75c8cfbbe78c6c37d754d923e88413acbdb6241be435c6af70a2a220f01649430187093350420c1a825232922333526fa7da89794159ae4b83feb91b400d8d01f2121c320e534f64ce44aa51ce7ba82015b384aefc1cff4b59f33cdd248060b71ef6f1635fbef61fe1ff0bca1d8e53cf920d6f8a2bcec1fe2409ec3067aa3bf9f1863afdf73961f1c89a7f93a3f3887692d7f75ddb43d223b006d88c1902bc4d8a150f2c5b076365d8600722c370230e3aa0f7a0d6bf8744ccd8ca442e39e0ea214153c6589a3e8436ae83398f260ac890a37dc43de0c60c25257410b26a24d244a9d532ec183d8d66b8dadf7b839afecea5fb7612aa16266238f6f7cefe7793fdae935fc06f82acaed8a2b6612b57ce4f5b9b4f3cfbacc6f60184fbb5594a94ae0a131ce272b47273dae492b22ec15246c78af8802f59946525e515c05b68786ae624ea3262150ae65ac5b726cf80ac2e5c8c5fe9a93a876a4b21ff67b43d8fcac590303a490e65e0600b9443e130b71a80f6ebf6dd053ff22db9812e5fa3a1ab431ff4fc77b6c8f4feb84f5c8432e76c5639cf2bb88967eaca9738a996cbb3de416043a0a5a8ffb17f9a828db329803f29d6d4097421994fe793fd6abe4c7e65b39aef5a96bed0f0937ba5540ad7d1b1dabd71ebfe6b2b1d8e35992c664069c5c7559a16de78f1bd37263e7d570ec090f1a92627b623ebefba1ba5eb6429aad86b23a621e5e8d5d9473c584a10c45887f6c30d6ef51a62fc25cd5dc691520dd9ad3bcece19400dfd55658f757578bcba10044f9f62f492279f2b2cfe7bcf3c9daef0bbef58f7b9de7e210eb2ea07ce9d375c5bca47cbba60d0f62b163af2798a16fa25c57dbfc396f3191f77b7ff8e45e406ca06244cd249249169cf5273cb2f7f925be96646c03a6be07053344eb43f8ae1e7b2cd4cbb031b10ec78146ee91411ea91014ca136069e62ad0d6eb31269b31618943491ea5a6e5623db7a4ae1e7abd7e20970f816b498c081513d1a33ac1414610d7cb7ba255294a7bba25c888189379a840cd1dc0c2cd45353e83857ab80790488caae7ecded7c29add63dc6fd78d5db9ad3fdf05f6fd7d8ed91125b80eb0ee3b22214cd2fd301504e765c99d0a12395109498691c2f2a8cf2b5f212c744586011939cdcf952d975224888232bd83fa93cd48067d229b923b80832063a64fed35974413cab6141726b63141c7e34445121a7579decff85a63f4b9bc2ddf537d5a2fb674fb36bcccf7c7850ad378c9f4528d5c62dbe9cf0ed4130b110b9041ef0103b36729fc916afac2211c0603525979e5f88abf827ddd0d535384445bb381483189244e4adf35c823972a99354c8f143665464dddbbcaa098a4bccf3f885916cb3363afb952ae74356c637fc4b2d53d2f8d3323a40307a2408037dc3553288b06092ec6ba0016110b8ecb2a226c160ff49195438b6a2ab25dd2f325abc1944d91a4ae5d97e7dcedb1b1315cc5a926477a628519eb50216422279925b3992d321569756537ec73b1b2dbdf8174ffcb9efd3f37df6eca601e17d5cdefff7bf3904d6e7ebfb9f97603833cde1efde73fdf6eb222a8a6abf8371eaf6eb3e21fa5584ea6c53f7e2d8be8f7db2ace4b1154f1e2b6da94f1229a4fcbea36a9aaf2b60ca22c98c4bfa58b59b17df5b4f835dbfef2b80aa662b13d2c7685bca1fc76b39836f1cdef40fef1fddb4d3ee3f1cdef1d596a0fffa8a6ed03b224837f00f91fd20f17747f573abf773abffd50fef95d068adcfd87a4fe2e4937df6ea68b3ff8747ef3fbaf402ce26f378b4d5b663f5eddfcfebda302f5dbcdb098ddfc2eabff04f28f1fcab71b28a64576f33bf87663b5c52a0af8f1e3db0d9ef29bdf8124816f37c6cba1f7c71f65c0a59bdfa56f37886f5f2a7dbb715e55bd27b2dd9774a46e7b3a8bb2c5cdef3fbeddfcaca6f9b62a4e1cddfc0ebe2b5d0948a0b3adc0627b45ed76a48ed4e928fff976631d21957e749e489f3ffa3fdf6eee3e4feafdf1c7b2582e627ef3fbbfa46fd237e9dfffd9f67312cfdb16da36dacd6d32cbe3db342eb269b1b85dcfe6d9a20ca2f8369adeeec7c33f8ae924a9c4e61fd1f41f6f87c533c522287838abdf8d9a5b3e8b1637df6e8679399b570f4195bc1973fbbbfd59b4bbec06f3495ced8ed16cb63fb2822a4a6e7e2f96427cbb71aa40c4cf3ddd9ea1386807de96d698e953112f9ea877e53e9ff6e3f2f9d88d17d53beaeda5774f5833bedc96f7bf37fbca7f3c43da9a4e8b9bdfabf932fef6df6fdbf66bad19ff2ff7e064f65b3ee36d61249e2fa66d4b83dfc0f79661946dab3c7193938db3eff3cff291ff7cbbe14115dcfc7eb363fde6d2a760b70d94137997862749c21c2d98f724661e86efbc0a91dbb2c77dd8007a563fc856cc25308d72b1e677bd21d1913dd40edebb082814e113fc6ea6af5fb6379fc4e1ed92d35b45b29042c57cab0aee42c5daf2982c5e89db2688f29dcb5dabe23f89b8c5be3e8337db6153bf206568ec54a2b0e8758677603d1cbc098798f0014c5fbdbf0deb7c4a1530dc2e774e6fc36967b20bbdfc999bd3de3232a4495490e5d0304140ebecd5f3edb3e3d6b579572e1f5855987733e6f4da906c4f062b36200be6597b88b2ee34a09dfd716fe72ed8ba28dbcbedf7bc0a1d1191627f7f52b57cefa54fbe5486fc2462ebbbb4e9056ade7fc7fb36e0066978bf04612ea4e19d9f0f8d837b4fcb7dc28d56dc789dcaec39c523cbf524da6c5551b0e1546de16286779dd5bebf56015533e64d9641f1eafbf37a0ffbfa73cabc5d38ee505f4f23c54c479bd9e368335bc672d98c06a8fd8b07201a4e7bd1bedd56f7d3d9ea7eaafe3328ac051f6cff60e717594f8777521579a464de2b38b0d7e9a57275c50c5285726732725ea595beebacda3627dd2a9411080dd28c6496f89eb5152fabedf8e086a89edade97eb729497cd47dfb96da7bd69a0154bd0a9b088acb70be1d9c3ddbd6c156acd1b75f389ee29d487927d0871573c850a47460d982c5ebb074b9f7cc7ce35e439a597bdb45ab1fca5cf9ffbe919d66228bf79774e4e8534bf405bbe71ad350feafe3accf9c585f96d5ddabea2602f023fb9d7beeaf3e2e01def5d400e52893c6fcfbe1ae7bb39f6e286f9aeeecfd00cfbe7d577a2f8f950f37deadbb721e5e69b3e7aedea0ddbade327f5e0a47befd4def3c691fc045dd186b581f7ede0cbf58a532478dea6fb7bed32fdca7dc3cc7daa37a3adbae099206ca1a9f0b319056ef6e1c2ff65517b318f4e4bd85b8227c15a969fc46a1974fed9f9d1011df027a4eb9d5cf39170ad74241574b7e2fb5eb8969f846bf0fdc73ffff905e17a5bfd0f446be903d17a5b9b9d10acc85d05747ffcf39fffb78ad6efa5eacfc85edbb36adaaa5ea764eeff6eadf7e2fcbf6e7ebbf9f7b33cbf1b5b6fc5f9c5f6ecfff0b88c0b1e17d1e6f7ff339956c932fc2d9ae5b793d93f26d36afb134e85d8dcaed4d7d2ffbf6e22318d8beab7c9ece6db4d342b7e4d27bbe35f5b82cda28af3fdf9be49de9efd1117abc5bb4b220863f1fe623e9dcc83edd1fb1bb3f2d8d5d54c2cf3787fb5cc2631df1dcee372b69856b3f9f4e9e6f395cdee7c319b57315fc4fb4f7ae2106fcfda67fffd4aedf9d7f6dbabb8ae6ebeddc4f3f96cbe55b77ee5dbd3576d19cde6f16cb16dcb459cafe2f9edeee72dd1d1063f79ff368ff35f8b8fa8b63f1fbf6377f77651cde6c124debe6936dfbc25ce837916b64c72db90f39337b7ffa7c564fb9e7774d32a4a6221926da1db61bfe574df6e26b3329bfc362d6e37412e7e5bc95b2e386bffdd4e67cb6a2a6ebedd643f16bf4d67b74139cd83289916f17cb32d667be1761e2f66cb7914df9ce2f3b7db176ddba788abdbe57cfbced9e266a753dd6ec769ab5c6d87c224aecbedc1b26819f7f3d12d8fc3e5643f3ab63fd57c5a4cb6ef586cdab9d692fffb49f1fdd74db8fcd57e47b8a9e2453b33f2721e2f16b761332de5d7177e6dc7d3eb0b93665abe3e6fc434dccdad2ad87efcad982eaafd85dd808be69bb29a3d1fdc06bb227727d1b44cda4edb9ff3d737f922783989a3b7a75c5655d03db8703b2daa785e04e236e6eb60ce17efc9849896d5347ab992e4c1abb3e7c7e741c1f75dfcfed6621956227eb99173f5e564fbdcabb3a8f3eae4f5072c9200bc3993d5ef6fce5520bf3a7f5764255eb553ad4addb767b76536adb793bd88667c5a4c5e1dde068b02bc3e0f8345fcbdf3e6cab408da69f67c65320b5f9f26f1eb97dfeecd78cfe7653bbd3e66340ff359352bac602ab6d36d5fed705a45cbf92a5e7c86761e4c8b7236139fa08d83fa1354cf7dbb9d12fb6e3ff7cc2c0a3f4355c64539293f4fb99d20b759bc59cf838b9e9ae7b3f905f471c4934bc8c524c8834f35cbd3134ffdffd9079efb201093d97c5a25f9571e8ea3e84b8fbdcc94cf3e5b0651167f66683f3db090b32facb8713e9d97c1621add4e667c71fbcc691727c9b66cf81314b7c17c1e6cf63cfb63da6a1ebf9f98c728f69c2389df8fdc77c44f2bde91353ffa35f9f0c6ed220a8ae22389644b50cdb2b838717bab46fd697926894519cf6fa364be95933f495dcec4e6d754883f272d3d53cd169f203ae46317ca5d3b89f90cd1cb8a19afa68b9d5af129fa9dac738ab414cb3c3c98941f92dd464194c49f269e89f70cf363e2ad1cd6ead09fa59fcdf3a0fa5c03be7f884f7ffdbaf091c9b49a4e8ad9fcd2fa4d79bdfdb24b9f2a785c5ff8cc2c4cbf50d296c57ee5b1ac12d3e2d34fcdc2348e3e9cc9efa9cb2d8b8f66a2ad5cf9b5a76ea3a00cc2a998569b2fbe6031e571b813353ff5f83c5e1d72f98fc9b71ad7c7aadf7bea6a1e148b72a77c5cf6c0ed4e41bffcb94b46c5cb5393e9178a4aaaead3ddfcf2d4339b8b66797e96291e79c1229e9fd0be4f3cb7483ea74e7f52e97e31955cfcc02d9f55e79bfc94767f40dc8a0e2f1aca79d24f70d31de1b3467f9e348fe79988abf9f45c1bbe27ff7c631e3cf919a67be4a1fd20fc350ff28b2b5bccf8e1000c97bf7e0562769bc487abcd64b66353e1f2d7eee02dc134e7c17c3adb163179772b0de3226e2bb3371cdc4edf5164f16a5a84cb79166f47f81fc756d68b4c4187f57f4ff1dc7879502e3e6357fa94ed29cec3987fd14a759c6e51f1d9fbfa7d60cf7aa158c4f3c9747b773b3fda499207559494ad55f60d651d14cd66dbe6ff08267b563d134131f96d369fdcd6b74f2ab998ad7f4d77ace7c8ed285854ea47f792204a0259fae8f672be8a9fac38a7095e8df7692cf807f42fa6a363770fad3cc7a8b6e23c50a48f3e69f161432c16c9eda976dcde7f3146b417ff28c38cff3a419f15b37591ccf60adf6ba2ed9c7ab1c41ddc7af9d6763fe50845399fd59bf737169bc56d5cc751101e3cb3bdf522e0178be0579cc4c19e8dbc275c16ad91ead9ca3a2d7efdb6925e5f5907f3625a4c16ef2ebf986393a06de9edcf6dc0453c579eaede46f3687752e55bae3ecd774b5efbfb2cfcefce9e6bdc9eee9781ddadb48cb7f3fa8d7d28106f2e45e5f2f5e9afbcdadb619f2f157155cd83d60efc7c6db6680d24af2f95b3563f7c65827cfbc83cfe25e2a812d3eacde5c5b49888f897984e9237a52e368b2810a2edaab8581dbbb5ef81e7eb55bca8c4eccdd7bdebc427fb77ab7e7ec50efe01d9f62d2f26a393548bb83a4bb30ac49407fb4dae4f523e338d4fd8ea778d94ef2cf3db9fdb703a79396c2bd81eefcdc1f9ce60bffdb9cd97a29a96413b44da0b8fcb5915f3723e2daa206c594ed1da95b613702f7c3e1db6ff9ec6d2f3c5a7ceda5fdb4ef7a7e5f7dda6c26c37737747cb45dba5fbfd85c3fd8676b4bdd979680f6e179ba26aadaa873b11d16ed7eaddbec4d3f98b85af9ae5ad0dfee0cebe490fae2f368b371b1cd1ac1dd1075b1ddb9f97d7efc7f9d316c8b79b65318d766afcfee87659fd02dfdf9eff684fb7c3fee6dbcd2a2ef86c7e7b66e1fa04d5ab25e31475fbb3e5329fa57b32e89f227ebd849ea04b76ebcc098ac3d5f104f1992fde0e4d5e2cb67f79bc58ecd8f34784cf837fb26c27d759baa795eb14a17c9b6cb5e91354535e041fdcdeae603bd67fec6e2bc32ee268398f6fc3299fce971fb6564bdaea6fbf66f3fc14d1d318ddbef03374c5f67dff7ee7e4faafb7dbdb7f2c8b69f5c796f11fdde8fef0f6cb96f78724fbcdef0fef7f747dbf3dfef6febfdf39e6feeb7386f413bc7cfbe69dd4fe9a68bb3094d5fc8961be103d6da2feed0bfc17fa022fe6d18b0bf0ce17fbbfe550b5d3b07fab16a73dab9ea95ee21600f84be216f6ae55e09a710bdbaaff1db7f077dcc2dfbcea2abcea8587bcc42d0414ac43c5948683c5c496bbcb5dead9f5c4a1aa1cca559b3a72389026ac3057a1f3b338e6476e368bfbbbe98fc7fbc96c723fedb150219ba19660a2ff9c0486be64465d8679347995867a3134c492e7dd39a3f684cb420aee7ac2a770361cb430912252ece55047b3c0b326db3f9f7626cc4b92d0eb2d98dd969373aaa63b9ff79e1418ba3434ea1553ac093712b17dbf2f77ab80aac5ab774e7caa664383a481d115d1a657f2813509a8bae69e3de1c68ffdb3b085328ea69dfbe1dd6cfb37b107bd24caf56a38a8faa1ac4acc4ba45f4e2f7d3a1e1adac47f6ebfde531aeae5ddf4e7e350ebad7dcf4c42a7f7cf50361f19856f9e1de5e68a0db25dd9afeb9a77b3d8e9956cda4bc2227b5f8f7d19a83b34e02afc7fd9bbb6e646713ffb81b66a0a8371c2c33e181264b04dda6073d19b050960ae69dbd8b86abffb962444a027ddc96ca57b6bfea587ae997683ae3f49e767eb9c53128be03379b76465e913e89bb2b16032296a0689a55f9ea0459d434d4dc2564d50dab717cf4b6100fdfc4cc7781e02bd0d3c217e1695745fb88768210cfa291f9118c60828251449f9ac1c36a727e8db1512ed9b016013a6f372efc9056ac3a3a14552e09b67b3bdc4a648addcf0ff43df3eace24fd55d414fcfa06fde8c855d41a7e3c50cc66f0fdc0402b70d2f3f94c76463a451795d5b3774ecbaf8a5b26fee2deafbb2f9711e3a49fb68340f440e40ef6504c6652ecc2602ca018997b8a789d23e6fa1b79b19e08d460bf1382edc7455580d7294efa8d085bd0ff3956f25a8b05324c5cd5e9cbeddcbf7e00415eb2628ae4d902aa7c0cbcf2bd16e0269dd40c9ad617fd7dc7d0d5bf904354bd813bb26360e133687b89f8d56b8532a174ee2158f4385d71002bb99f148d730b5a99e2b06c0755b84db6268491fdf4fa9daaf99e5b68a99945047ff6f56addaf30b20c86fb4bcc999ac0d2a5517a3e29eb4311415b2fee9585b0d02bb338ebf25982f578e70fac23f4b87c5cfad5a9a8bd37227284f2b66f12ee6c5b3930cd67092079e9d87e5ba7ed954cb1d5d87332db5ef9cdcfab64d651627352cb36a107738beda672757b4b8d69068cb4f71953d0bf5762b4ccf6cacf61e949783f8a27b43ae68e997f6f9a415f3fae952c506e184b82d4ad50ffa4df6aefae9522b4f97dfc729c099ceafa12f7982c15e0c03ff18ab602a4e45599194af6315e0e6ffdf59058a224d94c9bdfc9f0a7c39ab80b30a38ab80b30a38ab80b30a38ab80b30a38ab80b30a38ab80b30a38ab80b30a3e7e8fb30a38ab80b30a38ab80b30a38ab80b30a38ab80b30a38ab80b30a38ab80b30a38ab80b30a38ab80b30a38ab80b30a38abe0ffeda62eb9c8f4276805b822b2bb7551fd0976c1e85976d9eaeefeee8f500ce83daba9f0751403d272ce30e00c03be6f7dcdbef5e376f246343025f7061d955c820da44df974a96be4ab4d586ee2e756bd45406f07c4833ccc940bb9dc5faee317472dc24239195af49ec0f5a8acc1856df6ce2df2d53ca4a2f4e5d3a55af6a407ad8a037f4d89092d7b3e3caf52258dbcfc08b5f04e2bf25377019a8af86bea9da193b286ed22a2f0840851908bc98201ec24028ff137878a7da3423fc16d159b925d43d16dcdf6b23434f510f99680c4491e6679f694cecbf5c363bbbe6d4aad14eeb4b86697aef3b0340d7af1da6d8d07215e2e36b3ae1db5f120fc97a12579581a33e3915ea65f3a73e55b27341e69327ebf0953f24c77c17773869e9c2db5ecaeab8bf46fa945e6c850e0503112471eb66a622c6082409e0d2eda972b6d5e455a167fdb4ea960fec21202df1496e442f8faccdec763f7e210d281894ad8ec45b7dd4a2ab9301eb6d93902498ed2b80a45b78d0a77d40743538555a91e036f5aaddb8c7d46fce448bb17561e96300fd3acf7a75a956a134a9bca6cefcbe59b1fe53914dd33d4922cf0ed64f839f4136234b07c302e6b6d500eb904ef1e222d2e3b92cc39d226bb673ce7ed255e89f50d89d3665416195b32de473256927b1c8d51ef8db93943df6c916454f8bf2b6d5e6e8bfbb8fbac5c6e871e79aab02a94efcbb7f2463ef4649e7d37415af2dea5ed16fad604f597c7b3a3f1f8de257312b7f5dfebc56316d3d8e9dbcec65c3e20a0dca033fc7755a165a8caea87f85d2e36a4fc1727bbd3e2fffead97c6716270fa10d9b08718a4994da77f12d27c216b92b49c431a0e6938a4f92248c3f6865f619901a658506cc00893d49c648423ee8cc79ec8731c93a854c500b045a2109bef1adb0ccb99bf1a40bf51d2d5baaf6f95be6b7643dab86aef63db936f916fe6c6c2ae02bf23bb0d895bc06a08c9d2b7f1797f40c04d5071958d4554416f1a8740bf85a29b19e0318e0afdb8f73631f4618ecacd59a318ab3227c44c6966006652b58e03471503ef5ac3c1998dcf4e7c1610fc42c86083333ea5671b217d3132e4b68a77857b4092997deb498d979e50f62d9d2bbda72c9013e4ed66189bedbd280fd3b03353f905e64ae7f1cbf6b81cd6cbb0cb53ca308b9e22b0c3b88e10505745d7477ad631bc7642a2f5bd27d43e5403722d692323772a640edfe2e14e233edaf70d8b0be8a8c21eec86e4d93812933a10e338149326f2aed970ce8c4554472069227fc330c480f4ca08aee48c1fb6976103dc2f46f0ab90a71cf642dfb61e3722f15885857b8bbcabd09df1181f5c234f3fbe61934bfc2ef18d628ff73068fd5b0964c78e0bf3b101e4f8d15e49e15e12fea403e4f40b951448d33928e0a08083822f0005a3ede16f1690352aac63e451bb31afb757b4daa0bd7f5da6f7afc4824bef6c140b771a88d709b5fe5251677df7823c258b3c9c719b5167237640e2e4b2c79fbd7d3332b2128b80de42d1a5566499bb5d1fe6ed5a338e03d7f49ffd6996a9bac5192ece008d47f761bbd3b7bd5d232b77d1d3d9f1a9aaef6eebd2d0920c7a3021278173894dc1dd5a0ea1f7ebbb9b71596f7725ce686d77ddae1f1e4542f71748dbae563b7c2e1e3e270f9e6bd75a783480d292670559f7f44db94ae7af2b36b64567bd482de0f0389d9028bf86edc77d5fb555bc93d43c2019b2dad90aeef0e99f41472da127e7ccae11230554286748fb37a887fc3d411ef926a40ca5fc1601f744fa20b927a8917fcfc3c178401ff7d3b8e067f0098dfbba2d303a08cf8476cf2cf42457b0414eedf1de905dbafadc9c3ad0b3ebb0700f91a636916f13990b8c9622cf123a14d874f209d9de37f340b29bb0cc466da0e88adaef11d766e7f251ddc336e8a8a08829f0aec74e8a02b787d8e7ad3cab829ef59dc801803eaec76350282646377bcfaaa347fd4cdce9014cd0c2ca3f1a0732bf855e87e2ae47431841413fb9600443a417ca758790ec3c10af099befb055a5bd6f5706d0cf06c0a8fb5a436f139b226e4318478bfc029d69bc4cef99fd5e9711d84f91773d6ec4240fc4d3ed73e376ff6a3cbae72e0b6099458c4af78834f5b0c76b535abf3b2f768f0ce51db5a83466c602cff1ee67f13f9a977e7ec1682e8a5156c06c0a47eb4e6e1c9cf580fcb0f7eddd1ee49fecebcfe7c59488e44b6900771a122489f71bf946516d4c6460f6b4ce1c6af332f064d96cbb58faa16dae274f70a6b205ca21f0aeffb06d2ecde600fd36356cd506a5ea0495ee0dc700eacafc599d3b223532c923fcfec7f3f1a93ac35199a3b83b2381c66720e6c2ae70f1da3e7fa65e1277ba99779969f72db12aed817b3680dc449a9a207061fbe125f0ed2a6cd51a8de5775ae8db93b098b22c6ff2c3ba6076ad0e75bc7785defeb8a0b6973f5fc7b87dc4fe15670f313b17c937aaa2728ca8252f89e1c0b7732865f86c22769f663bafb6c4a217efd119dd6745eb18f8d66def91b38bac971db3f05ca82d7484ebea10d4e379756fdbae5ec79305e89b4da87d666ce9bcda9e4c6494c256cd91970b44fa08b82d92547cb6a47bef5a478b2c0ef0bc896e8e885c0a395b96bb564d50b1896d771d6f7b4ca08a7bef310e2433ef2c89632406f41706dfba049e951b8049e6ac635828ad0174bc8f74bf92d8b715ce66c99eeadec8d905ae4d34b16454da15f4ed3a10ec1c16fa042d6c93bd638e63ae409279803bf26b471d4a768e4afb21f02d9ce99928833502ee138ed7411c0ef63abb0e45fd88802275524de75024e7e639025779e55909f9966161e6b0705be8c907e8afdf249a1616ceee6358e4c7b7585315ad1496bf21832cf665faf27c3cfdd5ee8bfcd7c9e3f851963ccaf2e753c7d95fa228cc84bb997cff4f53c7d9dd64224c04f9eb5247dcf0df9838ced8a37d977f9a38befb284f1c79e2f86f481cc7bbc25bce48f13c918d9a615c07815b04be7b8c1eaa38f4dde4d9916bd42a2992ac06a54af7eb3793ef9ad05fa981db7ee65734ba2e9eb9440f97e8e1123d5ca2874bf470891e2ed1c3257ab8440f97e8e1123d5ca2874bf470891e2ed1c3257ab8440f97e8e1123d5ca2874bf470891e2ed1c3257ab8440f97e8e1123d5ca2874bf470891e2ed1c3257ab8440f97e8f9d7dde4f99fff050000ffff010000ffff0c4572d83c802c00`))) diff --git a/vendor/knative.dev/kn-plugin-func/repositories.go b/vendor/knative.dev/kn-plugin-func/repositories.go index 4f9dee180c..a797fb1253 100644 --- a/vendor/knative.dev/kn-plugin-func/repositories.go +++ b/vendor/knative.dev/kn-plugin-func/repositories.go @@ -31,9 +31,16 @@ type Repositories struct { path string // Optional uri of a single repo to use in leau of embedded and extensible. + // Enables single-repository mode. This replaces the default embedded repo + // and extended repositories. This is an important mode for both diskless + // (config-less) operation, such as security-restrited environments, and for + // running as a library in which case environmental settings should be + // ignored in favor of a more functional approach in which only inputs affect + // outputs. remote string - // backreference to the client enabling full api access for the repo manager + // backreference to the client enabling this repositorires manager to + // have full API access. client *Client } @@ -42,32 +49,17 @@ type Repositories struct { // full client API during implementations. func newRepositories(client *Client) *Repositories { return &Repositories{ - path: DefaultRepositoriesPath, client: client, + path: client.repositoriesPath, + remote: client.repositoriesURI, } } -// SetPath to repositories under management. -func (r *Repositories) SetPath(path string) { - r.path = path -} - // Path returns the currently active repositories path under management. func (r *Repositories) Path() string { return r.path } -// SetRemote enables single-repository mode. -// Enables single-repository mode. This replaces the default embedded repo -// and extended repositories. This is an important mode for both diskless -// (config-less) operation, such as security-restrited environments, and for -// running as a library in which case environmental settings should be -// ignored in favor of a more functional approach in which only inputs affect -// outputs. -func (r *Repositories) SetRemote(uri string) { - r.remote = uri -} - // List all repositories the current configuration of the repo manager has // defined. func (r *Repositories) List() ([]string, error) { diff --git a/vendor/knative.dev/kn-plugin-func/repository.go b/vendor/knative.dev/kn-plugin-func/repository.go index d9500a91c6..92b75acb76 100644 --- a/vendor/knative.dev/kn-plugin-func/repository.go +++ b/vendor/knative.dev/kn-plugin-func/repository.go @@ -27,7 +27,7 @@ const ( // DefaultTemplatesPath is the root of the defined repository DefaultTemplatesPath = "." - // Defaults for Builder and Builders not expressly defined as a pourposeful + // Defaults for Builder and Builders not expressly defined as a purposeful // delegation of choice. ) @@ -57,6 +57,9 @@ type Repository struct { // HealthEndpoints for all templates in the repository. Serves as the // default option which may be overridden per runtime and per template. HealthEndpoints `yaml:"healthEndpoints,omitempty"` + // BuildEnvs define environment variables for builders that can be used + // to parameterize different builders + BuildEnvs []Env `yaml:"buildEnvs,omitempty"` // Runtimes containing Templates loaded from the repo Runtimes []Runtime // FS is the filesystem underlying the repository, loaded from URI @@ -72,13 +75,17 @@ type Repository struct { // and libraries) type Runtime struct { // Name of the runtime - Name string `yaml:"-"` // use filesysem for names + Name string `yaml:"-"` // use filesystem for names // HealthEndpoints for all templates in the runtime. May be overridden // per template. HealthEndpoints `yaml:"healthEndpoints,omitempty"` - // BuildConfig defines attriutes 'builders' and 'buildpacks'. Here it serves + // BuildEnvs for all the templates in the runtime. May be overridden + // per template. + BuildEnvs []Env `yaml:"buildEnvs,omitempty"` + + // BuildConfig defines attributes 'builders' and 'buildpacks'. Here it serves // as the default option which may be overridden per template. Note that // unlike HealthEndpoints, it is inline, so no 'buildConfig' attribute is // added/expected; rather the Buildpacks and Builders are direct descendants @@ -103,9 +110,9 @@ type BuildConfig struct { // NewRepository creates a repository instance from any of: a path on disk, a // remote or local URI, or from the embedded default repo if uri not provided. -// Name (optional), if provided takes precidence over name derived from repo at +// Name (optional), if provided takes precedence over name derived from repo at // the given URI. -// URI (optional), the path either locally or remote from which to load the +// URI (optional), the path either locally or remote from which to load // the repository files. If not provided, the internal default is assumed. func NewRepository(name, uri string) (r Repository, err error) { r = Repository{ @@ -136,7 +143,7 @@ func NewRepository(name, uri string) (r Repository, err error) { // filesystemFromURI returns a filesystem from the data located at the // given URI. If URI is not provided, indicates the embedded repo should -// be loaded. URI can be a remote git repository (http:// https:// etc), +// be loaded. URI can be a remote git repository (http:// https:// etc.), // or a local file path (file://) which can be a git repo or a plain directory. func filesystemFromURI(uri string) (f Filesystem, err error) { // If not provided, indicates embedded. @@ -144,7 +151,7 @@ func filesystemFromURI(uri string) (f Filesystem, err error) { return pkgerFilesystem{}, nil } - // Attempt to get a filesystm from the uri as a remote repo. + // Attempt to get a filesystem from the uri as a remote repo. f, err = filesystemFromRepo(uri) if f != nil || err != nil { return // found a filesystem and/or an error @@ -196,7 +203,7 @@ func filesystemFromPath(uri string) (f Filesystem, err error) { return osFilesystem{root: parsed.Path}, nil } -// repositoryRuntimes returns runtimes defined in this repository's filesytem. +// repositoryRuntimes returns runtimes defined in this repository's filesystem. // The views are denormalized, using the parent repository's values // for inherited fields BuildConfig and HealthEndpoints as the default values // for the runtimes and templates. The runtimes and templates themselves can @@ -232,10 +239,11 @@ func repositoryRuntimes(r Repository) (runtimes []Runtime, err error) { Name: fi.Name(), BuildConfig: r.BuildConfig, HealthEndpoints: r.HealthEndpoints, + BuildEnvs: r.BuildEnvs, } // Runtime Manifest // Load the file if it exists, which may override values inherited from the - // repo such as builders, buildpacks and health endponts. + // repo such as builders, buildpacks and health endpoints. runtime, err = applyRuntimeManifest(r, runtime) if err != nil { return @@ -284,6 +292,7 @@ func runtimeTemplates(r Repository, runtime Runtime) (templates []Template, err Runtime: runtime.Name, BuildConfig: runtime.BuildConfig, HealthEndpoints: runtime.HealthEndpoints, + BuildEnvs: runtime.BuildEnvs, } // Template Manifeset @@ -420,7 +429,7 @@ func (r *Repository) Runtime(name string) (runtime Runtime, err error) { func (r *Repository) Write(path string) error { // NOTE: Writing internal .git directory does not work // - // A quirk of the git library's implementation is that the filesytem + // A quirk of the git library's implementation is that the filesystem // returned does not include the .git directory. This is usually not an // issue when utilizing the repository's filesystem (for writing templates), // but it does cause problems here (used for installing a repo locally) where diff --git a/vendor/knative.dev/kn-plugin-func/ssh/ssh_dialer.go b/vendor/knative.dev/kn-plugin-func/ssh/ssh_dialer.go index 356a9d0171..0a334f747d 100644 --- a/vendor/knative.dev/kn-plugin-func/ssh/ssh_dialer.go +++ b/vendor/knative.dev/kn-plugin-func/ssh/ssh_dialer.go @@ -13,7 +13,6 @@ import ( urlPkg "net/url" "os" "path/filepath" - "runtime" "strings" "time" @@ -38,7 +37,32 @@ type Config struct { type DialContextFn = func(ctx context.Context, network, addr string) (net.Conn, error) -func NewDialContext(url *urlPkg.URL, config Config) (DialContextFn, string, error) { +// NewDialContext allows access to docker daemon in a remote machine using SSH. +// +// It creates a new ContextDialer which dials docker daemon in the remote +// and also returns Docker Host URI as seen by the remote. +// +// Knowing the Docker Host is useful when mounting docker socket into a container. +// +// Dialing the remote docker daemon can be done in two ways: +// +// - Use SSH to tunnel Unix/TCP socket. +// +// - Use SSH to execute the "docker system dial-stdio" command in the remote and forward its stdio. +// +// +// The tunnel method is used whenever possible. +// The "stdio" method is used as a fallback when tunneling is not possible: +// e.g. when remote uses Windows' named pipe. +// +// When tunneling is used all connection dialed +// by the returned ContextDialer are tunneled via single SSH connection. +// The connection should be disposed when dialer is no longer needed. +// +// For this reason returned ContextDialer may also implement io.Closer. +// Caller of this function should check if the returned ContextDialer +// is also an instance of io.Closer and call Close() on it if it is. +func NewDialContext(url *urlPkg.URL, config Config) (ContextDialer, string, error) { sshConfig, err := NewSSHClientConfig(url, config) if err != nil { return nil, "", err @@ -75,23 +99,17 @@ func NewDialContext(url *urlPkg.URL, config Config) (DialContextFn, string, erro return nil, "", err } - var dialContext DialContextFn - if network == "npipe" { // ssh tunneling doesn't support tunneling of Windows' named pipes - dialContext, err = stdioDialContext(url, sshClient, config.Identity) - return dialContext, remoteDockerHost, err + dialContext, err := stdioDialContext(url, sshClient, config.Identity) + return contextDialerFn(dialContext), remoteDockerHost, err } d := dialer{sshClient: sshClient, addr: addr, network: network} + // moving ownership of sshClient from this function to the returned structure sshClient = nil - dialContext = d.DialContext - - runtime.SetFinalizer(&d, func(d *dialer) { - d.Close() - }) - return dialContext, remoteDockerHost, nil + return &d, remoteDockerHost, nil } type dialer struct { @@ -100,6 +118,16 @@ type dialer struct { addr string } +type ContextDialer interface { + DialContext(ctx context.Context, network, address string) (net.Conn, error) +} + +type contextDialerFn DialContextFn + +func (n contextDialerFn) DialContext(ctx context.Context, network, address string) (net.Conn, error) { + return n(ctx, network, address) +} + func (d *dialer) DialContext(ctx context.Context, n, a string) (net.Conn, error) { conn, err := d.Dial(d.network, d.addr) if err != nil { diff --git a/vendor/knative.dev/kn-plugin-func/template.go b/vendor/knative.dev/kn-plugin-func/template.go index 1b5a14d3d7..d7cd481137 100644 --- a/vendor/knative.dev/kn-plugin-func/template.go +++ b/vendor/knative.dev/kn-plugin-func/template.go @@ -18,6 +18,9 @@ type Template struct { // HealthEndpoints. The denormalized view of members which can be defined // first per repo or per runtime. HealthEndpoints `yaml:"healthEndpoints,omitempty"` + // BuildEnvs defines environment variables related to the builders, + // this can be used to parameterize the builders + BuildEnvs []Env `yaml:"buildEnvs,omitempty"` } // Fullname is a calculated field of [repo]/[name] used diff --git a/vendor/knative.dev/kn-plugin-func/templates.go b/vendor/knative.dev/kn-plugin-func/templates.go index 08a038d901..59d3cf9063 100644 --- a/vendor/knative.dev/kn-plugin-func/templates.go +++ b/vendor/knative.dev/kn-plugin-func/templates.go @@ -7,6 +7,7 @@ package function import ( "errors" + "os" "path/filepath" "strings" @@ -96,11 +97,17 @@ func (t *Templates) Get(runtime, fullname string) (Template, error) { return repo.Template(runtime, tplName) } -// Write a template to disk for the given Function +// Write a function's template to disk. // Returns a Function which may have been modified dependent on the content // of the template (which can define default Function fields, builders, // buildpacks, etc) func (t *Templates) Write(f Function) (Function, error) { + // Templates require an initially valid Function to write + // (has name, path, runtime etc) + if err := f.Validate(); err != nil { + return f, err + } + // The Function's Template template, err := t.Get(f.Runtime, f.Template) if err != nil { @@ -132,7 +139,7 @@ func (t *Templates) Write(f Function) (Function, error) { // so it's values are treated as defaults. // TODO: this begs the question: should the Template's manifest.yaml actually // be a partially-populated func.yaml? - if f.Builder == "" { // as a special fist case, this default comes from itself + if f.Builder == "" { // as a special first case, this default comes from itself f.Builder = f.Builders["default"] if f.Builder == "" { // still nothing? then use the template f.Builder = template.Builders["default"] @@ -144,6 +151,9 @@ func (t *Templates) Write(f Function) (Function, error) { if len(f.Buildpacks) == 0 { f.Buildpacks = template.Buildpacks } + if len(f.BuildEnvs) == 0 { + f.BuildEnvs = template.BuildEnvs + } if f.HealthEndpoints.Liveness == "" { f.HealthEndpoints.Liveness = template.HealthEndpoints.Liveness } @@ -152,7 +162,11 @@ func (t *Templates) Write(f Function) (Function, error) { } // Copy the template files from the repo filesystem to the new Function's root - return f, copy(templatePath, f.Root, repo.FS) + // removing the manifest (if it exists; errors ignored) + err = copy(templatePath, f.Root, repo.FS) // copy everything + _ = os.Remove(filepath.Join(f.Root, templateManifest)) // except the manifest + + return f, err } // Embedding Directives diff --git a/vendor/modules.txt b/vendor/modules.txt index 24afc23937..1502c9582f 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -1,4 +1,4 @@ -# cloud.google.com/go v0.84.0 +# cloud.google.com/go v0.97.0 cloud.google.com/go/compute/metadata # contrib.go.opencensus.io/exporter/ocagent v0.7.1-0.20200907061046-05415f1de66d contrib.go.opencensus.io/exporter/ocagent @@ -29,10 +29,10 @@ github.com/BurntSushi/toml github.com/BurntSushi/toml/internal # github.com/Masterminds/semver v1.5.0 github.com/Masterminds/semver -# github.com/Microsoft/go-winio v0.5.0 +# github.com/Microsoft/go-winio v0.5.1 github.com/Microsoft/go-winio github.com/Microsoft/go-winio/pkg/guid -# github.com/Microsoft/hcsshim v0.8.16 +# github.com/Microsoft/hcsshim v0.8.21 github.com/Microsoft/hcsshim/osversion # github.com/ProtonMail/go-crypto v0.0.0-20210428141323-04723f9f07d7 github.com/ProtonMail/go-crypto/bitcurves @@ -63,6 +63,8 @@ github.com/acomagu/bufpipe github.com/apex/log # github.com/beorn7/perks v1.0.1 github.com/beorn7/perks/quantile +# github.com/bits-and-blooms/bitset v1.2.0 +github.com/bits-and-blooms/bitset # github.com/blendle/zapdriver v1.3.1 github.com/blendle/zapdriver # github.com/buildpacks/imgutil v0.0.0-20211001201950-cf7ae41c3771 @@ -140,11 +142,11 @@ github.com/cloudevents/sdk-go/v2/event/datacodec/xml github.com/cloudevents/sdk-go/v2/protocol github.com/cloudevents/sdk-go/v2/protocol/http github.com/cloudevents/sdk-go/v2/types -# github.com/containerd/containerd v1.5.2 +# github.com/containerd/containerd v1.5.7 github.com/containerd/containerd/errdefs github.com/containerd/containerd/log github.com/containerd/containerd/platforms -# github.com/containerd/stargz-snapshotter/estargz v0.7.0 +# github.com/containerd/stargz-snapshotter/estargz v0.9.0 github.com/containerd/stargz-snapshotter/estargz github.com/containerd/stargz-snapshotter/estargz/errorutil # github.com/containers/image/v5 v5.10.6 @@ -161,7 +163,9 @@ github.com/containers/storage/pkg/mount github.com/containers/storage/pkg/reexec github.com/containers/storage/pkg/system github.com/containers/storage/pkg/unshare -# github.com/cpuguy83/go-md2man/v2 v2.0.0 +# github.com/coreos/go-semver v0.3.0 +github.com/coreos/go-semver/semver +# github.com/cpuguy83/go-md2man/v2 v2.0.1 github.com/cpuguy83/go-md2man/v2/md2man # github.com/davecgh/go-spew v1.1.1 github.com/davecgh/go-spew/spew @@ -237,11 +241,11 @@ github.com/emirpasic/gods/trees/binaryheap github.com/emirpasic/gods/utils # github.com/evanphx/json-patch v4.9.0+incompatible github.com/evanphx/json-patch -# github.com/evanphx/json-patch/v5 v5.5.0 +# github.com/evanphx/json-patch/v5 v5.6.0 github.com/evanphx/json-patch/v5 # github.com/form3tech-oss/jwt-go v3.2.2+incompatible github.com/form3tech-oss/jwt-go -# github.com/fsnotify/fsnotify v1.4.9 +# github.com/fsnotify/fsnotify v1.5.1 github.com/fsnotify/fsnotify # github.com/gdamore/encoding v1.0.0 github.com/gdamore/encoding @@ -285,6 +289,8 @@ github.com/gdamore/tcell/v2/terminfo/x/xfce github.com/gdamore/tcell/v2/terminfo/x/xterm github.com/gdamore/tcell/v2/terminfo/x/xterm_kitty github.com/gdamore/tcell/v2/terminfo/x/xterm_termite +# github.com/ghodss/yaml v1.0.0 +github.com/ghodss/yaml # github.com/go-errors/errors v1.0.1 github.com/go-errors/errors # github.com/go-git/gcfg v1.5.0 @@ -347,7 +353,7 @@ github.com/go-kit/log github.com/go-kit/log/level # github.com/go-logfmt/logfmt v0.5.0 github.com/go-logfmt/logfmt -# github.com/go-logr/logr v0.4.0 +# github.com/go-logr/logr v1.2.0 github.com/go-logr/logr # github.com/go-openapi/jsonpointer v0.19.5 github.com/go-openapi/jsonpointer @@ -502,9 +508,11 @@ github.com/kballard/go-shellquote github.com/kelseyhightower/envconfig # github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351 github.com/kevinburke/ssh_config -# github.com/klauspost/compress v1.13.0 +# github.com/klauspost/compress v1.13.6 +github.com/klauspost/compress github.com/klauspost/compress/fse github.com/klauspost/compress/huff0 +github.com/klauspost/compress/internal/snapref github.com/klauspost/compress/zstd github.com/klauspost/compress/zstd/internal/xxhash # github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de @@ -525,9 +533,9 @@ github.com/markbates/pkger/pkging github.com/markbates/pkger/pkging/embed github.com/markbates/pkger/pkging/mem github.com/markbates/pkger/pkging/stdos -# github.com/mattn/go-colorable v0.1.8 +# github.com/mattn/go-colorable v0.1.11 github.com/mattn/go-colorable -# github.com/mattn/go-isatty v0.0.13 +# github.com/mattn/go-isatty v0.0.14 github.com/mattn/go-isatty # github.com/mattn/go-runewidth v0.0.10 github.com/mattn/go-runewidth @@ -547,8 +555,11 @@ github.com/mgutz/ansi github.com/mitchellh/go-homedir # github.com/mitchellh/ioprogress v0.0.0-20180201004757-6a23b12fa88e github.com/mitchellh/ioprogress -# github.com/mitchellh/mapstructure v1.4.1 +# github.com/mitchellh/mapstructure v1.4.2 github.com/mitchellh/mapstructure +# github.com/moby/spdystream v0.2.0 +github.com/moby/spdystream +github.com/moby/spdystream/spdy # github.com/moby/sys/mount v0.2.0 github.com/moby/sys/mount # github.com/moby/sys/mountinfo v0.4.1 @@ -566,14 +577,14 @@ github.com/monochromegane/go-gitignore github.com/morikuni/aec # github.com/opencontainers/go-digest v1.0.0 github.com/opencontainers/go-digest -# github.com/opencontainers/image-spec v1.0.2-0.20190823105129-775207bd45b6 +# github.com/opencontainers/image-spec v1.0.2-0.20210730191737-8e42a01fb1b7 github.com/opencontainers/image-spec/specs-go github.com/opencontainers/image-spec/specs-go/v1 -# github.com/opencontainers/runc v1.0.0-rc93 +# github.com/opencontainers/runc v1.0.2 github.com/opencontainers/runc/libcontainer/user -# github.com/opencontainers/runtime-spec v1.0.3-0.20200929063507-e6143ca7d51d +# github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417 github.com/opencontainers/runtime-spec/specs-go -# github.com/opencontainers/selinux v1.8.0 +# github.com/opencontainers/selinux v1.8.2 github.com/opencontainers/selinux/go-selinux github.com/opencontainers/selinux/go-selinux/label github.com/opencontainers/selinux/pkg/pwalk @@ -598,7 +609,7 @@ github.com/prometheus/client_golang/prometheus/internal github.com/prometheus/client_golang/prometheus/promhttp # github.com/prometheus/client_model v0.2.0 github.com/prometheus/client_model/go -# github.com/prometheus/common v0.30.0 +# github.com/prometheus/common v0.31.1 github.com/prometheus/common/expfmt github.com/prometheus/common/internal/bitbucket.org/ww/goautoneg github.com/prometheus/common/model @@ -632,7 +643,7 @@ github.com/sirupsen/logrus # github.com/spf13/afero v1.6.0 github.com/spf13/afero github.com/spf13/afero/mem -# github.com/spf13/cast v1.3.1 +# github.com/spf13/cast v1.4.1 github.com/spf13/cast # github.com/spf13/cobra v1.2.1 ## explicit @@ -643,9 +654,14 @@ github.com/spf13/jwalterweatherman # github.com/spf13/pflag v1.0.5 ## explicit github.com/spf13/pflag -# github.com/spf13/viper v1.8.1 +# github.com/spf13/viper v1.9.0 ## explicit github.com/spf13/viper +github.com/spf13/viper/internal/encoding +github.com/spf13/viper/internal/encoding/hcl +github.com/spf13/viper/internal/encoding/json +github.com/spf13/viper/internal/encoding/toml +github.com/spf13/viper/internal/encoding/yaml # github.com/src-d/gcfg v1.4.0 github.com/src-d/gcfg github.com/src-d/gcfg/scanner @@ -657,8 +673,12 @@ github.com/stretchr/testify/assert github.com/subosito/gotenv # github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635 github.com/syndtr/gocapability/capability -# github.com/willf/bitset v1.1.11 -github.com/willf/bitset +# github.com/thediveo/enumflag v0.10.0 +github.com/thediveo/enumflag +# github.com/vbatts/tar-split v0.11.2 +github.com/vbatts/tar-split/archive/tar +# github.com/wavesoftware/go-ensure v1.0.0 +github.com/wavesoftware/go-ensure # github.com/xanzy/ssh-agent v0.3.0 github.com/xanzy/ssh-agent # github.com/xlab/treeprint v0.0.0-20181112141820-a009c3971eca @@ -694,7 +714,7 @@ go.starlark.net/syntax go.uber.org/atomic # go.uber.org/multierr v1.6.0 go.uber.org/multierr -# go.uber.org/zap v1.19.0 +# go.uber.org/zap v1.19.1 go.uber.org/zap go.uber.org/zap/buffer go.uber.org/zap/internal/bufferpool @@ -729,7 +749,7 @@ golang.org/x/crypto/ssh/knownhosts golang.org/x/mod/internal/lazyregexp golang.org/x/mod/module golang.org/x/mod/semver -# golang.org/x/net v0.0.0-20210929193557-e81a3d93ecf6 +# golang.org/x/net v0.0.0-20211020060615-d418f374d309 golang.org/x/net/context golang.org/x/net/context/ctxhttp golang.org/x/net/http/httpguts @@ -741,7 +761,7 @@ golang.org/x/net/internal/socks golang.org/x/net/internal/timeseries golang.org/x/net/proxy golang.org/x/net/trace -# golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f +# golang.org/x/oauth2 v0.0.0-20211005180243-6b3c2da341f1 golang.org/x/oauth2 golang.org/x/oauth2/authhandler golang.org/x/oauth2/google @@ -752,7 +772,7 @@ golang.org/x/oauth2/jwt # golang.org/x/sync v0.0.0-20210220032951-036812b2e83c golang.org/x/sync/errgroup golang.org/x/sync/semaphore -# golang.org/x/sys v0.0.0-20211002104244-808efd93c36d +# golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359 golang.org/x/sys/cpu golang.org/x/sys/execabs golang.org/x/sys/internal/unsafeheader @@ -793,7 +813,7 @@ golang.org/x/xerrors golang.org/x/xerrors/internal # gomodules.xyz/jsonpatch/v2 v2.2.0 gomodules.xyz/jsonpatch/v2 -# google.golang.org/api v0.50.0 +# google.golang.org/api v0.58.0 google.golang.org/api/support/bundler # google.golang.org/appengine v1.6.7 google.golang.org/appengine @@ -806,11 +826,11 @@ google.golang.org/appengine/internal/modules google.golang.org/appengine/internal/remote_api google.golang.org/appengine/internal/urlfetch google.golang.org/appengine/urlfetch -# google.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84 +# google.golang.org/genproto v0.0.0-20211027162914-98a5263abeca google.golang.org/genproto/googleapis/api/httpbody google.golang.org/genproto/googleapis/rpc/status google.golang.org/genproto/protobuf/field_mask -# google.golang.org/grpc v1.40.0 +# google.golang.org/grpc v1.41.0 google.golang.org/grpc google.golang.org/grpc/attributes google.golang.org/grpc/backoff @@ -847,6 +867,7 @@ google.golang.org/grpc/internal/status google.golang.org/grpc/internal/syscall google.golang.org/grpc/internal/transport google.golang.org/grpc/internal/transport/networktype +google.golang.org/grpc/internal/xds/env google.golang.org/grpc/keepalive google.golang.org/grpc/metadata google.golang.org/grpc/peer @@ -892,7 +913,7 @@ google.golang.org/protobuf/types/known/timestamppb google.golang.org/protobuf/types/known/wrapperspb # gopkg.in/inf.v0 v0.9.1 gopkg.in/inf.v0 -# gopkg.in/ini.v1 v1.62.0 +# gopkg.in/ini.v1 v1.63.2 gopkg.in/ini.v1 # gopkg.in/src-d/go-billy.v4 v4.3.2 gopkg.in/src-d/go-billy.v4 @@ -1005,7 +1026,7 @@ k8s.io/api/storage/v1beta1 ## explicit k8s.io/apiextensions-apiserver/pkg/apis/apiextensions k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1 -# k8s.io/apimachinery v0.21.4 +# k8s.io/apimachinery v0.22.3 => k8s.io/apimachinery v0.21.4 ## explicit k8s.io/apimachinery/pkg/api/apitesting/fuzzer k8s.io/apimachinery/pkg/api/equality @@ -1039,6 +1060,8 @@ k8s.io/apimachinery/pkg/util/diff k8s.io/apimachinery/pkg/util/duration k8s.io/apimachinery/pkg/util/errors k8s.io/apimachinery/pkg/util/framer +k8s.io/apimachinery/pkg/util/httpstream +k8s.io/apimachinery/pkg/util/httpstream/spdy k8s.io/apimachinery/pkg/util/intstr k8s.io/apimachinery/pkg/util/json k8s.io/apimachinery/pkg/util/jsonmergepatch @@ -1046,6 +1069,8 @@ k8s.io/apimachinery/pkg/util/managedfields k8s.io/apimachinery/pkg/util/mergepatch k8s.io/apimachinery/pkg/util/naming k8s.io/apimachinery/pkg/util/net +k8s.io/apimachinery/pkg/util/rand +k8s.io/apimachinery/pkg/util/remotecommand k8s.io/apimachinery/pkg/util/runtime k8s.io/apimachinery/pkg/util/sets k8s.io/apimachinery/pkg/util/strategicpatch @@ -1057,6 +1082,7 @@ k8s.io/apimachinery/pkg/util/yaml k8s.io/apimachinery/pkg/version k8s.io/apimachinery/pkg/watch k8s.io/apimachinery/third_party/forked/golang/json +k8s.io/apimachinery/third_party/forked/golang/netutil k8s.io/apimachinery/third_party/forked/golang/reflect # k8s.io/cli-runtime v0.21.4 ## explicit @@ -1183,9 +1209,12 @@ k8s.io/client-go/tools/pager k8s.io/client-go/tools/record k8s.io/client-go/tools/record/util k8s.io/client-go/tools/reference +k8s.io/client-go/tools/remotecommand k8s.io/client-go/transport +k8s.io/client-go/transport/spdy k8s.io/client-go/util/cert k8s.io/client-go/util/connrotation +k8s.io/client-go/util/exec k8s.io/client-go/util/flowcontrol k8s.io/client-go/util/homedir k8s.io/client-go/util/jsonpath @@ -1240,7 +1269,7 @@ k8s.io/gengo/parser k8s.io/gengo/types # k8s.io/klog v1.0.0 k8s.io/klog -# k8s.io/klog/v2 v2.8.0 +# k8s.io/klog/v2 v2.30.0 k8s.io/klog/v2 # k8s.io/kube-openapi v0.0.0-20210305001622-591a79e4bda7 k8s.io/kube-openapi/cmd/openapi-gen/args @@ -1297,7 +1326,19 @@ knative.dev/eventing-kafka/pkg/common/constants # knative.dev/hack v0.0.0-20210806075220-815cd312d65c ## explicit knative.dev/hack -# knative.dev/kn-plugin-func v0.20.0 => github.com/openshift-knative/kn-plugin-func v0.19.1-0.20211111003512-0804607608c3 +# knative.dev/kn-plugin-event v0.26.0 => github.com/openshift-knative/kn-plugin-event v0.26.2-0.20211209202740-89c860ca5062 +## explicit +knative.dev/kn-plugin-event/internal/cli/cmd +knative.dev/kn-plugin-event/pkg/cli +knative.dev/kn-plugin-event/pkg/cli/ics +knative.dev/kn-plugin-event/pkg/cli/retcode +knative.dev/kn-plugin-event/pkg/configuration +knative.dev/kn-plugin-event/pkg/event +knative.dev/kn-plugin-event/pkg/k8s +knative.dev/kn-plugin-event/pkg/metadata +knative.dev/kn-plugin-event/pkg/plugin +knative.dev/kn-plugin-event/pkg/sender +# knative.dev/kn-plugin-func v0.20.0 => github.com/openshift-knative/kn-plugin-func v0.19.1-0.20211209011132-6e9942151b08 ## explicit knative.dev/kn-plugin-func knative.dev/kn-plugin-func/buildpacks @@ -1490,7 +1531,9 @@ sigs.k8s.io/structured-merge-diff/v4/fieldpath sigs.k8s.io/structured-merge-diff/v4/schema sigs.k8s.io/structured-merge-diff/v4/typed sigs.k8s.io/structured-merge-diff/v4/value -# sigs.k8s.io/yaml v1.2.0 +# sigs.k8s.io/yaml v1.3.0 ## explicit sigs.k8s.io/yaml -# knative.dev/kn-plugin-func => github.com/openshift-knative/kn-plugin-func v0.19.1-0.20211111003512-0804607608c3 +# k8s.io/apimachinery => k8s.io/apimachinery v0.21.4 +# knative.dev/kn-plugin-event => github.com/openshift-knative/kn-plugin-event v0.26.2-0.20211209202740-89c860ca5062 +# knative.dev/kn-plugin-func => github.com/openshift-knative/kn-plugin-func v0.19.1-0.20211209011132-6e9942151b08 diff --git a/vendor/sigs.k8s.io/yaml/.gitignore b/vendor/sigs.k8s.io/yaml/.gitignore index e256a31e00..2dc92904ef 100644 --- a/vendor/sigs.k8s.io/yaml/.gitignore +++ b/vendor/sigs.k8s.io/yaml/.gitignore @@ -6,6 +6,10 @@ .project .settings/** +# Idea files +.idea/** +.idea/ + # Emacs save files *~ diff --git a/vendor/sigs.k8s.io/yaml/.travis.yml b/vendor/sigs.k8s.io/yaml/.travis.yml index d20e23eff4..54ed8f9cb9 100644 --- a/vendor/sigs.k8s.io/yaml/.travis.yml +++ b/vendor/sigs.k8s.io/yaml/.travis.yml @@ -1,8 +1,7 @@ language: go -dist: xenial -go: - - 1.12.x - - 1.13.x +arch: arm64 +dist: focal +go: 1.15.x script: - diff -u <(echo -n) <(gofmt -d *.go) - diff -u <(echo -n) <(golint $(go list -e ./...) | grep -v YAMLToJSON) diff --git a/vendor/sigs.k8s.io/yaml/README.md b/vendor/sigs.k8s.io/yaml/README.md index 5a651d9163..e81cc426be 100644 --- a/vendor/sigs.k8s.io/yaml/README.md +++ b/vendor/sigs.k8s.io/yaml/README.md @@ -107,8 +107,8 @@ func main() { } fmt.Println(string(y)) /* Output: - name: John age: 30 + name: John */ j2, err := yaml.YAMLToJSON(y) if err != nil { diff --git a/vendor/sigs.k8s.io/yaml/go.mod b/vendor/sigs.k8s.io/yaml/go.mod index 7224f34971..818bbb5193 100644 --- a/vendor/sigs.k8s.io/yaml/go.mod +++ b/vendor/sigs.k8s.io/yaml/go.mod @@ -4,5 +4,5 @@ go 1.12 require ( github.com/davecgh/go-spew v1.1.1 - gopkg.in/yaml.v2 v2.2.8 + gopkg.in/yaml.v2 v2.4.0 ) diff --git a/vendor/sigs.k8s.io/yaml/go.sum b/vendor/sigs.k8s.io/yaml/go.sum index 76e49483af..b7b8cbb104 100644 --- a/vendor/sigs.k8s.io/yaml/go.sum +++ b/vendor/sigs.k8s.io/yaml/go.sum @@ -1,9 +1,6 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= -gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.7 h1:VUgggvou5XRW9mHwD/yXxIYSMtY0zoKQf/v226p2nyo= -gopkg.in/yaml.v2 v2.2.7/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10= -gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= From 9276b6bd3e69ba67f5f8dbd1d38b75d0382b2966 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Chris=20Suszy=C5=84ski?= Date: Thu, 9 Dec 2021 22:47:35 +0100 Subject: [PATCH 3/3] Adding override script for kn-plugin-event --- hack/build.sh.d/kn-plugin-event.sh | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 hack/build.sh.d/kn-plugin-event.sh diff --git a/hack/build.sh.d/kn-plugin-event.sh b/hack/build.sh.d/kn-plugin-event.sh new file mode 100644 index 0000000000..10aba0c779 --- /dev/null +++ b/hack/build.sh.d/kn-plugin-event.sh @@ -0,0 +1,10 @@ +#!/usr/bin/env bash + +knEventVersion="$(grep 'knative.dev/kn-plugin-event ' "$(basedir)/go.mod" \ + | head -n 1 \ + | sed -s 's/.* \(v.[\.0-9]*\).*/\1/')" +readonly upstream_sender_image='gcr.io/knative-releases/kn-event-sender@sha256:8d562077864d6490438ac5b35dd352c6ffa6cd089e81fa06aaf6fe56a0374196' +readonly sender_image="${KN_PLUGIN_EVENT_SENDER_IMAGE:-${upstream_sender_image}}" +export EXTERNAL_LD_FLAGS="${EXTERNAL_LD_FLAGS:-} \ +-X knative.dev/kn-plugin-event/pkg/metadata.Image=${sender_image} \ +-X knative.dev/kn-plugin-event/pkg/metadata.Version=${knEventVersion}" \ No newline at end of file